diff --git a/addons/common/functions/fnc_progressBar.sqf b/addons/common/functions/fnc_progressBar.sqf index 69b91237e6..3191a57d72 100644 --- a/addons/common/functions/fnc_progressBar.sqf +++ b/addons/common/functions/fnc_progressBar.sqf @@ -53,6 +53,7 @@ _perFrameFunction = { _elapsedTime = time - _startTime; _errorCode = -1; + // this does not check: target fell unconscious, target died, target moved inside vehicle / left vehicle, target moved outside of players range, target moves at all. if (isNull (uiNamespace getVariable [QGVAR(ctrlProgressBar), controlNull])) then { _errorCode = 1; } else { diff --git a/addons/dragging/functions/fnc_handleAnimChanged.sqf b/addons/dragging/functions/fnc_handleAnimChanged.sqf index b5eb4d4d8f..91fa3d681b 100644 --- a/addons/dragging/functions/fnc_handleAnimChanged.sqf +++ b/addons/dragging/functions/fnc_handleAnimChanged.sqf @@ -13,7 +13,9 @@ if (_unit getVariable [QGVAR(isDragging), false]) then { private "_draggedObject"; _draggedObject = _unit getVariable [QGVAR(draggedObject), objNull]; - [_unit, _draggedObject] call FUNC(dropObject); + if (!isNull _draggedObject) then { + [_unit, _draggedObject] call FUNC(dropObject); + }; }; }; @@ -25,7 +27,9 @@ if (_unit getVariable [QGVAR(isCarrying), false]) then { private "_carriedObject"; _carriedObject = _unit getVariable [QGVAR(carriedObject), objNull]; - [_unit, _carriedObject] call FUNC(dropObject_carry); + if (!isNull _carriedObject) then { + [_unit, _carriedObject] call FUNC(dropObject_carry); + }; }; }; diff --git a/addons/dragging/functions/fnc_setCarryable.sqf b/addons/dragging/functions/fnc_setCarryable.sqf index 630f212b97..56bfa5bd7a 100644 --- a/addons/dragging/functions/fnc_setCarryable.sqf +++ b/addons/dragging/functions/fnc_setCarryable.sqf @@ -48,8 +48,8 @@ if (_type in _initializedClasses) exitWith {}; _initializedClasses pushBack _type; GVAR(initializedClasses_carry) = _initializedClasses; -_carryAction = [QGVAR(drag), localize "STR_ACE_Dragging_Carry", "", {[_player, _target] call FUNC(carryObject)}, {[_player, _target] call FUNC(canCarry)}] call EFUNC(interact_menu,createAction); -_dropAction = [QGVAR(drop), localize "STR_ACE_Dragging_Drop", "", {[_player, _target] call FUNC(dropObject_carry)}, {[_player, _target] call FUNC(canDrop_carry)}] call EFUNC(interact_menu,createAction); +_carryAction = [QGVAR(carry), localize "STR_ACE_Dragging_Carry", "", {[_player, _target] call FUNC(carryObject)}, {[_player, _target] call FUNC(canCarry)}] call EFUNC(interact_menu,createAction); +_dropAction = [QGVAR(drop_carry), localize "STR_ACE_Dragging_Drop", "", {[_player, _target] call FUNC(dropObject_carry)}, {[_player, _target] call FUNC(canDrop_carry)}] call EFUNC(interact_menu,createAction); [_type, 0, ["ACE_MainActions"], _carryAction] call EFUNC(interact_menu,addActionToClass); -[_type, 0, ["ACE_MainActions"], _dropAction] call EFUNC(interact_menu,addActionToClass); +[_type, 0, [], _dropAction] call EFUNC(interact_menu,addActionToClass); diff --git a/addons/dragging/functions/fnc_setDraggable.sqf b/addons/dragging/functions/fnc_setDraggable.sqf index b6e26a6f0a..da2d0310b4 100644 --- a/addons/dragging/functions/fnc_setDraggable.sqf +++ b/addons/dragging/functions/fnc_setDraggable.sqf @@ -52,4 +52,4 @@ _dragAction = [QGVAR(drag), localize "STR_ACE_Dragging_Drag", "", {[_player, _ta _dropAction = [QGVAR(drop), localize "STR_ACE_Dragging_Drop", "", {[_player, _target] call FUNC(dropObject)}, {[_player, _target] call FUNC(canDrop)}] call EFUNC(interact_menu,createAction); [_type, 0, ["ACE_MainActions"], _dragAction] call EFUNC(interact_menu,addActionToClass); -[_type, 0, ["ACE_MainActions"], _dropAction] call EFUNC(interact_menu,addActionToClass); +[_type, 0, [], _dropAction] call EFUNC(interact_menu,addActionToClass); diff --git a/addons/dragging/functions/fnc_startDrag.sqf b/addons/dragging/functions/fnc_startDrag.sqf index 1e286fb4a4..07ed7e5a90 100644 --- a/addons/dragging/functions/fnc_startDrag.sqf +++ b/addons/dragging/functions/fnc_startDrag.sqf @@ -40,4 +40,7 @@ _unit selectWeapon primaryWeapon _unit; // can't play action that depends on weapon if it was added the same frame [{_this playActionNow "grabDrag";}, _unit] call EFUNC(common,execNextFrame); +// prevents draging and carrying at the same time +_unit setVariable [QGVAR(isDragging), true, true]; + [FUNC(startDragPFH), 0.2, [_unit, _target, time + 5]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/dragging/functions/fnc_startDragPFH.sqf b/addons/dragging/functions/fnc_startDragPFH.sqf index b6515aa2d9..1d8c6f89f1 100644 --- a/addons/dragging/functions/fnc_startDragPFH.sqf +++ b/addons/dragging/functions/fnc_startDragPFH.sqf @@ -10,6 +10,17 @@ _timeOut = _this select 0 select 2; // timeout. Do nothing. Quit. time, because anim length is linked to ingame time. if (time > _timeOut) exitWith { [_this select 1] call CBA_fnc_removePerFrameHandler; + + // drop if in timeout + private "_draggedObject"; + _draggedObject = _unit getVariable [QGVAR(draggedObject), objNull]; + + if (!isNull _draggedObject) exitWith { + [_unit, _draggedObject] call FUNC(dropObject); + }; + + // re-enable everything + _unit setVariable [QGVAR(isDragging), false, true]; }; // unit is ready to start dragging diff --git a/addons/reloadlaunchers/$PBOPREFIX$ b/addons/reloadlaunchers/$PBOPREFIX$ new file mode 100644 index 0000000000..3425681cde --- /dev/null +++ b/addons/reloadlaunchers/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\reloadlaunchers \ No newline at end of file diff --git a/addons/reloadlaunchers/CfgEventHandlers.hpp b/addons/reloadlaunchers/CfgEventHandlers.hpp new file mode 100644 index 0000000000..0cd959a047 --- /dev/null +++ b/addons/reloadlaunchers/CfgEventHandlers.hpp @@ -0,0 +1,12 @@ + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_postInit)); + }; +}; diff --git a/addons/reloadlaunchers/CfgVehicles.hpp b/addons/reloadlaunchers/CfgVehicles.hpp new file mode 100644 index 0000000000..617aa26b5c --- /dev/null +++ b/addons/reloadlaunchers/CfgVehicles.hpp @@ -0,0 +1,15 @@ + +class CfgVehicles { + class Man; + class CAManBase: Man { + class ACE_Actions { + class GVAR(ReloadLauncher) { + displayName = "$STR_ACE_ReloadLaunchers_LoadLauncher"; + selection = "launcher"; + distance = 4; + condition = ""; + insertChildren = QUOTE(_this call FUNC(addMissileReloadActions)); + }; + }; + }; +}; diff --git a/addons/reloadlaunchers/CfgWeapons.hpp b/addons/reloadlaunchers/CfgWeapons.hpp new file mode 100644 index 0000000000..08fbdb76b0 --- /dev/null +++ b/addons/reloadlaunchers/CfgWeapons.hpp @@ -0,0 +1,11 @@ + +class CfgWeapons { + class Launcher_Base_F; + class launch_Titan_base: Launcher_Base_F { + GVAR(enabled) = 1; + }; + + class launch_RPG32_F: Launcher_Base_F { + GVAR(enabled) = 1; + }; +}; diff --git a/addons/reloadlaunchers/XEH_postInit.sqf b/addons/reloadlaunchers/XEH_postInit.sqf new file mode 100644 index 0000000000..437927602a --- /dev/null +++ b/addons/reloadlaunchers/XEH_postInit.sqf @@ -0,0 +1,4 @@ +// by commy2 +#include "script_component.hpp" + +["reloadLauncher", {_this call DFUNC(reloadLauncher)}] call EFUNC(common,addEventhandler); diff --git a/addons/reloadlaunchers/XEH_preInit.sqf b/addons/reloadlaunchers/XEH_preInit.sqf new file mode 100644 index 0000000000..3b60f99b8e --- /dev/null +++ b/addons/reloadlaunchers/XEH_preInit.sqf @@ -0,0 +1,11 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP(addMissileReloadActions); +PREP(canLoad); +PREP(getLoadableMissiles); +PREP(load); +PREP(reloadLauncher); + +ADDON = true; diff --git a/addons/reloadlaunchers/config.cpp b/addons/reloadlaunchers/config.cpp new file mode 100644 index 0000000000..a039ef87c4 --- /dev/null +++ b/addons/reloadlaunchers/config.cpp @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common","ace_interaction","ace_interact_menu"}; + author[] = {""}; + authorUrl = ""; + VERSION_CONFIG; + }; +}; + +#include "CfgEventHandlers.hpp" + +#include "CfgVehicles.hpp" +#include "CfgWeapons.hpp" diff --git a/addons/reloadlaunchers/functions/fnc_addMissileReloadActions.sqf b/addons/reloadlaunchers/functions/fnc_addMissileReloadActions.sqf new file mode 100644 index 0000000000..58cd53699e --- /dev/null +++ b/addons/reloadlaunchers/functions/fnc_addMissileReloadActions.sqf @@ -0,0 +1,48 @@ +/* + * Author: commy2 + * Create one action per reloadable missile + * + * Argument: + * 1: Player (Object) + * 0: Target (Object) + * 2: Parameters ??? (Array) + * + * Return value: + * Children actions (Array) + * + */ +#include "script_component.hpp" + +private ["_unit", "_target", "_parameters"]; + +_unit = _this select 1; +_target = _this select 0; +_parameters = _this select 2; // ??? + +private ["_actions", "_weapon", "_loadableMissiles"]; + +_actions = []; + +_weapon = secondaryWeapon _target; +_loadableMissiles = [_unit, _weapon] call FUNC(getLoadableMissiles); + +{ + private ["_name", "_displayName", "_statement", "_condition", "_action"]; + + _name = format [QGVAR(Missile_%1), _x]; + _displayName = format [localize "STR_ACE_ReloadLaunchers_LoadMagazine", getText (configFile >> "CfgMagazines" >> _x >> "displayName")]; + + _statement = { + (_this select 2) call DFUNC(load); + }; + + _condition = { + (_this select 2) call DFUNC(canLoad) + }; + + _action = [_name, _displayName, "", _statement, _condition, {}, [_unit, _target, _weapon, _x], "", 4] call EFUNC(interact_menu,createAction); + + _actions pushBack [_action, [], _unit]; +} forEach _loadableMissiles; + +_actions diff --git a/addons/reloadlaunchers/functions/fnc_canLoad.sqf b/addons/reloadlaunchers/functions/fnc_canLoad.sqf new file mode 100644 index 0000000000..5bbfe4dd87 --- /dev/null +++ b/addons/reloadlaunchers/functions/fnc_canLoad.sqf @@ -0,0 +1,41 @@ +/* + * Author: commy2 + * + * Check of the unit can reload the launcher of target unit. + * + * Argument: + * 0: Unit to do the reloading (Object) + * 1: Unit eqipped with launcher (Object) + * 2: weapon name (String) + * 3: missile name (String) + * + * Return value: + * NONE + */ +#include "script_component.hpp" + +private ["_unit", "_target", "_weapon", "_magazine"]; + +_unit = _this select 0; +_target = _this select 1; +_weapon = _this select 2; +_magazine = _this select 3; + +if (!alive _target) exitWith {false}; +if (vehicle _target != _target) exitWith {false}; +if !([_unit, _target, []] call EFUNC(common,canInteractWith)) exitWith {false}; + +// target is awake +if (_target getVariable ["ACE_isUnconscious", false]) exitWith {false}; + +// has secondary weapon equipped +if !(_weapon in weapons _target) exitWith {false}; + +// check if the target really needs to be reloaded +if (count secondaryWeaponMagazine _target > 0) exitWith {false}; + +// check if the launcher is compatible +if (getNumber (configFile >> "CfgWeapons" >> _weapon >> QGVAR(enabled)) == 0) exitWith {false}; + +// check if the magazine compatible with targets launcher +_magazine in ([_unit, _weapon] call FUNC(getLoadableMissiles)) diff --git a/addons/reloadlaunchers/functions/fnc_getLoadableMissiles.sqf b/addons/reloadlaunchers/functions/fnc_getLoadableMissiles.sqf new file mode 100644 index 0000000000..9b083a04c6 --- /dev/null +++ b/addons/reloadlaunchers/functions/fnc_getLoadableMissiles.sqf @@ -0,0 +1,28 @@ +/* + * Author: commy2 + * + * Return all magazine types from reloaders inventory that are compatible with given weapon. + * + * Argument: + * 0: Unit to to the reload (Object) + * 1: A launcher (String) + * + * Return value: + * Reloable magazines (Array) + */ +#include "script_component.hpp" + +private ["_unit", "_weapon"]; + +_unit = _this select 0; +_weapon = _this select 1; + +// get available magazines of reloader, Note: "magazines" does not include currently loaded magazines +private "_magazines"; +_magazines = magazines _unit; + +// case sensitvity +_magazines = [_magazines, {toLower _this}] call EFUNC(common,map); + +// get reloaders magazine types compatible with targets launcher. No duplicates. +[getArray (configFile >> "CfgWeapons" >> _weapon >> "magazines"), {toLower _this in _magazines}] call EFUNC(common,filter) diff --git a/addons/reloadlaunchers/functions/fnc_load.sqf b/addons/reloadlaunchers/functions/fnc_load.sqf new file mode 100644 index 0000000000..f6ad07e357 --- /dev/null +++ b/addons/reloadlaunchers/functions/fnc_load.sqf @@ -0,0 +1,48 @@ +/* + * Author: commy2 + * + * Reload a launcher + * + * Argument: + * 0: Unit with magazine (Object) + * 1: Unit with launcher (Object) + * 2: weapon name (String) + * 3: missile name (String) + * + * Return value: + * NONE + */ +#include "script_component.hpp" + +private ["_unit", "_target", "_weapon", "_magazine"]; + +_unit = _this select 0; +_target = _this select 1; +_weapon = _this select 2; +_magazine = _this select 3; + +private "_reloadTime"; +_reloadTime = getNumber (configFile >> "CfgWeapons" >> _weapon >> "magazineReloadTime"); + +// do animation +[_unit] call EFUNC(common,goKneeling); + +// show progress bar +private ["_onSuccess", "_onFailure", "_condition"]; + +_onSuccess = { + (_this select 0 select 0) removeMagazine (_this select 0 select 3); + ["reloadLauncher", _this select 0 select 0, _this select 0] call DEFUNC(common,targetEvent); + + [localize "STR_ACE_ReloadLaunchers_LauncherLoaded"] call DEFUNC(common,displayTextStructured); +}; + +_onFailure = { + [localize "STR_ACE_Common_ActionAborted"] call DEFUNC(common,displayTextStructured); +}; + +_condition = { + (_this select 0) call DFUNC(canLoad) && {(_this select 0 select 0) distance (_this select 0 select 1) < 4} +}; + +[_reloadTime, [_unit, _target, _weapon, _magazine], _onSuccess, _onFailure, localize "STR_ACE_ReloadLaunchers_LoadingLauncher", _condition] call EFUNC(common,progressBar); diff --git a/addons/reloadlaunchers/functions/fnc_reloadLauncher.sqf b/addons/reloadlaunchers/functions/fnc_reloadLauncher.sqf new file mode 100644 index 0000000000..36772f9dfd --- /dev/null +++ b/addons/reloadlaunchers/functions/fnc_reloadLauncher.sqf @@ -0,0 +1,30 @@ +/* + * Author: commy2 + * + * Reload a launcher + * + * Argument: + * 0: Unit to do the reloading (Object) + * 1: Target to rload (Object) + * 2: weapon name (String) + * 3: missile name (String) + * + * Return value: + * NONE + */ +#include "script_component.hpp" + +private ["_unit", "_weapon", "_magazine"]; + +_unit = _this select 0; +_target = _this select 1; +_weapon = _this select 2; +_magazine = _this select 3; + +_target selectWeapon _weapon; + +if (currentWeapon _target != _weapon) exitWith {}; +if (currentMagazine _target != "") exitWith {}; + +// command is wip, reload time for launchers is not intended. +_target addWeaponItem [_weapon, _magazine]; diff --git a/addons/reloadlaunchers/functions/script_component.hpp b/addons/reloadlaunchers/functions/script_component.hpp new file mode 100644 index 0000000000..9c129f36b1 --- /dev/null +++ b/addons/reloadlaunchers/functions/script_component.hpp @@ -0,0 +1 @@ +#include "\z\ace\addons\reloadlaunchers\script_component.hpp" \ No newline at end of file diff --git a/addons/reloadlaunchers/script_component.hpp b/addons/reloadlaunchers/script_component.hpp new file mode 100644 index 0000000000..bc6b7f6e6c --- /dev/null +++ b/addons/reloadlaunchers/script_component.hpp @@ -0,0 +1,12 @@ +#define COMPONENT reloadlaunchers +#include "\z\ace\addons\main\script_mod.hpp" + +#ifdef DEBUG_ENABLED_RELOADLAUNCHERS + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_ENABLED_RELOADLAUNCHERS + #define DEBUG_SETTINGS DEBUG_ENABLED_RELOADLAUNCHERS +#endif + +#include "\z\ace\addons\main\script_macros.hpp" \ No newline at end of file diff --git a/addons/reloadlaunchers/stringtable.xml b/addons/reloadlaunchers/stringtable.xml new file mode 100644 index 0000000000..6677153419 --- /dev/null +++ b/addons/reloadlaunchers/stringtable.xml @@ -0,0 +1,24 @@ + + + + + + Load launcher + Panzerabwehr laden + + + Loading launcher ... + Panzerabwehr wird geladen ... + + + Launcher loaded + Panzerabwehr geladen + + + + Load %1 + Lade %1 + + + +