9
9
* 1: Target <OBJECT|ARRAY>
10
10
* - Position must be in ATL format.
11
11
* 2: Duration <NUMBER> (default: 20)
12
- * 3: Stance <STRING> (default: "AUTO")
12
+ * 3: Fire Mode <NUMBER> (default: 4)
13
+ * - 0: Single shots (slow).
14
+ * - 1: Single shots (fast).
15
+ * - 2: Three round bursts (slow).
16
+ * - 3: Three round bursts (fast).
17
+ * - 4: Fully automatic (with pauses).
18
+ * - 5: Fully automatic (uninterrupted).
19
+ * - May not apply to weapons limited by long ammo reloading times.
20
+ * 4: Stance <STRING> (default: "AUTO")
21
+ * - Must be one of the modes used by the setUnitPos command.
13
22
*
14
23
* Return Value:
15
24
* None
@@ -27,6 +36,7 @@ params [
27
36
[" _unit" , objNull , [objNull , grpNull ]],
28
37
[" _target" , [0 , 0 , 0 ], [[], objNull ], 3 ],
29
38
[" _duration" , 20 , [0 ]],
39
+ [" _fireMode" , 4 , [0 ]],
30
40
[" _stance" , " AUTO" , [" " ]]
31
41
];
32
42
@@ -36,7 +46,7 @@ if (!local _unit) exitWith {
36
46
37
47
if (_unit isEqualType grpNull ) exitWith {
38
48
{
39
- [_x , _target , _duration , _stance ] call FUNC(suppressiveFire);
49
+ [_x , _target , _duration , _fireMode , _stance ] call FUNC(suppressiveFire);
40
50
} forEach units _unit ;
41
51
};
42
52
@@ -101,6 +111,16 @@ _unit lookAt _target;
101
111
_unit doWatch _target ;
102
112
_unit doTarget _target ;
103
113
114
+ // Get the rounds per burst and time between bursts based on the given fire mode
115
+ [
116
+ [1 , [2 , 3 , 4 ]],
117
+ [1 , [1 , 1.5 , 2 ]],
118
+ [3 , [2 , 3 , 4 ]],
119
+ [3 , [1 , 1.5 , 2 ]],
120
+ [10 , [1.25 , 1.5 , 1.75 ]],
121
+ [10 , [0 , 0 , 0 ]]
122
+ ] select (0 max _fireMode min 5 ) params [" _roundsPerBurst" , " _burstDelay" ];
123
+
104
124
// Force the unit to fire their weapon for the specified duration. Works better than using the doSuppressiveFire
105
125
// command which does not make units realiably fire at the target, especially at longer distances. Small initial
106
126
// delay to give units time to aim at the target. We ignore reloading and give units infinite ammo to create a
@@ -109,7 +129,21 @@ private _endTime = CBA_missionTime + _duration + TARGETING_DELAY;
109
129
110
130
[{
111
131
[{
112
- params [" _unit" , " _target" , " _isTempTarget" , " _abilities" , " _skills" , " _behaviour" , " _combatMode" , " _unitPos" , " _shotTime" , " _endTime" ];
132
+ params [
133
+ " _unit" ,
134
+ " _target" ,
135
+ " _isTempTarget" ,
136
+ " _abilities" ,
137
+ " _skills" ,
138
+ " _behaviour" ,
139
+ " _combatMode" ,
140
+ " _unitPos" ,
141
+ " _roundsPerBurst" ,
142
+ " _burstDelay" ,
143
+ " _currentBurstRounds" ,
144
+ " _shotTime" ,
145
+ " _endTime"
146
+ ];
113
147
114
148
if (
115
149
! alive _unit
@@ -144,63 +178,79 @@ private _endTime = CBA_missionTime + _duration + TARGETING_DELAY;
144
178
145
179
if (CBA_missionTime >= _shotTime ) then {
146
180
private _vehicle = vehicle _unit ;
181
+ private _turretPath = _vehicle unitTurret _unit ;
147
182
148
- if (_vehicle == _unit ) exitWith {
149
- weaponState _unit params [" _weapon" , " _muzzle" , " _fireMode" ];
150
-
151
- _unit setAmmo [_weapon , 1e6 ];
152
- _unit forceWeaponFire [_muzzle , _fireMode ];
153
- _this set [8 , CBA_missionTime + 0.1 ];
154
- };
155
-
156
- if (_unit call EFUNC(common,isUnitFFV)) exitWith {
157
- // Using UseMagazine action since forceWeaponFire command does not work for FFV units
158
- // UseMagazine action doesn't seem to work with currently loaded magazine (currentMagazineDetail)
159
- // Therefore, this relies on the unit having an extra magazine in their inventory
160
- // but should be fine in most situations
161
- private _weapon = currentWeapon _unit ;
162
- private _compatibleMagazines = _weapon call CBA_fnc_compatibleMagazines ;
163
- private _index = magazines _unit findIf {_x in _compatibleMagazines };
164
- if (_index == - 1 ) exitWith {};
165
-
166
- private _magazine = magazinesDetail _unit select _index ;
167
- _magazine call EFUNC(common,parseMagazineDetail) params [" _id" , " _owner" ];
168
-
169
- _unit setAmmo [_weapon , 1e6 ];
170
- CBA_logic action [" UseMagazine" , _unit , _unit , _owner , _id ];
171
- _this set [8 , CBA_missionTime + 0.1 ];
172
- };
183
+ switch (true ) do {
184
+ // On foot
185
+ case (_vehicle == _unit ): {
186
+ weaponState _unit params [" _weapon" , " _muzzle" , " _fireMode" ];
173
187
174
- private _turretPath = _vehicle unitTurret _unit ;
175
- private _muzzle = weaponState [ _vehicle , _turretPath ] select 1 ;
176
- _unit setAmmo [ _muzzle , 1e6 ] ;
188
+ _unit setAmmo [ _weapon , 1e6 ] ;
189
+ _unit forceWeaponFire [ _muzzle , _fireMode ] ;
190
+ } ;
177
191
178
- // Get the reload time for the current weapon state
179
- weaponState [_vehicle , _turretPath ] params [" _weapon" , " _muzzle" , " _fireMode" , " _magazine" , " _ammo" ];
192
+ // FFV
193
+ case (_unit call EFUNC(common,isUnitFFV)): {
194
+ // Using UseMagazine action since forceWeaponFire command does not work for FFV units
195
+ // UseMagazine action doesn't seem to work with currently loaded magazine (currentMagazineDetail)
196
+ // Therefore, this relies on the unit having an extra magazine in their inventory
197
+ // but should be fine in most situations
198
+ private _weapon = currentWeapon _unit ;
199
+ private _compatibleMagazines = _weapon call CBA_fnc_compatibleMagazines ;
200
+ private _index = magazines _unit findAny _compatibleMagazines ;
201
+ if (_index == - 1 ) exitWith {};
202
+
203
+ private _magazine = magazinesDetail _unit select _index ;
204
+ _magazine call EFUNC(common,parseMagazineDetail) params [" _id" , " _owner" ];
205
+
206
+ _unit setAmmo [_weapon , 1e6 ];
207
+ CBA_logic action [" UseMagazine" , _unit , _unit , _owner , _id ];
208
+ };
180
209
181
- private _config = configFile >> " CfgWeapons" >> _weapon ;
210
+ // Vehicle gunner
211
+ default {
212
+ private _muzzle = weaponState [_vehicle , _turretPath ] select 1 ;
213
+ _unit setAmmo [_muzzle , 1e6 ];
182
214
183
- if (_muzzle ! = _weapon ) then {
184
- _config = _config >> _muzzle ;
215
+ private _magazine = _vehicle currentMagazineDetailTurret _turretPath ;
216
+ _magazine call EFUNC(common,parseMagazineDetail) params [" _id" , " _owner" ];
217
+ _vehicle action [" UseMagazine" , _vehicle , _unit , _owner , _id ];
218
+ };
185
219
};
186
220
187
- if ( _muzzle ! = _fireMode ) then {
188
- _config = _config >> _fireMode ;
189
- } ;
221
+ // Set time until the next shot based on the weapon's ammo reloading time and whether the current burst is finished
222
+ private _reloadTime = [ _vehicle , _turretPath ] call EFUNC(common,getWeaponReloadTime) ;
223
+ _currentBurstRounds = _currentBurstRounds + 1 ;
190
224
191
- private _reloadTime = getNumber (_config >> " reloadTime" );
225
+ if (_currentBurstRounds >= _roundsPerBurst ) then {
226
+ _currentBurstRounds = 0 ;
192
227
193
- // Find the correct magazine id and owner and force the weapon to fire
194
- {
195
- _x params [" _xMagazine" , " _xTurretPath" , " _xAmmo" , " _id" , " _owner" ];
228
+ // Calculate the delay until the next burst
229
+ // Use ammo reloading time if it is longer to prevent firing before the weapon is ready
230
+ private _nextBurstDelay = random _burstDelay max _reloadTime ;
231
+ _shotTime = CBA_missionTime + _nextBurstDelay ;
232
+ } else {
233
+ _shotTime = CBA_missionTime + _reloadTime ;
234
+ };
196
235
197
- if (_xTurretPath isEqualTo _turretPath && {_xMagazine == _magazine && {_xAmmo == _ammo && {_xAmmo ! = 0 }}}) exitWith {
198
- _vehicle action [" UseMagazine" , _vehicle , _unit , _owner , _id ];
199
- _this set [8 , CBA_missionTime + _reloadTime ];
200
- };
201
- } forEach magazinesAllTurrets _vehicle ;
236
+ _this set [10 , _currentBurstRounds ];
237
+ _this set [11 , _shotTime ];
202
238
};
203
239
204
240
false // Continue
205
241
}, {}, _this ] call CBA_fnc_waitUntilAndExecute ;
206
- }, [_unit , _target , _isTempTarget , _abilities , _skills , _behaviour , _combatMode , _unitPos , 0 , _endTime ], TARGETING_DELAY] call CBA_fnc_waitAndExecute ;
242
+ }, [
243
+ _unit ,
244
+ _target ,
245
+ _isTempTarget ,
246
+ _abilities ,
247
+ _skills ,
248
+ _behaviour ,
249
+ _combatMode ,
250
+ _unitPos ,
251
+ _roundsPerBurst ,
252
+ _burstDelay ,
253
+ 0 , // _currentBurstRounds
254
+ 0 , // _shotTime
255
+ _endTime
256
+ ], TARGETING_DELAY] call CBA_fnc_waitAndExecute ;
0 commit comments