mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
e2ac18a05d
* advanced_ballistics * advanced_fatigue * advanced_throwing * ai * aircraft * arsenal * atragmx * attach * backpacks * ballistics * captives * cargo * chemlights * common * concertina_wire * cookoff * dagr * disarming * disposable * dogtags * dragging * explosives * fastroping * fcs * finger * frag * gestures * gforces * goggles * grenades * gunbag * hearing * hitreactions * huntir * interact_menu * interaction * inventory * kestrel4500 * laser * laserpointer * logistics_uavbattery * logistics_wirecutter * magazinerepack * map * map_gestures * maptools * markers * medical * medical_ai * medical_blood * medical_menu * microdagr * minedetector * missileguidance * missionmodules * mk6mortar * modules * movement * nametags * nightvision * nlaw * optics * optionsmenu * overheating * overpressure * parachute * pylons * quickmount * rangecard * rearm * recoil * refuel * reload * reloadlaunchers * repair * respawn * safemode * sandbag * scopes * slideshow * spectator * spottingscope * switchunits * tacticalladder * tagging * trenches * tripod * ui * vector * vehiclelock * vehicles * viewdistance * weaponselect * weather * winddeflection * yardage450 * zeus * arsenal defines.hpp * optionals * DEBUG_MODE_FULL 1 * DEBUG_MODE_FULL 2 * Manual fixes * Add SQF Validator check for #include after block comment * explosives fnc_openTimerUI * fix uniqueItems
111 lines
4.5 KiB
Plaintext
111 lines
4.5 KiB
Plaintext
#include "script_component.hpp"
|
|
/*
|
|
* Author: mharis001
|
|
* Zeus module function to make unit a suicide bomber.
|
|
*
|
|
* Arguments:
|
|
* 0: Unit that is suicide bomber <OBJECT>
|
|
* 1: Activation side <SIDE> (default: west)
|
|
* 2: Activation radius <NUMBER> (default: 10)
|
|
* 3: Explosion size (0 - Small, 1 - Medium, 2 - Large) <NUMBER> (default: 0)
|
|
* 4: Auto seek <BOOL> (default: false)
|
|
*
|
|
* Return Value:
|
|
* None
|
|
*
|
|
* Example:
|
|
* [unit, west, 10, 0, true] call ace_zeus_fnc_moduleSuicideBomber
|
|
*
|
|
* Public: No
|
|
*/
|
|
|
|
#define EXPLOSIVES ["R_TBG32V_F", "M_Mo_120mm_AT", "Bo_GBU12_LGB"]
|
|
#define DISTANCE_FAR 15
|
|
#define DISTANCE_CLOSE 2
|
|
#define MOVE_TIME 10
|
|
#define SCANNING_PERIOD 1
|
|
|
|
#ifdef DEBUG_MODE_FULL
|
|
#define SCANNING_PERIOD 0
|
|
#endif
|
|
|
|
TRACE_1("params",_this);
|
|
|
|
if (isNull (_this select 0)) exitWith {};
|
|
|
|
// Prevent another suicide bomber module being attached
|
|
_unit setVariable [QGVAR(suicideBomber), true, true];
|
|
|
|
// One time behaviour changes
|
|
if (_autoSeek) then {
|
|
[QEGVAR(ai,setUnitPos), [_unit, "UP"], _unit] call CBA_fnc_targetEvent;
|
|
[QEGVAR(ai,setSpeedMode), [_unit, "FULL"], _unit] call CBA_fnc_targetEvent;
|
|
[QEGVAR(ai,setBehaviour), [[_unit], "CARELESS"], _unit] call CBA_fnc_targetEvent;
|
|
[QEGVAR(ai,setCombatMode), [_unit, "BLUE"], _unit] call CBA_fnc_targetEvent;
|
|
[QEGVAR(ai,AISection), [[_unit], ["TARGET", "AUTOTARGET"], false], _unit] call CBA_fnc_targetEvent;
|
|
[QEGVAR(ai,allowFleeing), [_unit, 0], _unit] call CBA_fnc_targetEvent;
|
|
};
|
|
|
|
// Run PFH to make unit a suicide bomber
|
|
[{
|
|
params ["_args", "_pfhID"];
|
|
_args params [["_unit", objNull], ["_activationSide", west], ["_activationRadius", 10], ["_explosionSize", 0], ["_autoSeek", false]];
|
|
|
|
// Unit deleted or killed
|
|
if (isNull _unit || {!alive _unit}) exitWith {
|
|
[_pfhID] call CBA_fnc_removePerFrameHandler;
|
|
LOG("Unit deleted or killed, PFH removed");
|
|
};
|
|
|
|
if (!([_unit] call EFUNC(common,isAwake))) exitWith {};
|
|
|
|
// Detonation
|
|
private _nearObjects = (_unit nearObjects _activationRadius) select {side _x == _activationSide && {_x != _unit} && {alive _x}};
|
|
if !(_nearObjects isEqualTo []) then {
|
|
createVehicle [EXPLOSIVES select _explosionSize, _unit, [], 0, "CAN_COLLIDE"];
|
|
[_pfhID] call CBA_fnc_removePerFrameHandler;
|
|
LOG("Explosion created, PFH removed");
|
|
};
|
|
|
|
// Auto Seek
|
|
if (!_autoSeek) exitWith {};
|
|
|
|
private _memory = _unit getVariable [QGVAR(suicideBomber_memory), [nil, CBA_missionTime]];
|
|
_memory params ["_lastMove", "_lastTime"];
|
|
|
|
private _range = 100 + 100 * (_unit skillFinal "spotDistance"); // 100-200
|
|
private _nearestObjects = nearestObjects [_unit, [], _range] select {side _x == _activationSide && {_x != _unit} && {alive _x}};
|
|
|
|
#ifdef DEBUG_MODE_FULL
|
|
if !(isNil "_lastMove") then {
|
|
drawLine3D [_unit modelToWorldVisual [0, 0, 1], _lastMove, [1, 0, 0, 1]];
|
|
};
|
|
for "_i" from 0 to 35 do {
|
|
drawLine3D [(_unit getRelPos [_range, _i * 10]) vectorAdd [0, 0, 1], (_unit getRelPos [_range, (_i + 1) * 10]) vectorAdd [0, 0, 1], [0, 1, 0, 1]];
|
|
};
|
|
for "_i" from 0 to 35 do {
|
|
drawLine3D [(_unit getRelPos [_activationRadius, _i * 10]) vectorAdd [0, 0, 1], (_unit getRelPos [_activationRadius, (_i + 1) * 10]) vectorAdd [0, 0, 1], [0, 0, 1, 1]];
|
|
};
|
|
for "_i" from 0 to 359 do {
|
|
if (_i >= linearConversion [_lastTime - MOVE_TIME, _lastTime, CBA_missionTime, 0, 359, true]) then {
|
|
drawLine3D [(_unit getRelPos [2, _i]) vectorAdd [0, 0, 1], (_unit getRelPos [2, _i + 1]) vectorAdd [0, 0, 1], [1, 1, 0, 1]];
|
|
};
|
|
};
|
|
#endif
|
|
|
|
if (_nearestObjects isEqualTo []) exitWith {};
|
|
|
|
// Get relative position close to target to avoid bug where AI wont path to a certain position
|
|
private _moveToPos = (_nearestObjects select 0) getPos [1, random 360];
|
|
|
|
if (isNil "_lastMove" || // No move given yet
|
|
{_lastMove distance _moveToPos > DISTANCE_FAR} || // New target is too far from last move
|
|
{_lastMove distance _unit < DISTANCE_CLOSE} || // Unit has reached last move
|
|
{CBA_missionTime >= _lastTime} // Too much time passed between last move (also acts as a fail-safe if unit gets stuck)
|
|
) then {
|
|
[QEGVAR(ai,doMove), [[[_unit, _moveToPos]]], _unit] call CBA_fnc_targetEvent;
|
|
_unit setVariable [QGVAR(suicideBomber_memory), [_moveToPos, CBA_missionTime + MOVE_TIME]];
|
|
TRACE_2("Moving unit",_moveToPos,CBA_missionTime);
|
|
};
|
|
}, SCANNING_PERIOD, _this] call CBA_fnc_addPerFrameHandler;
|