From f776c1b72e329dce5d90ea963fd9438af65cba53 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Thu, 7 Mar 2024 23:52:40 -0600 Subject: [PATCH 01/10] Casings - Add support for dropped magazines (40mm shells) --- addons/casings/XEH_PREP.hpp | 1 + addons/casings/XEH_postInit.sqf | 4 +- .../casings/functions/fnc_createMagazine.sqf | 60 +++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 addons/casings/functions/fnc_createMagazine.sqf diff --git a/addons/casings/XEH_PREP.hpp b/addons/casings/XEH_PREP.hpp index 8a0738b2724..13b21542f74 100644 --- a/addons/casings/XEH_PREP.hpp +++ b/addons/casings/XEH_PREP.hpp @@ -1 +1,2 @@ PREP(createCasing); +PREP(createMagazine); diff --git a/addons/casings/XEH_postInit.sqf b/addons/casings/XEH_postInit.sqf index e91ab96c0d8..e9ca54bb6ac 100644 --- a/addons/casings/XEH_postInit.sqf +++ b/addons/casings/XEH_postInit.sqf @@ -3,5 +3,7 @@ if (!hasInterface || !GVAR(enabled)) exitWith {}; GVAR(cachedCasings) = createHashMap; +GVAR(cachedMagazines) = createHashMap; GVAR(casings) = []; -["CAManBase", "FiredMan", {call FUNC(createCasing)}] call CBA_fnc_addClassEventHandler; +["CAManBase", "FiredMan", LINKFUNC(createCasing)] call CBA_fnc_addClassEventHandler; +["CAManBase", "Reloaded", LINKFUNC(createMagazine)] call CBA_fnc_addClassEventHandler; diff --git a/addons/casings/functions/fnc_createMagazine.sqf b/addons/casings/functions/fnc_createMagazine.sqf new file mode 100644 index 00000000000..a1765c796b6 --- /dev/null +++ b/addons/casings/functions/fnc_createMagazine.sqf @@ -0,0 +1,60 @@ +#include "..\script_component.hpp" +/* + * Author: GabrielPearce / esteldunedain / Cyruz / diwako / PabstMirror + * Produces a casing matching the reloaded and dropped magazine + * + * Arguments: + * 0: unit - Object the event handler is assigned to + * 4: Old magazine (can be nil) - + * + * Return Value: + * None + * + * Example: + * [player, "", "","", ["1Rnd_HE_Grenade_shell", 0]] call ace_casings_fnc_createMagazine + * + * Public: No + */ + +params ["_unit", "", "", "", "_oldMagazine"]; +TRACE_2("createMagazine",_unit,_oldMagazine); + +if (_unit != ACE_player) exitWith {}; +if (isNil "_oldMagazine") exitWith {}; +_oldMagazine params ["_mag", "_ammo"]; +if (_ammo != 0) exitWith {}; + +private _modelPath = GVAR(cachedMagazines) getOrDefaultCall [_mag, { + switch (true) do { + case (_mag in compatibleMagazines ["arifle_Mk20_GL_F", "EGLM"]): { "A3\Weapons_F\MagazineProxies\mag_40x36_HE_1rnd.p3d" }; // Should cover most 40x36 + default { getText (configFile >> "CfgMagazines" >> _mag >> QGVAR(dropModel)) } + }; +}, true]; + +if (_modelPath isEqualTo "") exitWith {}; + +private _unitPos = getposASL _unit; +private _weapDir = _unit weaponDirection currentWeapon _unit; +private _ejectDir = _weapDir vectorCrossProduct [0, 0, 1]; +private _pos = _unitPos + vectorAdd (_weapDir vectorMultiply (-0.5 + random 2)) + vectorAdd (_ejectDir vectorMultiply (0.2 + random 2)); + +[ + { + params ["_modelPath", "_pos"]; + TRACE_2("creating magazine",_modelPath,_pos); + + private _lisPos = (lineIntersectsSurfaces [_pos, _pos vectorAdd [0,0,-1e11], objNull, objNull, true, 1, "ROADWAY", "FIRE"]) #0; + private _casing = createSimpleObject [_modelPath, (_lisPos #0 vectorAdd [0,0,0.010]), false]; // global + _casing setDir (random 360); + _casing setVectorUp _lisPos #1; + private _idx = GVAR(casings) pushBack _casing; + + for "_" from 0 to (_idx - GVAR(maxCasings)) do { + deleteVehicle (GVAR(casings) deleteAt 0); + }; + }, + [_modelPath,_pos], + 0.4 +] call CBA_fnc_waitAndExecute; From 3f9da5f3085ba58998496ac44e01c939cc204cc7 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Thu, 23 May 2024 19:44:45 -0500 Subject: [PATCH 02/10] Add `ace_common_fnc_addPlayerEH` --- addons/casings/XEH_postInit.sqf | 2 +- .../casings/functions/fnc_createMagazine.sqf | 6 +-- addons/common/XEH_PREP.hpp | 1 + addons/common/functions/fnc_addPlayerEH.sqf | 44 +++++++++++++++++++ 4 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 addons/common/functions/fnc_addPlayerEH.sqf diff --git a/addons/casings/XEH_postInit.sqf b/addons/casings/XEH_postInit.sqf index e9ca54bb6ac..b69e5476603 100644 --- a/addons/casings/XEH_postInit.sqf +++ b/addons/casings/XEH_postInit.sqf @@ -6,4 +6,4 @@ GVAR(cachedCasings) = createHashMap; GVAR(cachedMagazines) = createHashMap; GVAR(casings) = []; ["CAManBase", "FiredMan", LINKFUNC(createCasing)] call CBA_fnc_addClassEventHandler; -["CAManBase", "Reloaded", LINKFUNC(createMagazine)] call CBA_fnc_addClassEventHandler; +[QGVAR(reloaded), "Reloaded", LINKFUNC(createMagazine)] call EFUNC(common,addPlayerEH); diff --git a/addons/casings/functions/fnc_createMagazine.sqf b/addons/casings/functions/fnc_createMagazine.sqf index a1765c796b6..ab4fc6fe4b8 100644 --- a/addons/casings/functions/fnc_createMagazine.sqf +++ b/addons/casings/functions/fnc_createMagazine.sqf @@ -19,15 +19,15 @@ params ["_unit", "", "", "", "_oldMagazine"]; TRACE_2("createMagazine",_unit,_oldMagazine); -if (_unit != ACE_player) exitWith {}; if (isNil "_oldMagazine") exitWith {}; _oldMagazine params ["_mag", "_ammo"]; if (_ammo != 0) exitWith {}; private _modelPath = GVAR(cachedMagazines) getOrDefaultCall [_mag, { switch (true) do { - case (_mag in compatibleMagazines ["arifle_Mk20_GL_F", "EGLM"]): { "A3\Weapons_F\MagazineProxies\mag_40x36_HE_1rnd.p3d" }; // Should cover most 40x36 - default { getText (configFile >> "CfgMagazines" >> _mag >> QGVAR(dropModel)) } + // Should cover most 40x36 + case (_mag in compatibleMagazines ["arifle_Mk20_GL_F", "EGLM"]): { "A3\Weapons_F\MagazineProxies\mag_40x36_HE_1rnd.p3d" }; + default { getText (configFile >> "CfgMagazines" >> _mag >> QGVAR(model)) }; }; }, true]; diff --git a/addons/common/XEH_PREP.hpp b/addons/common/XEH_PREP.hpp index fb64d464df8..b77845f7397 100644 --- a/addons/common/XEH_PREP.hpp +++ b/addons/common/XEH_PREP.hpp @@ -264,6 +264,7 @@ PREP(_handleRequestAllSyncedEvents); PREP(addActionEventHandler); PREP(addActionMenuEventHandler); PREP(addMapMarkerCreatedEventHandler); +PREP(addPlayerEH); PREP(removeActionEventHandler); PREP(removeActionMenuEventHandler); diff --git a/addons/common/functions/fnc_addPlayerEH.sqf b/addons/common/functions/fnc_addPlayerEH.sqf new file mode 100644 index 00000000000..a80eff611ae --- /dev/null +++ b/addons/common/functions/fnc_addPlayerEH.sqf @@ -0,0 +1,44 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Adds event handler just to ace_player + * + * Arguments: + * 0: Key + * 1: Event Type + * 2: Event Code + * + * Return Value: + * None + * + * Example: + * ["example", "FiredNear", {systemChat str _this}] call ace_common_fnc_addPlayerEH + * + * Public: Yes +*/ +params [["_key", "", [""]], ["_type", "", [""]], ["_code", {}, [{}]]]; + +if (isNil QGVAR(playerEventsHash)) then { // init + GVAR(playerEventsHash) = createHashMap; + ["unit", { + params ["_newPlayer", "_oldPlayer"]; + TRACE_3("",_newPlayer,_oldPlayer,count GVAR(playerEventsHash)); + { + private _var = format [QGVAR(playerEvents_%1), _x]; + private _oldEH = _oldPlayer getVariable [_var, -1]; + _oldPlayer removeEventHandler [_y#0, _oldEH]; + _oldPlayer setVariable [_var, nil]; + + private _newEH = _newPlayer addEventHandler _y; + _newPlayer setVariable [_var, _newEH]; + } forEach GVAR(playerEventsHash); + }, false] call CBA_fnc_addPlayerEventHandler; +}; + +private _event = [_type, _code]; +GVAR(playerEventsHash) set [_key, _event]; + +if (isNull ACE_player) exitWith {}; +private _var = format [QGVAR(playerEvents_%1), _key]; +private _newEH = ACE_player addEventHandler _event; +ACE_player setVariable [_var, _newEH]; From 6c98b98c5bd32c7e4c6ea39d5c4e4414caac8ed4 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Sun, 9 Jun 2024 18:24:16 -0500 Subject: [PATCH 03/10] fix merge --- addons/common/functions/fnc_addPlayerEH.sqf | 44 --------------------- 1 file changed, 44 deletions(-) diff --git a/addons/common/functions/fnc_addPlayerEH.sqf b/addons/common/functions/fnc_addPlayerEH.sqf index 879465c706a..81d030fb62a 100644 --- a/addons/common/functions/fnc_addPlayerEH.sqf +++ b/addons/common/functions/fnc_addPlayerEH.sqf @@ -59,47 +59,3 @@ if (_ignoreVirtual && {(unitIsUAV ACE_player) || {getNumber (configOf ACE_player // Add event now private _newEH = ACE_player addEventHandler [_type, _code]; ACE_player setVariable [_key, _newEH]; -#include "..\script_component.hpp" -/* - * Author: PabstMirror - * Adds event handler just to ace_player - * - * Arguments: - * 0: Key - * 1: Event Type - * 2: Event Code - * - * Return Value: - * None - * - * Example: - * ["example", "FiredNear", {systemChat str _this}] call ace_common_fnc_addPlayerEH - * - * Public: Yes -*/ -params [["_key", "", [""]], ["_type", "", [""]], ["_code", {}, [{}]]]; - -if (isNil QGVAR(playerEventsHash)) then { // init - GVAR(playerEventsHash) = createHashMap; - ["unit", { - params ["_newPlayer", "_oldPlayer"]; - TRACE_3("",_newPlayer,_oldPlayer,count GVAR(playerEventsHash)); - { - private _var = format [QGVAR(playerEvents_%1), _x]; - private _oldEH = _oldPlayer getVariable [_var, -1]; - _oldPlayer removeEventHandler [_y#0, _oldEH]; - _oldPlayer setVariable [_var, nil]; - - private _newEH = _newPlayer addEventHandler _y; - _newPlayer setVariable [_var, _newEH]; - } forEach GVAR(playerEventsHash); - }, false] call CBA_fnc_addPlayerEventHandler; -}; - -private _event = [_type, _code]; -GVAR(playerEventsHash) set [_key, _event]; - -if (isNull ACE_player) exitWith {}; -private _var = format [QGVAR(playerEvents_%1), _key]; -private _newEH = ACE_player addEventHandler _event; -ACE_player setVariable [_var, _newEH]; From 1ba4b9c68383cffeb39ade002bdae66b5a17165d Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Thu, 2 Jan 2025 16:45:29 -0600 Subject: [PATCH 04/10] update to use `CBA_fnc_addBISPlayerEventHandler` --- addons/casings/XEH_postInit.sqf | 2 +- addons/casings/functions/fnc_createMagazine.sqf | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/casings/XEH_postInit.sqf b/addons/casings/XEH_postInit.sqf index 62771902dab..622dbc96db2 100644 --- a/addons/casings/XEH_postInit.sqf +++ b/addons/casings/XEH_postInit.sqf @@ -10,5 +10,5 @@ if (!hasInterface) exitWith {}; GVAR(casings) = []; ["CAManBase", "FiredMan", LINKFUNC(createCasing)] call CBA_fnc_addClassEventHandler; - [QGVAR(reloaded), "Reloaded", LINKFUNC(createMagazine)] call EFUNC(common,addPlayerEH); + [QGVAR(reloaded), "Reloaded", LINKFUNC(createMagazine)] call CBA_fnc_addBISPlayerEventHandler; }] call CBA_fnc_addEventHandler; diff --git a/addons/casings/functions/fnc_createMagazine.sqf b/addons/casings/functions/fnc_createMagazine.sqf index ab4fc6fe4b8..47429fff84d 100644 --- a/addons/casings/functions/fnc_createMagazine.sqf +++ b/addons/casings/functions/fnc_createMagazine.sqf @@ -4,7 +4,7 @@ * Produces a casing matching the reloaded and dropped magazine * * Arguments: - * 0: unit - Object the event handler is assigned to + * 0: unit - Object the reloaded event handler is assigned to * 4: Old magazine (can be nil) - * * Return Value: @@ -33,7 +33,7 @@ private _modelPath = GVAR(cachedMagazines) getOrDefaultCall [_mag, { if (_modelPath isEqualTo "") exitWith {}; -private _unitPos = getposASL _unit; +private _unitPos = getPosASL _unit; private _weapDir = _unit weaponDirection currentWeapon _unit; private _ejectDir = _weapDir vectorCrossProduct [0, 0, 1]; private _pos = _unitPos From bd91f5f99a0e58378d7ac944f764068bff0f4ea5 Mon Sep 17 00:00:00 2001 From: LinkIsGrim <69561145+LinkIsGrim@users.noreply.github.com> Date: Wed, 5 Feb 2025 05:08:22 -0300 Subject: [PATCH 05/10] feat: add support for magazine proxies/dropped model --- addons/casings/functions/fnc_createCasing.sqf | 28 ++++++------- .../casings/functions/fnc_createMagazine.sqf | 18 +++++++- docs/wiki/feature/casings.md | 4 +- docs/wiki/framework/casings-framework.md | 42 +++++++++++++++++++ 4 files changed, 72 insertions(+), 20 deletions(-) create mode 100644 docs/wiki/framework/casings-framework.md diff --git a/addons/casings/functions/fnc_createCasing.sqf b/addons/casings/functions/fnc_createCasing.sqf index 990bef16b2e..adf40caffda 100644 --- a/addons/casings/functions/fnc_createCasing.sqf +++ b/addons/casings/functions/fnc_createCasing.sqf @@ -23,26 +23,22 @@ if (!isNull objectParent _unit) exitWith {}; private _modelPath = GVAR(cachedCasings) getOrDefaultCall [_ammo, { private _cartridge = getText (configFile >> "CfgAmmo" >> _ammo >> "cartridge"); - if (_cartridge == "") then { // return (note: can't use exitWith) - "" - } else { - private _cartridgeConfig = configFile >> "CfgVehicles" >> _cartridge; + private _model = switch (true) do { + case (_cartridge == ""): { "" }; - // if explicitly defined, use ACE's config - if (isText (_cartridgeConfig >> QGVAR(model))) exitWith { - getText (_cartridgeConfig >> QGVAR(model)) - }; - // use casing's default model - private _model = getText (_cartridgeConfig >> "model"); - if ("a3\weapons_f\empty" in toLowerANSI _model) exitWith { "" }; + private _cartridgeConfig = configFile >> "CfgVehicles" >> _cartridge; + private _modelOverride = getText (_cartridgeConfig >> QGVAR(model)); - // Add file extension if missing (fileExists needs file extension) - if ((_model select [count _model - 4]) != ".p3d") then { - _model = _model + ".p3d"; - }; + case (_modelOverride != ""): { _modelOverride }; // Use the override if non-empty + default { getText (_cartridgeConfig >> "model") } // Use the casing's default model + }; - ["", _model] select (fileExists _model) + // Add file extension if missing (fileExists needs file extension) + if ((_model select [count _model - 4]) != ".p3d") then { + _model = _model + ".p3d"; }; + + ["", _model] select (!("a3\weapons_f\empty" in toLowerANSI _model) && fileExists _model) }, true]; if (_modelPath isEqualTo "") exitWith {}; diff --git a/addons/casings/functions/fnc_createMagazine.sqf b/addons/casings/functions/fnc_createMagazine.sqf index 47429fff84d..25f4210e855 100644 --- a/addons/casings/functions/fnc_createMagazine.sqf +++ b/addons/casings/functions/fnc_createMagazine.sqf @@ -24,11 +24,25 @@ _oldMagazine params ["_mag", "_ammo"]; if (_ammo != 0) exitWith {}; private _modelPath = GVAR(cachedMagazines) getOrDefaultCall [_mag, { - switch (true) do { + private _model = switch (true) do { // Should cover most 40x36 case (_mag in compatibleMagazines ["arifle_Mk20_GL_F", "EGLM"]): { "A3\Weapons_F\MagazineProxies\mag_40x36_HE_1rnd.p3d" }; - default { getText (configFile >> "CfgMagazines" >> _mag >> QGVAR(model)) }; + + private _magConfig = configFile >> "CfgMagazines" >> _mag; + private _modelOverride = getText (_magConfig >> QGVAR(model)); + + case (_modelOverride != ""): { _modelOverride }; // Use the override if non-empty + case (getNumber (_magConfig >> "modelSpecialIsProxy") == 1): { getText (_magConfig >> "modelSpecial") }; // Use the magazine's proxy + + default { getText (_magConfig >> "model") } // Use the magazine's dropped model }; + + // Add file extension if missing (fileExists needs file extension) + if ((_model select [count _model - 4]) != ".p3d") then { + _model = _model + ".p3d"; + }; + + ["", _model] select (!(_model regexMatch "(?:a3\weapons_f\empty|\ca\weapons\mag_univ).p3d") && fileExists _model) }, true]; if (_modelPath isEqualTo "") exitWith {}; diff --git a/docs/wiki/feature/casings.md b/docs/wiki/feature/casings.md index 8bcf24a6969..e1543f92dc0 100644 --- a/docs/wiki/feature/casings.md +++ b/docs/wiki/feature/casings.md @@ -2,7 +2,7 @@ layout: wiki title: Casings component: casings -description: Adds infantry bullet casings on the ground when weapons are fired. +description: Adds infantry bullet casings on the ground when weapons are fired and drops empty magazines when reloading. group: feature category: realism parent: wiki @@ -14,4 +14,4 @@ version: --- ## 1. Overview -Spits out casings from infantry weapons when fired. +Spits out casings from infantry weapons when fired and drops empty magazines when reloading. diff --git a/docs/wiki/framework/casings-framework.md b/docs/wiki/framework/casings-framework.md new file mode 100644 index 00000000000..df4ee6a9e4d --- /dev/null +++ b/docs/wiki/framework/casings-framework.md @@ -0,0 +1,42 @@ +--- +layout: wiki +title: Casings Framework +description: Explains how to set-up dropped magazine models with ACE3 casings system. +group: framework +order: 5 +parent: wiki +mod: ace +version: + major: 3 + minor: 0 + patch: 0 +--- + +## 1. Config Values + +```cpp +class CfgAmmo { // In order of priority + class MyAmmo { + cartridge = "CartridgeClassnameInCfgVehicles"; // if empty (""), no casing will be created + ace_casings_model = "path\to\casing\model.p3d"; // Dropped casing will have this model if not an empty string + }; +}; + +class CfgVehicles { + class MyCartridge { + model = "path\to\cartridge\model.p3d"; // If empty string or model, no casing will be created + }; +}; + +class CfgMagazines { + class MyMagazine { // In order of priority + // If magazine is compatible with vanilla Mk20's EGLM, model will always be "A3\Weapons_F\MagazineProxies\mag_40x36_HE_1rnd.p3d" + ace_casings_model = "path\to\magazine\model.p3d"; //Dropped magazine will have this model if not an empty string + modelSpecialIsProxy = 1; + modelSpecial = "path\to\magazine\proxy\model.p3d"; // Proxy model + model = "path\to\magazine\dropped\model.p3d"; // Dropped model + + // If model doesn't exist, is the default dropped magazine model (pouch), or is empty, no dropped magazine will be created. + }; +}; +``` From a729b371a063bdba38e5c32459a55da0254a5e8e Mon Sep 17 00:00:00 2001 From: Grim <69561145+LinkIsGrim@users.noreply.github.com> Date: Sat, 8 Feb 2025 23:41:01 -0300 Subject: [PATCH 06/10] Update addons/casings/functions/fnc_createCasing.sqf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jouni Järvinen --- addons/casings/functions/fnc_createCasing.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/casings/functions/fnc_createCasing.sqf b/addons/casings/functions/fnc_createCasing.sqf index adf40caffda..6f359bde115 100644 --- a/addons/casings/functions/fnc_createCasing.sqf +++ b/addons/casings/functions/fnc_createCasing.sqf @@ -38,7 +38,7 @@ private _modelPath = GVAR(cachedCasings) getOrDefaultCall [_ammo, { _model = _model + ".p3d"; }; - ["", _model] select (!("a3\weapons_f\empty" in toLowerANSI _model) && fileExists _model) + ["", _model] select (!("a3\weapons_f\empty" in toLowerANSI _model) && {fileExists _model}) }, true]; if (_modelPath isEqualTo "") exitWith {}; From fa967e7d94b3fdcd8e9ba5c7ef21cfa6ea548aa2 Mon Sep 17 00:00:00 2001 From: LinkIsGrim <69561145+LinkIsGrim@users.noreply.github.com> Date: Sun, 9 Feb 2025 00:18:09 -0300 Subject: [PATCH 07/10] fix: regex & undefined vars --- addons/casings/XEH_PREP.hpp | 1 + addons/casings/functions/fnc_createCasing.sqf | 37 +++------------- addons/casings/functions/fnc_createLitter.sqf | 32 ++++++++++++++ .../casings/functions/fnc_createMagazine.sqf | 43 +++++-------------- 4 files changed, 49 insertions(+), 64 deletions(-) create mode 100644 addons/casings/functions/fnc_createLitter.sqf diff --git a/addons/casings/XEH_PREP.hpp b/addons/casings/XEH_PREP.hpp index 13b21542f74..1dab059008f 100644 --- a/addons/casings/XEH_PREP.hpp +++ b/addons/casings/XEH_PREP.hpp @@ -1,2 +1,3 @@ PREP(createCasing); +PREP(createLitter); PREP(createMagazine); diff --git a/addons/casings/functions/fnc_createCasing.sqf b/addons/casings/functions/fnc_createCasing.sqf index 6f359bde115..c1c246a08c4 100644 --- a/addons/casings/functions/fnc_createCasing.sqf +++ b/addons/casings/functions/fnc_createCasing.sqf @@ -22,12 +22,15 @@ if (!isNull objectParent _unit) exitWith {}; private _modelPath = GVAR(cachedCasings) getOrDefaultCall [_ammo, { + private _cartridgeConfig = configNull; // private var in switch condition scope isn't available in the result block. + private _modelOverride = ""; // very annoying. + private _cartridge = getText (configFile >> "CfgAmmo" >> _ammo >> "cartridge"); private _model = switch (true) do { case (_cartridge == ""): { "" }; - private _cartridgeConfig = configFile >> "CfgVehicles" >> _cartridge; - private _modelOverride = getText (_cartridgeConfig >> QGVAR(model)); + _cartridgeConfig = configFile >> "CfgVehicles" >> _cartridge; + _modelOverride = getText (_cartridgeConfig >> QGVAR(model)); case (_modelOverride != ""): { _modelOverride }; // Use the override if non-empty default { getText (_cartridgeConfig >> "model") } // Use the casing's default model @@ -41,32 +44,4 @@ private _modelPath = GVAR(cachedCasings) getOrDefaultCall [_ammo, { ["", _model] select (!("a3\weapons_f\empty" in toLowerANSI _model) && {fileExists _model}) }, true]; -if (_modelPath isEqualTo "") exitWith {}; - -private _unitPos = getPosASL _unit; -// Distant shooters don't produce as many cases -if ((AGLToASL positionCameraToWorld [0,0,0]) vectorDistance _unitPos > 100 && {random 1 < 0.9}) exitWith {}; - -private _weapDir = _unit weaponDirection currentWeapon _unit; -private _ejectDir = _weapDir vectorCrossProduct [0, 0, 1]; -private _pos = _unitPos - vectorAdd (_weapDir vectorMultiply (-0.5 + random 2)) - vectorAdd (_ejectDir vectorMultiply (0.2 + random 2)); - -[ - { - params ["_modelPath", "_pos"]; - - private _lisPos = (lineIntersectsSurfaces [_pos, _pos vectorAdd [0,0,-1e11], objNull, objNull, true, 1, "ROADWAY", "FIRE"]) #0; - private _casing = createSimpleObject [_modelPath, (_lisPos #0 vectorAdd [0,0,0.005]), true]; - _casing setDir (random 360); - _casing setVectorUp _lisPos #1; - private _idx = GVAR(casings) pushBack _casing; - - for "_" from 0 to (_idx - GVAR(maxCasings)) do { - deleteVehicle (GVAR(casings) deleteAt 0); - }; - }, - [_modelPath,_pos], - 0.4 -] call CBA_fnc_waitAndExecute; +[_unit, _modelPath] call FUNC(createLitter); diff --git a/addons/casings/functions/fnc_createLitter.sqf b/addons/casings/functions/fnc_createLitter.sqf new file mode 100644 index 00000000000..694e5953b15 --- /dev/null +++ b/addons/casings/functions/fnc_createLitter.sqf @@ -0,0 +1,32 @@ +params ["_unit", "_modelPath", ["_force", false]]; + +if (_modelPath == "") exitWith {}; + +// Distant shooters don't produce as many cases +if (!_force && ((AGLToASL positionCameraToWorld [0,0,0]) vectorDistance _unitPos > 100 && {random 1 < 0.9})) exitWith {}; + +private _unitPos = getPosASL _unit; +private _weapDir = _unit weaponDirection currentWeapon _unit; +private _ejectDir = _weapDir vectorCrossProduct [0, 0, 1]; +private _pos = _unitPos + vectorAdd (_weapDir vectorMultiply (-0.5 + random 2)) + vectorAdd (_ejectDir vectorMultiply (0.2 + random 2)); + +[ + { + params ["_modelPath", "_pos"]; + TRACE_2("creating magazine",_modelPath,_pos); + + private _lisPos = (lineIntersectsSurfaces [_pos, _pos vectorAdd [0,0,-1e11], objNull, objNull, true, 1, "ROADWAY", "FIRE"]) #0; + private _casing = createSimpleObject [_modelPath, (_lisPos #0 vectorAdd [0,0,0.010]), false]; // global + _casing setDir (random 360); + _casing setVectorUp _lisPos #1; + private _idx = GVAR(casings) pushBack _casing; + + for "_" from 0 to (_idx - GVAR(maxCasings)) do { + deleteVehicle (GVAR(casings) deleteAt 0); + }; + }, + [_modelPath,_pos], + 0.4 +] call CBA_fnc_waitAndExecute; diff --git a/addons/casings/functions/fnc_createMagazine.sqf b/addons/casings/functions/fnc_createMagazine.sqf index 25f4210e855..0d917fe5c20 100644 --- a/addons/casings/functions/fnc_createMagazine.sqf +++ b/addons/casings/functions/fnc_createMagazine.sqf @@ -24,17 +24,20 @@ _oldMagazine params ["_mag", "_ammo"]; if (_ammo != 0) exitWith {}; private _modelPath = GVAR(cachedMagazines) getOrDefaultCall [_mag, { - private _model = switch (true) do { + private _magConfig = configNull; // private var in switch condition scope isn't available in the result block. + private _modelOverride = ""; // very annoying. + + private _model = switch true do { // Should cover most 40x36 case (_mag in compatibleMagazines ["arifle_Mk20_GL_F", "EGLM"]): { "A3\Weapons_F\MagazineProxies\mag_40x36_HE_1rnd.p3d" }; - private _magConfig = configFile >> "CfgMagazines" >> _mag; - private _modelOverride = getText (_magConfig >> QGVAR(model)); + _magConfig = configFile >> "CfgMagazines" >> _mag; + _modelOverride = getText (_magConfig >> QGVAR(model)); case (_modelOverride != ""): { _modelOverride }; // Use the override if non-empty - case (getNumber (_magConfig >> "modelSpecialIsProxy") == 1): { getText (_magConfig >> "modelSpecial") }; // Use the magazine's proxy + case (getNumber (_magConfig >> "modelSpecialIsProxy") == 1): {getText (_magConfig >> "modelSpecial")}; // Use the magazine's proxy - default { getText (_magConfig >> "model") } // Use the magazine's dropped model + default { getText (_magConfig >> "model") }; // Use the magazine's dropped model }; // Add file extension if missing (fileExists needs file extension) @@ -42,33 +45,7 @@ private _modelPath = GVAR(cachedMagazines) getOrDefaultCall [_mag, { _model = _model + ".p3d"; }; - ["", _model] select (!(_model regexMatch "(?:a3\weapons_f\empty|\ca\weapons\mag_univ).p3d") && fileExists _model) + ["", _model] select (!(_model regexMatch "(?:\\)?a3\\weapons_f\\(?:empty|ammo\\mag_univ).p3d") && {fileExists _model}) }, true]; -if (_modelPath isEqualTo "") exitWith {}; - -private _unitPos = getPosASL _unit; -private _weapDir = _unit weaponDirection currentWeapon _unit; -private _ejectDir = _weapDir vectorCrossProduct [0, 0, 1]; -private _pos = _unitPos - vectorAdd (_weapDir vectorMultiply (-0.5 + random 2)) - vectorAdd (_ejectDir vectorMultiply (0.2 + random 2)); - -[ - { - params ["_modelPath", "_pos"]; - TRACE_2("creating magazine",_modelPath,_pos); - - private _lisPos = (lineIntersectsSurfaces [_pos, _pos vectorAdd [0,0,-1e11], objNull, objNull, true, 1, "ROADWAY", "FIRE"]) #0; - private _casing = createSimpleObject [_modelPath, (_lisPos #0 vectorAdd [0,0,0.010]), false]; // global - _casing setDir (random 360); - _casing setVectorUp _lisPos #1; - private _idx = GVAR(casings) pushBack _casing; - - for "_" from 0 to (_idx - GVAR(maxCasings)) do { - deleteVehicle (GVAR(casings) deleteAt 0); - }; - }, - [_modelPath,_pos], - 0.4 -] call CBA_fnc_waitAndExecute; +[_unit, _modelPath, true] call FUNC(createLitter); From 4f1294650eb587bc9d0a9ee430fde0ac6ae9694e Mon Sep 17 00:00:00 2001 From: LinkIsGrim <69561145+LinkIsGrim@users.noreply.github.com> Date: Sun, 9 Feb 2025 00:19:09 -0300 Subject: [PATCH 08/10] fix: trace --- addons/casings/functions/fnc_createLitter.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/casings/functions/fnc_createLitter.sqf b/addons/casings/functions/fnc_createLitter.sqf index 694e5953b15..2f53c577cf4 100644 --- a/addons/casings/functions/fnc_createLitter.sqf +++ b/addons/casings/functions/fnc_createLitter.sqf @@ -15,7 +15,7 @@ private _pos = _unitPos [ { params ["_modelPath", "_pos"]; - TRACE_2("creating magazine",_modelPath,_pos); + TRACE_2("creating litter",_modelPath,_pos); private _lisPos = (lineIntersectsSurfaces [_pos, _pos vectorAdd [0,0,-1e11], objNull, objNull, true, 1, "ROADWAY", "FIRE"]) #0; private _casing = createSimpleObject [_modelPath, (_lisPos #0 vectorAdd [0,0,0.010]), false]; // global From f8f9f1c72302d21aa268cc721dc6c0fefa48ad33 Mon Sep 17 00:00:00 2001 From: LinkIsGrim <69561145+LinkIsGrim@users.noreply.github.com> Date: Sun, 9 Feb 2025 00:31:44 -0300 Subject: [PATCH 09/10] fix: include/function header --- addons/casings/functions/fnc_createLitter.sqf | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/addons/casings/functions/fnc_createLitter.sqf b/addons/casings/functions/fnc_createLitter.sqf index 2f53c577cf4..56b1443082a 100644 --- a/addons/casings/functions/fnc_createLitter.sqf +++ b/addons/casings/functions/fnc_createLitter.sqf @@ -1,9 +1,28 @@ +#include "..\script_component.hpp" +/* + * Author: esteldunedain / Cyruz / diwako + * Handles casing/dropped mag creation. + * + * Arguments: + * 0: Unit - Unit to create litter for + * 1: Model - Path to litter model + * 2: Force creation - Skip the distance + RNG check (default: false) + * + * Return Value: + * None + * + * Example: + * [player, "\a3\weapons_f\mag_univ.p3d"] call ace_casings_fnc_createLitter + * + * Public: No + */ + params ["_unit", "_modelPath", ["_force", false]]; if (_modelPath == "") exitWith {}; // Distant shooters don't produce as many cases -if (!_force && ((AGLToASL positionCameraToWorld [0,0,0]) vectorDistance _unitPos > 100 && {random 1 < 0.9})) exitWith {}; +if (!_force && {(AGLToASL positionCameraToWorld [0,0,0]) vectorDistance _unitPos > 100 && {random 1 < 0.9}}) exitWith {}; private _unitPos = getPosASL _unit; private _weapDir = _unit weaponDirection currentWeapon _unit; From f903812c96d7ce5814c6d8acff57a6bc9c532170 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Sun, 23 Feb 2025 17:44:35 -0600 Subject: [PATCH 10/10] Fix _unitPos --- addons/casings/functions/fnc_createLitter.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/casings/functions/fnc_createLitter.sqf b/addons/casings/functions/fnc_createLitter.sqf index 56b1443082a..f9a26c68418 100644 --- a/addons/casings/functions/fnc_createLitter.sqf +++ b/addons/casings/functions/fnc_createLitter.sqf @@ -21,10 +21,10 @@ params ["_unit", "_modelPath", ["_force", false]]; if (_modelPath == "") exitWith {}; +private _unitPos = getPosASL _unit; // Distant shooters don't produce as many cases if (!_force && {(AGLToASL positionCameraToWorld [0,0,0]) vectorDistance _unitPos > 100 && {random 1 < 0.9}}) exitWith {}; -private _unitPos = getPosASL _unit; private _weapDir = _unit weaponDirection currentWeapon _unit; private _ejectDir = _weapDir vectorCrossProduct [0, 0, 1]; private _pos = _unitPos