-
Notifications
You must be signed in to change notification settings - Fork 148
/
fnc_taskDefend.sqf
128 lines (104 loc) · 4.68 KB
/
fnc_taskDefend.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
/* ----------------------------------------------------------------------------
Function: CBA_fnc_taskDefend
Description:
A function for a group to defend a parsed location. Should be ran locally.
Units will mount nearby static machine guns and garrison in nearby buildings.
10% chance to patrol the radius unless specified differently (100% when no available building positions).
0% chance to hold defensive positions in combat unless specified differently.
Parameters:
_group - the group <GROUP, OBJECT>
_position - centre of area to defend <ARRAY, OBJECT, LOCATION, GROUP> (Default: _group)
_radius - radius of area to defend <NUMBER> (Default: 50)
_threshold - minimum building positions required to be considered for garrison <NUMBER> (Default: 3)
_patrol - chance for each unit to patrol instead of garrison, true for default, false for 0% <NUMBER, BOOLEAN> (Default: 0.1)
_hold - chance for each unit to hold their garrison in combat, true for 100%, false for 0% <NUMBER, BOOLEAN> (Default: 0)
Returns:
None
Examples:
(begin example)
[this] call CBA_fnc_taskDefend
(end)
Author:
Rommel, SilentSpike
---------------------------------------------------------------------------- */
params [
["_group", grpNull, [grpNull, objNull]],
["_position", [], [[], objNull, grpNull, locationNull], 3],
["_radius", 50, [0]],
["_threshold", 3, [0]],
["_patrol", 0.1, [true, 0]],
["_hold", 0, [true, 0]]
];
// Input validation stuff here
_group = _group call CBA_fnc_getGroup;
if !(local _group) exitWith {}; // Don't create waypoints on each machine
_position = [_position, _group] select (_position isEqualTo []);
_position = _position call CBA_fnc_getPos;
if (_patrol isEqualType true) then {
_patrol = [0, 0.1] select _patrol;
};
if (_hold isEqualType true) then {
_hold = parseNumber _hold;
};
// Start of the actual function
[_group] call CBA_fnc_clearWaypoints;
{
_x enableAI "PATH";
} forEach units _group;
private _statics = _position nearObjects ["StaticWeapon", _radius];
private _buildings = _position nearObjects ["Building", _radius];
// Filter out occupied statics
_statics = _statics select {locked _x != 2 && {(_x emptyPositions "Gunner") > 0}};
// Filter out buildings below the size threshold (and store positions for later use)
_buildings = _buildings select {
private _positions = _x buildingPos -1;
if (isNil {_x getVariable "CBA_taskDefend_positions"}) then {
_x setVariable ["CBA_taskDefend_positions", _positions];
};
count (_positions) >= _threshold
};
// If patrolling is enabled then the leader must be free to lead it
private _units = units _group;
if (_patrol > 0 && {count _units > 1}) then {
_units deleteAt (_units find (leader _group));
};
{
// 31% chance to occupy nearest free static weapon
if ((random 1 < 0.31) && {_statics isNotEqualTo []}) then {
_x assignAsGunner (_statics deleteAt 0);
[_x] orderGetIn true;
} else {
// Respect chance to patrol, or force if no building positions left
if !((_buildings isEqualTo []) || { (random 1 < _patrol) }) then {
private _building = selectRandom _buildings;
private _array = _building getVariable ["CBA_taskDefend_positions", []];
if (_array isNotEqualTo []) then {
private _pos = _array deleteAt (floor (random (count _array)));
// If building positions are all taken remove from possible buildings
if (_array isEqualTo []) then {
_buildings deleteAt (_buildings find _building);
_building setVariable ["CBA_taskDefend_positions", nil];
} else {
_building setVariable ["CBA_taskDefend_positions", _array];
};
// Wait until AI is in position then force them to stay
[_x, _pos, _hold] spawn {
params ["_unit", "_pos", "_hold"];
if (surfaceIsWater _pos) exitWith {};
_unit doMove _pos;
waitUntil {unitReady _unit};
if (random 1 < _hold) then {
_unit disableAI "PATH";
} else {
doStop _unit;
};
// This command causes AI to repeatedly attempt to crouch when engaged
// If ever fixed by BI then consider uncommenting
// _unit setUnitPos "UP";
};
};
};
};
} forEach _units;
// Unassigned (or combat reacted) units will patrol
[_group, _position, _radius, 5, "sad", "safe", "red", "limited"] call CBA_fnc_taskPatrol;