Merge branch 'master' into medical-rewrite

Conflicts:
	addons/medical/functions/fnc_treatment_failure.sqf
	addons/medical/functions/fnc_treatment_success.sqf
This commit is contained in:
PabstMirror 2017-05-14 14:50:36 -05:00
commit 1aebae32c5
80 changed files with 755 additions and 257 deletions

View File

@ -26,7 +26,7 @@
TRACE_1("Reading Ammo Config",_this);
private ["_ammo", "_airFriction", "_caliber", "_bulletLength", "_bulletMass", "_transonicStabilityCoef", "_dragModel", "_ballisticCoefficients", "_velocityBoundaries", "_atmosphereModel", "_ammoTempMuzzleVelocityShifts", "_muzzleVelocityTable", "_barrelLengthTable", "_result"];
_ammoConfig = configFile >> "CfgAmmo" >> _this;
private _ammoConfig = configFile >> "CfgAmmo" >> _this;
_airFriction = getNumber(_ammoConfig >> "airFriction");
_caliber = getNumber(_ammoConfig >> "ACE_caliber");

View File

@ -30,6 +30,6 @@ private _barrelLength = getNumber(_weaponConfig >> "ACE_barrelLength");
private _result = [_barrelTwist, _twistDirection, _barrelLength];
uiNamespace setVariable [format[QGVAR(%1), _weapon], _result];
uiNamespace setVariable [format[QGVAR(%1), _this], _result];
_result

View File

@ -54,7 +54,6 @@ GVAR(peakPower) = VO2MAX_STRENGTH * GVAR(VO2MaxPower);
GVAR(ae1PathwayPower) = GVAR(peakPower) / (13.3 + 16.7 + 113.3) * 13.3 * ANTPERCENT ^ 1.28 * 1.362;
GVAR(ae2PathwayPower) = GVAR(peakPower) / (13.3 + 16.7 + 113.3) * 16.7 * ANTPERCENT ^ 1.28 * 1.362;
GVAR(anPathwayPower) = GVAR(peakPower) - _ae1PathwayPower - _ae2PathwayPower;
GVAR(ppeBlackoutLast) = 100;
GVAR(lastBreath) = 0;

View File

@ -115,8 +115,7 @@ addMissionEventHandler ["Draw3D", { // Blue is predicted before throw, red is re
drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", [0,0,1,1], _newTrajAGL, 1, 1, 0, "", 2];
} forEach GVAR(predictedPath);
{
_newTrajAGL = _x;
drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", [1,0,0,1], _newTrajAGL, 1, 1, 0, "", 2];
drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", [1,0,0,1], _x, 1, 1, 0, "", 2];
} forEach GVAR(flightPath)
}];
#endif

View File

@ -48,7 +48,7 @@ if (_resetGunList) then {
[".338LM 250gr" , 872, 100, 0.0604821, -0.00059133, 3.81, 0, 2, 10, 120, 0, 0, 16.20, 8.58, 25.40, 0.645, 1, "ICAO", [[-15,853],[0,860],[10,867],[15,872],[25,886],[30,895],[35,906]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true],
[".338LM 300gr" , 792, 100, 0.0685883, -0.00052190, 3.81, 0, 2, 10, 120, 0, 0, 19.44, 8.58, 25.40, 0.759, 1, "ICAO", [[-15,773],[0,780],[10,787],[15,792],[25,806],[30,815],[35,826]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true],
[".338LM API526" , 872, 100, 0.0602535, -0.00069611, 3.81, 0, 2, 10, 120, 0, 0, 16.39, 8.58, 25.40, 0.760, 1, "ICAO", [[-15,853],[0,860],[10,867],[15,872],[25,886],[30,895],[35,906]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true],
[".338LM API526" , 872, 100, 0.0602535, -0.00069611, 3.81, 0, 2, 10, 120, 0, 0, 16.39, 8.58, 25.40, 0.580, 1, "ICAO", [[-15,853],[0,860],[10,867],[15,872],[25,886],[30,895],[35,906]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true],
[".300WM Mk248 Mod0" , 857, 100, 0.0621425, -0.00070530, 3.81, 0, 2, 10, 120, 0, 0, 12.31, 7.80, 25.40, 0.537, 1, "ICAO", [[-15,838],[0,845],[10,852],[15,857],[25,871],[30,880],[35,891]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true],
[".300WM Mk248 Mod1" , 839, 100, 0.0637038, -0.00061188, 3.81, 0, 2, 10, 120, 0, 0, 14.26, 7.80, 25.40, 0.619, 1, "ICAO", [[-15,820],[0,827],[10,834],[15,839],[25,853],[30,862],[35,873]] , [[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]], true],

View File

@ -57,7 +57,6 @@ if (_unit == _attachToVehicle) then { //Self Attachment
_actionID = _unit addAction [format ["<t color='#FF0000'>%1</t>", localize LSTRING(CancelAction)], {GVAR(placeAction) = PLACE_CANCEL}];
//Display to show virtual object:
private [];
_model = getText (configFile >> "CfgAmmo" >> _itemVehClass >> "model");
if (_model == "") then {
_model = getText (configFile >> "CfgVehicles" >> _itemVehClass >> "model");

View File

@ -21,7 +21,7 @@ TRACE_2("params",_attachToVehicle,_unit);
if ((vehicle _unit) != _unit) exitWith {false};
_attachedList = _attachToVehicle getVariable [QGVAR(attached), []];
private _attachedList = _attachToVehicle getVariable [QGVAR(attached), []];
if ((count _attachedList) == 0) exitWith {false};
private ["_inRange"];

View File

@ -30,7 +30,7 @@ if (_state) then {
_unit setVariable [QGVAR(escortedUnit), _target, true];
//Add Actionmenu to release captive
_actionID = _unit addAction [format ["<t color='#FF0000'>%1</t>", localize LSTRING(StopEscorting)],
private _actionID = _unit addAction [format ["<t color='#FF0000'>%1</t>", localize LSTRING(StopEscorting)],
{[(_this select 0), ((_this select 0) getVariable [QGVAR(escortedUnit), objNull]), false] call FUNC(doEscortCaptive);},
nil, 20, false, true, "", QUOTE(!isNull (GETVAR(_target,QGVAR(escortedUnit),objNull)))];

View File

@ -23,7 +23,7 @@ if (_unit == (vehicle _unit)) then {
[_unit, "ACE_AmovPercMstpScapWnonDnon", 1] call EFUNC(common,doAnimation);
};
} else {
_turretPath = [];
private _turretPath = [];
{
_x params ["_xUnit", "", "", "_xTurretPath"];
if (_unit == _xUnit) exitWith {_turretPath = _xTurretPath};

View File

@ -31,7 +31,7 @@ if (local _unit) then {
if (_unit getVariable [QGVAR(isHandcuffed), false]) then {
//Need to force animation for FFV turrets
_turretPath = [];
private _turretPath = [];
{
_x params ["_xUnit", "", "", "_xTurretPath"];
if (_unit == _xUnit) exitWith {_turretPath = _xTurretPath};

View File

@ -46,7 +46,7 @@ if (_respawn > 3) then {
};
[_unit, "setCaptive", QGVAR(Surrendered), false] call EFUNC(common,statusEffect_set);
if (_oldUnit getVariable [QGVAR(isEscorting), false]) then {
_oldUnit setVariable [QGVAR(isEscorting), false, true];
if (_unit getVariable [QGVAR(isEscorting), false]) then {
_unit setVariable [QGVAR(isEscorting), false, true];
};
};

View File

@ -462,8 +462,8 @@ GVAR(deviceKeyCurrentIndex) = -1;
["ACE3 Equipment", QGVAR(cycleDevice), (localize "STR_ACE_Common_cycleHandheldDevices"), {
[1] call FUNC(deviceKeyFindValidIndex);
if (GVAR(deviceKeyCurrentIndex) == -1) exitWith {false};
_displayName = ((GVAR(deviceKeyHandlingArray) select GVAR(deviceKeyCurrentIndex)) select 0);
_iconImage = ((GVAR(deviceKeyHandlingArray) select GVAR(deviceKeyCurrentIndex)) select 1);
private _displayName = ((GVAR(deviceKeyHandlingArray) select GVAR(deviceKeyCurrentIndex)) select 0);
private _iconImage = ((GVAR(deviceKeyHandlingArray) select GVAR(deviceKeyCurrentIndex)) select 1);
[_displayName, _iconImage] call FUNC(displayTextPicture);
true
},

View File

@ -111,7 +111,7 @@ if (isMultiplayer) then {
_addons = _addons - GVAR(ServerAddons);
if !(_addons isEqualTo []) then {
_errorMsg = format ["Client/Server Addon Mismatch. Client has extra addons: %1.",_addons];
private _errorMsg = format ["Client/Server Addon Mismatch. Client has extra addons: %1.",_addons];
ERROR(_errorMsg);

View File

@ -28,7 +28,7 @@ if (_searchOffsetOrName isEqualType "") then {
} forEach GVAR(deviceKeyHandlingArray);
} else {
if (count GVAR(deviceKeyHandlingArray) > 0) then {
_baseIndex = [GVAR(deviceKeyCurrentIndex) + _searchOffsetOrName, 0] select (GVAR(deviceKeyCurrentIndex) == -1);
private _baseIndex = [GVAR(deviceKeyCurrentIndex) + _searchOffsetOrName, 0] select (GVAR(deviceKeyCurrentIndex) == -1);
for "_offset" from _baseIndex to (count GVAR(deviceKeyHandlingArray) - 1 + _baseIndex) do {
private _realIndex = _offset % (count GVAR(deviceKeyHandlingArray));

View File

@ -23,7 +23,7 @@ private _doorTurrets = [];
_config = [_config, _x] call FUNC(getTurretConfigPath);
if (getNumber (_config >> "isCopilot" == 0) && {count getArray (_config >> "weapons") > 0}) then {
if (((getNumber (_config >> "isCopilot")) == 0) && {count getArray (_config >> "weapons") > 0}) then {
_doorTurrets pushBack _x;
};
false

View File

@ -25,9 +25,9 @@ private _altitude = getNumber (configFile >> "CfgWorlds" >> _map >> "elevationO
private _mapData = _map call FUNC(getMapData);
if (!(_mapData isEqualTo [])) then {
_lat = _mapData select 0;
_alt = _mapData select 1;
_altitude = _mapData select 1;
};
TRACE_2("Latitude and Altitude",_lat,_alt);
TRACE_2("Latitude and Altitude",_lat,_altitude);
private _UTM = [_long, _lat] call BIS_fnc_posDegToUTM;
private _easting = _UTM select 0;

View File

@ -71,6 +71,7 @@ if (_map in ["koplic"]) exitWith { [42, 0] };
if (_map in ["kunduz"]) exitWith { [37, 0] };
if (_map in ["lingor", "lingor3", "dingor"]) exitWith { [-4, 0] };
if (_map in ["lost", "lostw"]) exitWith { [60, 0] };
if (_map in ["lythium"]) exitWith { [34, 0] };
if (_map in ["malvinas"]) exitWith { [-52, 0] };
if (_map in ["marenice"]) exitWith { [51, 0] }; // CSA38 Mod (Czechoslovak army 1938 - Munich crisis), Lisatian Mountains.
if (_map in ["mcn_aliabad"]) exitWith { [36, 0] };

View File

@ -64,8 +64,8 @@ while {_startGrid == _originGrid} do {
private _realOffsetY = (parseNumber (_originGrid select [count _formatX, count _formatY])) * _stepY + _heightOffset - 1;
//Calculate MGRS 10digit step - they should both be 1 meter:
_stepXat5 = _stepX * 10 ^ ((count _formatX) - 5);
_stepYat5 = -1 * _stepY * 10 ^ ((count _formatY) - 5);
private _stepXat5 = _stepX * 10 ^ ((count _formatX) - 5);
private _stepYat5 = -1 * _stepY * 10 ^ ((count _formatY) - 5);
if (_stepYat5 < 0) then {
WARNING_1("Map Grid Warning (%1) - Northing is reversed.",worldName);

View File

@ -27,7 +27,7 @@ if (isNil QGVAR(publishSchedId)) then {
GVAR(publishSchedId) = [{
if (diag_tickTime > GVAR(publishNextTime)) then {
{
_x params [_unit, _varName];
_x params ["_unit", "_varName"];
_unit setVariable [_varName, _unit getVariable _varName, true];
false
} count GVAR(publishVarNames);

View File

@ -74,7 +74,7 @@ if (!isServer) then {
} forEach _files;
// display and log error messages
_fnc_cutComma = {
private _fnc_cutComma = {
_string = _this;
_string = toArray _string;

View File

@ -51,7 +51,7 @@ if (_target isKindOf "CAManBase") then {
} else {
// select no weapon and stop sprinting
_unit action ["SwitchWeapon", _unit, _unit, 99];
_unit action ["SwitchWeapon", _unit, _unit, 299];
[_unit, "AmovPercMstpSnonWnonDnon", 0] call EFUNC(common,doAnimation);
[_unit, "forceWalk", "ACE_dragging", true] call EFUNC(common,statusEffect_set);

View File

@ -2,6 +2,7 @@
PREP(addCellphoneIED);
PREP(addClacker);
PREP(addDetonateActions);
PREP(addDetonateHandler);
PREP(addExplosiveActions);
PREP(addToSpeedDial);
PREP(addTransmitterActions);

View File

@ -25,4 +25,6 @@ if (isServer) then {
GVAR(explosivesOrientations) = []
};
GVAR(detonationHandlers) = [];
ADDON = true;

View File

@ -43,7 +43,7 @@ _explosivesList = [];
{(_this select 2) call FUNC(detonateExplosive);},
{true},
{},
[_unit,_range,_x]
[_unit,_range,_x,_detonator]
] call EFUNC(interact_menu,createAction),
[],
_unit
@ -62,7 +62,7 @@ if (_detonator != "ACE_DeadManSwitch") then {
{(_this select 2) call FUNC(detonateExplosiveAll);},
{true},
{},
[_unit,_range,_explosivesList]
[_unit,_range,_explosivesList, _detonator]
] call EFUNC(interact_menu,createAction),
[],
_unit

View File

@ -0,0 +1,24 @@
/*
* Author: PabstMirror
* Add a explosive detonation handler.
* Should be called on all machines.
* Code needs to return BOOL: true(allowed) / false(blocked)
* See https://ace3mod.com/wiki/framework/explosives-framework.html for an example.
*
* Arguments:
* 0: Code <CODE>
* - Passed [Unit<OBJECT>, MaxRange <NUMBER>, Explosive <OBJECT>, FuzeTime <NUMBER>, TriggerItem <STRING>]
*
* Return Value:
* None
*
* Example:
* [{false}] call ace_explosives_fnc_addDetonateHandler;
*
* Public: Yes
*/
#include "script_component.hpp"
params [["_code", {true}, [{}]]];
GVAR(detonationHandlers) pushBack _code;

View File

@ -21,7 +21,7 @@ TRACE_2("params",_unit,_explosive);
if (GVAR(ExplodeOnDefuse) && {(random 1.0) < (getNumber (ConfigFile >> "CfgAmmo" >> typeOf _explosive >> QGVAR(explodeOnDefuseChance)))}) exitWith {
TRACE_1("exploding on defuse",_explosive);
[_unit, -1, [_explosive, 1], true] call FUNC(detonateExplosive);
[_unit, -1, [_explosive, 1], "#ExplodeOnDefuse"] call FUNC(detonateExplosive);
[QGVAR(explodeOnDefuse), [_explosive, _unit]] call CBA_fnc_globalEvent;
};

View File

@ -8,28 +8,35 @@
* 2: Explosive <ARRAY>
* 0: Explosive <OBJECT>
* 1: Fuse time <NUMBER>
* 3: Trigger Item Classname <STRING>
*
* Return Value:
* None
*
* Example:
* [player, 100, [Explosive, 1]] call ACE_Explosives_fnc_detonateExplosive; // has to be within range
* [player, -1, [Explosive, 1]] call ACE_Explosives_fnc_detonateExplosive; // range ignored.
* [player, 100, [Explosive, 1], "ACE_Clacker"] call ACE_Explosives_fnc_detonateExplosive; // has to be within range
* [player, -1, [Explosive, 1], "ACE_Cellphone"] call ACE_Explosives_fnc_detonateExplosive; // range ignored.
*
* Public: Yes
*/
#include "script_component.hpp"
params ["_unit", "_range", "_item"];
TRACE_3("params",_unit,_range,_item);
params ["_unit", "_range", "_item", ["_triggerClassname", "#unknown", [""]]];
TRACE_4("detonateExplosive",_unit,_range,_item,_triggerClassname);
private ["_result", "_ignoreRange", "_pos"];
_ignoreRange = (_range == -1);
_result = true;
if (!_ignoreRange && {(_unit distance (_item select 0)) > _range}) exitWith {TRACE_1("out of range",_range); false};
_result = true;
{
// Pass [Unit<OBJECT>, MaxRange <NUMBER>, Explosive <OBJECT>, FuzeTime <NUMBER>, TriggerItem <STRING>]
private _handlerResult = [_unit, _range, _item select 0, _item select 1, _triggerClassname] call _x;
if (_handlerResult isEqualTo false) then {TRACE_1("Handler Failed",_forEachIndex); _result = false};
} forEach GVAR(detonationHandlers);
if (!_result) exitWith {false};
if (getNumber (ConfigFile >> "CfgAmmo" >> typeOf (_item select 0) >> "TriggerWhenDestroyed") == 0) then {
private ["_exp", "_previousExp"];
_previousExp = _item select 0;

View File

@ -8,20 +8,21 @@
* 2: Explosives to detonate <ARRAY>
* 0: Explosive <OBJECT>
* 1: Fuse time <NUMBER>
* 3: Trigger Item Classname <STRING>
*
* Return Value:
* None
*
* Example:
* [player, -1, [[c4,0.5]]] call ACE_Explosives_fnc_detonateExplosiveAll;
* [player, -1, [[c4,0.5]], "ACE_Clacker"] call ACE_Explosives_fnc_detonateExplosiveAll;
*
* Public: No
*/
#include "script_component.hpp"
params ["_unit", "_range", "_explosivesList"];
TRACE_3("Params",_unit,_range,_explosivesList);
params ["_unit", "_range", "_explosivesList", "_triggerClassname"];
TRACE_4("Params",_unit,_range,_explosivesList,_triggerClassname);
{
[_unit,_range,_x] call FUNC(detonateExplosive);
[_unit,_range,_x,_triggerClassname] call FUNC(detonateExplosive);
} forEach _explosivesList;

View File

@ -41,6 +41,6 @@ if (_unit == ace_player) then {
playSound3D [QUOTE(PATHTO_R(Data\Audio\Cellphone_Ring.wss)),objNull, false, getPosASL (_this select 1),3.16228,1,75];
(_this select 0) setVariable [QGVAR(Dialing), false, true];
}, [_unit,_explosive select 0], 0.25 * (count _arr - 4)] call CBA_fnc_waitAndExecute;
[_explosive select 0,(0.25 * (count _arr - 1)) + (_explosive select 2)] call FUNC(startTimer);
[_explosive select 0,(0.25 * (count _arr - 1)) + (_explosive select 2), "ACE_Cellphone"] call FUNC(startTimer);
};
};

View File

@ -31,7 +31,7 @@ private _explosive = [_code] call FUNC(getSpeedDialExplosive);
if (_i >= (count _arr + 2)) then {
[_pfID] call CALLSTACK(CBA_fnc_removePerFrameHandler);
if ((count _explosive) > 0) then {
[_unit, -1, [_explosive select 0, _explosive select 2]] call FUNC(detonateExplosive);
[_unit, -1, [_explosive select 0, _explosive select 2], "ACE_Cellphone"] call FUNC(detonateExplosive);
};
_unit setVariable [QGVAR(Dialing), false, true];
if (_unit == ace_player) then {

View File

@ -26,7 +26,7 @@ private _range = getNumber (configFile >> "CfgWeapons" >> "ACE_DeadManSwitch" >>
private _deadman = [_unit, "DeadManSwitch"] call FUNC(getPlacedExplosives);
TRACE_2("placed",_deadman,_range);
{
[_unit, _range, _x, true] call FUNC(detonateExplosive);
[_unit, _range, _x, "ACE_DeadManSwitch"] call FUNC(detonateExplosive);
} forEach _deadman;
//Handle deadman connected to explosive in inventory
@ -47,5 +47,5 @@ if (_connectedInventoryExplosive != "") then {
private _explosive = createVehicle [_ammo, (getPos _unit), [], 0, "NONE"];
_explosive setPosASL (getPosASL _unit);
[_unit, -1, [_explosive, 0.5]] call FUNC(detonateExplosive); //Explode, ignoring range, with a 0.5 second delay
[_unit, -1, [_explosive, 0.5], "ACE_DeadManSwitch"] call FUNC(detonateExplosive); //Explode, ignoring range, with a 0.5 second delay
};

View File

@ -6,6 +6,7 @@
* Arguments:
* 0: Explosives objects to detonate <OBJECT or ARRAY>
* 1: Fuze delay (for each explosive; use negative number for random time up to value) <NUMBER> <OPTIONAL>
* 2: Trigger Item Classname <STRING><OPTIONAL>
*
* Return Value:
* None
@ -18,7 +19,7 @@
*/
#include "script_component.hpp"
params [["_explosiveArr", [], [[], objNull]], ["_fuzeTime", 0, [0]]];
params [["_explosiveArr", [], [[], objNull]], ["_fuzeTime", 0, [0]], ["_triggerClassname", "#scripted", [""]]];
if (_explosiveArr isEqualType objNull) then {
_explosiveArr = [_explosiveArr];
@ -26,5 +27,5 @@ if (_explosiveArr isEqualType objNull) then {
{
private _detTime = if (_fuzeTime < 0) then {random abs _fuzeTime} else {_fuzeTime};
[objNull, -1, [_x, _detTime]] call FUNC(detonateExplosive);
[objNull, -1, [_x, _detTime], _triggerClassname] call FUNC(detonateExplosive);
} forEach _explosiveArr;

View File

@ -5,6 +5,7 @@
* Arguments:
* 0: Explosive <OBJECT>
* 1: Time till detonate <NUMBER>
* 2: Trigger Item Classname <STRING><OPTIONAL>
*
* Return Value:
* None
@ -16,13 +17,13 @@
*/
#include "script_component.hpp"
params ["_explosive", "_delay"];
TRACE_2("params",_explosive,_delay);
params ["_explosive", "_delay", ["_triggerClassname", "#timer", [""]]];
TRACE_3("startTimer",_explosive,_delay,_triggerClassname);
[{
params ["_explosive"];
params ["_explosive", "_triggerClassname"];
TRACE_1("Explosive Going Boom",_explosive);
if (!isNull _explosive) then {
[_explosive, -1, [_explosive, 0]] call FUNC(detonateExplosive);
[_explosive, -1, [_explosive, 0], _triggerClassname] call FUNC(detonateExplosive);
};
}, [_explosive], _delay] call CBA_fnc_waitAndExecute;
}, [_explosive, _triggerClassname], _delay] call CBA_fnc_waitAndExecute;

View File

@ -14,7 +14,7 @@ if (isServer) then {
["ace_firedPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler;
["ace_firedNonPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler;
[LINKFUNC(masterPFH), 0, []] call CBA_fnc_addPerFrameHandler;
addMissionEventHandler ["EachFrame", {call FUNC(masterPFH)}];
}] call CBA_fnc_addEventHandler;
// Cache for ammo type configs

View File

@ -3,22 +3,26 @@
if (!hasInterface) exitWith {};
GVAR(pfID) = -1;
GVAR(playerIsVirtual) = false;
["ace_settingsInitialized", {
TRACE_1("SettingsInitialized eh",GVAR(enabledFor));
if (GVAR(enabledFor) == 0) exitWith {}; //Module has no effect if enabledFor is "None"
["unit", { // Add unit changed EH to check if player is either virtual (logic) or a UAV AI
params ["_unit"];
GVAR(playerIsVirtual) = ((getNumber (configFile >> "CfgVehicles" >> (typeOf _unit) >> "isPlayableLogic")) == 1) ||
{(getText (configFile >> "CfgVehicles" >> (typeOf _unit) >> "simulation")) == "UAVPilot"};
TRACE_3("unit changed",_unit,typeOf _unit,GVAR(playerIsVirtual));
}, true] call CBA_fnc_addPlayerEventHandler;
if (GVAR(enabledFor) == 2) exitWith { //PFEH is always on when enabledFor is "All"
[] call FUNC(addPFEH);
TRACE_1("adding perm PFEH",GVAR(pfID));
};
//PFEH only runs when player is in a type "Air" vehicle when enabledFor is "Aircraft"
if ((!isNull (vehicle ACE_player)) && {(vehicle ACE_player) isKindOf "Air"}) then { //"playerVehicleChanged" can happen before "settingInit"
[] call FUNC(addPFEH);
TRACE_1("adding temp PFEH [start in]",GVAR(pfID));
};
["vehicle", {
params ["", "_vehicle"];
TRACE_2("playerVehicleChanged",_vehicle,typeOf _vehicle);
@ -35,5 +39,5 @@ GVAR(pfID) = -1;
GVAR(pfID) = -1;
};
};
}] call CBA_fnc_addPlayerEventHandler;
}, true] call CBA_fnc_addPlayerEventHandler;
}] call CBA_fnc_addEventHandler;

View File

@ -17,7 +17,7 @@
if ((CBA_missionTime - GVAR(lastUpdateTime)) < INTERVAL) exitWith {};
GVAR(lastUpdateTime) = CBA_missionTime;
if (isNull ACE_player || !(alive ACE_player)) exitWith {};
if (GVAR(playerIsVirtual) || {!alive ACE_player}) exitWith {};
BEGIN_COUNTER(everyInterval);

View File

@ -53,7 +53,7 @@ if (isNil "_loudness") then {
};
} count _muzzles;
{
_ammoType = getText(configFile >> "CfgMagazines" >> _x >> "ammo");
private _ammoType = getText(configFile >> "CfgMagazines" >> _x >> "ammo");
_weaponMagazines set [_forEachIndex, [_x, _ammoType]];
} forEach _weaponMagazines;

View File

@ -27,6 +27,9 @@ if (_unit == _firer) exitWith {};
// camshake for player
if (_unit == ACE_player) then {
if (visibleMap) then {
openMap false;
};
addCamShake [3, 5, _damage + random 10];
};

View File

@ -18,7 +18,7 @@
*/
#include "script_component.hpp"
params ["_ars", "_elapsedTime", "_totalTime"];
params ["_args", "_elapsedTime", "_totalTime"];
_args params ["_magazineClassname", "_lastAmmoCount", "_simEvents"];
if !((_simEvents select 0) params ["_nextEventTime", "_nextEventIsBullet", "_nextEventMags"]) exitWith { ERROR("No Event"); false };

View File

@ -39,7 +39,7 @@ _unitLight params ["_flashlight", ""];
{[_player, _this select 2] call FUNC(switchFlashlight)}
};
_action = [_x, _displayName, _icon, _statement, {true}, {}, _x] call EFUNC(interact_menu,createAction);
private _action = [_x, _displayName, _icon, _statement, {true}, {}, _x] call EFUNC(interact_menu,createAction);
_actions pushBack [_action, [], _player];
} forEach _flashlightItems;

View File

@ -26,7 +26,7 @@ if (!isNil QGVAR(MouseMoveHandlerID)) then {
};
GVAR(MouseMoveHandlerID) = _mapCtrl ctrlAddEventHandler ["MouseMoving", {
// Don't transmit any data if we're using the map tools
if (!GVAR(EnableTransmit) || EGVAR(maptools,mapTool_isDragging) || EGVAR(maptools,mapTool_isRotating)) exitWith {};
if (!GVAR(EnableTransmit) || {(["ace_maptools"] call EFUNC(common,isModLoaded)) && {EGVAR(maptools,mapTool_isDragging) || EGVAR(maptools,mapTool_isRotating)}}) exitWith {};
params ["_control", "_posX", "_posY"];

View File

@ -27,7 +27,7 @@ addMissionEventHandler ["Draw3D", {
GVAR(debugDetector) params ["_detectorPointAGL", "_mines"];
drawIcon3D ["\A3\ui_f\data\map\markers\military\dot_CA.paa", [0,0,1,1], _detectorPointAGL, 1, 1, 0, "detector", 1, 0.02, "PuristaMedium"];
{
_name = format ["%1@%2", typeOf _x, (floor ((_x distance _detectorPointAGL) * 10)) / 10];
private _name = format ["%1@%2", typeOf _x, (floor ((_x distance _detectorPointAGL) * 10)) / 10];
if ((getNumber (configFile >> "CfgVehicles" >> (typeOf _x) >> QGVAR(detectable))) == 1) then {
drawIcon3D ["\A3\ui_f\data\map\markers\military\dot_CA.paa", [1,0,0,1], (ASLtoAGL (getPosASL _x)), 1, 1, 0, _name, 1, 0.02, "PuristaMedium"];
} else {

View File

@ -38,7 +38,7 @@ private _distance = 999;
if (isNull _intersectObject) then { //Terrain:
// Calculate the angle between the terrain and the back blast direction
_angle = 90 - acos (- (_surfaceNormal vectorDotProduct _direction));
private _angle = 90 - acos (- (_surfaceNormal vectorDotProduct _direction));
TRACE_3("Terrain Intersect",_surfaceNormal,_direction,_angle);
// Angles is below 25deg, no backblast at all
if (_angle < 25) exitWith {_distance = 999};

View File

@ -19,6 +19,8 @@
private ["_dummy","_magazineClass"];
params [["_target", objNull, [objNull]], ["_unit", objNull, [objNull]]];
if (!alive _target) exitWith {false};
if (GVAR(level) == 0 || {isNull _unit} || {!(_unit isKindOf "CAManBase")} || {!local _unit} || {([_unit, _target] call EFUNC(interaction,getInteractionDistance)) > REARM_ACTION_DISTANCE} || {_target getVariable [QGVAR(disabled), false]}) exitWith {false};
_dummy = _unit getVariable [QGVAR(dummy), objNull];

View File

@ -19,6 +19,7 @@
params [["_target", objNull, [objNull]], ["_unit", objNull, [objNull]]];
!(isNull _unit ||
{!alive _target} ||
{!(_unit isKindOf "CAManBase")} ||
{!local _unit} ||
{(_target distance _unit) > REARM_ACTION_DISTANCE} ||

View File

@ -19,6 +19,7 @@
params [["_target", objNull, [objNull]], ["_unit", objNull, [objNull]]];
!(isNull _unit ||
{!alive _target} ||
{!(_unit isKindOf "CAManBase")} ||
{!local _unit} ||
{(_target distance _unit) > REARM_ACTION_DISTANCE} ||

View File

@ -28,7 +28,7 @@
#define REARM_HOLSTER_WEAPON \
_unit setVariable [QGVAR(selectedWeaponOnRearm), currentWeapon _unit]; \
_unit action ["SwitchWeapon", _unit, _unit, 99];
_unit action ["SwitchWeapon", _unit, _unit, 299];
#define REARM_UNHOLSTER_WEAPON \
_weaponSelect = _unit getVariable QGVAR(selectedWeaponOnRearm); \

View File

@ -5,7 +5,7 @@
class GVAR(Refuel) { \
displayName = CSTRING(Refuel); \
distance = REFUEL_ACTION_DISTANCE; \
condition = "true"; \
condition = "alive _target"; \
statement = ""; \
showDisabled = 0; \
priority = 2; \

View File

@ -26,6 +26,7 @@ if (_target isKindOf "AllVehicles") then {
};
!(isNull _nozzle ||
{!alive _target} ||
{_engine} ||
{([_unit, _target] call EFUNC(interaction,getInteractionDistance)) > REFUEL_ACTION_DISTANCE} ||
{!isNull (_target getVariable [QGVAR(nozzle), objNull])})

View File

@ -33,7 +33,7 @@ private _posB = (getPosASL _nozzle) vectorAdd [0,0,-1000];
private _intersections = lineIntersectsSurfaces [_posA, _posB, _unit, _nozzle, true, 1, "GEOM"];
TRACE_1("",_intersections);
if (_intersections isEqualTo []) then {
_groundPosition set [2, (getTerrainHeightASL _groundPosition) vectorAdd [0,0,0.005]];
_groundPosition set [2, (getTerrainHeightASL _groundPosition) + 0.005];
} else {
_groundPosition = ((_intersections select 0) select 0) vectorAdd [0,0,0.005];
};

View File

@ -22,7 +22,9 @@ if (isNull _target ||
{_target isKindOf "AllVehicles"} ||
{_target getVariable [QGVAR(jerryCan), false]}) exitWith {};
[_target, _fuelAmount] call FUNC(setFuel);
if (isServer) then {
[_target, _fuelAmount] call FUNC(setFuel); // has global effects
};
_target setVariable [QGVAR(jerryCan), true];
_target setVariable [QGVAR(source), _target];

View File

@ -23,7 +23,7 @@
#define REFUEL_HOLSTER_WEAPON \
_unit setVariable [QGVAR(selectedWeaponOnRefuel), currentWeapon _unit]; \
_unit call EFUNC(common,fixLoweredRifleAnimation); \
_unit action ["SwitchWeapon", _unit, _unit, 99];
_unit action ["SwitchWeapon", _unit, _unit, 299];
#define REFUEL_UNHOLSTER_WEAPON \
_weaponSelect = _unit getVariable QGVAR(selectedWeaponOnRefuel); \

View File

@ -56,7 +56,7 @@ _processedHitpoints = [];
// An action to remove the wheel is required
_name = format ["Remove_%1_%2", _forEachIndex, _hitpoint];
_text = localize LSTRING(RemoveWheel);
private _text = localize LSTRING(RemoveWheel);
_condition = {[_this select 1, _this select 0, _this select 2 select 0, "RemoveWheel"] call DFUNC(canRepair)};
_statement = {[_this select 1, _this select 0, _this select 2 select 0, "RemoveWheel"] call DFUNC(repair)};
_action = [_name, _text, _icon, _statement, _condition, {}, [_hitpoint], _position, 2] call EFUNC(interact_menu,createAction);

View File

@ -40,7 +40,7 @@ _weaponSelect = (_caller getVariable [QGVAR(selectedWeaponOnrepair), ""]);
if (_weaponSelect != "") then {
_caller selectWeapon _weaponSelect;
} else {
_caller action ["SwitchWeapon", _caller, _caller, 99];
_caller action ["SwitchWeapon", _caller, _caller, 299];
};
{

View File

@ -40,7 +40,7 @@ _weaponSelect = (_caller getVariable [QGVAR(selectedWeaponOnrepair), ""]);
if (_weaponSelect != "") then {
_caller selectWeapon _weaponSelect;
} else {
_caller action ["SwitchWeapon", _caller, _caller, 99];
_caller action ["SwitchWeapon", _caller, _caller, 299];
};
//Unclaim repair objects:

View File

@ -44,7 +44,7 @@ if (!isNil "_activeWeaponAndMuzzle") then {
private _index = 0;
while {
_index < 100 && {currentWeaponMode _unit != _activeWeaponMode}
_index < 299 && {currentWeaponMode _unit != _activeWeaponMode}
} do {
_unit action ["SwitchWeapon", _unit, _unit, _index];
_index = _index + 1;

View File

@ -56,7 +56,7 @@ if (inputAction "nextWeapon" > 0) then {
// switch to last mode
_index = 0;
while {
_index < 100 && {currentMuzzle _unit != _weapon || {currentWeaponMode _unit != _mode}}
_index < 299 && {currentMuzzle _unit != _weapon || {currentWeaponMode _unit != _mode}}
} do {
_unit action ["SwitchWeapon", _unit, _unit, _index];
_index = _index + 1;

View File

@ -43,7 +43,7 @@ class CfgVehicles {
class ACE_Actions: ACE_Actions{
class ACE_MainActions: ACE_MainActions {
selection = "main_gun";
selection = "main_turret_axis";
class ACE_Pickup {
selection = "";
displayName = CSTRING(PickUp);

View File

@ -77,7 +77,7 @@ private _v3 = _v2 vectorCrossProduct _v1;
TRACE_3("Reference:", _v1, _v2, _v3);
_fnc_isOk = {
private _fnc_isOk = {
params ["_rx", "_ry"];
private _startPosASL2 = _touchingPoint vectorAdd (_v2 vectorMultiply _rx) vectorAdd (_v3 vectorMultiply _ry) vectorAdd (_v1 vectorMultiply (-0.06));
private _endPosASL2 = _startPosASL2 vectorAdd (_v1 vectorMultiply (0.12));

View File

@ -19,4 +19,4 @@ params ["_unit"];
_unit call EFUNC(common,fixLoweredRifleAnimation);
_unit action ["SwitchWeapon", _unit, _unit, 99];
_unit action ["SwitchWeapon", _unit, _unit, 299];

View File

@ -42,7 +42,7 @@ private _mode = _modes select _index;
_index = 0;
while {
_index < 100 && {currentMuzzle _unit != _muzzle || {currentWeaponMode _unit != _mode}}
_index < 299 && {currentMuzzle _unit != _muzzle || {currentWeaponMode _unit != _mode}}
} do {
_unit action ["SwitchWeapon", _unit, _unit, _index];
_index = _index + 1;

View File

@ -42,7 +42,7 @@ private _muzzle = _muzzles select _index;
_index = 0;
while {
_index < 100 && {currentMuzzle _unit != _muzzle}
_index < 299 && {currentMuzzle _unit != _muzzle}
} do {
_unit action ["SwitchWeapon", _unit, _unit, _index];
_index = _index + 1;

View File

@ -31,7 +31,7 @@ if (_turret isEqualTo [] && {_unit == driver _vehicle}) then {
_index = 0;
while {
_index < 100 && {currentWeapon _vehicle != _weapon}
_index < 299 && {currentWeapon _vehicle != _weapon}
} do {
_unit action ["SwitchWeapon", _vehicle, _unit, _index];
_index = _index + 1;
@ -46,7 +46,7 @@ if (_turret isEqualTo [] && {_unit == driver _vehicle}) then {
_index = 0;
while {
_index < 100 && {_vehicle currentWeaponTurret _turret != _weapon}
_index < 299 && {_vehicle currentWeaponTurret _turret != _weapon}
} do {
_unit action ["SwitchWeapon", _vehicle, _unit, _index];
_index = _index + 1;

View File

@ -62,11 +62,9 @@ simulWeatherSync;
["ace_settingsInitialized",{
TRACE_1("ace_settingsInitialized eh",GVAR(syncRain));
//Create a 0 sec delay PFEH to update rain every frame:
// update rain every frame:
if (GVAR(syncRain)) then {
[{
0 setRain GVAR(ACE_rain);
}, 0, []] call CBA_fnc_addPerFrameHandler;
addMissionEventHandler ["EachFrame", {0 setRain GVAR(ACE_rain)}];
};
//Create a 1 sec delay PFEH to update wind/rain/temp/humidity:

View File

@ -160,6 +160,12 @@ class CfgVehicles {
displayName = CSTRING(ModuleSearchNearby_DisplayName);
function = QFUNC(moduleSearchNearby);
};
class GVAR(moduleSuppressiveFire): GVAR(moduleBase) {
curatorCanAttach = 1;
category = QGVAR(AI);
displayName = CSTRING(ModuleSuppressiveFire_DisplayName);
function = QFUNC(moduleSuppressiveFire);
};
class GVAR(moduleSetMedic): GVAR(moduleBase) {
curatorCanAttach = 1;
category = QGVAR(Medical);

View File

@ -4,6 +4,7 @@ PREP(bi_moduleCurator);
PREP(bi_moduleMine);
PREP(bi_moduleProjectile);
PREP(bi_moduleRemoteControl);
PREP(getModuleDestination);
PREP(handleZeusUnitAssigned);
PREP(moduleAddSpareTrack);
PREP(moduleAddSpareWheel);
@ -16,6 +17,8 @@ PREP(moduleSetMedic);
PREP(moduleSetMedicalVehicle);
PREP(moduleSetMedicalFacility);
PREP(moduleSimulation);
PREP(moduleSuppressiveFire);
PREP(moduleSuppressiveFireLocal);
PREP(moduleSurrender);
PREP(moduleTeleportPlayers);
PREP(moduleUnconscious);

View File

@ -14,6 +14,7 @@ QGVAR(GlobalSkillAI) addPublicVariableEventHandler FUNC(moduleGlobalSetSkill);
[QGVAR(modulePatrolArea), CBA_fnc_taskPatrol] call CBA_fnc_addEventHandler;
[QGVAR(moduleSearchNearby), CBA_fnc_searchNearby] call CBA_fnc_addEventHandler;
[QGVAR(moduleSearchArea), CBA_fnc_taskSearchArea] call CBA_fnc_addEventHandler;
[QGVAR(suppressiveFire), LINKFUNC(moduleSuppressiveFireLocal)] call CBA_fnc_addEventHandler;
// Editable object commands must be ran on server, this events are used in the respective module
if (isServer) then {

View File

@ -12,6 +12,7 @@ class CfgPatches {
QGVAR(moduleSearchArea),
QGVAR(moduleSearchNearby),
QGVAR(moduleSimulation),
QGVAR(moduleSuppressiveFire),
QGVAR(moduleTeleportPlayers)
};
weapons[] = {};

View File

@ -0,0 +1,79 @@
/*
* Author: PabstMirror
* Allows zeus to click to indicate a 3d position.
*
* Arguments:
* 0: The souce object <OBJECT>
* 1: Code to run when position is ready <CODE>
* - Code is passed [0: Successful <BOOL>, 1: Object <OBJECT>, 2: Position ASL <ARRAY>]
* 2: Text <STRING><OPTIONAL>
* 3: Icon image file <STRING><OPTIONAL>
* 4: Icon color <ARRAY><OPTIONAL>
*
* Return Value:
* None
*
* Example:
* [player, {systemChat format ["Done %1", _this]}] call ace_zeus_fnc_getModuleDestination
*
* Public: No
*/
#include "script_component.hpp"
params ["_object", "_code", ["_text", ""], ["_icon", "\a3\ui_f\data\IGUI\Cfg\Cursors\select_target_ca.paa"], ["_color", [1,0,0,1]]];
if (missionNamespace getVariable [QGVAR(moduleDestination_running), false]) exitWith {
[false, _object, [0,0,0]] call _code;
ERROR("getModuleDestination already running");
};
GVAR(moduleDestination_running) = true;
// Add mouse button eh for the zeus display (triggered from 2d or 3d)
GVAR(moduleDestination_displayEH) = [(findDisplay 312), "mouseButtonDown", {
params ["", "_mouseButton"];
if (_mouseButton != 0) exitWith {}; // Only watch for LMB
_thisArgs params ["_object", "_code"];
private _mousePosASL = if (ctrlShown ((findDisplay 312) displayCtrl 50)) then {
private _pos2d = (((findDisplay 312) displayCtrl 50) ctrlMapScreenToWorld getMousePosition);
_pos2d set [2, getTerrainHeightASL _pos2d];
_pos2d
} else {
AGLToASL (screenToWorld getMousePosition);
};
TRACE_2("placed",_object,_mousePosASL);
[true, _object, _mousePosASL] call _code;
GVAR(moduleDestination_running) = false;
}, [_object, _code]] call CBA_fnc_addBISEventHandler;
// Add draw eh for the zeus map - draws the 2d icon and line
GVAR(moduleDestination_mapDrawEH) = [((findDisplay 312) displayCtrl 50), "draw", {
params ["_mapCtrl"];
_thisArgs params ["_object", "_text", "_icon", "_color"];
private _pos2d = (((findDisplay 312) displayCtrl 50) ctrlMapScreenToWorld getMousePosition);
_mapCtrl drawIcon [_icon, _color, _pos2d, 24, 24, 45, _text, 1, 0.03, "TahomaB", "right"];
_mapCtrl drawLine [getPos _object, _pos2d, _color];
}, [_object, _text, _icon, _color]] call CBA_fnc_addBISEventHandler;
[{
(_this select 0) params ["_object", "_code", "_text", "_icon", "_color"];
if ((isNull _object) || {isNull findDisplay 312} || {!isNull findDisplay 49}) then {
TRACE_3("null-exit",isNull _object,isNull findDisplay 312,isNull findDisplay 49);
GVAR(moduleDestination_running) = false;
[false, _object, [0,0,0]] call _code;
};
if (GVAR(moduleDestination_running)) then {
// Draw the 3d icon and line
private _mousePosAGL = screenToWorld getMousePosition;
drawIcon3D [_icon, _color, _mousePosAGL, 1.5, 1.5, 45, _text];
drawLine3D [_mousePosAGL, ASLtoAGL (getPosASL _object), _color];;
} else {
TRACE_3("cleaning up",_this select 1, GVAR(moduleDestination_displayEH), GVAR(moduleDestination_mapDrawEH));
(_this select 1) call CBA_fnc_removePerFrameHandler;
(findDisplay 312) displayRemoveEventHandler ["mouseButtonDown", GVAR(moduleDestination_displayEH)];
((findDisplay 312) displayCtrl 50) ctrlRemoveEventHandler ["draw", GVAR(moduleDestination_mapDrawEH)];
GVAR(moduleDestination_displayEH) = nil;
GVAR(moduleDestination_mapDrawEH) = nil;
};
}, 0, [_object, _code, _text, _icon, _color]] call CBA_fnc_addPerFrameHandler;

View File

@ -0,0 +1,117 @@
/*
* Author: bux, PabstMirror
* Commands the selected unit or group to start suppressive fire on the unit, group or location the module is placed on
*
* Arguments:
* 0: The module logic <OBJECT>
* 1: Synchronized units <ARRAY>
* 2: Activated <BOOL>
*
* Return Value:
* None
*
* Public: No
*/
// #define DRAW_ZEUS_INFO
#include "script_component.hpp"
if (canSuspend) exitWith {[FUNC(moduleSuppressiveFire), _this] call CBA_fnc_directCall;};
params ["_logic", "_units", "_activated"];
if !(_activated && local _logic) exitWith {};
// Validate the module target
private _unit = effectiveCommander (attachedTo _logic);
TRACE_3("moduleSuppressiveFire placed",_unit,typeOf _unit,typeOf _logic);
deleteVehicle _logic; // cleanup logic now, we just needed it to get the attached unit
if (isNull _unit) exitWith {
[LSTRING(NothingSelected)] call FUNC(showMessage);
};
if (!alive _unit) exitWith {
[localize LSTRING(OnlyAlive)] call FUNC(showMessage);
};
if ([_unit] call EFUNC(common,isPlayer)) exitWith {
["str_a3_cfgvehicles_moduleremotecontrol_f_errorPlayer"] call FUNC(showMessage);
};
[_unit, {
params ["_successful", "_unit", "_mousePosASL"];
TRACE_3("getModuleDestination return",_successful,_unit,_mousePosASL);
if (!_successful) exitWith {};
if (!alive _unit) exitWith {};
private _vehicle = vehicle _unit;
private _targetASL = _mousePosASL vectorAdd [0,0,0.6]; // mouse pos is at ground level zero, raise up a bit;
private _artilleryMag = "";
if ((getNumber (configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "artilleryScanner")) == 1) then {
// Artillery - Get mortar ammo type and verify in range
if (isNull gunner _vehicle) exitWith {_targetASL = [];};
{
private _ammo = getText (configFile >> "CfgMagazines" >> _x >> "ammo");
private _hit = getNumber (configFile >> "CfgAmmo" >> _ammo >> "hit");
if (_hit > 20) exitWith {_artilleryMag = _x;};
} forEach getArtilleryAmmo [_vehicle];
TRACE_1("getArtilleryAmmo",_artilleryMag);
if (_artilleryMag == "") exitWith {_targetASL = [];};
private _eta = _vehicle getArtilleryETA [ASLtoAGL _targetASL, _artilleryMag];
TRACE_1("getArtilleryETA",_eta);
if (_eta < 0) exitWith {
[ELSTRING(Interaction,NotInRange)] call FUNC(showMessage);
_targetASL = [];
};
["TOF: %1 sec", _eta toFixed 1] call FUNC(showMessage);
} else {
// Direct fire - Get a target position that will work
private _lis = lineIntersectsSurfaces [eyePos _unit, _targetASL, _unit, _vehicle];
if ((count _lis) > 0) then { // If point is hidden, unit won't fire, do a ray cast to find where they should shoot at
_targetASL = ((_lis select 0) select 0);
TRACE_1("using ray cast pos",_mousePosASL distance _targetASL);
};
if (_unit isEqualTo _vehicle) then { // Max range a unit can fire seems to be based on the weapon's config
private _distance = _targetASL vectorDistance eyePos _unit;
private _maxWeaponRange = getNumber (configFile >> "CfgWeapons" >> (currentWeapon _unit) >> "maxRange");
TRACE_3("",_distance,_maxWeaponRange,currentWeapon _unit);
if (_distance > (_maxWeaponRange - 50)) then {
if (_distance > (2.5 * _maxWeaponRange)) then {
_targetASL = [];
[ELSTRING(Interaction,NotInRange)] call FUNC(showMessage);
} else {
// 1-2.5x the weapon max range, find a virtual point the AI can shoot at (won't have accurate elevation, but it will put rounds downrange)
private _fakeElevation = (_distance / 100000) * (_distance - _maxWeaponRange);
_targetASL = (eyePos _unit) vectorAdd (((eyePos _unit) vectorFromTo _targetASL) vectorMultiply (_maxWeaponRange - 50)) vectorAdd [0,0,_fakeElevation];
TRACE_2("using virtual halfway point",_mousePosASL distance _targetASL,_fakeElevation);
};
};
};
};
if (_targetASL isEqualTo []) exitWith {};
private _units = [_unit];
if (_unit == (leader _unit)) then {_units = units _unit;};
if (_artilleryMag != "") then {_units = [gunner _vehicle];};
{
if (((_unit distance _x) < 30) && {!([_x] call EFUNC(common,isPlayer))} && {[_x] call EFUNC(common,isAwake)}) then {
TRACE_2("sending event",_x,_targetASL);
[QGVAR(suppressiveFire), [_x, _targetASL, _artilleryMag], _x] call CBA_fnc_targetEvent;
};
} forEach _units;
#ifdef DRAW_ZEUS_INFO
[eyePos _unit, _mousePosASL, [0,0,1,1]] call EFUNC(common,addLineToDebugDraw);
[eyePos _unit, _targetASL, [1,0,0,1]] call EFUNC(common,addLineToDebugDraw);
if (_unit != _vehicle) then {
[_vehicle] call CBA_fnc_addUnitTrackProjectiles;
} else {
{
[_x] call CBA_fnc_addUnitTrackProjectiles;
} forEach _units;
};
#endif
}, (localize LSTRING(ModuleSuppressiveFire_DisplayName))] call FUNC(getModuleDestination);

View File

@ -0,0 +1,39 @@
/*
* Author: bux, PabstMirror
* Commands the selected unit or group to start suppressive fire on the unit, group or location the module is placed on
*
* Arguments:
* 0: Unit <OBJECT>
* 1: Fire Pos ASL <ARRAY>
* 2: Artiller Magazine <STRING>
*
* Return Value:
* None
*
* Public: No
*/
#include "script_component.hpp"
params ["_unit", "_targetASL", "_artilleryMag"];
TRACE_4("moduleSuppressiveFireLocal",_unit,local _unit,_targetASL,_artilleryMag);
if (_artilleryMag != "") exitWith {
(vehicle _unit) doArtilleryFire [ASLtoAGL _targetASL, _artilleryMag, 4];
TRACE_3("doArtilleryFire",_unit,_targetASL,_artilleryMag);
};
[{
params ["_unit", "_burstsLeft", "_nextRun", "_targetASL", "_artilleryMag"];
if (!alive _unit) exitWith {true};
if (CBA_missionTime >= _nextRun) then {
_burstsLeft = _burstsLeft - 1;
_this set [1, _burstsLeft];
_this set [2, _nextRun + 4];
_unit doSuppressiveFire _targetASL;
TRACE_2("doSuppressiveFire",_unit,_targetASL);
};
(_burstsLeft <= 0)
}, {
TRACE_1("Done",_this);
}, [_unit, 11, CBA_missionTime, _targetASL, _artilleryMag]] call CBA_fnc_waitUntilAndExecute;

View File

@ -822,5 +822,8 @@
<German>Ungültiger Radius eingegeben</German>
<Korean>알 수 없는 반경 입력됨</Korean>
</Key>
<Key ID="STR_ACE_Zeus_ModuleSuppressiveFire_DisplayName">
<English>Suppressive Fire</English>
</Key>
</Package>
</Project>

View File

@ -24,6 +24,8 @@ Keeping track of Arma 3 issues that need to be fixed.
- [Heisenberg: T82108: Switching between optic modes of a sniper scope (AMS, DMS, MOS) will result in a blurred vision](https://feedback.bistudio.com/T82108)
- [AgentRev: T80668: setObjectTextureGlobal causing "Cannot load texture" errors when used with valid mission files](https://feedback.bistudio.com/T80668)
- [BaerMitUmlaut: T120030: Particles do not render properly since 1.62](https://feedback.bistudio.com/T120030)
- [Killzone_Kid: T79689: magazineTurretAmmo and setMagazineTurretAmmo do not function as expected if there are multiple magazines of the same type](https://feedback.bistudio.com/T79689)
- [nekoarrow: T122981: setMagazineTurretAmmo locality issue](https://feedback.bistudio.com/T122981)
**Resolved:**

View File

@ -104,7 +104,7 @@ Horus ATragMX software considers atmospheric conditions, gun data, ammunition, r
### 3.5 Example with `Add New Gun` in `GunList`
- Open the [Range Card]({{ site.baseurl }}/wiki/feature/rangecard.html) and check the cartridge, the caliber, the bullet weight and the muzzle velocities.
- Open the [Range Card]({{ site.baseurl }}/wiki/feature/rangecard.html) and check the cartridge, the bullet diameter, the bullet weight and the muzzle velocities.
- Open the AtragMx and the `Atmsphr` column, select `Default` and `Done`. [[Manual]](https://horusvision.com/download/manual_Horus_ATrag-v385.pdf#page=15)
- Select `Add New Gun` in the `GunList`. [[Manual]](https://horusvision.com/download/manual_Horus_ATrag-v385.pdf#page=25)
- Add a `New Gun Name` and `Open Gun`.
@ -113,16 +113,18 @@ Horus ATragMX software considers atmospheric conditions, gun data, ammunition, r
- Select `M` (Metric unit) at the top right.
- Open the `Muz Vel Table` in the `Options` menu or click on `MV` in the `Gun` column.
- Edit manually the `Muzzle Velocity Table` according with the [Range Card]({{ site.baseurl }}/wiki/feature/rangecard.html) and `Done`. [[Manual]](https://horusvision.com/download/manual_Horus_ATrag-v385.pdf#page=22)
- The `C1 coefficient` of the bullet can be found, for example, in the Eden Editor `Config Viewer`:
- The `C1 coefficient` of the bullet can be found with the Eden Editor `Config Viewer`:
> configfile >> "CfgAmmo" >> "Range card cartridge" >> "ACE_ballisticCoefficients"
> configfile >> "CfgAmmo" >> "Range card cartridge" >> "ACE_dragModel"
- *The AtragMx accepts only **G1 ballistic coefficient**.*
- *G7 ballistic coefficient can be converted, for example, with the online [JBM Ballistics Calculators](http://www.jbmballistics.com/cgi-bin/jbmgf-5.1.cgi)*.
- Optionally, `Save Gun` and `Done` in the `GunList`.
For advanced users, the ballistic coefficient can be calculated by using the [360 Degree Training Course mission](https://forums.bistudio.com/forums/topic/171228-sp-360-degree-training-course/) as a chronograph at different distances and [JBM Ballistics Calculators](http://www.jbmballistics.com/cgi-bin/jbmbcv-5.1.cgi) for example, or an another ballistic software at your own convenience.
> Note: The ballistic coefficient can be calculated by using the [360 Degree Training Course mission](https://forums.bistudio.com/forums/topic/171228-sp-360-degree-training-course/) as a chronograph at different distances and [JBM Ballistics Calculators](http://www.jbmballistics.com/cgi-bin/jbmbcv-5.1.cgi) for example, an another ballistic software at your own convenience, or the [AtragMx Truing Tool](#33-example-with-truing-tool).
## 4. Official Manual and Horus Videos

View File

@ -170,3 +170,34 @@ Name | Use
0 | `player` | Unit explosive will connect to
1 | `claymore1` | Explosive object that will be connected
2 | `"ACE_Clacker"` | Detonator type class name
#### 5.3 Detonation Handler.
Detonation Handlers are called when something attempts to trigger an explosive. They can be used to block the detonation.
These are only used for script based triggers like clackers, cellphone and timers (anything that uses `detonateExplosive`).
Sensor based triggers like AT Mines, Tripwires are uneffected.
All added handlers will be called, if ANY one returns false, the detonation will be blocked.
`[{CODE}] call ace_explosives_fnc_addDetonateHandler;`
CODE will be passed `[Unit<OBJECT>, MaxRange <NUMBER>, Explosive <OBJECT>, FuzeTime <NUMBER>, TriggerItem <STRING>]` and should return a bool: true(allowed) / false(blocked)
#### 5.3.1 Example
Jammer that blocks RF triggers:
```cpp
[{
params ["_unit", "_range", "_explosive", "_fuzeTime", "_triggerItem"];
if (_triggerItem == "ace_cellphone") exitWith { systemChat "Blocking Cell Phone"; false }; // always block cell phones
if (_triggerItem == "ace_m26_clacker") exitWith {
_range = _range / 1000;
private _actualRange = _unit distance _explosive;
systemChat format ["Limited Range For RF Clacker [%1m / %2m]", _actualRange toFixed 1, _range toFixed 1];
(_actualRange < _range) // return bool
};
// allow anything else (like timers / wired clackers)
true
}] call ace_explosives_fnc_addDetonateHandler;
```

View File

@ -1,7 +1,7 @@
class CfgAmmo {
class Default;
class BulletBase;
class R3F_9x19_Ball: BulletBase {
class R3F_9x19_Ball: BulletBase { // ACE_9x19_Ball
ACE_caliber = 9.017;
ACE_bulletLength = 15.494;
ACE_bulletMass = 8.0352;
@ -13,7 +13,7 @@ class CfgAmmo {
ACE_muzzleVelocities[] = {340, 370, 400};
ACE_barrelLengths[] = {101.6, 127.0, 228.6};
};
class R3F_556x45_Ball: BulletBase {
class R3F_556x45_Ball: BulletBase { // B_556x45_Ball, AtragMx GunList: 5.56x45mm M855
ACE_caliber = 5.69;
ACE_bulletLength = 23.012;
ACE_bulletMass = 4.0176;
@ -25,7 +25,7 @@ class CfgAmmo {
ACE_muzzleVelocities[] = {723, 764, 796, 825, 843, 866, 878, 892, 906, 915, 922, 900};
ACE_barrelLengths[] = {210.82, 238.76, 269.24, 299.72, 330.2, 360.68, 391.16, 419.1, 449.58, 480.06, 508.0, 609.6};
};
class R3F_762x51_Ball: BulletBase {
class R3F_762x51_Ball: BulletBase { // B_762x51_Ball, AtragMx GunList: 7.62x51mm M80
ACE_caliber = 7.823;
ACE_bulletLength = 28.956;
ACE_bulletMass = 9.4608;
@ -37,7 +37,7 @@ class CfgAmmo {
ACE_muzzleVelocities[] = {700, 800, 820, 833, 845};
ACE_barrelLengths[] = {254.0, 406.4, 508.0, 609.6, 660.4};
};
class R3F_127x99_Ball: BulletBase {
class R3F_127x99_Ball: BulletBase { // B_127x99_Ball, AtragMx GunList: 12.7x99mm
ACE_caliber = 12.954;
ACE_bulletLength = 58.674;
ACE_bulletMass = 41.9256;
@ -49,7 +49,7 @@ class CfgAmmo {
ACE_muzzleVelocities[] = {900};
ACE_barrelLengths[] = {700};
};
class R3F_127x99_PEI: R3F_127x99_Ball {
class R3F_127x99_PEI: R3F_127x99_Ball { // B_127x99_Ball, AtragMx GunList: 12.7x99mm
ACE_caliber = 12.954;
ACE_bulletLength = 58.674;
ACE_bulletMass = 41.9256;
@ -61,7 +61,7 @@ class CfgAmmo {
ACE_muzzleVelocities[] = {900};
ACE_barrelLengths[] = {700};
};
class R3F_127x99_Ball2: BulletBase {
class R3F_127x99_Ball2: BulletBase { // B_127x99_Ball, AtragMx GunList: 12.7x99mm
ACE_caliber = 12.954;
ACE_bulletLength = 58.674;
ACE_bulletMass = 41.9256;
@ -73,7 +73,7 @@ class CfgAmmo {
ACE_muzzleVelocities[] = {900};
ACE_barrelLengths[] = {736.6};
};
class R3F_127x99_PEI2: R3F_127x99_Ball2 {
class R3F_127x99_PEI2: R3F_127x99_Ball2 { // B_127x99_Ball, AtragMx GunList: 12.7x99mm
ACE_caliber = 12.954;
ACE_bulletLength = 58.674;
ACE_bulletMass = 41.9256;
@ -85,7 +85,7 @@ class CfgAmmo {
ACE_muzzleVelocities[] = {900};
ACE_barrelLengths[] = {736.6};
};
class R3F_127x99_Ball3: BulletBase {
class R3F_127x99_Ball3: BulletBase { // B_127x99_Ball, AtragMx GunList: 12.7x99mm
ACE_caliber = 12.954;
ACE_bulletLength = 58.674;
ACE_bulletMass = 41.9256;

View File

@ -1,81 +1,138 @@
class Mode_SemiAuto;
class CfgWeapons {
class Pistol_Base_F;
class Rifle_Base_F;
class R3F_Famas_F1: Rifle_Base_F {
ACE_barrelTwist=304.8;
ACE_barrelLength=488;
ACE_RailHeightAboveBore = 10.6;
ACE_barrelTwist = 304.8; // 12"
ACE_barrelLength = 488.0;
};
class R3F_Famas_surb: R3F_Famas_F1 {
ACE_barrelTwist=304.8;
ACE_barrelLength=403.86;
ACE_RailHeightAboveBore = 5.4;
ACE_barrelTwist = 228.6; // 9"
ACE_barrelLength = 450.0; // Beretta barrel
};
class R3F_Famas_G2: R3F_Famas_F1 {
ACE_RailHeightAboveBore = 10.6;
ACE_barrelTwist = 228.6; // 9"
ACE_barrelLength = 488.0;
};
class R3F_Famas_felin: R3F_Famas_G2 {
ACE_RailHeightAboveBore = 5.4;
ACE_barrelTwist = 177.8; // 7"
ACE_barrelLength = 450.0; // Beretta barrel
};
class R3F_FRF2: Rifle_Base_F {
ACE_RailHeightAboveBore = 2.2;
ACE_barrelTwist = 304.8;
ACE_barrelLength=650;
ACE_barrelLength = 650.0;
class Single: Mode_SemiAuto {
dispersion = 0.00029; // 1 MOA
};
};
class R3F_PGM_Hecate_II: Rifle_Base_F {
ACE_RailHeightAboveBore = 2.0;
ACE_barrelTwist = 381.0;
ACE_barrelLength=700;
ACE_barrelLength = 700.0;
class Single: Mode_SemiAuto {
dispersion = 0.00029;
};
};
class R3F_M107: Rifle_Base_F {
ACE_RailHeightAboveBore = 3.6;
ACE_barrelTwist = 381.0;
ACE_barrelLength = 736.6;
class Single: Mode_SemiAuto {
dispersion = 0.00029;
};
class R3F_TAC50: Rifle_Base_F
{
};
class R3F_TAC50: Rifle_Base_F {
ACE_RailHeightAboveBore = 3.2;
ACE_barrelTwist = 381.0;
ACE_barrelLength = 736.6;
class Single: Mode_SemiAuto {
dispersion = 0.00029;
};
};
class R3F_Minimi: Rifle_Base_F {
ACE_RailHeightAboveBore = 4.0;
ACE_barrelTwist = 177.8;
ACE_barrelLength = 347.98;
};
class R3F_Minimi_HG: R3F_Minimi {
};
class R3F_Minimi_762: R3F_Minimi {
ACE_RailHeightAboveBore = 4.0;
ACE_barrelTwist = 304.8;
ACE_barrelLength = 502.92;
};
class R3F_Minimi_762_HG: R3F_Minimi_762 {
class R3F_SIG551: Rifle_Base_F {
ACE_RailHeightAboveBore = 4.2;
ACE_barrelTwist = 177.8;
ACE_barrelLength = 363.0;
};
class R3F_HK417M: Rifle_Base_F {
ACE_RailHeightAboveBore = 3.4;
ACE_barrelTwist = 279.4;
ACE_barrelLength=406;
ACE_barrelLength = 406.0;
};
class R3F_HK417S_HG: R3F_HK417M
{
class R3F_HK417S_HG: R3F_HK417M {
ACE_RailHeightAboveBore = 3.4;
ACE_barrelTwist = 279.4;
ACE_barrelLength=305;
ACE_barrelLength = 305.0;
};
class R3F_HK417L: R3F_HK417M {
ACE_RailHeightAboveBore = 3.4;
ACE_barrelTwist = 279.4;
ACE_barrelLength=508;
ACE_barrelLength = 508.0;
class Single: Mode_SemiAuto {
dispersion = 0.00029;
};
};
class R3F_HK416M: Rifle_Base_F {
ACE_RailHeightAboveBore = 3.4;
ACE_barrelTwist = 177.8;
ACE_barrelLength = 368.3;
};
class R3F_HK416M_HG: R3F_HK416M {};
class R3F_HK416S_HG: R3F_HK416M_HG {
ACE_RailHeightAboveBore = 3.4;
ACE_barrelTwist = 177.8;
ACE_barrelLength = 279.4;
};
class R3F_MP5SD: Rifle_Base_F {
ACE_RailHeightAboveBore = 4.5;
ACE_barrelTwist = 254.0;
ACE_barrelLength = 144.78;
};
class R3F_MP5A5: R3F_MP5SD {
ACE_RailHeightAboveBore = 4.5;
ACE_barrelTwist = 254.0;
ACE_barrelLength = 226.06;
};
class R3F_M4S90: Rifle_Base_F {
ACE_RailHeightAboveBore = 2.2;
ACE_twistDirection = 0;
ACE_barrelTwist = 0;
ACE_barrelLength = 144.78;
};
class R3F_PAMAS: Pistol_Base_F {
ACE_barrelTwist=248.92;
ACE_barrelLength=124.46;
ACE_barrelTwist = 250.0;
ACE_barrelLength = 125.0;
};
class R3F_HKUSP: Pistol_Base_F {
ACE_barrelTwist = 250.0;
ACE_barrelLength = 121.0;
};
class ItemCore;
class InventoryOpticsItem_Base_F;
class R3F_AIMPOINT: ItemCore {
ACE_ScopeHeightAboveRail = 3.0;
};
class R3F_EOTECH: ItemCore {
ACE_ScopeHeightAboveRail = 3.8;
};
class R3F_J4: ItemCore {
ACE_ScopeHeightAboveRail = 3.0;
ACE_ScopeAdjust_Vertical[] = {-8, 8};
ACE_ScopeAdjust_Horizontal[] = {-8, 8};
ACE_ScopeAdjust_VerticalIncrement = 0.2;
@ -89,7 +146,14 @@ class CfgWeapons {
};
};
};
class R3F_FELIN: ItemCore {
ACE_ScopeHeightAboveRail = 4.2;
};
class R3F_FELIN_FRF2: ItemCore {
ACE_ScopeHeightAboveRail = 4.0;
};
class R3F_J8: ItemCore {
ACE_ScopeHeightAboveRail = 4.4;
ACE_ScopeAdjust_Vertical[] = {-10, 10};
ACE_ScopeAdjust_Horizontal[] = {-10, 10};
ACE_ScopeAdjust_VerticalIncrement = 0.1;
@ -103,8 +167,9 @@ class CfgWeapons {
};
};
};
class R3F_J8_MILDOT: R3F_J8 {
ACE_ScopeAdjust_Vertical[] = { -10, 10 };
class R3F_J8_MILDOT: R3F_J8 { // Scope rail 30 MOA
ACE_ScopeHeightAboveRail = 4.4;
ACE_ScopeAdjust_Vertical[] = {-2, 18};
ACE_ScopeAdjust_Horizontal[] = {-10, 10};
ACE_ScopeAdjust_VerticalIncrement = 0.1;
ACE_ScopeAdjust_HorizontalIncrement = 0.1;
@ -118,6 +183,7 @@ class CfgWeapons {
};
};
class R3F_J10: ItemCore {
ACE_ScopeHeightAboveRail = 4.4;
ACE_ScopeAdjust_Vertical[] = {-10, 10};
ACE_ScopeAdjust_Horizontal[] = {-10, 10};
ACE_ScopeAdjust_VerticalIncrement = 0.1;
@ -131,8 +197,9 @@ class CfgWeapons {
};
};
};
class R3F_J10_MILDOT: R3F_J10 {
ACE_ScopeAdjust_Vertical[] = { -10, 10 };
class R3F_J10_MILDOT: R3F_J10 { // Scope rail 30 MOA
ACE_ScopeHeightAboveRail = 4.4;
ACE_ScopeAdjust_Vertical[] = {-2, 18};
ACE_ScopeAdjust_Horizontal[] = {-10, 10};
ACE_ScopeAdjust_VerticalIncrement = 0.1;
ACE_ScopeAdjust_HorizontalIncrement = 0.1;
@ -146,6 +213,7 @@ class CfgWeapons {
};
};
class R3F_ZEISS: ItemCore {
ACE_ScopeHeightAboveRail = 4.6;
ACE_ScopeAdjust_Vertical[] = {0, 23};
ACE_ScopeAdjust_Horizontal[] = {-7, 7};
ACE_ScopeAdjust_VerticalIncrement = 0.1;
@ -160,9 +228,10 @@ class CfgWeapons {
};
};
class R3F_NF: ItemCore {
ACE_ScopeAdjust_Vertical[] = { -0.9, 34 };
ACE_ScopeHeightAboveRail = 4.2;
ACE_ScopeAdjust_Vertical[] = {0, 30};
ACE_ScopeAdjust_Horizontal[] = {-11, 11};
ACE_ScopeAdjust_VerticalIncrement = 0.2;
ACE_ScopeAdjust_VerticalIncrement = 0.1;
ACE_ScopeAdjust_HorizontalIncrement = 0.1;
class ItemInfo: InventoryOpticsItem_Base_F {
class OpticsModes {
@ -174,8 +243,9 @@ class CfgWeapons {
};
};
class R3F_NF42: ItemCore {
ACE_ScopeAdjust_Vertical[] = { -27.3, 27.3 };
ACE_ScopeAdjust_Horizontal[] = { -27.3, 27.3};
ACE_ScopeHeightAboveRail = 4.2;
ACE_ScopeAdjust_Vertical[] = {0, 24};
ACE_ScopeAdjust_Horizontal[] = {-9, 9};
ACE_ScopeAdjust_VerticalIncrement = 0.1;
ACE_ScopeAdjust_HorizontalIncrement = 0.1;
class ItemInfo: InventoryOpticsItem_Base_F {
@ -187,4 +257,7 @@ class CfgWeapons {
};
};
};
class R3F_OB50: ItemCore {
ACE_ScopeHeightAboveRail = 4.0;
};
};

View File

@ -28,7 +28,7 @@
class EGVAR(refuel,Refuel) { \
displayName = ECSTRING(refuel,Refuel); \
distance = 7; \
condition = "true"; \
condition = "alive _target"; \
statement = ""; \
showDisabled = 0; \
priority = 2; \
@ -105,6 +105,17 @@ class CfgVehicles {
};
class CommanderOptics;
};
class Air;
class Helicopter: Air {
class Turrets;
};
class Helicopter_Base_F: Helicopter {
class Turrets: Turrets {
class MainTurret;
};
};
class rhs_bmd_base: Tank_F {
EGVAR(refuel,fuelCapacity) = 300;
class Turrets: Turrets {
@ -279,7 +290,6 @@ class CfgVehicles {
EGVAR(refuel,fuelCapacity) = 3600;
};
class Helicopter_Base_F;
class Helicopter_Base_H: Helicopter_Base_F {
class EventHandlers;
};
@ -334,15 +344,33 @@ class CfgVehicles {
};
};
class Heli_Attack_02_base_F;
class Heli_Attack_02_base_F: Helicopter_Base_F {};
class rhs_mi28_base: Heli_Attack_02_base_F {
class Turrets: Turrets {
class MainTurret: MainTurret {
EGVAR(fcs,enabled) = 0;
};
};
};
class RHS_Ka52_base : Heli_Attack_02_base_F {
EGVAR(refuel,fuelCapacity) = 1870;
EGVAR(fastroping,enabled) = 0;
class Turrets: Turrets {
class MainTurret: MainTurret {
EGVAR(fcs,enabled) = 0;
};
};
};
class RHS_Mi24_base : Heli_Attack_02_base_F {
EGVAR(refuel,fuelCapacity) = 1851;
EGVAR(fastroping,enabled) = 0;
class Turrets: Turrets {
class MainTurret: MainTurret {
EGVAR(fcs,enabled) = 0;
};
};
};
class rhs_t80b : rhs_tank_base {

View File

@ -41,7 +41,7 @@
class EGVAR(refuel,Refuel) { \
displayName = ECSTRING(refuel,Refuel); \
distance = 7; \
condition = "true"; \
condition = "alive _target"; \
statement = ""; \
showDisabled = 0; \
priority = 2; \

66
tools/sqf_linter.py Normal file
View File

@ -0,0 +1,66 @@
#!/usr/bin/env python3
# Requires: https://github.com/LordGolias/sqf
import fnmatch
import os
import sys
import argparse
from sqf.parser import parse
import sqf.analyzer
from sqf.exceptions import SQFParserError
def analyze(filename, writer=sys.stdout):
warnings = 0
errors = 0
with open(filename, 'r') as file:
code = file.read()
try:
result = parse(code)
except SQFParserError as e:
print("{}:".format(filename))
writer.write(' [%d,%d]:%s\n' % (e.position[0], e.position[1] - 1, e.message))
return 0, 1
exceptions = sqf.analyzer.analyze(result).exceptions
if (exceptions):
print("{}:".format(filename))
for e in exceptions:
if (e.message.startswith("error")):
errors += 1
else:
warnings += 1
writer.write(' [%d,%d]:%s\n' % (e.position[0], e.position[1] - 1, e.message))
return warnings, errors
def main():
print("#########################")
print("# Lint Check #")
print("#########################")
sqf_list = []
all_warnings = 0
all_errors = 0
parser = argparse.ArgumentParser()
parser.add_argument('-m','--module', help='only search specified module addon folder', required=False, default=".")
args = parser.parse_args()
for root, dirnames, filenames in os.walk('../addons' + '/' + args.module):
for filename in fnmatch.filter(filenames, '*.sqf'):
sqf_list.append(os.path.join(root, filename))
for filename in sqf_list:
warnings, errors = analyze(filename)
all_warnings += warnings
all_errors += errors
print ("Parse Errors {0} - Warnings {1}".format(all_errors,all_warnings))
# return (all_errors + all_warnings)
return all_errors
if __name__ == "__main__":
main()