diff --git a/TO_MERGE/agm/SwitchUnits/UI/IconSwitchUnits_ca.paa b/addons/_switchunits/UI/IconSwitchUnits_ca.paa similarity index 100% rename from TO_MERGE/agm/SwitchUnits/UI/IconSwitchUnits_ca.paa rename to addons/_switchunits/UI/IconSwitchUnits_ca.paa diff --git a/TO_MERGE/agm/SwitchUnits/clientInit.sqf b/addons/_switchunits/clientInit.sqf similarity index 100% rename from TO_MERGE/agm/SwitchUnits/clientInit.sqf rename to addons/_switchunits/clientInit.sqf diff --git a/TO_MERGE/agm/SwitchUnits/config.cpp b/addons/_switchunits/config.cpp similarity index 100% rename from TO_MERGE/agm/SwitchUnits/config.cpp rename to addons/_switchunits/config.cpp diff --git a/TO_MERGE/agm/SwitchUnits/functions/fn_addMapFunction.sqf b/addons/_switchunits/functions/fn_addMapFunction.sqf similarity index 100% rename from TO_MERGE/agm/SwitchUnits/functions/fn_addMapFunction.sqf rename to addons/_switchunits/functions/fn_addMapFunction.sqf diff --git a/TO_MERGE/agm/SwitchUnits/functions/fn_handleMapClick.sqf b/addons/_switchunits/functions/fn_handleMapClick.sqf similarity index 100% rename from TO_MERGE/agm/SwitchUnits/functions/fn_handleMapClick.sqf rename to addons/_switchunits/functions/fn_handleMapClick.sqf diff --git a/TO_MERGE/agm/SwitchUnits/functions/fn_initPlayer.sqf b/addons/_switchunits/functions/fn_initPlayer.sqf similarity index 100% rename from TO_MERGE/agm/SwitchUnits/functions/fn_initPlayer.sqf rename to addons/_switchunits/functions/fn_initPlayer.sqf diff --git a/TO_MERGE/agm/SwitchUnits/functions/fn_isValidAi.sqf b/addons/_switchunits/functions/fn_isValidAi.sqf similarity index 100% rename from TO_MERGE/agm/SwitchUnits/functions/fn_isValidAi.sqf rename to addons/_switchunits/functions/fn_isValidAi.sqf diff --git a/TO_MERGE/agm/SwitchUnits/functions/fn_markAiOnMap.sqf b/addons/_switchunits/functions/fn_markAiOnMap.sqf similarity index 100% rename from TO_MERGE/agm/SwitchUnits/functions/fn_markAiOnMap.sqf rename to addons/_switchunits/functions/fn_markAiOnMap.sqf diff --git a/TO_MERGE/agm/SwitchUnits/functions/fn_module.sqf b/addons/_switchunits/functions/fn_module.sqf similarity index 100% rename from TO_MERGE/agm/SwitchUnits/functions/fn_module.sqf rename to addons/_switchunits/functions/fn_module.sqf diff --git a/TO_MERGE/agm/SwitchUnits/functions/fn_nearestPlayers.sqf b/addons/_switchunits/functions/fn_nearestPlayers.sqf similarity index 100% rename from TO_MERGE/agm/SwitchUnits/functions/fn_nearestPlayers.sqf rename to addons/_switchunits/functions/fn_nearestPlayers.sqf diff --git a/TO_MERGE/agm/SwitchUnits/functions/fn_switchBack.sqf b/addons/_switchunits/functions/fn_switchBack.sqf similarity index 100% rename from TO_MERGE/agm/SwitchUnits/functions/fn_switchBack.sqf rename to addons/_switchunits/functions/fn_switchBack.sqf diff --git a/TO_MERGE/agm/SwitchUnits/functions/fn_switchUnit.sqf b/addons/_switchunits/functions/fn_switchUnit.sqf similarity index 100% rename from TO_MERGE/agm/SwitchUnits/functions/fn_switchUnit.sqf rename to addons/_switchunits/functions/fn_switchUnit.sqf diff --git a/TO_MERGE/agm/SwitchUnits/stringtable.xml b/addons/_switchunits/stringtable.xml similarity index 100% rename from TO_MERGE/agm/SwitchUnits/stringtable.xml rename to addons/_switchunits/stringtable.xml diff --git a/addons/switchunits/CfgEventHandlers.hpp b/addons/switchunits/CfgEventHandlers.hpp new file mode 100644 index 0000000000..8af0265fe2 --- /dev/null +++ b/addons/switchunits/CfgEventHandlers.hpp @@ -0,0 +1,5 @@ +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE( call compile preprocessFileLineNumbers PATHTOF(XEH_preInit.sqf) ); + }; +}; \ No newline at end of file diff --git a/addons/switchunits/UI/IconSwitchUnits_ca.paa b/addons/switchunits/UI/IconSwitchUnits_ca.paa new file mode 100644 index 0000000000..b5868f0423 Binary files /dev/null and b/addons/switchunits/UI/IconSwitchUnits_ca.paa differ diff --git a/addons/switchunits/XEH_preInit.sqf b/addons/switchunits/XEH_preInit.sqf new file mode 100644 index 0000000000..7443b79565 --- /dev/null +++ b/addons/switchunits/XEH_preInit.sqf @@ -0,0 +1,11 @@ +#include "script_component.hpp" + +PREP(addMapFunction); +PREP(handleMapClick); +PREP(initPlayer); +PREP(isValidAi); +PREP(markAiOnMap); +PREP(module); +PREP(nearestPlayers); +PREP(switchBack); +PREP(switchUnit); diff --git a/addons/switchunits/config.cpp b/addons/switchunits/config.cpp new file mode 100644 index 0000000000..628865c703 --- /dev/null +++ b/addons/switchunits/config.cpp @@ -0,0 +1,17 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + units[] = {}; + weapons[] = {}; + requiredVersion = 0.60; + requiredAddons[] = {"ace_core"}; + version = "0.95"; + versionStr = "0.95"; + versionAr[] = {0,95,0}; + author[] = {""}; + authorUrl = ""; + }; +}; + +#include "CfgEventHandlers.hpp" \ No newline at end of file diff --git a/addons/switchunits/functions/fnc_addMapFunction.sqf b/addons/switchunits/functions/fnc_addMapFunction.sqf new file mode 100644 index 0000000000..f65725aacf --- /dev/null +++ b/addons/switchunits/functions/fnc_addMapFunction.sqf @@ -0,0 +1,23 @@ +/* + Name: AGM_SwitchUnits_fnc_addMapFunction + + Author(s): + bux578 + + Description: + Adds a mapClick Eventhandler + + Parameters: + 0: OBJECT - unit + 1: ARRAY - sided + + Returns: + VOID +*/ + +private ["_unit"]; +_unit = _this select 0; + +["theMapClick", "onMapSingleClick", { + [_this, _pos, _shift, _alt] call AGM_SwitchUnits_fnc_handleMapClick; +}, [_unit, _sides]] call BIS_fnc_addStackedEventHandler; diff --git a/addons/switchunits/functions/fnc_handleMapClick.sqf b/addons/switchunits/functions/fnc_handleMapClick.sqf new file mode 100644 index 0000000000..642baed1bd --- /dev/null +++ b/addons/switchunits/functions/fnc_handleMapClick.sqf @@ -0,0 +1,41 @@ +/* + Name: AGM_SwitchUnits_fnc_handleMapClick + + Author(s): + bux578 + + Description: + Finds the clicked unit + + Parameters: + 0: OBJECT - MapClickEventHandlerArgs + 0: OBJECT - unit to switch to + 1: ARRAY - sides + + Returns: + VOID +*/ + +private ["_args", "_currentPlayerUnit", "_sides", "_pos", "_sideNearest"]; + +_currentPlayerUnit = (_this select 0) select 0; +_sides = (_this select 0) select 1; +_pos = _this select 1; + +_sideNearest = []; + +{ + if ([_x] call AGM_SwitchUnits_fnc_isValidAi && (side group _x in _sides)) then { + _sideNearest pushBack _x; + }; +} forEach (nearestObjects [_pos, ["Man"], 20]); + + +if (count _sideNearest > 0) then { + private ["_switchUnit"]; + + _switchUnit = _sideNearest select 0; + [_currentPlayerUnit, _switchUnit] call AGM_SwitchUnits_fnc_switchUnit; + + openMap false; +}; diff --git a/addons/switchunits/functions/fnc_initPlayer.sqf b/addons/switchunits/functions/fnc_initPlayer.sqf new file mode 100644 index 0000000000..c3ee6ce7b2 --- /dev/null +++ b/addons/switchunits/functions/fnc_initPlayer.sqf @@ -0,0 +1,48 @@ +/* + Name: AGM_SwitchUnits_fnc_initPlayer + + Author(s): + bux578 + + Description: + Initializes the player + + Parameters: + 0: OBJECT - player + 1: ARRAY - Array containing selected sides + + Returns: + VOID +*/ + +private ["_playerUnit", "_sides"]; + +_playerUnit = _this select 0; +_sides = _this select 1; + +if (vehicle _playerUnit == _playerUnit) then { + + [_sides] call AGM_SwitchUnits_fnc_markAiOnMap; + + _playerUnit setVariable ["AGM_SwitchUnits_IsPlayerUnit", true]; + _playerUnit allowDamage false; + + AGM_SwitchUnits_OriginalUnit = _playerUnit; + AGM_SwitchUnits_OriginalName = [_playerUnit] call AGM_Core_fnc_getName; + AGM_SwitchUnits_OriginalGroup = group _playerUnit; + + // remove all starting gear of a player + removeAllWeapons _playerUnit; + removeGoggles _playerUnit; + removeHeadgear _playerUnit; + removeVest _playerUnit; + removeAllAssignedItems _playerUnit; + clearAllItemsFromBackpack _playerUnit; + removeBackpack _playerUnit; + _playerUnit linkItem "ItemMap"; + removeUniform _playerUnit; + + [_playerUnit, "AGM_SwitchUnits", true] call AGM_Core_fnc_setForceWalkStatus; + + [_playerUnit, _sides] call AGM_SwitchUnits_fnc_addMapFunction; +}; diff --git a/addons/switchunits/functions/fnc_isValidAi.sqf b/addons/switchunits/functions/fnc_isValidAi.sqf new file mode 100644 index 0000000000..f91b27ffbe --- /dev/null +++ b/addons/switchunits/functions/fnc_isValidAi.sqf @@ -0,0 +1,25 @@ +/* + Name: AGM_SwitchUnits_fnc_isValidAi + + Author(s): + bux578 + + Description: + Checks if AI is a valid target for switching + + Parameters: + 0: OBJECT - unit + + Returns: + VOID +*/ + +private ["_unit"]; + +_unit = _this select 0; + +!([_unit] call AGM_Core_fnc_isPlayer +|| {_unit in playableUnits} +|| {vehicle _unit != _unit} +|| {_unit getVariable ["AGM_SwitchUnits_IsPlayerUnit", false]} +|| {_unit getVariable ["AGM_SwitchUnits_IsPlayerControlled", false]}) diff --git a/addons/switchunits/functions/fnc_markAiOnMap.sqf b/addons/switchunits/functions/fnc_markAiOnMap.sqf new file mode 100644 index 0000000000..05865bc060 --- /dev/null +++ b/addons/switchunits/functions/fnc_markAiOnMap.sqf @@ -0,0 +1,64 @@ +/* + Name: AGM_SwitchUnits_fnc_markAiOnMap + + Author(s): + bux578 + + Description: + Creates markers for AI units for given sides + Marks players in a different color + + Parameters: + 0: OBJECT - side + + Returns: + VOID +*/ + +private ["_sidesToShow"]; +_sidesToShow = _this select 0; + +_sidesToShow spawn { + + private ["_sides", "_allMarkerNames"]; + _sides = _this; + _allMarkerNames = []; + + while { true } do { + sleep 1.5; + + // delete markers + { + deleteMarkerLocal _x; + } forEach _allMarkerNames; + + // create markers + { + if (([_x] call AGM_SwitchUnits_fnc_isValidAi && (side group _x in _sides)) || (_x getVariable ["AGM_SwitchUnits_IsPlayerControlled", false])) then { + private ["_markerName", "_marker", "_markerColor"]; + + //_markerName = format ["%1", [_x] call AGM_Core_fnc_getName]; + _markerName = str _x; + + _marker = createMarkerLocal [_markerName, position _x]; + _markerName setMarkerTypeLocal "mil_triangle"; + _markerName setMarkerShapeLocal "ICON"; + _markerName setMarkerSizeLocal [0.5,0.7]; + _markerName setMarkerDirLocal getDir _x; + + // commy's one liner magic + _markerColor = format ["Color%1", side group _x]; + + if ((_x getVariable ["AGM_SwitchUnits_IsPlayerControlled", false])) then { + _markerName setMarkerColorLocal "ColorOrange"; + _markerName setMarkerTextLocal (_x getVariable ["AGM_SwitchUnits_PlayerControlledName",""]); + } else { + _markerName setMarkerColorLocal _markerColor; + _markerName setMarkerTextLocal (getText (configFile >> "CfgVehicles" >> typeOf _x >> "displayName")); + }; + + _allMarkerNames pushBack _markerName; + }; + } forEach allUnits; + }; +}; diff --git a/addons/switchunits/functions/fnc_module.sqf b/addons/switchunits/functions/fnc_module.sqf new file mode 100644 index 0000000000..43ec26199a --- /dev/null +++ b/addons/switchunits/functions/fnc_module.sqf @@ -0,0 +1,38 @@ +/* + Name: AGM_SwitchUnits_fnc_module + + Author(s): + bux578 + + Description: + Initializes the SwitchUnits module + + Parameters: + 0: OBJECT - module logic + 1: ARRAY - list of affected units + 2: BOOLEAN - isActivated + + Returns: + BOOLEAN (Good practice to include one) +*/ + +if !(isServer) exitWith {}; + +_logic = _this select 0; +_activated = _this select 2; + +if !(_activated) exitWith {}; + +AGM_SwitchUnits_Module = true; + +["AGM_SwitchUnits_EnableSwitchUnits", true] call AGM_Core_fnc_setParameter; + +[_logic, "AGM_SwitchUnits_SwitchToWest", "SwitchToWest"] call AGM_Core_fnc_readBooleanParameterFromModule; +[_logic, "AGM_SwitchUnits_SwitchToEast", "SwitchToEast"] call AGM_Core_fnc_readBooleanParameterFromModule; +[_logic, "AGM_SwitchUnits_SwitchToIndependent", "SwitchToIndependent"] call AGM_Core_fnc_readBooleanParameterFromModule; +[_logic, "AGM_SwitchUnits_SwitchToCivilian", "SwitchToCivilian"] call AGM_Core_fnc_readBooleanParameterFromModule; + +[_logic, "AGM_SwitchUnits_EnableSafeZone", "EnableSafeZone"] call AGM_Core_fnc_readBooleanParameterFromModule; +[_logic, "AGM_SwitchUnits_SafeZoneRadius", "SafeZoneRadius"] call AGM_Core_fnc_readNumericParameterFromModule; + +diag_log text "[AGM]: SwitchUnits Module Initialized."; diff --git a/addons/switchunits/functions/fnc_nearestPlayers.sqf b/addons/switchunits/functions/fnc_nearestPlayers.sqf new file mode 100644 index 0000000000..04b185c455 --- /dev/null +++ b/addons/switchunits/functions/fnc_nearestPlayers.sqf @@ -0,0 +1,31 @@ +/* + Name: AGM_SwitchUnits_fnc_nearestPlayers + + Author(s): + bux578 + + Description: + Returns an array of alive players in a given radius around a given location + + Parameters: + 0: POSTION - Center position + 1: NUMBER - Radius + + Returns: + ARRAY - Player units +*/ + +private ["_position", "_radius", "_nearestPlayers"]; + +_position = _this select 0; +_radius = _this select 1; + +_nearestPlayers = []; + +{ + if ([_x] call AGM_Core_fnc_isPlayer && {alive _x}) then { + _nearestPlayers pushBack _x; + }; +} forEach (nearestObjects [_position, ["Man"], _radius]); + + _nearestPlayers diff --git a/addons/switchunits/functions/fnc_switchBack.sqf b/addons/switchunits/functions/fnc_switchBack.sqf new file mode 100644 index 0000000000..eba84d57f6 --- /dev/null +++ b/addons/switchunits/functions/fnc_switchBack.sqf @@ -0,0 +1,29 @@ +/* + Name: AGM_SwitchUnits_fnc_switchBack + + Author(s): + bux578 + + Description: + Switches back to the original player unit + This method needs to be "spawn"ed + + Parameters: + 0: OBJECT - original player unit + 1: OBJECT - respawned unit + + Returns: + VOID +*/ + +private ["_originalPlayerUnit", "_currentUnit"]; +_originalPlayerUnit = _this select 0; +_currentUnit = _this select 1; + +[_originalPlayerUnit] joinSilent AGM_SwitchUnits_OriginalGroup; + +waitUntil {local _originalPlayerUnit}; + +selectPlayer _originalPlayerUnit; + +deleteVehicle _currentUnit; diff --git a/addons/switchunits/functions/fnc_switchUnit.sqf b/addons/switchunits/functions/fnc_switchUnit.sqf new file mode 100644 index 0000000000..ddb2a1d523 --- /dev/null +++ b/addons/switchunits/functions/fnc_switchUnit.sqf @@ -0,0 +1,79 @@ +/* + Name: AGM_SwitchUnits_fnc_switchUnit + + Author(s): + bux578 + + Description: + Selects the new given player unit + + Parameters: + 0: OBJECT - the unit to switch to + + Returns: + VOID +*/ + +private ["_newUnit"]; + +_newUnit = _this select 1; + +// don't switch to original player units +if (!([_newUnit] call AGM_SwitchUnits_fnc_isValidAi)) exitWith {}; + +_newUnit spawn { + private ["_unit", "_allNearestPlayers", "_oldUnit", "_respawnEhId", "_oldOwner", "_leave"]; + + _unit = _this; + + _leave = false; + + if (AGM_SwitchUnits_EnableSafeZone) then { + + _allNearestPlayers = [position _unit, AGM_SwitchUnits_SafeZoneRadius] call AGM_SwitchUnits_fnc_nearestPlayers; + _nearestEnemyPlayers = [_allNearestPlayers, {((side AGM_SwitchUnits_OriginalGroup) getFriend (side _this) < 0.6) && !(_this getVariable ["AGM_SwitchUnits_IsPlayerControlled", false])}] call AGM_Core_fnc_filter; + + if (count _nearestEnemyPlayers > 0) exitWith { + _leave = true; + }; + }; + + // exitWith doesn't exit past the "if(EnableSafeZone)" block + if (_leave) exitWith { + [localize "STR_AGM_SwitchUnits_TooCloseToEnemy"] call AGM_Core_fnc_displayTextStructured; + }; + + // should switch locality + // This doesn't work anymore, because one's now able to switch to units from a different side + //[_unit] joinSilent group player; + [[_unit, player], "{(_this select 0) setVariable ['AGM_SwitchUnits_OriginalOwner', owner (_this select 0), true]; (_this select 0) setOwner owner (_this select 1)}", 1] call AGM_Core_fnc_execRemoteFnc; + + _oldUnit = player; + waitUntil {sleep 0.2; local _unit}; + + _oldUnit setVariable ["AGM_SwitchUnits_IsPlayerControlled", false, true]; + _oldUnit setVariable ["AGM_SwitchUnits_PlayerControlledName", "", true]; + + _respawnEhId = _unit getVariable ["AGM_SwitchUnits_RespawnEhId", -1]; + if (_respawnEhId != -1) then { + _oldUnit removeEventHandler ["Respawn", _respawnEhId]; + }; + + selectPlayer _unit; + + _unit setVariable ["AGM_SwitchUnits_IsPlayerControlled", true, true]; + _unit setVariable ["AGM_SwitchUnits_PlayerControlledName", AGM_SwitchUnits_OriginalName, true]; + + _respawnEhId = _unit addEventHandler ["Respawn", { + [AGM_SwitchUnits_OriginalUnit, _this select 0] spawn AGM_SwitchUnits_fnc_switchBack; + }]; + _unit setVariable ["AGM_SwitchUnits_RespawnEhId", _respawnEhId, true]; + + // set owner back to original owner + _oldOwner = _oldUnit getVariable["AGM_SwitchUnits_OriginalOwner", -1]; + if (_oldOwner > -1) then { + [[_oldUnit, _oldOwner], "{(_this select 0) setOwner (_this select 1)}", 1] call AGM_Core_fnc_execRemoteFnc; + }; + + [localize "STR_AGM_SwitchUnits_SwitchedUnit"] call AGM_Core_fnc_displayTextStructured; +}; diff --git a/addons/switchunits/script_component.hpp b/addons/switchunits/script_component.hpp new file mode 100644 index 0000000000..40058509c2 --- /dev/null +++ b/addons/switchunits/script_component.hpp @@ -0,0 +1,12 @@ +#define COMPONENT blank +#include "\z\ace\addons\main\script_mod.hpp" + +#ifdef DEBUG_ENABLED_BLANK + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_BLANK + #define DEBUG_SETTINGS DEBUG_SETTINGS_BLANK +#endif + +#include "\z\ace\addons\main\script_macros.hpp" \ No newline at end of file