-
Notifications
You must be signed in to change notification settings - Fork 185
/
fn_resupplyTruck.sqf
410 lines (319 loc) · 10.6 KB
/
fn_resupplyTruck.sqf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
// ******************************************************************************************
// * This project is licensed under the GNU Affero GPL v3. Copyright © 2016 A3Wasteland.com *
// ******************************************************************************************
// @file Name: fn_resupplyTruck.sqf
// @file Author: Wiking, AgentRev, micovery
#define RESUPPLY_TRUCK_DISTANCE (10 max (sizeOf typeOf _vehicle * 0.75)) // this must match the addAction condition in fn_setupResupplyTruck.sqf
#define REARM_TIME_SLICE 5
#define REPAIR_TIME_SLICE 1
#define REFUEL_TIME_SLICE 1
#define PRICE_RELATIONSHIP 4 // resupply price = brand-new store price divided by PRICE_RELATIONSHIP
#define RESUPPLY_TIMEOUT 30
// Check if mutex lock is active.
if (mutexScriptInProgress) exitWith {
titleText ["You are already performing another action.", "PLAIN DOWN", 0.5];
};
mutexScriptInProgress = true;
doCancelAction = false;
params ["", ["_unit",objNull,[objNull]]];
_vehicle = vehicle _unit;
//check if caller is in vehicle
if (_vehicle == _unit) exitWith {};
_resupplyThread = [_vehicle, _unit] spawn
{
params ["_vehicle", "_unit"];
_vehClass = typeOf _vehicle;
_vehCfg = configFile >> "CfgVehicles" >> _vehClass;
_vehName = getText (_vehCfg >> "displayName");
_isUAV = (round getNumber (_vehCfg >> "isUav") >= 1);
_isStaticWep = _vehClass isKindOf "StaticWeapon";
scopeName "resupplyTruckThread";
_price = 1000; // price = 1000 for vehicles not found in vehicle store
_variant = _vehicle getVariable ["A3W_vehicleVariant", ""];
if (_variant != "") then { _variant = "variant_" + _variant };
{
if (_vehClass == _x select 1 && (_variant == "" || {_variant in _x})) exitWith
{
_price = _x select 2;
_price = round (_price / PRICE_RELATIONSHIP);
};
} forEach (call allVehStoreVehicles + call staticGunsArray);
_titleText = { titleText [_this, "PLAIN DOWN", ((REARM_TIME_SLICE max 1) / 10) max 0.3] };
_checkAbortConditions =
{
private _abortText = "";
private _pauseText = "";
private "_checkCondition";
call
{
if (doCancelAction) exitWith
{
doCancelAction = false;
_abortText = "Cancelled by player.";
};
if (!alive player) exitWith
{
_abortText = "You have been killed.";
};
// Abort if vehicle is no longer local, otherwise commands won't do anything
_checkCondition = {!local _vehicle};
if (call _checkCondition) exitWith
{
_pauseText = "Take back control of the vehicle.";
_abortText = "Another player took control of the vehicle.";
};
// Abort if vehicle is destroyed
_checkCondition = {!alive _vehicle};
if (call _checkCondition) exitWith
{
_abortText = "The vehicle has been destroyed.";
};
// Abort if no resupply vehicle in proximity
_checkCondition = {{alive _x && {_x getVariable ["A3W_resupplyTruck", false]}} count (_vehicle nearEntities ["AllVehicles", RESUPPLY_TRUCK_DISTANCE]) == 0};
if (call _checkCondition) exitWith
{
_pauseText = "Move closer to a resupply vehicle.";
_abortText = "Too far from resupply vehicle.";
};
// Abort if player gets out of vehicle
_checkCondition = {vehicle _unit != _vehicle};
if (!_isUAV && !_isStaticWep && _checkCondition) exitWith
{
_pauseText = "Get back in the vehicle.";
_abortText = "You are not in the vehicle.";
};
// Abort if someone gets in the gunner seat
_checkCondition = {alive gunner _vehicle};
if (!_isUAV && _checkCondition) exitWith
{
_pauseText = "The gunner seat must be empty.";
_abortText = "Someone is in the gunner seat.";
};
};
if (_pauseText != "") then
{
private "_i";
for [{_i = RESUPPLY_TIMEOUT}, {_i > 0 && _checkCondition && !doCancelAction}, {_i = _i - 1}] do
{
_vehicle setVariable ["A3W_resupplyTruckTimeout", true];
titleText [format ["%1\n%2", _pauseText, format ["Resupply sequence timeout in %1", _i]], "PLAIN DOWN", 0.5];
sleep 1;
};
_vehicle setVariable ["A3W_resupplyTruckTimeout", nil];
if !(call _checkCondition) then
{
_abortText = "";
titleText ["", "PLAIN DOWN", 0.5];
};
if (doCancelAction) then
{
_abortText = "Cancelled by player.";
};
};
if (_abortText != "") then
{
titleText [format ["%1\n%2", _abortText, "Resupply sequence aborted"], "PLAIN DOWN", 0.5];
breakTo "resupplyTruckThread";
};
};
// Check if player has enough money
_checkPlayerMoney =
{
if (player getVariable ["cmoney",0] < _price) then
{
_text = format ["%1\n%2", format ["Not enough money, you need $%1 to resupply %2", _price, _vehName], "Resupply sequence aborted"];
[_text, 10] call mf_notify_client;
breakTo "resupplyTruckThread";
};
};
call
{
if (_isStaticWep) then
{
_text = format ["%1\n%2", "Resupply sequence started", "Please get out of the static weapon."];
titleText [_text, "PLAIN DOWN", 0.5];
sleep 5;
call _checkAbortConditions;
};
call _checkPlayerMoney;
call _checkAbortConditions;
_vehicle setVariable ["A3W_truckResupplyEngineEH", _vehicle addEventHandler ["Engine",
{
params ["_vehicle", "_started"];
(_vehicle getVariable "A3W_truckResupplyThread") params [["_resupplyThread", scriptNull, [scriptNull]]];
if (_started && !scriptDone _resupplyThread && !(_vehicle getVariable ["A3W_resupplyTruckTimeout", false])) then
{
_vehicle engineOn false;
};
}]];
_vehicle engineOn false;
if (player getVariable ["cmoney",0] >= _price) then
{
_msg = format ["%1<br/><br/>%2", format ["It will cost you $%1 to resupply %2.", _price, _vehName], "Do you want to proceed?"];
if !([_msg, "Resupply Vehicle", true, true] call BIS_fnc_guiMessage) then
{
breakTo "resupplyTruckThread";
};
};
call _checkAbortConditions;
call _checkPlayerMoney;
//start resupply here
player setVariable ["cmoney", (player getVariable ["cmoney",0]) - _price, true];
_text = format ["%1\n%2", format ["You paid $%1 to resupply %2.", _price, _vehName], "Please stand by..."];
[_text, 10] call mf_notify_client;
[] spawn fn_savePlayerData;
call _checkAbortConditions;
private _pathArrs = [];
// Collect turret mag data
{
_x params ["_mag", "_path", "_ammo"];
if (_mag != "FakeWeapon" && _mag select [0,5] != "Pylon") then
{
_pathArr = [_pathArrs, _path] call fn_getFromPairs;
_new = isNil "_pathArr";
if (_new) then { _pathArr = [] };
_index = [_pathArr, _mag, 1] call fn_addToPairs;
if (_ammo < getNumber (configFile >> "CfgMagazines" >> _mag >> "count")) then
{
(_pathArr select _index) set [2, true]; // mark mag for reload
};
if (_new) then { _pathArrs pushBack [_path, _pathArr] };
};
} forEach magazinesAllTurrets _vehicle;
_checkDone = true;
// Reload turret mags
{
_x params ["_path", "_magPairs"];
{
_x params ["_mag", "_qty", ["_notFull", false]];
if (_notFull) then
{
if (_checkDone) then
{
_checkDone = false;
sleep 3;
};
call _checkAbortConditions;
_magName = getText (configFile >> "CfgMagazines" >> _mag >> "displayName");
_text = format ["Reloading %1...", [_vehName, _magName] select (_magName != "")];
_text call _titleText;
sleep (REARM_TIME_SLICE / 2);
call _checkAbortConditions;
if (_qty isEqualTo 1) then
{
_vehicle setMagazineTurretAmmo [_mag, getNumber (configFile >> "CfgMagazines" >> _mag >> "count"), _path];
}
else
{
_vehicle removeMagazinesTurret [_mag, _path];
private "_i";
for "_i" from 1 to _qty do
{
_vehicle addMagazineTurret [_mag, _path];
};
};
sleep (REARM_TIME_SLICE / 2);
};
} forEach _magPairs;
} forEach _pathArrs;
_pylonPaths = (configProperties [_vehCfg >> "Components" >> "TransportPylonsComponent" >> "Pylons", "isClass _x"]) apply {getArray (_x >> "turret")};
{
if (_x != "") then
{
_magCfg = configFile >> "CfgMagazines" >> _x;
if (_vehicle ammoOnPylon (_forEachIndex + 1) < getNumber (_magCfg >> "count")) then
{
call _checkAbortConditions;
_text = format ["Reloading %1...", getText (_magCfg >> "displayName")];
_text call _titleText;
sleep (REARM_TIME_SLICE / 2);
call _checkAbortConditions;
_vehicle setPylonLoadOut [_forEachIndex + 1, _x, true, _pylonPaths select _forEachIndex];
sleep (REARM_TIME_SLICE / 2);
};
};
} forEach getPylonMagazines _vehicle;
[_vehicle, false, true, true] call A3W_fnc_setVehicleLoadout;
_checkDone = true;
(getAllHitPointsDamage _vehicle) params ["_hitPoints", "_selections", "_dmgValues"];
if (!isNil "_hitPoints") then
{
_repairSlice = if (count _hitPoints > 0) then { REPAIR_TIME_SLICE min (10 / (count _hitPoints)) } else { 0 }; // no longer than 10 seconds
{
if (_dmgValues select _forEachIndex > 0.001) then
{
if (_checkDone) then
{
_checkDone = false;
sleep 3;
};
call _checkAbortConditions;
"Repairing..." call _titleText;
sleep (_repairSlice / 2);
call _checkAbortConditions;
if (_x != "") then
{
_vehicle setHitpointDamage [_x, 0];
}
else
{
_selName = _selections select _forEachIndex;
if (_selName != "") then
{
_vehicle setHit [_selName, 0];
};
};
sleep (_repairSlice / 2);
_repaired = true;
};
} forEach _hitPoints;
};
if (damage _vehicle > 0.001) then
{
call _checkAbortConditions;
"Repairing..." call _titleText;
sleep 1;
call _checkAbortConditions;
_vehicle setDamage 0;
_repaired = true;
};
// reset ejection seat crap
if (_vehicle isKindOf "Plane") then
{
{ _vehicle animate [_x, 0, true] } forEach ["canopy_hide", "ejection_seat_motion", "ejection_seat_hide"];
};
_checkDone = true;
if (fuel _vehicle < 0.999 && !_isStaticWep) then
{
while {fuel _vehicle < 0.999} do
{
if (_checkDone) then
{
_checkDone = false;
sleep 3;
};
call _checkAbortConditions;
"Refueling..." call _titleText;
sleep (REFUEL_TIME_SLICE / 2);
call _checkAbortConditions;
_vehicle setFuel ((fuel _vehicle) + 0.1);
sleep (REFUEL_TIME_SLICE / 2);
};
};
titleText ["Your vehicle is ready.", "PLAIN DOWN", 0.5];
};
};
_vehicle setVariable ["A3W_truckResupplyThread", _resupplyThread];
// Secondary thread for cleanup in case of error in resupply thread
[_vehicle, _resupplyThread] spawn
{
params ["_vehicle", "_resupplyThread"];
waitUntil {scriptDone _resupplyThread};
_ehID = _vehicle getVariable ["A3W_truckResupplyEngineEH", -1];
if (_ehID isEqualType 0) then
{
_vehicle removeEventHandler ["Engine", _ehID];
};
_vehicle setVariable ["A3W_truckResupplyEngineEH", nil];
mutexScriptInProgress = false;
};