· 8 years ago · Jul 03, 2018, 01:54 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 30;
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
34LastPosition = [];
35
36_uid = "PersistentVehicle"; // Needs to be a valid UID that exists in the account table (best to use a server owners uid)
37
38
39_vehicleItemsAllowed = getNumber (configFile >> "CfgSettings" >> "VehicleSpawn" >> "vehicleItemsAllowed");
40_allowedItems = getArray (configFile >> "CfgSettings" >> "VehicleSpawn" >> "allowedItems");
41_maximumItemsPerVehicle = getNumber (configFile >> "CfgSettings" >> "VehicleSpawn" >> "maximumItemsPerVehicle");
42_maximumItemsPerVehicle = _maximumItemsPerVehicle +1;
43_groundDamageChance = getNumber (configFile >> "CfgSettings" >> "VehicleSpawn" >> "groundDamageChance");
44_groundMaximumDamage = getNumber (configFile >> "CfgSettings" >> "VehicleSpawn" >> "groundMaximumDamage");
45_randomizeFuel = ((getNumber(configFile >> "CfgSettings" >> "VehicleSpawn" >> "randomizeFuel")) isEqualTo 1);
46_fuel = (getNumber(configFile >> "CfgSettings" >> "VehicleSpawn" >> "fuel"));
47_randomizeAmmo = ((getNumber(configFile >> "CfgSettings" >> "VehicleSpawn" >> "randomizeAmmo")) isEqualTo 1);
48_ammo = (getNumber(configFile >> "CfgSettings" >> "VehicleSpawn" >> "ammo"));
49
50/*
51 How the vehicle array works -
52
53 Select 0 - Vehicle class name
54 Select 1 - Number - amount limit, will only maintain this many vehicles on the server
55 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
56 Select 3 - Boolean - If true, will spawn the vehicle on a random road, if false, will look to the positions above.
57
58*/
59
60_vehicleArray =
61[
62 //TOTAL VEHICLE COUNT 126
63 //Cars&Trucks Civil
64 ["Exile_Car_Lada_Hipster",3,[],true],
65 ["Exile_Car_Lada_Green",3,[],true],
66 ["Lada_Civ_01",3,[],true],
67 ["volha_Civ_03",3,[],true],
68 ["Octavia_Civ_03",3,[],true],
69 ["Exile_Car_SUVXL_Black",3,[],true],
70 ["SUV_civ_04",3,[],true],
71 ["C_Offroad_01_F",3,[],true],
72 ["DDR_Car_MB4WDOpen",3,[],true],
73 ["C_Offroad_02_unarmed_F",3,[],true],
74 ["C_SUV_01_F",3,[],true],
75 ["Exile_Car_Golf_Black",3,[],true],
76 ["C_Hatchback_01_sport_F",3,[],true],
77 ["C_Hatchback_01_F",3,[],true],
78 ["Ikarus_Govnodav_01",3,[],true],
79 ["C_Van_01_box_F",3,[],true],
80 ["C_Van_02_vehicle_F",3,[],true],
81 ["RHS_Ural_Open_Civ_01",3,[],true],
82 ["RHS_Ural_Civ_02",3,[],true],
83 ["Exile_Car_LandRover_Urban",3,[],true],
84 ["Exile_Car_LandRover_Green",3,[],true],
85 ["Exile_Car_LandRover_Ambulance_Green",3,[],true],
86 //Cars Miliary Low
87 ["rhssaf_un_uaz_open",2,[],true],
88 ["rhsgref_un_uaz",2,[],true],
89 ["UAZ_Base",2,[],true],
90 ["rhsgref_nat_uaz",2,[],true],
91 ["rhsgref_cdf_b_reg_uaz_open",2,[],true],
92 ["rhsgref_cdf_b_reg_uaz",2,[],true],
93 ["B_G_Offroad_01_F",2,[],true],
94 ["O_G_Offroad_01_F",2,[],true],
95 //Cars Miliary High
96 ["rhsusf_m998_w_s_2dr_fulltop",1,[],true],
97 ["rhsusf_m1025_w_s",1,[],true],
98 ["rhsusf_m1025_w",1,[],true],
99 ["rhsusf_m998_w_4dr_halftop",1,[],true],
100 ["rhsusf_m998_w_4dr_fulltop",1,[],true],
101 ["rhsusf_m998_w_4dr",1,[],true],
102 ["rhsgref_hidf_M998_4dr_halftop",1,[],true],
103 ["rhsgref_hidf_m998_4dr",1,[],true],
104 ["rhsgref_hidf_M998_4dr_fulltop",1,[],true],
105 ["rhsgref_hidf_m1025",1,[],true],
106 ["rhsusf_rg33_usmc_wd",1,[],true],
107 ["rhsgref_BRDM2UM",1,[],true],
108 ["rhsgref_BRDM2UM_msv",1,[],true],
109 ["rhs_tigr_m_3camo_vmf",1,[],true],
110 ["rhs_tigr_3camo_vdv",1,[],true],
111 ["rhs_tigr_m_vdv",1,[],true],
112 ["rhs_tigr_msv",1,[],true],
113 //Tanks Unarmed
114 ["rhsusf_m113_usarmy_unarmed",1,[],true],
115 //Cars Military Armed
116 ["rhsusf_rg33_m2_usmc_wd",1,[],true],
117 ["rhsgref_BRDM2_HQ",1,[],true],
118 ["rhsgref_BRDM2_HQ_msv",1,[],true],
119 ["rhs_tigr_sts_vdv",1,[],true],
120 ["rhsgref_ins_uaz_dshkm",1,[],true],
121 ["rhsusf_m1025_w_m2",1,[],true],
122 ["rhsusf_m1025_w_mk19",1,[],true],
123 ["Exile_Car_Offroad_Armed_Guerilla09",1,[],true],
124 //Trucks Military Armed
125 ["rhsusf_M1078A1P2_B_M2_WD_fmtv_usarmy",1,[],true],
126 ["rhsusf_M1078A1P2_B_M2_WD_flatbed_fmtv_usarmy",1,[],true],
127 //Trucks Military
128 ["rhsgref_un_ural",1,[],true],
129 ["rhsusf_M977A4_usarmy_wd",1,[],true],
130 ["rhsusf_M1078A1P2_B_WD_CP_fmtv_usarmy",1,[],true],
131 ["rhsusf_M1078A1P2_B_WD_fmtv_usarmy",1,[],true],
132 ["rhsusf_M1084A1P2_WD_fmtv_usarmy",1,[],true],
133 ["rhsusf_M1083A1P2_WD_fmtv_usarmy",1,[],true],
134 ["rhsgref_cdf_b_ural_open",2,[],true],
135 ["rhsgref_cdf_b_ural",1,[],true],
136 ["rhsgref_cdf_b_gaz66o",2,[],true],
137 ["rhsgref_cdf_b_gaz66_flat",1,[],true],
138 ["rhsgref_cdf_b_gaz66",1,[],true],
139 ["Exile_Car_Van_Guerilla07",1,[],true],
140 ["rhs_kamaz5350_msv",1,[],true],
141 ["rhs_kamaz5350_open_msv",1,[],true],
142 ["rhs_kamaz5350_flatbed_cover_msv",1,[],true],
143 ["rhs_gaz66_vv",1,[],true]
144 //Choppers
145 //["Exile_Chopper_Hellcat_Green",3,[[4802.56,10243.9,5.00714],[5059.92,2385.6,10.003],[12225.4,12604.1,-0.00332642]],false],
146 //["Exile_Chopper_Hummingbird_Green",4,[[4976.39,2407.29,5.00132],[4716.86,2590.72,13.6383],[12022.1,12797,5.12157],[12240.8,12590.1,0.00131226]],false]
147 //["Exile_Chopper_Mohawk_FIA",1,[[17550.5,13240.5,0],[26783.6,24673,0]],false],
148 //["Exile_Chopper_Orca_CSAT",1,[[3732.07,12976.3,20]],false]*/
149];
150
151{
152 for "_i" from 0 to (_x select 1) do
153 {
154 _cancelSpawn = false;
155 _obj = _x select 0;
156 _count = count allMissionObjects _obj;
157 _positionCount = (count (_x select 2));
158 _isRandomRoadPos = _x select 3;
159
160 if !(_count >= _x select 1) then
161 {
162 _vehicleClass = _x select 0;
163 _position = selectRandom (_x select 2);
164
165 if !(_isRandomRoadPos) then
166 {
167 _foundSafePos = false;
168 _failSafe = 15;
169 _checks = 0;
170 waitUntil
171 {
172 _position = selectRandom (_x select 2);
173 _nearVehicles = count (nearestObjects [_position, ["LandVehicle","Air"], 500]);
174 if (_nearVechicles == 0) then
175 {
176 _foundSafePos = true;
177 };
178 _checks = _checks + 1;
179 if (_checks >= _failSafe) then {_cancelSpawn = true; _foundSafePos = true;};
180 _foundSafePos
181 };
182 }
183 else
184 {
185 _foundSafePos = false;
186 waitUntil
187 {
188 _spawnCenter = getArray(configFile >> "CfgWorlds" >> worldName >> "centerPosition"); //Center of your map
189 _min = 15; // minimum distance from the center position (Number) in meters
190 _max = 16000; // maximum distance from the center position (Number) in meters
191 _mindist = 10; // minimum distance from the nearest object (Number) in meters, ie. spawn at least this distance away from anything within x meters..
192 _water = 0; // water mode 0: cannot be in water , 1: can either be in water or not , 2: must be in water
193 _shoremode = 0; // 0: does not have to be at a shore , 1: must be at a shore
194 _blackList = [[[0, 0],[0,0]]];
195
196 _startPosRoad = [_spawnCenter,_min,_max,_mindist,_water,10,_shoremode,_blackList] call BIS_fnc_findSafePos; //Find random spot on the map
197 _onRoadCheck = _startPosRoad nearRoads 100; //Find road objects 100m from spot
198 _countPossibleRoads = count _onRoadCheck; // count road objects
199
200 if (_countPossibleRoads == 0) then
201 {
202 }
203 else
204 {
205 _road = _onRoadCheck select 0;
206 _position = getPos _road;
207 _foundSafePos = true;
208 };
209 uiSleep 0.1;
210 _foundSafePos
211 };
212 };
213 if !(_cancelSpawn) then
214 {
215 if !(_debugForSP) then
216 {
217 _pinCode = format ["%1%2%3%4",round (random 8 +1),round (random 8 +1),round (random 8 +1),round (random 8 +1)];
218 _vehicleObject = [_vehicleClass, _position, (random 360), true,_pinCode] call ExileServer_object_vehicle_createPersistentVehicle;
219 _hitpointsData = getAllHitPointsDamage _vehicleobject;
220 _WDchance = floor random 11; //random number to determine whether or not to damage wheels
221
222 if !(_hitpointsData isEqualTo []) then {
223 _hitpoints = _hitpointsData select 0;{
224 if ((random 100) < _groundDamageChance) then{
225 _vehicleobject setHitPointDamage [_x, random _groundMaximumDamage];
226 };
227 }forEach _hitpoints;
228 };
229 if (_randomizeFuel) then
230 {
231 _vehicleobject setFuel (random _fuel);
232 }
233 else
234 {
235 _vehicleobject setFuel _fuel;
236 };
237 if (_randomizeAmmo) then
238 {
239 _vehicleobject setVehicleAmmo (random _ammo);
240 }
241 else
242 {
243 _vehicleobject setVehicleAmmo _ammo;
244 };
245 if (_WDchance == 0) then { _vehicleObject setHit ["wheel_1_1_steering", 1];}; // added for random damage chance.
246 if (_WDchance == 1) then
247 {
248 _vehicleObject setHit ["wheel_2_1_steering", 1];
249 _vehicleObject setHit ["wheel_2_2_steering", 1];
250 _vehicleObject setHit ["wheel_1_2_steering", 1];
251 _vehicleObject setHit ["wheel_1_1_steering", 1];
252 };
253 if (_WDchance == 2) then { _vehicleObject setHit ["wheel_1_2_steering", 0.6];};
254 if (_WDchance == 3) then { _vehicleObject setHit ["wheel_2_2_steering", 1];};
255 if (_WDchance == 4) then
256 {
257 _vehicleObject setHit ["wheel_2_1_steering", 1];
258 _vehicleObject setHit ["wheel_2_2_steering", 1];
259 _vehicleObject setHit ["wheel_1_2_steering", 1];
260 _vehicleObject setHit ["wheel_1_1_steering", 1];
261 };
262 if (_WDchance == 5) then { _vehicleObject setHit ["wheel_2_1_steering", 1];};
263 if (_WDchance == 6) then
264 {
265 _vehicleObject setHit ["wheel_1_2_steering", 1];
266 _vehicleObject setHit ["wheel_2_2_steering", 1];
267 };
268 if (_WDchance == 7) then { _vehicleObject setHit ["wheel_2_2_steering", 1];};
269 if (_WDchance == 8) then
270 {
271 _vehicleObject setHit ["wheel_2_1_steering", 1];
272 _vehicleObject setHit ["wheel_2_2_steering", 1];
273 _vehicleObject setHit ["wheel_1_2_steering", 1];
274 _vehicleObject setHit ["wheel_1_1_steering", 1];
275 };
276 if (_WDchance == 9) then
277 {
278 _vehicleObject setHit ["wheel_2_2_steering", 1];
279 _vehicleObject setHit ["wheel_2_2_steering", 1];
280 };
281 if (_WDchance == 10) 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", 1];
286 _vehicleObject setHit ["wheel_1_1_steering", 1];
287 };
288
289 _vehicleObject setVariable ["ExileOwnerUID", _uid];
290 _vehicleObject setVariable ["ExileIsLocked",0];
291 _vehicleObject lock 0;
292 _vehicleObject call ExileServer_object_vehicle_database_insert;
293 _vehicleObject call ExileServer_object_vehicle_database_update;
294 _vehicleObject enableSimulationGlobal True;
295
296 clearWeaponCargoGlobal _vehicleObject;
297 clearMagazineCargoGlobal _vehicleObject;
298 clearItemCargoGlobal _vehicleObject;
299 clearBackpackCargoGlobal _vehicleObject;
300
301 if (_vehicleItemsAllowed isEqualTo 1) then {
302 _itemsAdded = 0;
303 _itemsPerVehicle = floor (random _maximumItemsPerVehicle);
304 while{_itemsAdded < _itemsPerVehicle} do {
305 _itemAdd = _allowedItems select (floor (random (count _allowedItems)));
306 _cargoType = _itemAdd call ExileClient_util_cargo_getType;
307 switch (_cargoType) do {
308 case 1: { _vehicleObject addMagazineAmmoCargo [_itemAdd, 1, 1]; };
309 case 2: { _vehicleObject addWeaponCargoGlobal [_itemAdd, 1]; };
310 case 3: { _vehicleObject addBackpackCargoGlobal [_itemAdd, 1]; };
311 default { _vehicleObject addItemCargoGlobal [_itemAdd, 1, 1]; };
312 };
313 _itemsAdded = _itemsAdded + 1;
314 _vehicleObject call ExileServer_object_vehicle_database_update;
315 };
316 };
317 diag_log format ["[Event: Persistent Spawns] -- Spawned a %1 at location: %2 -- Max allowed: %3",_x select 0,_position, _x select 1];
318 //[format["[Event: Persistent Spawns] -- Spawned a %1 at location: %2 -- Max allowed: %3",_x select 0,_position, _x select 1]] call MAR_fnc_log;
319 }
320 else
321 {
322 _vehicleObject = createVehicle [_vehicleClass,_position,[], 0, "NONE"];
323 _hitpointsData = getAllHitPointsDamage _vehicleobject;
324 _WDchance = floor random 11; //random number to determine whether or not to damage wheels
325
326 if !(_hitpointsData isEqualTo []) then {
327 _hitpoints = _hitpointsData select 0;{
328 if ((random 100) < _groundDamageChance) then{
329 _vehicleobject setHitPointDamage [_x, random _groundMaximumDamage];
330 };
331 }forEach _hitpoints;
332 };
333 if (_randomizeFuel) then
334 {
335 _vehicleobject setFuel (random _fuel);
336 }
337 else
338 {
339 _vehicleobject setFuel _fuel;
340 };
341 if (_randomizeAmmo) then
342 {
343 _vehicleobject setVehicleAmmo (random _ammo);
344 }
345 else
346 {
347 _vehicleobject setVehicleAmmo _ammo;
348 };
349 if (_WDchance == 0) then { _vehicleObject setHit ["wheel_1_1_steering", 1];}; // added for random damage chance.
350 if (_WDchance == 1) then
351 {
352 _vehicleObject setHit ["wheel_2_1_steering", 1];
353 _vehicleObject setHit ["wheel_2_2_steering", 1];
354 _vehicleObject setHit ["wheel_1_2_steering", 1];
355 _vehicleObject setHit ["wheel_1_1_steering", 1];
356 };
357 if (_WDchance == 2) then { _vehicleObject setHit ["wheel_1_2_steering", 0.6];};
358 if (_WDchance == 3) then { _vehicleObject setHit ["wheel_2_2_steering", 1];};
359 if (_WDchance == 4) then
360 {
361 _vehicleObject setHit ["wheel_2_1_steering", 1];
362 _vehicleObject setHit ["wheel_2_2_steering", 1];
363 _vehicleObject setHit ["wheel_1_2_steering", 1];
364 _vehicleObject setHit ["wheel_1_1_steering", 1];
365 };
366 if (_WDchance == 5) then { _vehicleObject setHit ["wheel_2_1_steering", 1];};
367 if (_WDchance == 6) then
368 {
369 _vehicleObject setHit ["wheel_1_2_steering", 1];
370 _vehicleObject setHit ["wheel_2_2_steering", 1];
371 };
372 if (_WDchance == 7) then { _vehicleObject setHit ["wheel_2_2_steering", 1];};
373 if (_WDchance == 8) then
374 {
375 _vehicleObject setHit ["wheel_2_1_steering", 1];
376 _vehicleObject setHit ["wheel_2_2_steering", 1];
377 _vehicleObject setHit ["wheel_1_2_steering", 1];
378 _vehicleObject setHit ["wheel_1_1_steering", 1];
379 };
380 if (_WDchance == 9) then
381 {
382 _vehicleObject setHit ["wheel_2_2_steering", 1];
383 _vehicleObject setHit ["wheel_2_2_steering", 1];
384 };
385 if (_WDchance == 10) then
386 {
387 _vehicleObject setHit ["wheel_2_1_steering", 1];
388 _vehicleObject setHit ["wheel_2_2_steering", 1];
389 _vehicleObject setHit ["wheel_1_2_steering", 1];
390 _vehicleObject setHit ["wheel_1_1_steering", 1];
391 };
392
393 _vehicleObject enableSimulationGlobal True;
394 clearWeaponCargoGlobal _vehicleObject;
395 clearMagazineCargoGlobal _vehicleObject;
396 clearItemCargoGlobal _vehicleObject;
397 clearBackpackCargoGlobal _vehicleObject;
398
399 if (_vehicleItemsAllowed isEqualTo 1) then {
400 _itemsAdded = 0;
401 _itemsPerVehicle = floor (random _maximumItemsPerVehicle);
402 while{_itemsAdded < _itemsPerVehicle} do {
403 _itemAdd = _allowedItems select (floor (random (count _allowedItems)));
404 _cargoType = _itemAdd call ExileClient_util_cargo_getType;
405 switch (_cargoType) do {
406 case 1: { _vehicleObject addMagazineAmmoCargo [_itemAdd, 1, 1]; };
407 case 2: { _vehicleObject addWeaponCargoGlobal [_itemAdd, 1]; };
408 case 3: { _vehicleObject addBackpackCargoGlobal [_itemAdd, 1]; };
409 default { _vehicleObject addItemCargoGlobal [_itemAdd, 1, 1]; };
410 };
411 _itemsAdded = _itemsAdded + 1;
412 };
413 };
414 _marker = createMarker [format["HeliCrash%1", diag_tickTime], _position];
415 _marker setMarkerType "mil_dot";
416 _marker setMarkerText "Vehicle";
417 };
418 }
419 else
420 {
421 if !(_debugForSP) then
422 {
423 //[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;
424 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];
425 }
426 else
427 {
428 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];
429 };
430 };
431 };
432 };
433
434} forEach _vehicleArray;
435
436_scriptComplete = true;
437
438waitUntil
439{
440 diag_log format ["ExileServer - Finished spawning world vehicles"];
441 //["ExileServer - Finished spawning world vehicles"] call MAR_fnc_log;
442 _scriptComplete
443};