· 7 years ago · Oct 10, 2018, 04:52 PM
1/*
2
3 Remove the comments on the MARMA logs if you want to log the spawns to MARMA.
4
5 The _uid variable MUST be changed to a valid UID that already exists in the account table.
6
7 How it works -
8
9 On server init, the script will count AllMissionObjects (X) on a per vehicle basis listed in the array below. If there is less than the defined amount the server will spawn a persistent vehicle with a random pin number
10 UNLOCKED at the defined or random road position.
11
12 This script can be used to replace the standard EXILE world vehicle spawns, so that the vehicles that are spawned are persistent. Players will not know the pin number, but its still a "benefit" to them as the vehicle they find
13 is persistent. And hey, they might just guess the number..
14
15 This script accounts for ALL vehicles, purchased or other wise. So if players have bought vehicles, and those vehicles exceed the maximum defined number in tbe below array, the server wont spawn anymore.
16
17 Configure the _vehicleArray below
18 Adjust the safePos parameters line 132 - 138
19
20 Original by secondcoming and edited by El' Rabito
21 V0.8
22*/
23
24uiSleep 120;
25
26diag_log ["ExileServer - Spawning persistent vehicle spawns"];
27["ExileServer - Spawning world persistent vehicles"] call MAR_fnc_log;
28
29private ["_count","_uid","_debugForSP","_vehicle","_vehicleArray","_count","_vehicleClass","_position","_positionCount","_pinCode","_vehicleObject","_randomizeFuel","_fuel","_randomizeAmmo","_ammo","_nearVehicles","_nearVechicleCount","_marker","_cancelSpawn","_isRandomRoadPos","_road","_scriptComplete","_groundDamageChance","_groundMaximumDamage"];
30
31_scriptComplete = false;
32_debugForSP = false; // If true , when the script is run in the editor it will create markers on the vehicle spawns.
33
34_uid = "PersistentVehicle"; // Needs to be a valid UID that exists in the account table (best to use a server owners uid)
35
36
37_vehicleItemsAllowed = getNumber (configFile >> "CfgSettings" >> "VehicleSpawn" >> "vehicleItemsAllowed");
38_allowedItems = getArray (configFile >> "CfgSettings" >> "VehicleSpawn" >> "allowedItems");
39_maximumItemsPerVehicle = getNumber (configFile >> "CfgSettings" >> "VehicleSpawn" >> "maximumItemsPerVehicle");
40_maximumItemsPerVehicle = _maximumItemsPerVehicle +1;
41_groundDamageChance = getNumber (configFile >> "CfgSettings" >> "VehicleSpawn" >> "groundDamageChance");
42_groundMaximumDamage = getNumber (configFile >> "CfgSettings" >> "VehicleSpawn" >> "groundMaximumDamage");
43_randomizeFuel = ((getNumber(configFile >> "CfgSettings" >> "VehicleSpawn" >> "randomizeFuel")) isEqualTo 1);
44_fuel = (getNumber(configFile >> "CfgSettings" >> "VehicleSpawn" >> "fuel"));
45_randomizeAmmo = ((getNumber(configFile >> "CfgSettings" >> "VehicleSpawn" >> "randomizeAmmo")) isEqualTo 1);
46_ammo = (getNumber(configFile >> "CfgSettings" >> "VehicleSpawn" >> "ammo"));
47
48/*
49 How the vehicle array works -
50
51 Select 0 - Vehicle class name
52 Select 1 - Number - amount limit, will only maintain this many vehicles on the server
53 Select 2 - Array of positions EG [[0,0,0].[0,0,0]] - Will randomly select one of the positions per vehicle, if the position is occupied it will try for the other positions
54 Select 3 - Boolean - If true, will spawn the vehicle on a random road, if false, will look to the positions above.
55
56*/
57
58_vehicleArray =
59[
60 //TOTAL VEHICLE COUNT 100
61 //Cars&Trucks Civil
62 ["Exile_Car_Lada_Hipster",2,[],true],
63 ["Exile_Car_Lada_Green",2,[],true],
64 ["Lada_Civ_01",2,[],true],
65 ["volha_Civ_03",2,[],true],
66 ["Octavia_Civ_03",2,[],true],
67 ["Exile_Car_SUVXL_Black",2,[],true],
68 ["SUV_civ_04",2,[],true],
69 ["C_Offroad_01_F",2,[],true],
70 ["DDR_Car_MB4WDOpen",2,[],true],
71 ["C_Offroad_02_unarmed_F",2,[],true],
72 ["C_SUV_01_F",1,[],true],
73 ["Exile_Car_Golf_Black",1,[],true],
74 ["C_Hatchback_01_sport_F",2,[],true],
75 ["C_Hatchback_01_F",1,[],true],
76 ["Ikarus_Govnodav_01",2,[],true],
77 ["C_Van_01_box_F",2,[],true],
78 ["RHS_Ural_Open_Civ_01",1,[],true],
79 ["RHS_Ural_Civ_02",1,[],true],
80 ["Exile_Car_LandRover_Urban",2,[],true],
81 ["Exile_Car_LandRover_Green",2,[],true],
82 ["Exile_Car_LandRover_Ambulance_Green",2,[],true],
83 //Cars Miliary Low
84 ["rhssaf_un_uaz_open",3,[],true],
85 ["rhsgref_un_uaz",3,[],true],
86 ["rhsgref_nat_uaz",3,[],true],
87 ["rhsgref_cdf_b_reg_uaz_open",3,[],true],
88 ["rhsgref_cdf_b_reg_uaz",3,[],true],
89 ["B_G_Offroad_01_F",3,[],true],
90 ["O_G_Offroad_01_F",3,[],true],
91 //Cars Miliary High
92 ["rhsusf_m998_w_s_2dr_fulltop",1,[],true],
93 ["rhsusf_m1025_w_s",1,[],true],
94 ["rhsusf_m1025_w",1,[],true],
95 ["rhsusf_m998_w_4dr_halftop",1,[],true],
96 ["rhsusf_m998_w_4dr",1,[],true],
97 ["rhsgref_hidf_M998_4dr_halftop",1,[],true],
98 ["rhsgref_hidf_m998_4dr",1,[],true],
99 ["rhsgref_hidf_m1025",1,[],true],
100 ["rhsusf_rg33_usmc_wd",1,[],true],
101 ["rhsgref_BRDM2UM",1,[],true],
102 ["rhsgref_BRDM2UM_msv",1,[],true],
103 ["rhs_tigr_vdv",1,[],true],
104 ["rhs_tigr_3camo_vdv",1,[],true],
105 ["rhs_tigr_m_vdv",1,[],true],
106 ["rhs_tigr_m_3camo_vdv",1,[],true],
107 //Trucks Military
108 ["rhsgref_un_ural",1,[],true],
109 ["rhsusf_M977A4_usarmy_wd",1,[],true],
110 ["rhsusf_M1078A1P2_B_WD_CP_fmtv_usarmy",1,[],true],
111 ["rhsusf_M1084A1P2_WD_fmtv_usarmy",1,[],true],
112 ["rhsusf_M1083A1P2_WD_fmtv_usarmy",1,[],true],
113 ["rhsgref_cdf_b_ural_open",1,[],true],
114 ["rhsgref_cdf_b_ural",1,[],true],
115 ["rhsgref_cdf_b_gaz66o",1,[],true],
116 ["rhsgref_cdf_b_gaz66",1,[],true],
117 ["Exile_Car_Van_Guerilla07",1,[],true],
118 ["rhs_zil131_open_msv",1,[],true],
119 ["rhs_zil131_flatbed_cover_msv",1,[],true],
120 ["rhs_zil131_msv",1,[],true],
121 ["rhs_kamaz5350_msv",1,[],true],
122 ["rhs_kamaz5350_open_msv",1,[],true],
123 ["rhs_gaz66_vv",1,[],true],
124 ////RARE CARS
125 ["rhsusf_m113_usarmy_unarmed",1,[],true],
126 ["rhsusf_m113_usarmy",1,[],true],
127 ["rhsusf_m113_usarmy_M2_90",1,[],true],
128 ["rhsgref_BRDM2_HQ_b",1,[],true],
129 ["rhsusf_M1220_M2_usarmy_wd",1,[],true],
130 ["rhsusf_M1232_M2_usarmy_wd",1,[],true],
131 ["rhsusf_rg33_m2_usmc_wd",1,[],true],
132 ["rhsusf_M1078A1P2_B_M2_WD_fmtv_usarmy",1,[],true],
133 ["rhsusf_M1084A1P2_B_M2_WD_fmtv_usarmy",1,[],true],
134 ["rhsusf_M977A4_BKIT_M2_usarmy_wd",1,[],true],
135 ["I_G_Van_01_fuel_F",1,[],true],
136 ["rhsusf_M978A4_usarmy_wd",1,[],true],
137 ["rhsusf_M978A4_BKIT_usarmy_wd",1,[],true],
138 ["rhsgref_cdf_b_ural_fuel",1,[],true],
139 ["O_T_Truck_03_fuel_ghex_F",1,[],true],
140 //Choppers
141 ["Exile_Chopper_Hummingbird_Civillian_Digital",2,[[4523.42,15902.9,0.2],[10410.5,7689.42,5.2],[12780.1,15248,7.66596],[12013,17764.5,0.2],[5175.73,7472.54,0.31]],false],
142 ["rhs_uh1h_hidf",1,[[5374.08,2438.29,0.2],[14297.3,3877.02,0.2],[14911.6,3408.89,0.2],[4638.42,15213.1,0.2],[12068.3,17783.2,0.2]],false],
143 ["rhs_uh1h_un",2,[[10992.7,19182.6,0.2],[6861.06,16598.7,0.2],[4802.63,7638.69,0.2],[6827.55,1225.38,0.2],[4876.09,2617.99,0.2],[14064.9,4392.25,0.2]],false],
144 ["rhsgref_cdf_reg_Mi8amt",2,[[4873.65,15186.4,0.2],[4706.22,7609.3,0.2],[5286.79,2437.15,0.2],[14963.8,3430.19,0.2],[12207.3,17784.6,0.2],[12781.9,14786,0.2]],false],
145 ["rhs_ka60_grey",1,[[4758.32,7720.21,0.3],[4519.02,15899.8,0.3],[4890.88,15252.3,0.3],[12013.6,17764.2,0.3],[1981.91,5146.42,11.89],[14881.4,3382.72,0.3]],false],
146 ["RHS_MELB_H6M",1,[[14559.1,3562.25,0.2],[2149.51,5182.96,12.4779],[5882.86,17475,0.2],[1063.84,7677.47,0.2],[12287.2,6725.18,0.2],[3205.32,9302.31,0.2]],false]
147
148];
149
150KK_fnc_arrayShufflePlus = {
151 private ["_arr","_cnt"];
152 _arr = _this select 0;
153 _cnt = count _arr;
154 for "_i" from 1 to (_this select 1) do {
155 _arr pushBack (_arr deleteAt floor random _cnt);
156 };
157 _arr
158};
159
160
161{
162 for "_i" from 0 to (_x select 1) do
163 {
164 _cancelSpawn = false;
165 _obj = _x select 0;
166 _count = count allMissionObjects _obj;
167 _positionCount = (count (_x select 2));
168 _isRandomRoadPos = _x select 3;
169
170 if !(_count >= _x select 1) then
171 {
172 _vehicleClass = _x select 0;
173 _position = selectRandom ([_x select 2, 50] call KK_fnc_arrayShufflePlus);
174
175
176 if !(_isRandomRoadPos) then
177 {
178 _foundSafePos = false;
179 _failSafe = 15;
180 _checks = 0;
181 waitUntil
182 {
183 _position = selectRandom (_x select 2);
184 _nearVehicles = nearestObjects [_position, ["Car","Truck","Air","Tank"], 100];
185 _nearVechicleCount = count _nearVehicles;
186 if (_nearVechicleCount == 0) then
187 {
188 _foundSafePos = true;
189 };
190 _checks = _checks + 1;
191 if (_checks >= _failSafe) then {_cancelSpawn = true; _foundSafePos = true;};
192 _foundSafePos
193 };
194}
195 else
196 {
197 _foundSafePos = false;
198 waitUntil
199 {
200 _spawnCenter = getArray(configFile >> "CfgWorlds" >> worldName >> "centerPosition"); //Center of your map
201 _min = 15; // minimum distance from the center position (Number) in meters
202 _max = 10000; // maximum distance from the center position (Number) in meters
203 _mindist = 10; // minimum distance from the nearest object (Number) in meters, ie. spawn at least this distance away from anything within x meters..
204 _water = 0; // water mode 0: cannot be in water , 1: can either be in water or not , 2: must be in water
205 _shoremode = 0; // 0: does not have to be at a shore , 1: must be at a shore
206 _blackList = [[[0, 0],[0,0]]];
207
208 _startPosRoad = [_spawnCenter,_min,_max,_mindist,_water,10,_shoremode,_blackList] call BIS_fnc_findSafePos; //Find random spot on the map
209 _onRoadCheck = _startPosRoad nearRoads 200; //Find road objects 100m from spot
210 _countPossibleRoads = count _onRoadCheck; // count road objects
211
212 if (_countPossibleRoads == 0) then
213 {
214 }
215 else
216 {
217 _road = _onRoadCheck select 0;
218 _position = getPos _road;
219 _foundSafePos = true;
220 };
221 uiSleep 0.1;
222 _foundSafePos
223 };
224 };
225 if !(_cancelSpawn) then
226 {
227 if !(_debugForSP) then
228 {
229 _pinCode = format ["%1%2%3%4",round (random 8 +1),round (random 8 +1),round (random 8 +1),round (random 8 +1)];
230 _vehicleObject = [_vehicleClass, _position, (random 360), true,_pinCode] call ExileServer_object_vehicle_createPersistentVehicle;
231 _hitpointsData = getAllHitPointsDamage _vehicleobject;
232 _WDchance = floor random 11; //random number to determine whether or not to damage wheels
233
234 if !(_hitpointsData isEqualTo []) then {
235 _hitpoints = _hitpointsData select 0;{
236 if ((random 100) < _groundDamageChance) then{
237 _vehicleobject setHitPointDamage [_x, random _groundMaximumDamage];
238 };
239 }forEach _hitpoints;
240 };
241 if (_randomizeFuel) then
242 {
243 _vehicleobject setFuel (random _fuel);
244 }
245 else
246 {
247 _vehicleobject setFuel _fuel;
248 };
249 if (_randomizeAmmo) then
250 {
251 _vehicleobject setVehicleAmmo (random _ammo);
252 }
253 else
254 {
255 _vehicleobject setVehicleAmmo _ammo;
256 };
257 if (_WDchance == 0) then { _vehicleObject setHit ["wheel_1_1_steering", 1];}; // added for random damage chance.
258 if (_WDchance == 1) then
259 {
260 _vehicleObject setHit ["wheel_2_1_steering", 1];
261 _vehicleObject setHit ["wheel_2_2_steering", 1];
262 _vehicleObject setHit ["wheel_1_2_steering", 1];
263 _vehicleObject setHit ["wheel_1_1_steering", 1];
264 };
265 if (_WDchance == 2) then { _vehicleObject setHit ["wheel_1_2_steering", 1];};
266 if (_WDchance == 3) then { _vehicleObject setHit ["wheel_2_2_steering", 1];};
267 if (_WDchance == 4) then
268 {
269 _vehicleObject setHit ["wheel_2_1_steering", 1];
270 _vehicleObject setHit ["wheel_2_2_steering", 1];
271 _vehicleObject setHit ["wheel_1_2_steering", 1];
272 _vehicleObject setHit ["wheel_1_1_steering", 1];
273 };
274 if (_WDchance == 5) then { _vehicleObject setHit ["wheel_2_1_steering", 1];};
275 if (_WDchance == 6) then
276 {
277 _vehicleObject setHit ["wheel_1_2_steering", 1];
278 _vehicleObject setHit ["wheel_2_2_steering", 1];
279 };
280 if (_WDchance == 7) then { _vehicleObject setHit ["wheel_2_2_steering", 1];};
281 if (_WDchance == 8) then
282 {
283 _vehicleObject setHit ["wheel_2_1_steering", 1];
284 _vehicleObject setHit ["wheel_2_2_steering", 1];
285 _vehicleObject setHit ["wheel_1_2_steering", 0.9];
286 _vehicleObject setHit ["wheel_1_1_steering", 0.9];
287 };
288 if (_WDchance == 9) then
289 {
290 _vehicleObject setHit ["wheel_2_2_steering", 1];
291 _vehicleObject setHit ["wheel_2_2_steering", 1];
292 };
293 if (_WDchance == 10) then
294 {
295 _vehicleObject setHit ["wheel_2_1_steering", 1];
296 _vehicleObject setHit ["wheel_2_2_steering", 1];
297 _vehicleObject setHit ["wheel_1_2_steering", 1];
298 _vehicleObject setHit ["wheel_1_1_steering", 1];
299 };
300
301 _vehicleObject setVariable ["ExileOwnerUID", _uid];
302 _vehicleObject setVariable ["ExileIsLocked",0];
303 _vehicleObject lock 0;
304 _vehicleObject call ExileServer_object_vehicle_database_insert;
305 _vehicleObject call ExileServer_object_vehicle_database_update;
306 _vehicleObject enableSimulationGlobal true;
307
308 clearWeaponCargoGlobal _vehicleObject;
309 clearMagazineCargoGlobal _vehicleObject;
310 clearItemCargoGlobal _vehicleObject;
311 clearBackpackCargoGlobal _vehicleObject;
312
313 if (_vehicleItemsAllowed isEqualTo 1) then {
314 _itemsAdded = 0;
315 _itemsPerVehicle = floor (random _maximumItemsPerVehicle);
316 while{_itemsAdded < _itemsPerVehicle} do {
317 _itemAdd = _allowedItems select (floor (random (count _allowedItems)));
318 _cargoType = _itemAdd call ExileClient_util_cargo_getType;
319 switch (_cargoType) do {
320 case 1: { _vehicleObject addMagazineAmmoCargo [_itemAdd, 1, 1]; };
321 case 2: { _vehicleObject addWeaponCargoGlobal [_itemAdd, 1]; };
322 case 3: { _vehicleObject addBackpackCargoGlobal [_itemAdd, 1]; };
323 default { _vehicleObject addItemCargoGlobal [_itemAdd, 1, 1]; };
324 };
325 _itemsAdded = _itemsAdded + 1;
326 _vehicleObject call ExileServer_object_vehicle_database_update;
327 };
328 };
329 diag_log format ["[Event: Persistent Spawns] -- Spawned a %1 at location: %2 -- Max allowed: %3",_x select 0,_position, _x select 1];
330 //[format["[Event: Persistent Spawns] -- Spawned a %1 at location: %2 -- Max allowed: %3",_x select 0,_position, _x select 1]] call MAR_fnc_log;
331 }
332 else
333 {
334 _vehicleObject = createVehicle [_vehicleClass,_position,[], 0, "NONE"];
335 _hitpointsData = getAllHitPointsDamage _vehicleobject;
336 _WDchance = floor random 11; //random number to determine whether or not to damage wheels
337
338 if !(_hitpointsData isEqualTo []) then {
339 _hitpoints = _hitpointsData select 0;{
340 if ((random 100) < _groundDamageChance) then{
341 _vehicleobject setHitPointDamage [_x, random _groundMaximumDamage];
342 };
343 }forEach _hitpoints;
344 };
345 if (_randomizeFuel) then
346 {
347 _vehicleobject setFuel (random _fuel);
348 }
349 else
350 {
351 _vehicleobject setFuel _fuel;
352 };
353 if (_randomizeAmmo) then
354 {
355 _vehicleobject setVehicleAmmo (random _ammo);
356 }
357 else
358 {
359 _vehicleobject setVehicleAmmo _ammo;
360 };
361 if (_WDchance == 0) then { _vehicleObject setHit ["wheel_1_1_steering", 1];}; // added for random damage chance.
362 if (_WDchance == 1) then
363 {
364 _vehicleObject setHit ["wheel_2_1_steering", 1];
365 _vehicleObject setHit ["wheel_2_2_steering", 1];
366 _vehicleObject setHit ["wheel_1_2_steering", 1];
367 _vehicleObject setHit ["wheel_1_1_steering", 1];
368 };
369 if (_WDchance == 2) then { _vehicleObject setHit ["wheel_1_2_steering", 1];};
370 if (_WDchance == 3) then { _vehicleObject setHit ["wheel_2_2_steering", 1];};
371 if (_WDchance == 4) then
372 {
373 _vehicleObject setHit ["wheel_2_1_steering", 1];
374 _vehicleObject setHit ["wheel_2_2_steering", 1];
375 _vehicleObject setHit ["wheel_1_2_steering", 1];
376 _vehicleObject setHit ["wheel_1_1_steering", 1];
377 };
378 if (_WDchance == 5) then { _vehicleObject setHit ["wheel_2_1_steering", 1];};
379 if (_WDchance == 6) then
380 {
381 _vehicleObject setHit ["wheel_1_2_steering", 0.9];
382 _vehicleObject setHit ["wheel_2_2_steering", 0.8];
383 };
384 if (_WDchance == 7) then { _vehicleObject setHit ["wheel_2_2_steering", 1];};
385 if (_WDchance == 8) then
386 {
387 _vehicleObject setHit ["wheel_2_1_steering", 0.6];
388 _vehicleObject setHit ["wheel_2_2_steering", 0.6];
389 _vehicleObject setHit ["wheel_1_2_steering", 0.8];
390 _vehicleObject setHit ["wheel_1_1_steering", 0.8];
391 };
392 if (_WDchance == 9) then
393 {
394 _vehicleObject setHit ["wheel_2_2_steering", 1];
395 _vehicleObject setHit ["wheel_2_2_steering", 1];
396 };
397 if (_WDchance == 10) then
398 {
399 _vehicleObject setHit ["wheel_2_1_steering", 1];
400 _vehicleObject setHit ["wheel_2_2_steering", 1];
401 _vehicleObject setHit ["wheel_1_2_steering", 1];
402 _vehicleObject setHit ["wheel_1_1_steering", 1];
403 };
404
405 _vehicleObject enableSimulationGlobal true;
406 clearWeaponCargoGlobal _vehicleObject;
407 clearMagazineCargoGlobal _vehicleObject;
408 clearItemCargoGlobal _vehicleObject;
409 clearBackpackCargoGlobal _vehicleObject;
410
411 if (_vehicleItemsAllowed isEqualTo 1) then {
412 _itemsAdded = 0;
413 _itemsPerVehicle = floor (random _maximumItemsPerVehicle);
414 while{_itemsAdded < _itemsPerVehicle} do {
415 _itemAdd = _allowedItems select (floor (random (count _allowedItems)));
416 _cargoType = _itemAdd call ExileClient_util_cargo_getType;
417 switch (_cargoType) do {
418 case 1: { _vehicleObject addMagazineAmmoCargo [_itemAdd, 1, 1]; };
419 case 2: { _vehicleObject addWeaponCargoGlobal [_itemAdd, 1]; };
420 case 3: { _vehicleObject addBackpackCargoGlobal [_itemAdd, 1]; };
421 default { _vehicleObject addItemCargoGlobal [_itemAdd, 1, 1]; };
422 };
423 _itemsAdded = _itemsAdded + 1;
424 };
425 };
426 _marker = createMarker [format["HeliCrash%1", diag_tickTime], _position];
427 _marker setMarkerType "mil_dot";
428 _marker setMarkerText "Vehicle";
429 };
430 }
431 else
432 {
433 if !(_debugForSP) then
434 {
435 //[format["[Event: Persistent Spawns] -- Could not find valid spawn position for %1 at position %2 -- exiting try for this vehicle",_x select 0,_position]] call MAR_fnc_log;
436 diag_log format["[Event: Persistent Spawns] -- Could not find valid spawn position for %1 at position %2 -- exiting try for this vehicle",_x select 0,_position];
437 }
438 else
439 {
440 hint format["[Event: Persistent Spawns] -- Could not find valid spawn position for %1 at position %2 -- exiting try for this vehicle",_x select 0,_position];
441 };
442 };
443 };
444 };
445
446} forEach _vehicleArray;
447
448_scriptComplete = true;
449
450waitUntil
451{
452 diag_log format ["ExileServer - Finished spawning world vehicles"];
453 ["ExileServer - Finished spawning world vehicles"] call MAR_fnc_log;
454 _scriptComplete
455};