2015-01-12 18:22:58 +00:00
// ACE - Common
2015-12-30 07:07:55 +00:00
// #define ENABLE_PERFORMANCE_COUNTERS
2016-01-13 00:18:12 +00:00
// #define DEBUG_MODE_FULL
2015-09-21 15:00:53 +00:00
#include "script_component.hpp"
2015-08-30 20:26:43 +00:00
2015-09-21 15:00:53 +00:00
//////////////////////////////////////////////////
// Get Map Data
//////////////////////////////////////////////////
//Find MGRS zone and 100km grid for current map
[] call FUNC(getMGRSdata);
//Prepare variables for FUNC(getMapGridFromPos)/FUNC(getMapPosFromGrid)
[] call FUNC(getMapGridData);
//////////////////////////////////////////////////
// Eventhandlers
//////////////////////////////////////////////////
2016-01-13 00:18:12 +00:00
//Status Effect EHs:
2016-06-03 19:07:49 +00:00
[QGVAR(setStatusEffect), {_this call FUNC(statusEffect_set)}] call CBA_fnc_addEventHandler;
2020-08-23 00:37:15 +00:00
["forceWalk", false, ["ace_advanced_fatigue", "ACE_SwitchUnits", "ACE_Attach", "ACE_dragging", "ACE_Explosives", "ACE_Ladder", "ACE_Sandbag", "ACE_refuel", "ACE_rearm", "ACE_Trenches", "ace_medical_fracture"]] call FUNC(statusEffect_addType);
2019-05-12 04:13:59 +00:00
["blockSprint", false, ["ace_advanced_fatigue", "ace_medical_fracture"]] call FUNC(statusEffect_addType);
2017-12-06 16:22:07 +00:00
["setCaptive", true, [QEGVAR(captives,Handcuffed), QEGVAR(captives,Surrendered)]] call FUNC(statusEffect_addType);
2017-08-22 18:27:11 +00:00
["blockDamage", false, ["fixCollision", "ACE_cargo"]] call FUNC(statusEffect_addType);
2016-05-03 18:52:43 +00:00
["blockEngine", false, ["ACE_Refuel"]] call FUNC(statusEffect_addType);
2017-12-07 17:26:21 +00:00
["blockThrow", false, ["ACE_Attach", "ACE_concertina_wire", "ACE_dragging", "ACE_Explosives", "ACE_Ladder", "ACE_rearm", "ACE_refuel", "ACE_Sandbag", "ACE_Trenches", "ACE_tripod"]] call FUNC(statusEffect_addType);
2017-12-06 16:22:07 +00:00
["setHidden", true, ["ace_unconscious"]] call FUNC(statusEffect_addType);
2021-09-25 16:16:15 +00:00
["blockRadio", false, [QEGVAR(captives,Handcuffed), QEGVAR(captives,Surrendered), "ace_unconscious"]] call FUNC(statusEffect_addType);
2022-05-08 18:20:15 +00:00
["blockSpeaking", false, ["ace_unconscious"]] call FUNC(statusEffect_addType);
2016-01-13 00:18:12 +00:00
2016-06-03 19:07:49 +00:00
[QGVAR(forceWalk), {
2016-01-13 00:18:12 +00:00
params ["_object", "_set"];
TRACE_2("forceWalk EH",_object,_set);
_object forceWalk (_set > 0);
2016-05-22 15:29:05 +00:00
}] call CBA_fnc_addEventHandler;
2017-12-06 16:22:07 +00:00
2016-06-03 19:07:49 +00:00
[QGVAR(blockSprint), { //Name reversed from `allowSprint` because we want NOR logic
2016-01-16 23:27:42 +00:00
params ["_object", "_set"];
TRACE_2("blockSprint EH",_object,_set);
_object allowSprint (_set == 0);
2016-05-22 15:29:05 +00:00
}] call CBA_fnc_addEventHandler;
2017-12-06 16:22:07 +00:00
2016-09-30 08:38:27 +00:00
[QGVAR(setAnimSpeedCoef), {
params ["_object", "_set"];
_object setAnimSpeedCoef _set;
}] call CBA_fnc_addEventHandler;
2017-12-23 00:47:43 +00:00
2016-06-03 19:07:49 +00:00
[QGVAR(setCaptive), {
2016-01-13 00:18:12 +00:00
params ["_object", "_set"];
2016-01-16 23:27:42 +00:00
TRACE_2("setCaptive EH",_object,_set);
2017-12-06 16:22:07 +00:00
_object setCaptive (_set > 0);
}] call CBA_fnc_addEventHandler;
[QGVAR(setHidden), {
params ["_object", "_set"];
TRACE_2("setHidden EH",_object,_set);
2018-02-21 10:05:17 +00:00
// May report nil. Default to factor 1.
private _vis = [_object getUnitTrait "camouflageCoef"] param [0, 1];
2017-12-06 15:55:01 +00:00
if (_set > 0) then {
2017-12-09 03:39:35 +00:00
if (_vis != 0) then {
_object setVariable [QGVAR(oldVisibility), _vis];
2017-12-06 15:55:01 +00:00
_object setUnitTrait ["camouflageCoef", 0];
2017-12-29 01:48:20 +00:00
{
2018-01-02 15:26:13 +00:00
if (side _x != side group _object) then {
_x forgetTarget _object;
};
2017-12-29 01:48:20 +00:00
} forEach allGroups;
2017-12-06 15:55:01 +00:00
};
} else {
2017-12-09 03:39:35 +00:00
_vis = _object getVariable [QGVAR(oldVisibility), _vis];
_object setUnitTrait ["camouflageCoef", _vis];
2017-12-06 15:55:01 +00:00
};
2016-05-22 15:29:05 +00:00
}] call CBA_fnc_addEventHandler;
2017-12-06 16:22:07 +00:00
2021-09-25 16:16:15 +00:00
[QGVAR(blockRadio), {
params ["_object", "_set"];
TRACE_2("blockRadio EH",_object,_set);
if (_object isEqualTo ACE_Player && {_set > 0}) then {
call FUNC(endRadioTransmission);
};
2022-01-30 17:56:20 +00:00
if (["task_force_radio"] call FUNC(isModLoaded)) then {
2021-09-25 16:16:15 +00:00
_object setVariable ["tf_unable_to_use_radio", _set > 0, true];
};
2022-01-30 17:56:20 +00:00
if (["acre_main"] call FUNC(isModLoaded)) then {
2022-03-08 22:40:48 +00:00
_object setVariable ["acre_sys_core_isDisabledRadio", _set > 0, true];
2021-09-25 16:16:15 +00:00
};
}] call CBA_fnc_addEventHandler;
2022-05-08 18:20:15 +00:00
[QGVAR(blockSpeaking), {
params ["_object", "_set"];
TRACE_2("blockSpeaking EH",_object,_set);
if (["acre_main"] call FUNC(isModLoaded)) then {
_object setVariable ["acre_sys_core_isDisabled", _set > 0, true];
};
if (["task_force_radio"] call FUNC(isModLoaded)) then {
_object setVariable ["tf_voiceVolume", [1, 0] select (_set > 0), true];
};
}] call CBA_fnc_addEventHandler;
2016-06-03 19:07:49 +00:00
[QGVAR(blockDamage), { //Name reversed from `allowDamage` because we want NOR logic
2016-01-13 00:18:12 +00:00
params ["_object", "_set"];
if ((_object isKindOf "CAManBase") && {(["ace_medical"] call FUNC(isModLoaded))}) then {
TRACE_2("blockDamage EH (using medical)",_object,_set);
2017-12-07 17:26:21 +00:00
_object setVariable [QEGVAR(medical,allowDamage), (_set == 0), true];
2016-01-13 00:18:12 +00:00
} else {
TRACE_2("blockDamage EH (using allowDamage)",_object,_set);
_object allowDamage (_set == 0);
};
2016-05-22 15:29:05 +00:00
}] call CBA_fnc_addEventHandler;
2017-12-06 16:22:07 +00:00
2016-06-03 19:07:49 +00:00
[QGVAR(blockEngine), {
2016-05-03 18:52:43 +00:00
params ["_vehicle", "_set"];
_vehicle setVariable [QGVAR(blockEngine), _set > 0, true];
_vehicle engineOn false;
2016-05-22 15:29:05 +00:00
}] call CBA_fnc_addEventHandler;
2016-01-13 00:18:12 +00:00
2019-03-24 08:26:00 +00:00
[QGVAR(setMass), {
params ["_object", "_mass"];
_object setMass _mass;
}] call CBA_fnc_addEventHandler;
2015-12-18 17:08:10 +00:00
//Add a fix for BIS's zeus remoteControl module not reseting variables on DC when RC a unit
//This variable is used for isPlayer checks
if (isServer) then {
addMissionEventHandler ["HandleDisconnect", {
params ["_dcPlayer"];
private _zeusLogic = getAssignedCuratorLogic _dcPlayer;
if ((!isNil "_zeusLogic") && {!isNull _zeusLogic}) then {
{
if ((_x getvariable ["bis_fnc_moduleRemoteControl_owner", objnull]) isEqualTo _dcPlayer) exitWith {
2016-10-02 10:55:31 +00:00
INFO_3("[%1] DC - Was Zeus [%2] while controlling unit [%3] - manually clearing `bis_fnc_moduleRemoteControl_owner`", [_x] call FUNC(getName), _dcPlayer, _x);
2015-12-18 17:08:10 +00:00
_x setVariable ["bis_fnc_moduleRemoteControl_owner", nil, true];
};
2015-12-20 03:17:36 +00:00
nil
2015-12-18 17:08:10 +00:00
} count (curatorEditableObjects _zeusLogic);
};
}];
};
2015-09-21 15:00:53 +00:00
// Event to log Fix Headbug output
2016-06-03 19:38:16 +00:00
[QGVAR(headbugFixUsed), {
2015-09-21 15:00:53 +00:00
params ["_profileName", "_animation"];
2016-10-02 10:55:31 +00:00
INFO_2("Headbug Used: Name: %1, Animation: %2",_profileName,_animation);
2016-05-22 15:29:05 +00:00
}] call CBA_fnc_addEventHandler;
2015-08-02 01:01:35 +00:00
2016-06-04 10:12:56 +00:00
[QGVAR(fixCollision), FUNC(fixCollision)] call CBA_fnc_addEventHandler;
[QGVAR(fixFloating), FUNC(fixFloating)] call CBA_fnc_addEventHandler;
[QGVAR(fixPosition), FUNC(fixPosition)] call CBA_fnc_addEventHandler;
2015-08-02 01:01:35 +00:00
2019-09-05 20:56:53 +00:00
["ace_loadPersonEvent", LINKFUNC(loadPersonLocal)] call CBA_fnc_addEventHandler;
["ace_unloadPersonEvent", LINKFUNC(unloadPersonLocal)] call CBA_fnc_addEventHandler;
2015-06-11 22:56:11 +00:00
2016-06-04 10:12:56 +00:00
[QGVAR(lockVehicle), {
2015-03-18 10:29:58 +00:00
_this setVariable [QGVAR(lockStatus), locked _this];
_this lock 2;
2016-05-22 15:29:05 +00:00
}] call CBA_fnc_addEventHandler;
2015-03-18 10:29:58 +00:00
2016-06-04 10:12:56 +00:00
[QGVAR(unlockVehicle), {
2015-03-18 10:29:58 +00:00
_this lock (_this getVariable [QGVAR(lockStatus), locked _this]);
2016-05-22 15:29:05 +00:00
}] call CBA_fnc_addEventHandler;
2016-06-04 10:12:56 +00:00
[QGVAR(setDir), {(_this select 0) setDir (_this select 1)}] call CBA_fnc_addEventHandler;
[QGVAR(setFuel), {(_this select 0) setFuel (_this select 1)}] call CBA_fnc_addEventHandler;
[QGVAR(engineOn), {(_this select 0) engineOn (_this select 1)}] call CBA_fnc_addEventHandler;
[QGVAR(setSpeaker), {(_this select 0) setSpeaker (_this select 1)}] call CBA_fnc_addEventHandler;
[QGVAR(selectLeader), {(_this select 0) selectLeader (_this select 1)}] call CBA_fnc_addEventHandler;
[QGVAR(setVelocity), {(_this select 0) setVelocity (_this select 1)}] call CBA_fnc_addEventHandler;
[QGVAR(playMove), {(_this select 0) playMove (_this select 1)}] call CBA_fnc_addEventHandler;
[QGVAR(playMoveNow), {(_this select 0) playMoveNow (_this select 1)}] call CBA_fnc_addEventHandler;
2016-07-12 14:16:01 +00:00
[QGVAR(playAction), {(_this select 0) playAction (_this select 1)}] call CBA_fnc_addEventHandler;
[QGVAR(playActionNow), {(_this select 0) playActionNow (_this select 1)}] call CBA_fnc_addEventHandler;
2016-06-04 10:12:56 +00:00
[QGVAR(switchMove), {(_this select 0) switchMove (_this select 1)}] call CBA_fnc_addEventHandler;
[QGVAR(setVectorDirAndUp), {(_this select 0) setVectorDirAndUp (_this select 1)}] call CBA_fnc_addEventHandler;
2017-09-21 18:43:35 +00:00
[QGVAR(addWeaponItem), {(_this select 0) addWeaponItem [(_this select 1), (_this select 2)]}] call CBA_fnc_addEventHandler;
2015-03-24 18:07:39 +00:00
2019-05-03 15:03:17 +00:00
[QGVAR(setVanillaHitPointDamage), {
params ["_object", "_hitPointAnddamage"];
2019-05-03 15:09:16 +00:00
private _damageDisabled = !isDamageAllowed _object;
2019-05-03 15:03:17 +00:00
2019-05-03 15:09:16 +00:00
if (_damageDisabled) then {
2019-05-03 15:03:17 +00:00
_object allowDamage true;
};
_object setHitPointDamage _hitPointAnddamage;
2019-05-03 15:09:16 +00:00
if (_damageDisabled) then {
2019-05-03 15:03:17 +00:00
_object allowDamage false;
};
}] call CBA_fnc_addEventHandler;
2016-05-21 17:59:44 +00:00
// Request framework
2016-06-03 00:29:30 +00:00
[QGVAR(requestCallback), FUNC(requestCallback)] call CBA_fnc_addEventHandler;
[QGVAR(receiveRequest), FUNC(receiveRequest)] call CBA_fnc_addEventHandler;
2016-05-21 17:59:44 +00:00
2016-06-03 00:29:30 +00:00
[QGVAR(systemChatGlobal), {systemChat _this}] call CBA_fnc_addEventHandler;
2016-05-21 17:59:44 +00:00
2015-07-03 01:14:58 +00:00
if (isServer) then {
2016-06-03 19:38:16 +00:00
[QGVAR(hideObjectGlobal), {(_this select 0) hideObjectGlobal (_this select 1)}] call CBA_fnc_addEventHandler;
[QGVAR(enableSimulationGlobal), {(_this select 0) enableSimulationGlobal (_this select 1)}] call CBA_fnc_addEventHandler;
2017-04-11 14:59:32 +00:00
[QGVAR(setShotParents), {(_this select 0) setShotParents [_this select 1, _this select 2]}] call CBA_fnc_addEventHandler;
2016-06-03 00:29:30 +00:00
["ace_setOwner", {(_this select 0) setOwner (_this select 1)}] call CBA_fnc_addEventHandler;
[QGVAR(serverLog), FUNC(serverLog)] call CBA_fnc_addEventHandler;
2019-12-07 21:18:50 +00:00
[QGVAR(claimSafe), LINKFUNC(claimSafeServer)] call CBA_fnc_addEventHandler;
2015-07-03 01:14:58 +00:00
};
2015-01-11 16:42:31 +00:00
2015-09-21 15:00:53 +00:00
//////////////////////////////////////////////////
// Set up remote execution
//////////////////////////////////////////////////
2015-01-11 16:42:31 +00:00
2015-04-18 02:26:27 +00:00
// Synced ACE events
// Handle JIP scenario
2015-09-21 15:00:53 +00:00
if (!isServer) then {
2016-06-03 19:38:16 +00:00
["ace_playerJIP", {
2016-10-02 10:55:31 +00:00
INFO("JIP event synchronization initialized");
2016-06-04 19:05:26 +00:00
["ACEa", [player]] call CBA_fnc_serverEvent;
2016-05-22 15:29:05 +00:00
}] call CBA_fnc_addEventHandler;
2015-04-18 02:26:27 +00:00
} else {
2016-06-04 19:05:26 +00:00
["ACEa", FUNC(_handleRequestAllSyncedEvents)] call CBA_fnc_addEventHandler;
2015-04-18 02:26:27 +00:00
};
2015-09-21 15:00:53 +00:00
2016-06-04 19:05:26 +00:00
["ACEe", FUNC(_handleSyncedEvent)] call CBA_fnc_addEventHandler;
["ACEs", FUNC(_handleRequestSyncedEvent)] call CBA_fnc_addEventHandler;
2015-09-21 15:00:53 +00:00
2015-08-06 05:28:43 +00:00
if (isServer) then {
[FUNC(syncedEventPFH), 0.5, []] call CBA_fnc_addPerFrameHandler;
};
2015-08-11 18:10:42 +00:00
2015-09-21 15:00:53 +00:00
//////////////////////////////////////////////////
// Check files, previous installed version etc.
//////////////////////////////////////////////////
2019-12-18 20:43:40 +00:00
private _currentVersion = getText (configFile >> "CfgPatches" >> QUOTE(ADDON) >> "versionStr");
2015-12-14 12:17:48 +00:00
private _previousVersion = profileNamespace getVariable ["ACE_VersionNumberString", ""];
2015-09-21 15:00:53 +00:00
// check previous version number from profile
if (_currentVersion != _previousVersion) then {
2017-12-10 18:13:17 +00:00
INFO_2("Updating ACE from [%1] to [%2]",_previousVersion,_currentVersion);
[_previousVersion] call FUNC(cbaSettings_transferUserSettings);
2015-09-21 15:00:53 +00:00
profileNamespace setVariable ["ACE_VersionNumberString", _currentVersion];
};
2015-05-09 11:25:19 +00:00
call FUNC(checkFiles);
2015-04-18 02:26:27 +00:00
2015-06-13 03:57:01 +00:00
2015-09-21 15:00:53 +00:00
//////////////////////////////////////////////////
2016-06-03 00:59:18 +00:00
// Set up ace_settingsInitialized eventhandler
2015-09-21 15:00:53 +00:00
//////////////////////////////////////////////////
2021-10-11 20:48:30 +00:00
["CBA_settingsInitialized", {
2015-09-21 15:00:53 +00:00
[
GVAR(checkPBOsAction),
GVAR(checkPBOsCheckAll),
2015-12-03 05:58:41 +00:00
GVAR(checkPBOsWhitelist)
2015-09-21 15:00:53 +00:00
] call FUNC(checkPBOs)
2016-05-22 15:29:05 +00:00
}] call CBA_fnc_addEventHandler;
2015-09-21 15:00:53 +00:00
2015-06-13 03:57:01 +00:00
2015-09-21 15:00:53 +00:00
/***************************************************************************/
/***************************************************************************/
/** everything that only player controlled machines need, goes below this **/
/***************************************************************************/
/***************************************************************************/
2015-04-18 02:26:27 +00:00
2015-01-11 16:42:31 +00:00
if (!hasInterface) exitWith {};
2015-09-21 15:00:53 +00:00
//////////////////////////////////////////////////
// Set up mouse wheel eventhandler
//////////////////////////////////////////////////
call FUNC(assignedItemFix);
2015-09-21 16:37:19 +00:00
2015-09-21 15:00:53 +00:00
// @todo remove?
2015-01-11 16:42:31 +00:00
enableCamShake true;
2015-09-21 15:00:53 +00:00
2016-05-31 06:53:28 +00:00
//FUNC(showHud) needs to be refreshed if it was set during mission init
["ace_infoDisplayChanged", {
2021-10-10 16:55:14 +00:00
if (GVAR(showHudHash) isNotEqualTo createHashMap) then {
2016-05-31 06:53:28 +00:00
[] call FUNC(showHud);
};
}] call CBA_fnc_addEventHandler;
2015-09-21 15:00:53 +00:00
//////////////////////////////////////////////////
// Eventhandler to set player names
//////////////////////////////////////////////////
2015-01-12 04:02:33 +00:00
// Set the name for the current player
2016-06-22 09:16:55 +00:00
["unit", {
2015-09-21 15:00:53 +00:00
params ["_newPlayer","_oldPlayer"];
2015-04-30 18:49:38 +00:00
2015-01-16 15:14:18 +00:00
if (alive _newPlayer) then {
2017-02-10 19:03:12 +00:00
[FUNC(setName), [_newPlayer]] call CBA_fnc_execNextFrame;
2015-01-12 21:34:01 +00:00
};
2015-09-21 15:00:53 +00:00
2015-01-16 15:14:18 +00:00
if (alive _oldPlayer) then {
2017-02-10 19:03:12 +00:00
[FUNC(setName), [_oldPlayer]] call CBA_fnc_execNextFrame;
2015-01-12 21:34:01 +00:00
};
2020-04-24 21:59:47 +00:00
}, true] call CBA_fnc_addPlayerEventHandler;
2015-01-13 23:27:42 +00:00
2015-09-21 15:00:53 +00:00
//////////////////////////////////////////////////
// Set up numerous eventhanders for player controlled units
//////////////////////////////////////////////////
2017-04-11 15:06:29 +00:00
TRACE_1("adding unit playerEH to set ace_player",isNull cba_events_oldUnit);
2016-06-22 00:31:25 +00:00
["unit", {
ACE_player = (_this select 0);
2017-04-11 15:06:29 +00:00
}, true] call CBA_fnc_addPlayerEventHandler;
2016-06-22 00:31:25 +00:00
2018-09-17 19:03:28 +00:00
// Clear uniqueItems cache on loadout change
["loadout", {
GVAR(uniqueItemsCache) = nil;
}] call CBA_fnc_addPlayerEventHandler;
2018-10-12 12:59:40 +00:00
// Backwards compatiblity for old ace event
2015-09-21 15:00:53 +00:00
GVAR(OldIsCamera) = false;
2018-10-12 12:59:40 +00:00
["featureCamera", {
params ["_player", "_cameraName"];
GVAR(OldIsCamera) = _cameraName != "";
["ace_activeCameraChanged", [_player, GVAR(OldIsCamera)]] call CBA_fnc_localEvent;
}, true] call CBA_fnc_addPlayerEventHandler;
2015-04-18 20:06:42 +00:00
2017-08-22 21:07:45 +00:00
// Add event handler for UAV control change
ACE_controlledUAV = [objNull, objNull, [], ""];
addMissionEventHandler ["PlayerViewChanged", {
// On non-server client this command is semi-broken
// arg index 5 should be the controlled UAV, but it will often be objNull (delay from locality switching?)
// On PlayerViewChanged event, start polling for new uav state for a few seconds (should be done within a few frames)
2017-12-29 01:48:20 +00:00
2017-08-22 21:07:45 +00:00
params ["", "", "", "", "_newCameraOn", "_UAV"];
TRACE_2("PlayerViewChanged",_newCameraOn,_UAV);
2017-12-29 01:48:20 +00:00
2017-08-22 21:07:45 +00:00
[{
if (isNull player) exitWith {true};
private _UAV = getConnectedUAV player;
if (!alive player) then {_UAV = objNull;};
2019-09-04 00:05:45 +00:00
private _position = [player] call FUNC(getUavControlPosition);
2017-08-22 21:07:45 +00:00
private _seatAI = objNull;
private _turret = [];
switch (toLower _position) do {
case (""): {
_UAV = objNull; // set to objNull if not actively controlling
};
case ("driver"): {
_turret = [-1];
_seatAI = driver _UAV;
};
case ("gunner"): {
_turret = [0];
_seatAI = gunner _UAV;
};
};
2017-12-29 01:48:20 +00:00
2017-08-22 21:07:45 +00:00
private _newArray = [_UAV, _seatAI, _turret, _position];
if (_newArray isEqualTo ACE_controlledUAV) exitWith {false}; // no change yet
2017-12-29 01:48:20 +00:00
2017-08-22 21:07:45 +00:00
TRACE_2("Seat Change",_newArray,ACE_controlledUAV);
ACE_controlledUAV = _newArray;
["ACE_controlledUAV", _newArray] call CBA_fnc_localEvent;
2017-12-29 01:48:20 +00:00
2017-08-22 21:07:45 +00:00
// stay in the loop as we might switch from gunner -> driver, and there may be a empty position event in-between
false
}, {}, [], 3, {TRACE_1("timeout",_this);}] call CBA_fnc_waitUntilAndExecute;
}];
2015-04-18 20:06:42 +00:00
2015-09-21 15:00:53 +00:00
//////////////////////////////////////////////////
// Eventhandlers for player controlled machines
//////////////////////////////////////////////////
2015-04-18 20:06:42 +00:00
2016-06-04 10:12:56 +00:00
[QGVAR(displayTextStructured), {_this call FUNC(displayTextStructured)}] call CBA_fnc_addEventHandler;
[QGVAR(displayTextPicture), {_this call FUNC(displayTextPicture)}] call CBA_fnc_addEventHandler;
2015-04-18 20:06:42 +00:00
2016-06-04 10:12:56 +00:00
["ace_unconscious", {
2015-09-21 15:00:53 +00:00
params ["_unit", "_isUnconscious"];
2015-04-18 20:06:42 +00:00
2015-09-21 15:00:53 +00:00
if (local _unit && {!_isUnconscious}) then {
[_unit, false, QFUNC(loadPerson), west /* dummy side */] call FUNC(switchToGroupSide);
};
2016-05-22 15:29:05 +00:00
}] call CBA_fnc_addEventHandler;
2015-04-18 20:06:42 +00:00
2016-05-24 13:13:11 +00:00
["ace_useItem", DFUNC(useItem)] call CBA_fnc_addEventHandler;
2016-02-18 01:54:43 +00:00
2015-01-28 20:38:04 +00:00
2015-09-21 15:00:53 +00:00
//////////////////////////////////////////////////
// Add various canInteractWith conditions
//////////////////////////////////////////////////
2015-03-15 08:26:16 +00:00
2016-03-12 13:06:45 +00:00
["isNotDead", {
2016-07-07 07:10:14 +00:00
params ["_unit"];
2016-03-12 13:06:45 +00:00
alive _unit
}] call FUNC(addCanInteractWithCondition);
2015-03-15 15:12:37 +00:00
["notOnMap", {!visibleMap}] call FUNC(addCanInteractWithCondition);
2015-09-21 15:00:53 +00:00
2015-03-31 21:06:28 +00:00
["isNotInside", {
2015-09-21 15:00:53 +00:00
params ["_unit", "_target"];
2015-03-31 21:06:28 +00:00
// Players can always interact with himself if not boarded
2015-09-21 15:00:53 +00:00
vehicle _unit == _unit ||
2015-03-31 21:06:28 +00:00
// Players can always interact with his vehicle
2015-09-21 15:00:53 +00:00
{vehicle _unit == _target} ||
2015-03-31 21:06:28 +00:00
// Players can always interact with passengers of the same vehicle
2017-08-22 21:07:45 +00:00
{_unit != _target && {vehicle _unit == vehicle _target}} ||
// Players can always interact with connected UAV
{!(isNull (ACE_controlledUAV select 0))}
2015-03-31 21:06:28 +00:00
}] call FUNC(addCanInteractWithCondition);
2015-04-17 23:44:53 +00:00
2015-12-30 07:48:43 +00:00
["isNotInZeus", {isNull curatorCamera}] call FUNC(addCanInteractWithCondition);
2016-07-07 13:47:37 +00:00
2020-02-22 22:07:32 +00:00
["isNotUnconscious", {
params ["_unit"];
lifeState _unit != "INCAPACITATED"
}] call FUNC(addCanInteractWithCondition);
2016-07-07 13:47:37 +00:00
//////////////////////////////////////////////////
// Set up reload mutex
//////////////////////////////////////////////////
GVAR(isReloading) = false;
2021-03-03 21:31:07 +00:00
GVAR(reloadMutex_lastMagazines) = [];
// When reloading, the new magazine is removed from inventory, an animation plays and then the old magazine is added
// If the animation is interrupted, the new magazine will be lost
["loadout", {
params ["_unit", "_newLoadout"];
private _mags = magazines _unit;
// if our magazine count dropped by 1, we might be reloading
if ((count GVAR(reloadMutex_lastMagazines)) - (count _mags) == 1) then {
private _weapon = currentWeapon _unit;
private _muzzle = currentMuzzle _unit;
if (_weapon == "") exitWith {};
private _wpnMzlConfig = configFile >> "CfgWeapons" >> _weapon;
if (_muzzle != _weapon) then { _wpnMzlConfig = _wpnMzlConfig >> _muzzle; };
private _compatMags = [_wpnMzlConfig] call CBA_fnc_compatibleMagazines;
private _lastCompatMagCount = {_x in _compatMags} count GVAR(reloadMutex_lastMagazines);
private _curCompatMagCount = {_x in _compatMags} count _mags;
TRACE_3("",_wpnMzlConfig,_lastCompatMagCount,_curCompatMagCount);
if (_lastCompatMagCount - _curCompatMagCount != 1) exitWith {}; // check if magazines for our specific muzzle dropped by 1
private _gesture = getText (_wpnMzlConfig >> "reloadAction");
if (_gesture == "") exitWith {}; //Ignore weapons with no reload gesture (binoculars)
private _isLauncher = _weapon isKindOf ["Launcher", configFile >> "CfgWeapons"];
2021-06-28 05:01:32 +00:00
private _duration = 0;
if (_isLauncher) then {
_duration = getNumber (configfile >> "CfgMovesMaleSdr" >> "States" >> _gesture >> "speed");
};
if (_duration == 0) then {
_duration = getNumber (configfile >> "CfgGesturesMale" >> "States" >> _gesture >> "speed");
};
2021-03-03 21:31:07 +00:00
if (_duration != 0) then {
_duration = if (_duration < 0) then { abs _duration } else { 1 / _duration };
} else {
2021-06-28 05:01:32 +00:00
_duration = 6;
2021-03-03 21:31:07 +00:00
};
2016-07-07 13:47:37 +00:00
2021-03-03 21:31:07 +00:00
TRACE_2("Reloading, blocking gestures",_weapon,_duration);
GVAR(reloadingETA) = CBA_missionTime + _duration;
2016-07-08 13:12:47 +00:00
2021-03-03 21:31:07 +00:00
if (!GVAR(isReloading)) then {
GVAR(isReloading) = true;
2016-07-08 13:12:47 +00:00
2021-03-03 21:31:07 +00:00
[{
CBA_missionTime > GVAR(reloadingETA)
},{
GVAR(isReloading) = false;
}] call CBA_fnc_waitUntilAndExecute;
2016-07-07 13:47:37 +00:00
};
};
2021-03-03 21:31:07 +00:00
GVAR(reloadMutex_lastMagazines) = _mags;
}, true] call CBA_fnc_addPlayerEventHandler;
2016-07-07 13:47:37 +00:00
2015-09-21 16:37:19 +00:00
//////////////////////////////////////////////////
// Set up PlayerJIP eventhandler
//////////////////////////////////////////////////
2015-04-18 02:26:27 +00:00
// Lastly, do JIP events
2015-04-18 01:23:26 +00:00
// JIP Detection and event trigger. Run this at the very end, just in case anything uses it
2015-09-21 16:37:19 +00:00
// Note: usage of player is most likely on purpose
2015-08-27 03:39:27 +00:00
if (didJip) then {
2015-04-18 01:23:26 +00:00
// We are jipping! Get ready and wait, and throw the event
[{
2015-09-21 16:37:19 +00:00
if(!isNull player && GVAR(settingsInitFinished)) then {
2016-06-03 19:38:16 +00:00
["ace_playerJIP", [player]] call CBA_fnc_localEvent;
2015-09-21 16:37:19 +00:00
[_this select 1] call CBA_fnc_removePerFrameHandler;
2015-04-30 18:49:38 +00:00
};
2015-08-04 07:34:31 +00:00
}, 0, []] call CBA_fnc_addPerFrameHandler;
2015-04-18 01:23:26 +00:00
};
2015-05-10 19:59:53 +00:00
2015-09-21 15:00:53 +00:00
//////////////////////////////////////////////////
// CBA key input handling
//////////////////////////////////////////////////
2015-05-10 19:59:53 +00:00
//Device Handler:
GVAR(deviceKeyHandlingArray) = [];
GVAR(deviceKeyCurrentIndex) = -1;
2015-08-07 01:33:38 +00:00
// Register localizations for the Keybinding categories
2019-12-07 21:40:44 +00:00
["ACE3 Equipment", LLSTRING(ACEKeybindCategoryEquipment)] call CBA_fnc_registerKeybindModPrettyName;
["ACE3 Common", LLSTRING(ACEKeybindCategoryCommon)] call CBA_fnc_registerKeybindModPrettyName;
["ACE3 Weapons", LLSTRING(ACEKeybindCategoryWeapons)] call CBA_fnc_registerKeybindModPrettyName;
["ACE3 Movement", LLSTRING(ACEKeybindCategoryMovement)] call CBA_fnc_registerKeybindModPrettyName;
["ACE3 Scope Adjustment", LLSTRING(ACEKeybindCategoryScopeAdjustment)] call CBA_fnc_registerKeybindModPrettyName;
["ACE3 Vehicles", LLSTRING(ACEKeybindCategoryVehicles)] call CBA_fnc_registerKeybindModPrettyName;
["ACE3 Equipment", QGVAR(openDevice), LLSTRING(toggleHandheldDevice), {
2015-05-10 19:59:53 +00:00
[] call FUNC(deviceKeyFindValidIndex);
if (GVAR(deviceKeyCurrentIndex) == -1) exitWith {false};
[] call ((GVAR(deviceKeyHandlingArray) select GVAR(deviceKeyCurrentIndex)) select 3);
2015-05-12 03:48:03 +00:00
true
2015-05-10 19:59:53 +00:00
},
{false},
2015-09-21 15:00:53 +00:00
[0xC7, [false, false, false]], false] call CBA_fnc_addKeybind; //Home Key
2015-05-10 19:59:53 +00:00
2019-12-07 21:40:44 +00:00
["ACE3 Equipment", QGVAR(closeDevice), LLSTRING(closeHandheldDevice), {
2015-05-10 19:59:53 +00:00
[] call FUNC(deviceKeyFindValidIndex);
if (GVAR(deviceKeyCurrentIndex) == -1) exitWith {false};
[] call ((GVAR(deviceKeyHandlingArray) select GVAR(deviceKeyCurrentIndex)) select 4);
2015-05-12 03:48:03 +00:00
true
2015-05-10 19:59:53 +00:00
},
{false},
2015-09-21 15:00:53 +00:00
[0xC7, [false, true, false]], false] call CBA_fnc_addKeybind; //CTRL + Home Key
2015-05-10 19:59:53 +00:00
2019-12-07 21:40:44 +00:00
["ACE3 Equipment", QGVAR(cycleDevice), LLSTRING(cycleHandheldDevices), {
2015-05-10 19:59:53 +00:00
[1] call FUNC(deviceKeyFindValidIndex);
if (GVAR(deviceKeyCurrentIndex) == -1) exitWith {false};
2017-05-14 19:48:05 +00:00
private _displayName = ((GVAR(deviceKeyHandlingArray) select GVAR(deviceKeyCurrentIndex)) select 0);
private _iconImage = ((GVAR(deviceKeyHandlingArray) select GVAR(deviceKeyCurrentIndex)) select 1);
2015-05-10 19:59:53 +00:00
[_displayName, _iconImage] call FUNC(displayTextPicture);
2015-05-12 03:48:03 +00:00
true
2015-05-10 19:59:53 +00:00
},
{false},
2015-09-21 15:00:53 +00:00
[0xC7, [true, false, false]], false] call CBA_fnc_addKeybind; //SHIFT + Home Key
2015-06-05 22:50:04 +00:00
2022-05-18 18:07:47 +00:00
["ACE3 Weapons", QGVAR(unloadWeapon), localize LSTRING(unloadWeapon), {
// Conditions:
if !([ACE_player, objNull, ["isNotInside"]] call FUNC(canInteractWith)) exitWith {false};
private _currentWeapon = currentWeapon ACE_player;
if !(_currentWeapon != primaryWeapon _unit && {_currentWeapon != handgunWeapon _unit} && {_currentWeapon != secondaryWeapon _unit}) exitWith {false};
private _currentMuzzle = currentMuzzle ACE_player;
private _currentAmmoCount = ACE_player ammo _currentMuzzle;
if (_currentAmmoCount < 1) exitWith {false};
// Statement:
[ACE_player, _currentWeapon, _currentMuzzle, _currentAmmoCount, false] call FUNC(unloadUnitWeapon);
true
}, {false}, [19, [false, false, true]], false] call CBA_fnc_addKeybind; //ALT + R Key
2022-08-25 16:56:54 +00:00
["CBA_loadoutSet", {
params ["_unit", "_loadout"];
// remove if with https://github.com/CBATeam/CBA_A3/pull/1548
if (count _loadout == 2) then {
_loadout = _loadout select 0;
};
_loadout params ["_primaryWeaponArray"];
if ((_primaryWeaponArray param [0, ""]) == "ACE_FakePrimaryWeapon") then {
TRACE_1("Ignoring fake gun",_primaryWeaponArray);
_loadout set [0, []];
};
}] call CBA_fnc_addEventHandler;
2015-05-14 23:45:53 +00:00
GVAR(commonPostInited) = true;