From 35658e41cc9b8ed8ea19053b546eb510cb8ddc63 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Mon, 19 Aug 2024 07:50:54 +0200 Subject: [PATCH 01/26] Docs - Update Arma 3 Issues (#10207) Update arma-3-issues.md --- docs/wiki/development/arma-3-issues.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/wiki/development/arma-3-issues.md b/docs/wiki/development/arma-3-issues.md index 506bfde222..379fb7d5bb 100644 --- a/docs/wiki/development/arma-3-issues.md +++ b/docs/wiki/development/arma-3-issues.md @@ -14,7 +14,6 @@ Keeping track of Arma 3 issues that need to be fixed. - [bux578: T79355: MineDetector equipable in Launcher slot](https://feedback.bistudio.com/T79355) - [bux578: T79534: Zeus / Curator Add Remote Controlled Event](https://feedback.bistudio.com/T79534) -- [bux578: T79827: Add script commands "addPrimaryWeaponMagazine" and "addSecondaryWeaponMagazine"](https://feedback.bistudio.com/T79827) - [bux578: T80358: Add/Alter script command to add perfectly configured weapons to cargo](https://feedback.bistudio.com/T80358) - [commy2: T79801: Unexpected behavior of += array in configs](https://feedback.bistudio.com/T79801) - [commy2: T81029: setVariable is not always JIP persistent](https://feedback.bistudio.com/T81029) @@ -23,11 +22,12 @@ Keeping track of Arma 3 issues that need to be fixed. - [Jaynus: T82046: Display event handler return values for mouse buttons should be respected](https://feedback.bistudio.com/T82046) - [Heisenberg: T82108: Switching between optic modes of a sniper scope (AMS, DMS, MOS) will result in a blurred vision](https://feedback.bistudio.com/T82108) - [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:** - [Nou: T79119: Memory points rfemur, lfemur, and other leg memory points returned incorrectly with SQF command selectionPosition](https://feedback.bistudio.com/T79119) - [commy2: T81503: isLightOn doesn't recognize destroyed light bulbs for streetlamps](https://feedback.bistudio.com/T81503) - [commy2: T83771: splitString scripting command causes game crash](https://feedback.bistudio.com/T83771) +- [bux578: T79827: Add script commands "addPrimaryWeaponMagazine" and "addSecondaryWeaponMagazine"](https://feedback.bistudio.com/T79827) +- [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) From 81f44e6e7ab7e44c4f6a9ff635008a929a493e4b Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Mon, 19 Aug 2024 07:51:37 +0200 Subject: [PATCH 02/26] Realistic Names - Fix bad inheritance from #10202 (#10225) Fix bad inheritance from #10202 --- addons/realisticnames/CfgVehicles.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/addons/realisticnames/CfgVehicles.hpp b/addons/realisticnames/CfgVehicles.hpp index 00298d0c24..ba95cf147d 100644 --- a/addons/realisticnames/CfgVehicles.hpp +++ b/addons/realisticnames/CfgVehicles.hpp @@ -1043,20 +1043,20 @@ class CfgVehicles { }; // RPG-32 - class Weapon_launch_RPG32_ghex_F: Weapon_Base_F { + class Weapon_launch_RPG32_ghex_F: Launcher_Base_F { displayName = CSTRING(launch_RPG32_ghex); }; // P99 - class Weapon_hgun_P07_khk_F: Weapon_Base_F { + class Weapon_hgun_P07_khk_F: Pistol_Base_F { displayName = CSTRING(hgun_P07_khk); }; - class Weapon_hgun_P07_blk_F: Weapon_Base_F { + class Weapon_hgun_P07_blk_F: Pistol_Base_F { displayName = CSTRING(hgun_P07_blk); }; // Makarov - class Weapon_hgun_Pistol_01_F: Weapon_Base_F { + class Weapon_hgun_Pistol_01_F: Pistol_Base_F { displayName = CSTRING(hgun_Pistol_01); }; @@ -1081,12 +1081,12 @@ class CfgVehicles { }; // FNX-45 (Green) - class Weapon_hgun_Pistol_heavy_01_green_F: Weapon_Base_F { + class Weapon_hgun_Pistol_heavy_01_green_F: Pistol_Base_F { displayName = CSTRING(hgun_Pistol_heavy_01_green_Name); }; // RPG-32 (Green) - class Weapon_launch_RPG32_green_F: Weapon_Base_F { + class Weapon_launch_RPG32_green_F: Launcher_Base_F { displayName = CSTRING(launch_RPG32_green_Name); }; From 962b498e6ad021dab2ef2f095b59dd0d96635013 Mon Sep 17 00:00:00 2001 From: Enrico Machado Date: Tue, 20 Aug 2024 02:31:43 +0100 Subject: [PATCH 03/26] Translation - Improve Portuguese (#10159) * Update stringtable.xml * Update stringtable.xml --- addons/dogtags/stringtable.xml | 10 +++++----- addons/medical_treatment/stringtable.xml | 14 +++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/addons/dogtags/stringtable.xml b/addons/dogtags/stringtable.xml index 73d2d07e56..ff0af0db4e 100644 --- a/addons/dogtags/stringtable.xml +++ b/addons/dogtags/stringtable.xml @@ -13,7 +13,7 @@ Piastrina 兵籍牌 兵籍牌 - Dog Tag + Chapa de Identificação Placa de identidad Künye @@ -29,7 +29,7 @@ Controlla Piastrina 檢查兵籍牌 检查兵籍牌 - Verificar Dog Tag + Verificar chapa de identificação Verificar placa de identidad Künyeyi Kontrol Et @@ -77,7 +77,7 @@ Piastrina presa da %1... 從%1身上拿取兵籍牌... 从%1身上拿取兵籍牌... - Dogtag pego de %1... + Chapa de identificação pega de %1... Tomada placa de identidad de %1... Künye %1 kişisinden alındı @@ -93,7 +93,7 @@ Qualcun altro ha già preso la piastrina... 已經有人把他的兵籍牌拿走了... 已经有人把他的兵籍牌拿走了... - Alguém já pegou essa dogtag... + Alguém já pegou essa chapa de identificação... Alguien más ha tomado la placa de identidad Başka biri zaten künyeyi almış @@ -106,7 +106,7 @@ Indicatore su schermo per il controllo delle piastrine Wyświetlacz ekranowy dla sprawdzania nieśmiertelników Экран для проверки жетонов - Tela de Exibição para verificar dogtags + Tela de exibição para verificar chapas de identificação Visualización en pantalla de placa de identidad Affichage à l'écran pour le contrôle des plaques. Okno na obrazovce pro kontrolu známek diff --git a/addons/medical_treatment/stringtable.xml b/addons/medical_treatment/stringtable.xml index 2be4541677..6211a05359 100644 --- a/addons/medical_treatment/stringtable.xml +++ b/addons/medical_treatment/stringtable.xml @@ -1874,7 +1874,7 @@ Auto-morfin Morfium autoinjektor Autoiniettore di Morfina - Auto-injetor de morfina + Autoinjetor de Morfina モルヒネ自動注射器 자동주사기 (모르핀) 吗啡自动注射器 @@ -1921,7 +1921,7 @@ Auto-injecteur d'adénosine Autoiniettore di Adenosina Auto-adenosine - Auto-injetor de Adenosina + Autoinjetor de Adenosina Аденозин в пневмошприце アデノシン自動注射器 자동주사기 (아데노신) @@ -1969,7 +1969,7 @@ Auto-atropine Atropin autoinjektor Autoiniettore di Atropina - Auto-injetor de Atropina + Autoinjetor de Atropina アトロピン自動注射器 자동주사기 (아트로핀) 阿托品自动注射器 @@ -2018,7 +2018,7 @@ Auto-adrenalin Epinefrin autoinjektor Autoiniettore di Epinefrina - Auto-injetor de epinefrina + Autoinjetor de Epinefrina アドレナリン自動注射器 자동주사기 (에피네프린) 肾上腺素自动注射器 @@ -2432,7 +2432,7 @@ Operationsset Sebészeti készlet Kit chirurgico - Kit Cirurgico + Kit Cirúrgico Chirurgická sada 手術キット 봉합 키트 @@ -2449,7 +2449,7 @@ Operationsset für fortgeschrittene medizinische Feldversorgung Sebészeti készlet komplex orvosi feladatok terepen való ellátására Kit chirurgico per trattamenti avanzati sul campo. - Kit Cirurgico para uso de tratamento médico avançado em campo + Kit Cirúrgico para uso de tratamento médico avançado em campo Chirurgická sada určená k pokročilejším zdravotnickým zákrokům v poli 手術キットは戦場で高度な処置をする為に用いる 야전 상황에서 고급 의료 처치를 위해 사용되는 봉합 키트 @@ -2466,7 +2466,7 @@ Trousse chirurgicale pour le traitement avancé sur le terrain. Sebészeti készlet komplex orvosi feladatok terepen való ellátására Kit chirurgico per trattamenti avanzati sul campo. - Kit Cirurgico para uso de tratamento médico avançado em campo. + Kit Cirúrgico para uso de tratamento médico avançado em campo. Chirurgická sada určená k pokročilejším zdravotnickým zákrokům v poli 手術キットは戦場で高度な処置をする為に用いる 야전 상황에서 고급 의료 처치를 위해 사용되는 봉합 키트 From 268277849970ab9811d7499edfb6bad2a47d43a9 Mon Sep 17 00:00:00 2001 From: Dart <59131299+DartRuffian@users.noreply.github.com> Date: Tue, 20 Aug 2024 10:47:47 -0500 Subject: [PATCH 04/26] HEMTT - Use extends for launch presets (#10231) Use extends for launch presets --- .hemtt/project.toml | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/.hemtt/project.toml b/.hemtt/project.toml index f5ed361e3e..a9535dd2ba 100644 --- a/.hemtt/project.toml +++ b/.hemtt/project.toml @@ -34,32 +34,26 @@ workshop = [ ] [hemtt.launch.spe] -workshop = [ - "450814997", # CBA_A3 -] +extends = "default" dlc = [ "spe" ] [hemtt.launch.vn] -workshop = [ - "450814997", # CBA_A3's Workshop ID -] +extends = "default" dlc = [ "S.O.G. Prairie Fire", ] [hemtt.launch.ws] -workshop = [ - "450814997", # CBA_A3's Workshop ID -] +extends = "default" dlc = [ "Western Sahara", ] [hemtt.launch.rhs] +extends = "default" workshop = [ - "450814997", # CBA_A3's Workshop ID "843425103", # RHS AFRF Workshop ID "843577117", # RHS USAF Workshop ID "843593391", # RHS GREF Workshop ID From 80b2fa9a05bdb73e1ba2acae8192f57334dae976 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Tue, 20 Aug 2024 21:23:21 +0200 Subject: [PATCH 05/26] Vehicle damage - Code cleanup (#9831) * Cook-off improvements * More changes * Update fnc_getVehicleAmmo.sqf * Better engine fire placement * Update fnc_detonateAmmunition.sqf * Update XEH_postInit.sqf * Update fnc_getVehicleAmmo.sqf * Update events-framework.md * Various improvements * Separate effect handling * Tweaks * Update XEH_postInit.sqf * Prevent double ammo detonation * Fixed objects not being able to cook-off again * Added incendiary rounds as source of box cookoff * Converted enable setting to bool * Fixed brackets * Update fnc_cookOff.sqf * Update CfgEden.hpp * Removed GVAR(enable), added GVAR(enableFire) back * Vehicle damage fixes * Made hitpoint hash common * Update fnc_addEventHandler.sqf * Update fnc_medicalDamage.sqf * Update fnc_handleBail.sqf * Changed API * Remove `CBA_fnc_getConfigEntry` as much as possible, as it's 2x slower * More cleanup * More cleanup * Fix merging issues, remove turret tossing * Update translations * More cleanup * Reverted some logic back to original, minor tweaks & fixes * Fix undefined variable * Cleanup * Fixed bad logic * Update addons/vehicle_damage/script_macros.hpp Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com> * Update addons/vehicle_damage/functions/fnc_handleDamage.sqf * Update addons/vehicle_damage/stringtable.xml Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com> * Update addons/vehicle_damage/stringtable.xml Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com> * Update addons/vehicle_damage/XEH_postInit.sqf Co-authored-by: PabstMirror --------- Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com> Co-authored-by: PabstMirror --- addons/vehicle_damage/CfgAmmo.hpp | 3 - addons/vehicle_damage/CfgEventHandlers.hpp | 12 +- addons/vehicle_damage/CfgVehicles.hpp | 3 +- addons/vehicle_damage/XEH_PREP.hpp | 19 +- addons/vehicle_damage/XEH_postInit.sqf | 100 ++--- addons/vehicle_damage/config.cpp | 2 +- .../vehicle_damage/functions/fnc_abandon.sqf | 23 +- .../functions/fnc_addDamage.sqf | 42 -- .../functions/fnc_addEventHandler.sqf | 127 +++--- .../functions/fnc_blowOffTurret.sqf | 3 +- .../fnc_calculatePenetrationInfo.sqf | 118 ------ .../vehicle_damage/functions/fnc_detonate.sqf | 27 -- .../functions/fnc_handleBail.sqf | 66 ++-- .../functions/fnc_handleCookoff.sqf | 84 ++-- .../functions/fnc_handleDamage.sqf | 115 +++--- .../fnc_handleDamageEjectIfDestroyed.sqf | 2 +- .../functions/fnc_handleDetonation.sqf | 60 ++- .../functions/fnc_handleVehicleDamage.sqf | 95 ++--- .../vehicle_damage/functions/fnc_knockOut.sqf | 34 +- .../functions/fnc_processHit.sqf | 363 ++++++++++-------- .../functions/fnc_setDamage.sqf | 45 +++ addons/vehicle_damage/initSettings.inc.sqf | 18 +- addons/vehicle_damage/script_macros.hpp | 12 +- addons/vehicle_damage/stringtable.xml | 52 +-- docs/wiki/feature/vehicledamage.md | 19 +- .../wiki/framework/vehicledamage-framework.md | 6 +- 26 files changed, 694 insertions(+), 756 deletions(-) delete mode 100644 addons/vehicle_damage/functions/fnc_addDamage.sqf delete mode 100644 addons/vehicle_damage/functions/fnc_calculatePenetrationInfo.sqf delete mode 100644 addons/vehicle_damage/functions/fnc_detonate.sqf create mode 100644 addons/vehicle_damage/functions/fnc_setDamage.sqf diff --git a/addons/vehicle_damage/CfgAmmo.hpp b/addons/vehicle_damage/CfgAmmo.hpp index 408c3e7b15..ad84fbc53c 100644 --- a/addons/vehicle_damage/CfgAmmo.hpp +++ b/addons/vehicle_damage/CfgAmmo.hpp @@ -21,9 +21,6 @@ class CfgAmmo { class M_Vorona_HEAT; class M_SPG9_HEAT; class R_MRAAWS_HEAT_F; - class B_338_Ball; - - class ACE_G_40mm_HE; CREATE_INCENDIARY_AMMO(BulletBase, BulletCore, 0.1); CREATE_INCENDIARY_AMMO(ShellBase, ShellCore, 1.0); diff --git a/addons/vehicle_damage/CfgEventHandlers.hpp b/addons/vehicle_damage/CfgEventHandlers.hpp index 74ffec132e..f6503c2479 100644 --- a/addons/vehicle_damage/CfgEventHandlers.hpp +++ b/addons/vehicle_damage/CfgEventHandlers.hpp @@ -1,19 +1,17 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; -class Extended_PostInit_EventHandlers { - class ADDON { - init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); - }; -}; - class Extended_PreInit_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; diff --git a/addons/vehicle_damage/CfgVehicles.hpp b/addons/vehicle_damage/CfgVehicles.hpp index 9ea47711ea..96a6e956e6 100644 --- a/addons/vehicle_damage/CfgVehicles.hpp +++ b/addons/vehicle_damage/CfgVehicles.hpp @@ -28,6 +28,7 @@ class CfgVehicles { GVAR(engineFireProb) = 0.5; GVAR(detonationDuringFireProb) = 0.2; GVAR(canHaveFireRing) = 0; + EGVAR(cookoff,canHaveFireJet) = 1; }; class Wheeled_APC_F: Car_F { GVAR(hullDetonationProb) = 0.2; @@ -38,6 +39,7 @@ class CfgVehicles { GVAR(engineFireProb) = 0.5; GVAR(detonationDuringFireProb) = 0.2; GVAR(canHaveFireRing) = 0; + EGVAR(cookoff,canHaveFireJet) = 1; }; class APC_Tracked_01_base_F: Tank_F {}; class B_APC_Tracked_01_base_F: APC_Tracked_01_base_F {}; @@ -288,4 +290,3 @@ class CfgVehicles { GVAR(canHaveFireRing) = 1; }; }; - diff --git a/addons/vehicle_damage/XEH_PREP.hpp b/addons/vehicle_damage/XEH_PREP.hpp index a7eb519881..20075cbd4a 100644 --- a/addons/vehicle_damage/XEH_PREP.hpp +++ b/addons/vehicle_damage/XEH_PREP.hpp @@ -1,14 +1,13 @@ PREP(abandon); PREP(addEventHandler); -PREP(handleBail); -PREP(handleVehicleDamage); -PREP(handleCookoff); -PREP(detonate); -PREP(processHit); -PREP(handleDetonation); -PREP(handleDamage); -PREP(knockOut); -PREP(addDamage); -PREP(handleDamageEjectIfDestroyed); PREP(blowOffTurret); +PREP(handleBail); +PREP(handleCookoff); +PREP(handleDamage); +PREP(handleDamageEjectIfDestroyed); +PREP(handleDetonation); +PREP(handleVehicleDamage); +PREP(knockOut); PREP(medicalDamage); +PREP(processHit); +PREP(setDamage); diff --git a/addons/vehicle_damage/XEH_postInit.sqf b/addons/vehicle_damage/XEH_postInit.sqf index 9784d335ed..5e15599735 100644 --- a/addons/vehicle_damage/XEH_postInit.sqf +++ b/addons/vehicle_damage/XEH_postInit.sqf @@ -1,53 +1,65 @@ #include "script_component.hpp" -["ace_settingsInitialized", { +// Init eject from destroyed vehicles +// See https://github.com/acemod/ACE3/pull/6330 +// Still valid for Arma 2.16 +{ + [_x, "Init", { + params ["_vehicle"]; + + if (!alive _vehicle) exitWith {}; + + TRACE_2("ejectIfDestroyed init",_vehicle,typeOf _vehicle); + + _vehicle addEventHandler ["HandleDamage", {call FUNC(handleDamageEjectIfDestroyed)}]; + }, true, [], true] call CBA_fnc_addClassEventHandler; +} forEach EJECT_IF_DESTROYED_VEHICLES; + +["CBA_settingsInitialized", { TRACE_1("settings init",GVAR(enabled)); - if (GVAR(enabled)) then { - [QGVAR(medicalDamage), LINKFUNC(medicalDamage)] call CBA_fnc_addEventHandler; - [QGVAR(bailOut), { - params ["_center", "_crewman", "_vehicle"]; - TRACE_3("bailOut",_center,_crewman,_vehicle); + if (!GVAR(enabled)) exitWith {}; - if (isPlayer _crewman) exitWith {}; - if (!alive _crewman || {!([_crewman] call EFUNC(common,isAwake))}) exitWith {}; + [QGVAR(medicalDamage), LINKFUNC(medicalDamage)] call CBA_fnc_addEventHandler; - unassignVehicle _crewman; - _crewman leaveVehicle _vehicle; - doGetOut _crewman; - - private _angle = floor (random 360); - private _dist = (30 + (random 10)); - private _escape = _center getPos [_dist, _angle]; - - _crewman doMove _escape; - _crewman setSpeedMode "FULL"; - }] call CBA_fnc_addEventHandler; - - ["Tank", "init", LINKFUNC(addEventHandler), true, [], true] call CBA_fnc_addClassEventHandler; - ["Wheeled_APC_F", "init", LINKFUNC(addEventHandler), true, [], true] call CBA_fnc_addClassEventHandler; - - if (GVAR(enableCarDamage)) then { - ["Car", "init", LINKFUNC(addEventHandler), true, [], true] call CBA_fnc_addClassEventHandler; - }; - - // Blow off turret effect - // TODO: Add blowing-off-turret effect to vehicles that cook-off but aren't destroyed (no catastrophic explosion) - // The problem is that vehicles are repairable if they haven't been destroyed. So if the turret is gone and vehicle is repaired, how do we handle that? - ["Tank", "Killed", { - if (_this select 3 && random 1 < 0.15) then { - (_this select 0) call FUNC(blowOffTurret); - }; - }, true, [], true] call CBA_fnc_addClassEventHandler; + if (isServer) then { + // To set source and instigator, setDamage must be executed on the server + [QGVAR(setDamage), {(_this select 0) setDamage (_this select 1)}] call CBA_fnc_addEventHandler; }; - // init eject from destroyed vehicle - { - [_x, "init", { - params ["_vehicle"]; - if (!alive _vehicle) exitWith {}; - TRACE_2("ejectIfDestroyed init",_vehicle,typeOf _vehicle); - _vehicle addEventHandler ["HandleDamage", {call FUNC(handleDamageEjectIfDestroyed)}]; - }, true, [], true] call CBA_fnc_addClassEventHandler; - } forEach EJECT_IF_DESTROYED_VEHICLES; + [QGVAR(bailOut), { + params ["_vehicle", "_unit"]; + + TRACE_2("bailOut",_vehicle,_unit); + + // Ignore players and the dead + if (_unit call EFUNC(common,isPlayer) || {!(_unit call EFUNC(common,isAwake))}) exitWith {}; + + unassignVehicle _unit; + _unit leaveVehicle _vehicle; + doGetOut _unit; + + private _angle = floor (random 360); + private _dist = 30 + (random 10); + private _escape = _vehicle getPos [_dist, _angle]; + + _unit doMove _escape; + _unit setSpeedMode "FULL"; + }] call CBA_fnc_addEventHandler; + + GVAR(vehicleClassesHitPointHash) = createHashMap; + + ["Tank", "Init", LINKFUNC(addEventHandler), true, [], true] call CBA_fnc_addClassEventHandler; + + // Wheeled_APC_F inherits from Car + [["Wheeled_Apc_F", "Car"] select GVAR(enableCarDamage), "Init", LINKFUNC(addEventHandler), true, [], true] call CBA_fnc_addClassEventHandler; + + // Blow off turret effect + // TODO: Add blowing-off-turret effect to vehicles that cook-off but aren't destroyed (no catastrophic explosion) + // The problem is that vehicles are repairable if they haven't been destroyed. So if the turret is gone and vehicle is repaired, how do we handle that? + ["Tank", "Killed", { + if (_this select 3 && random 1 < 0.15) then { + (_this select 0) call FUNC(blowOffTurret); + }; + }] call CBA_fnc_addClassEventHandler; }] call CBA_fnc_addEventHandler; diff --git a/addons/vehicle_damage/config.cpp b/addons/vehicle_damage/config.cpp index 6b4f7cf685..24b2abda5b 100644 --- a/addons/vehicle_damage/config.cpp +++ b/addons/vehicle_damage/config.cpp @@ -7,7 +7,7 @@ class CfgPatches { weapons[] = {}; requiredVersion = REQUIRED_VERSION; // ammo/vehicle config defines touch all of these - requiredAddons[] = { "ace_common", "ace_cookoff" }; + requiredAddons[] = {"ace_common", "ace_cookoff"}; author = ECSTRING(common,ACETeam); authors[] = {"tcvm"}; url = ECSTRING(main,URL); diff --git a/addons/vehicle_damage/functions/fnc_abandon.sqf b/addons/vehicle_damage/functions/fnc_abandon.sqf index 83b06a80df..3539e21a97 100644 --- a/addons/vehicle_damage/functions/fnc_abandon.sqf +++ b/addons/vehicle_damage/functions/fnc_abandon.sqf @@ -4,29 +4,34 @@ * Forces the AI currently in a vehicle to bail out. * * Arguments: - * 0: The vehicle in which to bail out + * 0: Vehicle * * Return Value: * None * * Example: - * [tank2] call ace_vehicle_damage_fnc_abandon; + * cursorObject call ace_vehicle_damage_fnc_abandon * * Public: No */ params ["_vehicle"]; -TRACE_2("abandon",_vehicle,(crew _vehicle) select {alive _x}); -if (_vehicle getVariable [QGVAR(allowCrewInImmobile), false]) exitWith {}; // check for API +// Check for API +if (_vehicle getVariable [QGVAR(allowCrewInImmobile), false]) exitWith { + TRACE_1("API prevented crew from dismounting",_vehicle); +}; + +TRACE_1("abandon",_vehicle); [{ params ["_vehicle"]; + _vehicle allowCrewInImmobile false; - private _center = getPosASL _vehicle; - TRACE_2("bailing out crew after delay",_vehicle,_center); + TRACE_2("bailing out crew after delay",_vehicle,crew _vehicle); + { - [QGVAR(bailOut), [_center, _x, _vehicle], _x] call CBA_fnc_targetEvent; - } forEach crew _vehicle; -}, _this, random MAX_CREW_BAILOUT_TIME] call CBA_fnc_waitAndExecute; + [QGVAR(bailOut), [_vehicle, _x], _x] call CBA_fnc_targetEvent; + } forEach (crew _vehicle); +}, _vehicle, random MAX_CREW_BAILOUT_TIME] call CBA_fnc_waitAndExecute; diff --git a/addons/vehicle_damage/functions/fnc_addDamage.sqf b/addons/vehicle_damage/functions/fnc_addDamage.sqf deleted file mode 100644 index 35475bd36c..0000000000 --- a/addons/vehicle_damage/functions/fnc_addDamage.sqf +++ /dev/null @@ -1,42 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: tcvm - * Sets vehicle damage based on HitIndex. Failing that it falls back to HitPoint name. - * - * Arguments: - * 0: The vehicle - * 1: Hit Index - * 2: Hit Point - * 3: Damage - * 4: Whether or not to cap the damage to maximum part damage (default: True) - * - * Return Value: - * None - * - * Example: - * [vehicle player, 234, "HitHull"] call ace_vehicle_damage_fnc_addDamage - * - * Public: No - */ - -params ["_vehicle", "_hitIndex", "_hitPoint", "_damage", ["_capDamageAtCurret", true]]; - -private _currentDamage = _vehicle getHitPointDamage _hitPoint; -if (_capDamageAtCurret && { _damage < _currentDamage }) exitWith { - TRACE_4("capping damage at current",_capDamageAtCurret,_damage,_currentDamage,_hitPoint); -}; - -TRACE_4("adding damage to vehicle",_vehicle,_hitIndex,_hitPoint,_damage); -if (_hitPoint isEqualTo "#structural") then { - _hitPoint = "hithull"; - _hitIndex = -1; -}; -if (_hitIndex >= 0) then { - _vehicle setHitIndex [_hitIndex, _damage, true]; -} else { - _vehicle setHitPointDamage [_hitPoint, _damage, true]; -}; - -if (_hitPoint == "hitengine" && {_damage > 0.9}) then { - [QEGVAR(cookoff,engineFireServer), _vehicle] call CBA_fnc_serverEvent; -}; diff --git a/addons/vehicle_damage/functions/fnc_addEventHandler.sqf b/addons/vehicle_damage/functions/fnc_addEventHandler.sqf index 05f8e084c2..3fdbf9ec20 100644 --- a/addons/vehicle_damage/functions/fnc_addEventHandler.sqf +++ b/addons/vehicle_damage/functions/fnc_addEventHandler.sqf @@ -1,110 +1,137 @@ #include "..\script_component.hpp" /* - * Author: tcvm + * Author: tcvm, johnb43 * Adds the event handler to a vehicle. * * Arguments: - * 0: The vehicle in which to add the event handler to + * 0: Vehicle * * Return Value: * None * * Example: - * [tank2] call ace_vehicle_damage_fnc_addEventHandler; + * cursorObject call ace_vehicle_damage_fnc_addEventHandler * * Public: No */ -params["_vehicle"]; +params ["_vehicle"]; TRACE_2("addEventHandler",_vehicle,GVAR(enabled)); -if !(GVAR(enabled)) exitWith { +if (!GVAR(enabled)) exitWith { #ifdef DEBUG_MODE_FULL - [{ ["Warning: Vehicle Damage not enabled...", 2] call CBA_fnc_notify; }, [], 5] call CBA_fnc_waitAndExecute; + [CBA_fnc_notify, ["Warning: Vehicle Damage not enabled", 2], 5] call CBA_fnc_waitAndExecute; #endif }; -private _hitpointHash = [[], nil] call CBA_fnc_hashCreate; +if (!isNil {_vehicle getVariable QGVAR(handleDamage)}) exitWith {}; + +_vehicle allowCrewInImmobile true; + +// No clue why, but for some reason this needs to be exec'd next frame or else it isn't the last event handler in the system. +// Maybe its overridden somewhere else, but this makes sure it is the last one +[{ + params ["_vehicle"]; + + if (!isNil {_vehicle getVariable QGVAR(handleDamage)}) exitWith {}; + + TRACE_1("added eh",_vehicle); + + _vehicle setVariable [QGVAR(hitHash), createHashMap]; + _vehicle setVariable [QGVAR(handleDamage), _vehicle addEventHandler ["HandleDamage", {_this call FUNC(handleDamage)}]]; +}, _vehicle] call CBA_fnc_execNextFrame; + +private _typeOf = typeOf _vehicle; + +if (_typeOf in GVAR(vehicleClassesHitPointHash)) exitWith {}; + +private _hitPointHash = createHashMap; private _vehicleConfig = configOf _vehicle; -private _hitpointsConfig = _vehicleConfig >> "HitPoints"; -private _turretConfig = _vehicleConfig >> "Turrets"; -private _eraHitpoints = ([_vehicleConfig >> QGVAR(eraHitpoints), "ARRAY", []] call CBA_fnc_getConfigEntry) apply {toLowerANSI _x}; -private _slatHitpoints = ([_vehicleConfig >> QGVAR(slatHitpoints), "ARRAY", []] call CBA_fnc_getConfigEntry) apply {toLowerANSI _x}; +private _hitPointsConfig = _vehicleConfig >> "HitPoints"; // Add hitpoint names to config for quick lookup { - _x params ["_hitpoints", "_type"]; + _x params ["_hitPoints", "_hitArea"]; + { - [_hitpointHash, toLowerANSI _x, [_type, _hitpointsConfig >> _x, toLowerANSI _x]] call CBA_fnc_hashSet; - } forEach _hitpoints; + _hitPointHash set [toLowerANSI _x, [_hitArea, abs getNumber (_hitPointsConfig >> _x >> "minimalHit")]]; + } forEach _hitPoints; } forEach ALL_HITPOINTS; -_vehicle setVariable [QGVAR(hitpointHash), _hitpointHash]; - -// gun and turret hitpoints arent hardcoded anymore - dig through config to find correct names -private _iterateThroughConfig = { - params ["_vehicle", "_config", "_iterateThroughConfig", "_hitpointAliases"]; +// Gun and turret hitpoints aren't hardcoded anymore - dig through config to find correct names +private _fnc_iterateThroughConfig = { + params ["_config"]; TRACE_1("checking config",_config); + private _configName = toLowerANSI configName _config; - private _isGun = ([_config >> "isGun", "NUMBER", 0] call CBA_fnc_getConfigEntry) == 1; - private _isTurret = ([_config >> "isTurret", "NUMBER", 0] call CBA_fnc_getConfigEntry) == 1; + private _isGun = getNumber (_config >> "isGun") == 1; + private _isTurret = getNumber (_config >> "isTurret") == 1; private _isEra = _configName in _eraHitpoints; private _isSlat = _configName in _slatHitpoints; private _isMisc = false; - // prevent incompatibilites with old mods - if (_configName isEqualTo "hitturret") then { + // Prevent incompatibilites with old mods + if (_configName == "hitturret") then { _isTurret = true; }; - if (_configName isEqualTo "hitgun") then { + + if (_configName == "hitgun") then { _isGun = true; }; - private _hash = _vehicle getVariable QGVAR(hitpointHash); { - _x params ["_hitType", "_hitPoints"]; + _x params ["_hitArea", "_hitPoints"]; + if (_configName in _hitPoints) then { - [_hash, _configName, [_hitType, _config, _configName]] call CBA_fnc_hashSet; + _hitPointHash set [_configName, [_hitArea, abs getNumber (_config >> "minimalHit")]]; _isMisc = true; }; - } forEach _hitpointAliases; + } forEach _hitPointAliases; if (_isGun || _isTurret || _isEra || _isSlat || _isMisc) then { - TRACE_6("found gun/turret/era/slat/misc",_isGun,_isTurret,_isEra,_isSlat,_isMisc,_hash); if (_isGun) then { - [_hash, _configName, ["gun", _config, _configName]] call CBA_fnc_hashSet; + _hitPointHash set [_configName, ["gun", abs getNumber (_config >> "minimalHit")]]; }; if (_isTurret) then { - [_hash, _configName, ["turret", _config, _configName]] call CBA_fnc_hashSet; + _hitPointHash set [_configName, ["turret", abs getNumber (_config >> "minimalHit")]]; }; if (_isEra) then { - [_hash, _configName, ["era", _config, _configName]] call CBA_fnc_hashSet; + _hitPointHash set [_configName, ["era", abs getNumber (_config >> "minimalHit")]]; }; if (_isSlat) then { - [_hash, _configName, ["slat", _config, _configName]] call CBA_fnc_hashSet; + _hitPointHash set [_configName, ["slat", abs getNumber (_config >> "minimalHit")]]; }; - _vehicle setVariable [QGVAR(hitpointHash), _hash]; + + TRACE_6("found gun/turret/era/slat/misc",_isGun,_isTurret,_isEra,_isSlat,_isMisc,_hash); } else { { - [_vehicle, _x, _iterateThroughConfig, _hitpointAliases] call _iterateThroughConfig; + _x call _fnc_iterateThroughConfig; } forEach configProperties [_config, "isClass _x", true]; }; }; -private _hitpointAliases = [_vehicleConfig >> QGVAR(hitpointAlias), "ARRAY", []] call CBA_fnc_getConfigEntry; -TRACE_1("hitpoint alias",_hitpointAliases); -[_vehicle, _hitpointsConfig, _iterateThroughConfig, _hitpointAliases] call _iterateThroughConfig; -[_vehicle, _turretConfig, _iterateThroughConfig, _hitpointAliases] call _iterateThroughConfig; +private _turretConfig = _vehicleConfig >> "Turrets"; +private _eraHitpoints = (getArray (_vehicleConfig >> QGVAR(eraHitpoints))) apply {toLowerANSI _x}; +private _slatHitpoints = (getArray (_vehicleConfig >> QGVAR(slatHitpoints))) apply {toLowerANSI _x}; -_vehicle allowCrewInImmobile true; -private _eh = _vehicle getVariable [QGVAR(handleDamage), nil]; -if (isNil "_eh") then { - // no clue why, but for some reason this needs to exec'd next frame or else it isnt the last event handler in the system. - // Maybe its overridden somewhere else, but this makes sure it is the last one - [{ - params ["_vehicle"]; - TRACE_1("EH not added yet - added eh now",_vehicle); - private _hd = _vehicle addEventHandler ["HandleDamage", { _this call FUNC(handleDamage) }]; - _vehicle setVariable [QGVAR(handleDamage), _hd]; - }, [_vehicle]] call CBA_fnc_execNextFrame; +private _fnc_toLowerCase = { + _this apply { + if (_x isEqualType []) then { + _x call _fnc_toLowerCase + } else { + toLowerANSI _x + }; + }; }; + +// Convert areas to lower case +private _hitPointAliases = (getArray (_vehicleConfig >> QGVAR(hitpointAlias))) call _fnc_toLowerCase; + +TRACE_1("hitpoint alias",_hitPointAliases); + +_hitPointsConfig call _fnc_iterateThroughConfig; +_turretConfig call _fnc_iterateThroughConfig; + +GVAR(vehicleClassesHitPointHash) set [_typeOf, _hitPointHash]; + +nil diff --git a/addons/vehicle_damage/functions/fnc_blowOffTurret.sqf b/addons/vehicle_damage/functions/fnc_blowOffTurret.sqf index 818fe6f6ef..9c9e5036da 100644 --- a/addons/vehicle_damage/functions/fnc_blowOffTurret.sqf +++ b/addons/vehicle_damage/functions/fnc_blowOffTurret.sqf @@ -10,7 +10,7 @@ * None * * Example: - * (vehicle player) call ace_vehicle_damage_fnc_blowOffTurret + * cursorObject call ace_vehicle_damage_fnc_blowOffTurret * * Public: No */ @@ -19,6 +19,7 @@ // The sudden change in the model would cause nearby PhysX objects to get stuck [{ params ["_vehicle"]; + TRACE_1("blowOffTurret",_vehicle); (getArray (configOf _vehicle >> QGVAR(turret))) params [["_model", "", [""]], ["_offset", [0, 0, 0], [[]], 3]]; diff --git a/addons/vehicle_damage/functions/fnc_calculatePenetrationInfo.sqf b/addons/vehicle_damage/functions/fnc_calculatePenetrationInfo.sqf deleted file mode 100644 index 4e847c2d36..0000000000 --- a/addons/vehicle_damage/functions/fnc_calculatePenetrationInfo.sqf +++ /dev/null @@ -1,118 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: tcvm - * Calculates whether or not hit penetrated given armour or not. Only enabled with advanced penetration simulation turned on. - * - * Arguments: - * 0: Source of damage - * 1: The vehicle - * 2: Projectile that hit - * 3: Hitpoint damaged - * - * Return Value: - * None - * - * Example: - * [myVehicle, projectile, 5, 0.663] call ace_vehicle_damage_fnc_calculatePenetrationInfo; - * - * Public: No - */ - -params ["_source", "_vehicle", "_projectileData", "_hitpointConfig"]; -_projectileData params ["_projectileType", "_projectileConfig"]; -/* - http://www.longrods.ch/peneq.php - https://www.scribd.com/doc/267210898/57-mm-APFSDS-2-000-m#download - Perforation Calculation of APFSDS: - Tungsten/Depleted Uranium: Rods - P/Lw = a * (1 / tanh(b0 + b1 * (Lw/D))) * cos^m (theta) * sqrt (Pp / Pt) * e^((-(c0 + c1 * BHNT) * BHNT) / (Pp * Vt^2)) - - Steel Rods - P/Lw = a * (1 / tanh(b0 + b1 * (Lw/D))) * cos^m (theta) * sqrt (Pp / Pt) * e^((-c * BHNT^k * BHNP^n) / (Pp * Vt^2)) - - Penetration Calculation of Tungsten APFSDS (Used for all penetrators): - P/Lw = a * (1 / tanh(b0 + b1 * (Lw/D))) sqrt (Pp / Pt) * e^((-(c0 + c1 * BHNT) * BHNT) / (Pp * Vt^2)) - - where: - Penetrator: - D = Diameter of penetrator rod (always 22mm) - L = Total length of penetrator in millimeters (always 950mm) - Lw = Working length of rod in millimeters - Vt = impact velocity in Kilometers/Second - theta = NATO Obliquity angle of Penetration - Pp = Penetrator Density in kg/m^3 - BHNP = Brinell hardness number of penetrator - - Target: - Pt = target density in kg/m^3 (always 7840kg/m^3) - d = plate thickness in millimeters - BHNT = Brinell hardness number of target (always 350) - - Material Data: - Tungsten: - Pp = 19300 - BHNP = N/A - - a = 0.994 - c0 = 134.5 - c1 = -0.148 - - Depleted Uranium: - Pp = 18600 - BHNP = N/A - - a = 0.825 - c0 = 90.0 - c1 = -0.0849 - - Steel: - Pp = 7850 - BHNP = 500 - - a = 1.104 - c = 9874 - k = 0.3598 - n = -0.2342 - - Cofficients: - m = -0.224 - b0 = 0.283 - b1 = 0.0656 -*/ - -private _enabled = ([_hitpointConfig >> QGVAR(enabled), "NUMBER", 0] call CBA_fnc_getConfigEntry) == 1; -#define MATERIAL_ARRAY ([[0, 0, 0, 0, 0, 0], "steel", [7850, 500, 1.104, 9874, 0.3598, -0.2342], "tungsten", [19300, 0, 0.994, 134.5, -0.148], "depleted_uranium", [18600, 0, 0.825, 90, -0.0849]]) -private _rodMaterialStr = [_projectileConfig >> QGVAR(material), "STRING", "tungsten"] call CBA_fnc_getConfigEntry; -private _rodMaterialParams = MATERIAL_ARRAY select (1 + MATERIAL_ARRAY find toLowerANSI _rodMaterial); - -if !(_enabled) exitWith { [false, 0, 0, 0, 0] }; -if (_rodMaterialParams isEqualTo [0, 0, 0, 0, 0, 0]) exitWith { [] }; - -private _tanX = 2 * (0.283 * 0.0656 * (1)); -private _tanh = 1 / (((exp _tanX) - 1) / ((exp _tanX) + 1)); -private _cosm = (cos 0) ^ -0.224; -private _lw = 950; // technically this would be something else depending on armour slant but this is a good enough aproximation - -private _aproximateVelocity = 0; - -private _perf_pLw = 0; -private _pen_pLw = 0; -if (_rodMaterialStr isEqualTo "steel") then { - _rodMaterialParams params ["_Pp", "_BHNP", "_a", "_c", "_k", "_n"]; - private _exp = (-_c * 350^_k * _BHNP^_n) / (_Pp * _aproximateVelocity * _aproximateVelocity); - _pen_pLw = _a * _tanh * sqrt (_Pp / 7840) * exp _exp; - _perf_pLw = _pen_pLw * _cosm; -} else { - _rodMaterialParams params ["_Pp", "_BHNP", "_a", "_c0", "_c1"]; - private _exp = (-(_c0 + _c1 * 350) * 350) / (_Pp * _aproximateVelocity * _aproximateVelocity); - _pen_pLw = _a * _tanh * _cosm * sqrt (_Pp / 7840) * exp _exp; - _perf_pLw = _pen_pLw * _cosm; -}; - -private _perforationDistance = _lw * _perf_pLw; -private _penetrationDistance = _lw * _pen_pLw; -private _hitpointEffectiveArmour = [_hitpointConfig >> QGVAR(thickness), "NUMBER", 0] call CBA_fnc_getConfigEntry; -private _hitpointEffectiveSlope = [_hitpointConfig >> QGVAR(slope), "NUMBER", 0] call CBA_fnc_getConfigEntry; -_penetrationDistance = _penetrationDistance * cos (_hitpointEffectiveSlope); - -[_penetrationDistance > _hitpointEffectiveArmour, _penetrationDistance - _hitpointEffectiveArmour, _penetrationDistance, _perforationDistance, _hitpointEffectiveArmour] diff --git a/addons/vehicle_damage/functions/fnc_detonate.sqf b/addons/vehicle_damage/functions/fnc_detonate.sqf deleted file mode 100644 index 7f0dce28c9..0000000000 --- a/addons/vehicle_damage/functions/fnc_detonate.sqf +++ /dev/null @@ -1,27 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: tcvm - * Detonates vehicle ammo and heavily wounds all inside. - * - * Arguments: - * 0: The vehicle - * 1: Person who caused detonation (default: objNull) - * - * Return Value: - * None - * - * Example: - * [tank2] call ace_vehicle_damage_fnc_detonate; - * - * Public: No - */ - -params ["_vehicle", ["_injurer", objNull]]; - -if (((_vehicle call EFUNC(cookoff,getVehicleAmmo)) select 1) > 0) then { - { - [QGVAR(medicalDamage), [_x, _injurer, _injurer], _x] call CBA_fnc_targetEvent; - } forEach (crew _vehicle); -}; - -[QEGVAR(cookoff,detonateAmmunitionServer), [_vehicle, false, _injurer, _injurer]] call CBA_fnc_serverEvent; diff --git a/addons/vehicle_damage/functions/fnc_handleBail.sqf b/addons/vehicle_damage/functions/fnc_handleBail.sqf index 97aad2cd32..6c9f23c82b 100644 --- a/addons/vehicle_damage/functions/fnc_handleBail.sqf +++ b/addons/vehicle_damage/functions/fnc_handleBail.sqf @@ -4,64 +4,66 @@ * Handles whether or not the crew should bail. * * Arguments: - * 0: The vehicle - * 1: Can the vehicle move? - * 2: Can the vehicle shoot? + * 0: Vehicle * * Return Value: * None * * Example: - * [tank1, false, true] call ace_vehicle_damage_fnc_handleBail + * cursorObject call ace_vehicle_damage_fnc_handleBail * * Public: No */ -params ["_vehicle", "_canMove", "_canShoot"]; -private _isCar = (_vehicle isKindOf "Car" && { !(_vehicle isKindOf "Wheeled_APC_F") }); +params ["_vehicle"]; +TRACE_1("handleBail",_vehicle); -if (_canMove) then { - _canMove = alive driver _vehicle; -}; +private _isCar = _vehicle isKindOf "Car" && {!(_vehicle isKindOf "Wheeled_APC_F")}; -if (_canShoot) then { - _canShoot = alive gunner _vehicle; -}; +// canFire command is broken, hence the variable +private _canMove = (_vehicle getVariable [QGVAR(canMove), true]) && {alive driver _vehicle}; +private _canShoot = (_vehicle getVariable [QGVAR(canShoot), true]) && {alive gunner _vehicle}; -_vehicle setVariable[QGVAR(canMove), _canMove]; -_vehicle setVariable[QGVAR(canShoot), _canShoot]; +_vehicle setVariable [QGVAR(canMove), _canMove]; +_vehicle setVariable [QGVAR(canShoot), _canShoot]; private _rand = random 1; if (_isCar) then { - if !(_canMove) then { - [_vehicle] spawn FUNC(abandon); - LOG_3("[%1] can't move and is bailing and is a car [%2 | %3]",_vehicle,_canMove,_isCar); + if (!_canMove) then { + _vehicle call FUNC(abandon); + + TRACE_3("car immobile - bailing",_vehicle,_canMove,_isCar); }; } else { - if (!_canMove && !_canShoot ) exitWith { // If you can't move and you can't shoot, you better GTFO - [_vehicle] spawn FUNC(abandon); - LOG_3("[%1] is a sitting duck and is bailing [%2 | %3]",_vehicle,_canMove,_canShoot); + // If you can't move and you can't shoot, you better GTFO + if (!_canMove && !_canShoot) exitWith { + _vehicle call FUNC(abandon); + + TRACE_3("immobile and can't shoot - bailing",_vehicle,_canMove,_canShoot); }; - if (!_canShoot && !_isCar) then { - if (BAILOUT_CHANCE_SHOOT > _rand) then { // 50% chance of bailing out if turret/gun is destroyed - [_vehicle] spawn FUNC(abandon); - LOG_4("[%1] Cannot shoot and is bailing with chance [%2] [%3 | %4]",_vehicle,_rand,_canMove,_canShoot); + if (!_canShoot) then { + // 50% chance of bailing out if turret/gun is disabled + if (BAILOUT_CHANCE_SHOOT > _rand) then { + _vehicle call FUNC(abandon); + + TRACE_4("can't shoot - bailing",_vehicle,_rand,_canMove,_canShoot); } else { _vehicle allowFleeing 1; - LOG_4("[%1] Cannot shoot and is fleeing with chance [%2] [%3 | %4]",_vehicle,_rand,_canMove,_canShoot); + + TRACE_4("fleeing",_vehicle,_rand,_canMove,_canShoot); }; }; - if !(_canMove) then { - if (BAILOUT_CHANCE_MOVE > _rand) then { // 80% Chance of bailing out if engine is destroyed - [_vehicle] spawn FUNC(abandon); - LOG_4("[%1] Cannot move and is bailing with chance [%2] [%3 | %4]",_vehicle,_rand,_canMove,_canShoot); + if (!_canMove) then { + // 80% Chance of bailing out if engine is disabled + if (BAILOUT_CHANCE_MOVE > _rand) then { + _vehicle call FUNC(abandon); + + TRACE_4("immobile - bailing",_vehicle,_rand,_canMove,_canShoot); } else { - LOG_4("[%1] Cannot move and is bunkering with chance [%2] [%3 | %4]",_vehicle,_rand,_canMove,_canShoot); + TRACE_4("immobile - bunkering",_vehicle,_rand,_canMove,_canShoot); }; }; }; - - diff --git a/addons/vehicle_damage/functions/fnc_handleCookoff.sqf b/addons/vehicle_damage/functions/fnc_handleCookoff.sqf index 3e7b83ebb6..4558359695 100644 --- a/addons/vehicle_damage/functions/fnc_handleCookoff.sqf +++ b/addons/vehicle_damage/functions/fnc_handleCookoff.sqf @@ -1,59 +1,71 @@ #include "..\script_component.hpp" /* * Author: tcvm - * Checks hitpoint damage and determines if a vehicle should cookoff. + * Checks hitpoint damage and determines if a vehicle should cook off. * * Arguments: - * 0: The vehicle + * 0: Vehicle * 1: Chance of fire * 2: Intensity of cookoff - * 3: Person who instigated cookoff (default: objNull) - * 4: Part of vehicle which got hit (default: "") - * 5: Whether or not the vehicle can spawn ring-fire effect (default: false) - * 6: Can Jet (default: true) + * 3: Source of damage + * 4: Person who caused damage + * 5: Part of vehicle which got hit (default: "") + * 6: Whether or not the vehicle can spawn ring-fire effect (default: false) + * 7: Whether or not the vehicle can spawn jet-fire effect (default: true) * * Return Value: - * If cooked off + * If vehicle started or already cooking off * * Example: - * [tank2, 0.1, 5] call ace_vehicle_damage_fnc_handleCookoff; + * [cursorObject, 0.1, 5, player, player] call ace_vehicle_damage_fnc_handleCookoff * * Public: No */ -params ["_vehicle", "_chanceOfFire", "_intensity", ["_injurer", objNull], ["_hitPart", ""], ["_canRing", false], ["_canJet", true]]; +params ["_vehicle", "_chanceOfFire", "_intensity", "_source", "_instigator", ["_hitPart", ""], ["_canRing", true], ["_canJet", true]]; +TRACE_8("handleCookoff",_vehicle,_chanceOfFire,_intensity,_source,_instigator,_hitPart,_canRing,_canJet); // Ignore if the vehicle is already cooking off -if (_vehicle getVariable [QEGVAR(cookoff,isCookingOff), false]) exitWith {true}; +if (_vehicle getVariable [QEGVAR(cookoff,isCookingOff), false]) exitWith { + TRACE_3("already cooking off",_vehicle,_chanceOfFire,_intensity); + + true // return +}; _chanceOfFire = _chanceOfFire * EGVAR(cookoff,probabilityCoef); -if (_chanceOfFire >= random 1) exitWith { - private _configOf = configOf _vehicle; - private _fireDetonateChance = [_configOf >> QGVAR(detonationDuringFireProb), "number", 0] call CBA_fnc_getConfigEntry; - if (_canRing) then { - _canRing = ([_configOf >> QGVAR(canHaveFireRing), "number", 0] call CBA_fnc_getConfigEntry) == 1; - }; +// Failure to cook off +if (_chanceOfFire == 0 || {_chanceOfFire < random 1}) exitWith { + TRACE_3("no cook-off",_vehicle,_chanceOfFire,_intensity); - if (_canJet) then { - _canJet = ([_configOf >> QEGVAR(cookoff,canHaveFireJet), "number", 1] call CBA_fnc_getConfigEntry) == 1; - }; - - private _delayWithSmoke = _chanceOfFire < random 1; - private _detonateAfterCookoff = (_fireDetonateChance / 4) > random 1; - - private _source = ""; - if (_hitPart == "engine") then { - _source = ["hit_engine_point", "HitPoints"]; - }; - - [QEGVAR(cookOff,cookOffServer), [_vehicle, _intensity, _injurer, _injurer, _delayWithSmoke, _fireDetonateChance, _detonateAfterCookoff, _source, _canRing, _canJet]] call CBA_fnc_serverEvent; - LOG_4("Cooking-off [%1] with a chance-of-fire [%2] - Delayed Smoke | Detonate after cookoff [%3 | %4]",_vehicle,_chanceOfFire,_delayWithSmoke,_detonateAfterCookoff); - [_vehicle] spawn FUNC(abandon); - LOG_1("[%1] is on fire is bailing",_vehicle); - - true + false // return }; -LOG_2("[%1] No Cook-off - Chance of fire [%2]",_vehicle,_chanceOfFire); -false +// Vehicle will cook off +private _configOf = configOf _vehicle; +private _fireDetonateChance = getNumber (_configOf >> QGVAR(detonationDuringFireProb)); + +if (_canRing) then { + _canRing = getNumber (_configOf >> QGVAR(canHaveFireRing)) == 1; +}; + +if (_canJet) then { + _canJet = getNumber (_configOf >> QEGVAR(cookoff,canHaveFireJet)) == 1; +}; + +private _delaySmoke = _chanceOfFire < random 1; +private _detonateAfterCookoff = (_fireDetonateChance / 4) > random 1; + +private _source = ""; + +if (_hitPart == "engine") then { + _source = ["hit_engine_point", "HitPoints"]; +}; + +[QEGVAR(cookOff,cookOffServer), [_vehicle, _intensity, _injurer, _injurer, _delayWithSmoke, _fireDetonateChance, _detonateAfterCookoff, _source, _canRing, _canJet]] call CBA_fnc_serverEvent; +TRACE_4("cooking-off",_vehicle,_chanceOfFire,_delaySmoke,_detonateAfterCookoff); + +// Abandon vehicle +_vehicle call FUNC(abandon); + +true // return diff --git a/addons/vehicle_damage/functions/fnc_handleDamage.sqf b/addons/vehicle_damage/functions/fnc_handleDamage.sqf index 51bf1be97d..733d4f2321 100644 --- a/addons/vehicle_damage/functions/fnc_handleDamage.sqf +++ b/addons/vehicle_damage/functions/fnc_handleDamage.sqf @@ -4,91 +4,88 @@ * Called by "HandleDamage" event handler. Sets up hit array for this frame's damage. * * Arguments: - * 0: The vehicle - * 1: Name of selection where unit was damaged (unused) - * 2: Damage taken - * 3: Source unit of damage (unused) + * 0: Vehicle + * 1: Selection + * 2: New level of damage + * 3: Source of damage * 4: Projectile that caused damage - * 5: Hit part index of hit point - * 6: Instigator of damage (unused) - * 7: Hit point config name + * 5: Hit index + * 6: Person who caused damage + * 7: Hit point * * Return Value: - * Current or maximum damage of part + * Current or maximum damage of part * * Example: - * [myVehicle, projectile, 5, 0.663] call ace_vehicle_damage_fnc_handleDamage; + * [cursorObject, "hit_engine_point", 0.5, player, projectile, 1, player, "HitEngine"] call ace_vehicle_damage_fnc_handleDamage * * Public: No */ -params ["_vehicle", "_hitSelection", "_damage", "", "_projectile", "_hitIndex", "", "_hitPoint"]; -TRACE_6("HandleDamage event inputs",_vehicle,_hitSelection,_damage,_projectile,_hitIndex,_hitPoint); +params ["_vehicle", "_selection", "_newDamage", "_source", "_projectile", "_hitIndex", "_instigator", "_hitPoint"]; +TRACE_8("handleDamage",_vehicle,_selection,_newDamage,_source,_projectile,_hitIndex,_instigator,_hitPoint); -private _returnHit = if (_hitSelection isNotEqualTo "") then { +if (!local _vehicle) exitWith {}; + +private _currentDamage = if (_selection != "") then { _vehicle getHitIndex _hitIndex } else { damage _vehicle }; if !(_projectile in ["ace_ammoExplosion", "ACE_ammoExplosionLarge"]) then { - if (local _vehicle) then { - // set up hit array so we can execute all damage next frame. Always in order of hit done. - private _hitHash = _vehicle getVariable [QGVAR(hitHash), nil]; - if (isNil "_hitHash") then { - _hitHash = [[], nil] call CBA_fnc_hashCreate; - }; - private _currentFrameArray = [_hitHash, diag_frameNo] call CBA_fnc_hashGet; - if (isNil "_currentFrameArray") then { - _currentFrameArray = []; - }; - // if a valid hit, process it - if !((_hitPoint find "#light") >= 0 || { _damage <= 0 }) then { - if (_currentFrameArray isEqualTo []) then { - [{ - params ["_vehicle", "_processingFrame"]; - private _frameHash = _vehicle getVariable [QGVAR(hitHash), nil]; - private _hitArray = [_frameHash, _processingFrame] call CBA_fnc_hashGet; - if (_hitArray isEqualTo []) exitWith {}; + // If an invalid hit, don't process it + if (_newDamage <= 0 || {"#light" in _hitPoint}) exitWith {}; - reverse _hitArray; - TRACE_3("processing data from old frame",diag_frameNo,_processingFrame,_hitArray); - { - _x params ["_vehicle", "_selection", "_damage", "_injurer", "_projectile", "_hitIndex", "", "_hitPoint"]; + // Set up hit array so we can execute all damage next frame. Always in order of hit done. + private _hitHash = _vehicle getVariable QGVAR(hitHash); + private _currentFrameArray = _hitHash getOrDefault [diag_frameNo, [], true]; - private _returnHit = if (_selection isNotEqualTo "") then { - _vehicle getHitIndex _hitIndex - } else { - damage _vehicle - }; + if (_currentFrameArray isEqualTo []) then { + [{ + params ["_vehicle", "_processingFrame"]; - private _newDamage = _damage - _returnHit; - if !([_vehicle, _hitPoint, _hitIndex, _injurer, _returnHit, _newDamage, _projectile, _selection] call FUNC(handleVehicleDamage)) exitWith { - LOG_2("cancelling rest of vehicle damage queue ( [%1] items left out of [%2] )",(count (_hitArray#1)) - _forEachIndex,count (_hitArray#1)) - }; - } forEach _hitArray; + private _hitHash = _vehicle getVariable QGVAR(hitHash); + private _hitArray = _hitHash deleteAt _processingFrame; - [_frameHash, _processingFrame] call CBA_fnc_hashRem; + if (_hitArray isEqualTo []) exitWith {}; - }, [_vehicle, diag_frameNo]] call CBA_fnc_execNextFrame; - }; - _currentFrameArray pushBack _this; - }; + TRACE_3("processing data from old frame",diag_frameNo,_processingFrame,_hitArray); - [_hitHash, diag_frameNo, _currentFrameArray] call CBA_fnc_hashSet; - _vehicle setVariable [QGVAR(hitHash), _hitHash]; + // Start from newest damage and work backwards + { + _x params ["_vehicle", "_selection", "_newDamage", "_source", "_projectile", "_hitIndex", "_instigator", "_hitPoint"]; + + private _currentDamage = if (_selection != "") then { + _vehicle getHitIndex _hitIndex + } else { + damage _vehicle + }; + + private _addedDamage = _newDamage - _currentDamage; + + TRACE_1("handleDamage",_currentDamage); + + if !([_vehicle, _hitPoint, _hitIndex, _selection, _addedDamage, _projectile, _source, _instigator] call FUNC(handleVehicleDamage)) exitWith { + TRACE_2("cancelling rest of vehicle damage queue",(count (_hitArray#1)) - _forEachIndex,count (_hitArray#1)) + }; + } forEachReversed _hitArray; + }, [_vehicle, diag_frameNo]] call CBA_fnc_execNextFrame; }; + + _currentFrameArray pushBack _this; }; -// damage is never to be handled in-engine. Always handle out of engine with this event handler -// don't return 0 or else old parts will be reset in damage -private _criticalDamageIndex = (CRITICAL_HITPOINTS findIf { _x isEqualTo _hitPoint }) + 1; -if (_criticalDamageIndex > 0) then { - _returnHit = (_returnHit min (CRITICAL_HITPOINTS select _criticalDamageIndex)); +// Damage is never to be handled in-engine. Always handle out of engine with this event handler +// Don't return 0 or else old parts will be reset in damage +private _criticalDamageIndex = CRITICAL_HITPOINTS findIf {_x == _hitPoint}; + +if (_criticalDamageIndex != -1) then { + _currentDamage = _currentDamage min (CRITICAL_HITPOINTS_THRESHOLDS select _criticalDamageIndex); }; -if (_hitPoint isEqualTo "" && _hitIndex < 0) then { - _returnHit = _returnHit min 0.89; +if (_hitPoint == "" && {_hitIndex < 0}) then { + _currentDamage = _currentDamage min 0.89; }; -_returnHit +_currentDamage diff --git a/addons/vehicle_damage/functions/fnc_handleDamageEjectIfDestroyed.sqf b/addons/vehicle_damage/functions/fnc_handleDamageEjectIfDestroyed.sqf index fdf6f9c6d3..10485d5ce9 100644 --- a/addons/vehicle_damage/functions/fnc_handleDamageEjectIfDestroyed.sqf +++ b/addons/vehicle_damage/functions/fnc_handleDamageEjectIfDestroyed.sqf @@ -20,7 +20,7 @@ params ["_vehicle", "", "", "", "_ammo"]; if (alive _vehicle) exitWith {}; -TRACE_2("ejectIfDestroyed HDEH",typeOf _vehicle,_this); +TRACE_2("handleDamageEjectIfDestroyed",typeOf _vehicle,_this); if (!IS_EXPLOSIVE_AMMO(_ammo)) then { { diff --git a/addons/vehicle_damage/functions/fnc_handleDetonation.sqf b/addons/vehicle_damage/functions/fnc_handleDetonation.sqf index 8f317323fa..9fdaa3b0c2 100644 --- a/addons/vehicle_damage/functions/fnc_handleDetonation.sqf +++ b/addons/vehicle_damage/functions/fnc_handleDetonation.sqf @@ -1,37 +1,59 @@ #include "..\script_component.hpp" /* - * Author: tcvm - * Checks hitpoint damage and determines if a vehicle should cookoff. + * Author: tcvm, johnb43 + * Checks hitpoint damage and determines if a vehicle should detonate its ammo. * * Arguments: - * 0: The vehicle + * 0: Vehicle * 1: Chance of detonation - * 2: Vehicle ammo array - * 3: How much explosive ammo is inside vehicle - * 4: How much non-explosive ammo inside vehicle - * 5: Person who instigated damage (default: objNull) + * 2: If the vehicle should be knocked out + * 3: If the crew should be injured + * 4: Source of damage + * 5: Person who caused damage * * Return Value: - * Detonated + * None * * Example: - * [tank2, 0.5] call ace_vehicle_damage_fnc_handleDetonation; + * [cursorObject, 0.5, true, player, player] call ace_vehicle_damage_fnc_handleDetonation * * Public: No */ -params ["_vehicle", "_chanceOfDetonate", "_vehicleAmmo", "_explosiveAmmoCount", "_nonExplosiveAmmoCount", ["_injurer", objNull]]; - -private _isKnockedOut = _explosiveAmmoCount > 0; +params ["_vehicle", "_chanceToDetonate", "_knockOut", "_injureCrew", "_source", "_instigator"]; // Ignore if the vehicle is already detonating ammo -if (_vehicle getVariable [QEGVAR(cookoff,isAmmoDetonating), false]) exitWith {_isKnockedOut}; +if (_vehicle getVariable [QEGVAR(cookoff,isAmmoDetonating), false]) exitWith { + TRACE_2("already detonating",_vehicle,_chanceToDetonate); -if (_chanceOfDetonate >= random 1) exitWith { - [_vehicle, _injurer, _vehicleAmmo] call FUNC(detonate); - LOG_2("Detonating [%1] with a chance-to-detonate [%2]",_vehicle,_chanceOfDetonate); - _isKnockedOut + if (_knockOut) then { + [_vehicle, _source, _instigator] call FUNC(knockOut); + }; + + _knockOut // return }; -LOG_2("[%1] No Detonation - Chance of detonation [%2]",_vehicle,_chanceOfDetonate); -false +// Failure to detonate +if (_chanceToDetonate == 0 || {_chanceToDetonate < random 1}) exitWith { + TRACE_2("no detonation",_vehicle,_chanceToDetonate); + + false // return +}; + +// Vehicle will be detonated +if (_injureCrew) then { + { + [QGVAR(medicalDamage), [_x, _source, _instigator], _x] call CBA_fnc_targetEvent; + } forEach (crew _vehicle); +}; + +TRACE_2("detonation",_vehicle,_chanceToDetonate); + +// Detonate the vehicle +[QEGVAR(cookoff,detonateAmmunitionServer), [_vehicle, false, _source, _instigator]] call CBA_fnc_serverEvent; + +if (_knockOut) then { + [_vehicle, _source, _instigator] call FUNC(knockOut); +}; + +_knockOut // return diff --git a/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf b/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf index 02033b83be..4654b616d0 100644 --- a/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf +++ b/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf @@ -4,96 +4,101 @@ * Process vehicle hit. * * Arguments: - * 0: The vehicle - * 1: The hitpoint which got hit - * 2: The index of what got hit - * 3: The damage that the new part took - * 4: Person who hit vehicle - * 5: Damage before hit - * 6: Damage after hit - * 7: Projectile - * 8: Selection that got hit + * 0: Vehicle + * 1: Hit point + * 2: Hit index + * 3: Selection + * 4: Added damage to part + * 5: Projectile + * 6: Source of damage + * 7: Person who caused damage * * Return Value: - * Whether or not to continue handling last frame's damage + * Whether or not to continue handling last frame's damage * * Example: - * [ace_vehicle_damage_fnc_handleVehicleDamage, tank1, "Hit_Engine", 12]] call CBA_fnc_execNextFrame + * [ace_vehicle_damage_fnc_handleVehicleDamage, [cursorObject, "HitEngine", 12, "hit_engine_point", 0.25, projectile, player, player]] call CBA_fnc_execNextFrame * * Public: No */ -params["_vehicle", "_hitPoint", "_hitIndex", "_injurer", "_oldDamage", "_newDamage", "_projectile", "_selection"]; -TRACE_6("handleVehicleDamage",_vehicle,_hitPoint,_hitIndex,_injurer,_oldDamage,_newDamage); -if !(alive _vehicle) exitWith { - private _eventHandler = _vehicle getVariable[QGVAR(handleDamage), nil]; - if !(isNil "_eventHandler") then { - _vehicle removeEventHandler ["HandleDamage", _eventHandler]; +params ["_vehicle", "_hitPoint", "_hitIndex", "_selection", "_addedDamage", "_projectile", "_source", "_instigator"]; +TRACE_8("handleVehicleDamage",_vehicle,_hitPoint,_hitIndex,_selection,_addedDamage,_projectile,_source,_instigator); + +if (!alive _vehicle) exitWith { + private _handleDamageEH = _vehicle getVariable [QGVAR(handleDamage), nil]; + + if (!isNil "_handleDamageEH") then { + _vehicle removeEventHandler ["HandleDamage", _handleDamageEH]; }; - LOG_1("Vehicle [%1] no longer alive",_vehicle); - true + + TRACE_1("vehicle no longer alive",_vehicle); + + false }; _hitPoint = toLowerANSI _hitPoint; -private _hitpointHash = _vehicle getVariable [QGVAR(hitpointHash), []]; -private _type = if (_hitpointHash isEqualTo []) then { - "exit" -} else { - ([_hitpointHash, _hitPoint] call CBA_fnc_hashGet) select 0 -}; +private _hitPointHash = GVAR(vehicleClassesHitPointHash) getOrDefault [typeOf _vehicle, createHashMap]; +private _type = (_hitPointHash getOrDefault [_hitPoint, []]) select 0; -if (isNil "_type") then { - _type = "exit"; -}; - -// generic structural damage will be transfered into hull damage for simulation's sake +// Generic structural damage will be transfered into hull damage for simulation's sake private _structural = false; -if (_selection isEqualTo "") then { + +if (_selection == "") then { _type = "hull"; _hitPoint = "hithull"; _structural = true; + TRACE_1("structural damage",_selection); - _newDamage = abs _newDamage; + + _addedDamage = abs _addedDamage; }; -if (_type isEqualTo "exit") exitWith { LOG_1("No relevant hitpoints hit [%1]. Exiting",_hitPoint); true }; +if (isNil "_type") exitWith { + TRACE_1("no relevant hitpoints hit, exiting",_hitPoint); + + true +}; // Ignore multiple hits at the same time private _ignoreHit = false; private _ignoreBailCheck = false; private _multHit = _vehicle getVariable [QGVAR(hitTime), nil]; + if (isNil "_multHit") then { - _vehicle setVariable[QGVAR(hitTime), [CBA_missionTime, _injurer, [_hitPoint]]]; + _vehicle setVariable [QGVAR(hitTime), [CBA_missionTime, _source, [_hitPoint]]]; } else { private _hitPointInOldArray = _hitPoint in (_multHit select 2); - private _withinTime = (CBA_missionTime <= (_multHit select 0) + CONST_TIME) && { _injurer == (_multHit select 1) }; + private _withinTime = (CBA_missionTime <= (_multHit select 0) + CONST_TIME) && {_source == (_multHit select 1)}; + if (_hitPointInOldArray && _withinTime) then { _ignoreHit = true; } else { // If the hitpoint isnt in the old array then that means that the time expired and a new array should be generated - if !(_hitPointInOldArray) then { + if (!_hitPointInOldArray) then { private _oldHitPoints = _multHit select 2; _oldHitPoints pushBack _hitPoint; - _vehicle setVariable [QGVAR(hitTime), [CBA_missionTime, _injurer, _oldHitPoints]]; + _vehicle setVariable [QGVAR(hitTime), [CBA_missionTime, _source, _oldHitPoints]]; + _ignoreBailCheck = true; } else { - _vehicle setVariable [QGVAR(hitTime), [CBA_missionTime, _injurer, [_hitPoint]]]; + _vehicle setVariable [QGVAR(hitTime), [CBA_missionTime, _source, [_hitPoint]]]; }; }; }; + if (_ignoreHit && !_structural) exitWith { - LOG_3("Ignoring multiple hits done to vehicle [%1] by [%2] -- hitpoint [%3].",_vehicle,_injurer,_hitPoint); + TRACE_3("ignoring multiple hits done to vehicle",_vehicle,_source,_hitPoint); + true }; -LOG_3("Processing hit done to vehicle [%1] by [%2] at time [%3].",_vehicle,_injurer,CBA_missionTime); -if !([_vehicle, _projectile, _hitIndex, _newDamage, [_hitpointHash, _hitPoint] call CBA_fnc_hashGet, _injurer] call FUNC(processHit)) exitWith { false }; +TRACE_3("processing hit done to vehicle",_vehicle,_source,CBA_missionTime); -private _canMove = _vehicle getVariable[QGVAR(canMove), true]; -private _canShoot = _vehicle getVariable[QGVAR(canShoot), true]; +if !([_vehicle, _hitPoint, _hitIndex, _addedDamage, _projectile, _source, _instigator] call FUNC(processHit)) exitWith {false}; -if !(_ignoreBailCheck) then { - [_vehicle, _canMove, _canShoot] call FUNC(handleBail); +if (!_ignoreBailCheck) then { + _vehicle call FUNC(handleBail); }; true diff --git a/addons/vehicle_damage/functions/fnc_knockOut.sqf b/addons/vehicle_damage/functions/fnc_knockOut.sqf index 5c8d1697a6..753255c99f 100644 --- a/addons/vehicle_damage/functions/fnc_knockOut.sqf +++ b/addons/vehicle_damage/functions/fnc_knockOut.sqf @@ -1,37 +1,37 @@ #include "..\script_component.hpp" /* * Author: tcvm - * Knock out vehicle from battle. Destroy all internal hitpoints. + * Knock out a vehicle from battle by destroying all internal hitpoints. * * Arguments: - * 0: The vehicle + * 0: Vehicle + * 1: Source of damage + * 2: Person who caused damage * * Return Value: * None * * Example: - * [vehicle player] call ace_vehicle_damage_fnc_knockOut + * [cursorObject, player, player] call ace_vehicle_damage_fnc_knockOut * * Public: No */ -params ["_vehicle"]; -private _hash = _vehicle getVariable [QGVAR(hitpointHash), nil]; -if (isNil "_hash") exitWith {}; +params ["_vehicle", "_source", "_instigator"]; +TRACE_3("knockOut",_vehicle,_source,_instigator); -[_hash, { - private _hitpointAlias = _value#0; - if (_hitpointAlias isEqualTo "hull") then { - [_vehicle, -1, _key, 0.89] call FUNC(addDamage); +{ + private _hitArea = _y select 0; + + if (_hitArea == "hull") then { + [_vehicle, _x, -1, 0.89, _source, _instigator] call FUNC(setDamage); } else { - if (_hitpointAlias in ["fuel", "turret", "gun", "engine"]) then { - if ((0.3 > random 1) || { _hitpointAlias isEqualTo "engine" }) then { - [_vehicle, -1, _key, 1] call FUNC(addDamage); + if (_hitArea in ["fuel", "turret", "gun", "engine"]) then { + if ((0.3 > random 1) || {_hitArea == "engine"}) then { + [_vehicle, _x, -1, 1, _source, _instigator] call FUNC(setDamage); } else { - private _currentDamage = _vehicle getHitpointDamage _key; - [_vehicle, -1, _key, (_currentDamage + (0.3 max random 1)) min 1] call FUNC(addDamage); + [_vehicle, _x, -1, ((_vehicle getHitPointDamage _x) + (0.3 max random 1)) min 1, _source, _instigator] call FUNC(setDamage); }; }; }; -}] call CBA_fnc_hashEachPair; - +} forEach (GVAR(vehicleClassesHitPointHash) getOrDefault [typeOf _vehicle, createHashMap]); diff --git a/addons/vehicle_damage/functions/fnc_processHit.sqf b/addons/vehicle_damage/functions/fnc_processHit.sqf index ff1a0adadd..9c87c4b037 100644 --- a/addons/vehicle_damage/functions/fnc_processHit.sqf +++ b/addons/vehicle_damage/functions/fnc_processHit.sqf @@ -1,133 +1,132 @@ #include "..\script_component.hpp" /* - * Author: tcvm + * Author: tcvm, johnb43 * Process hit by projectile against vehicle and apply appropiate damage to part. * * Arguments: - * 0: The vehicle - * 1: Projectile that hit - * 2: Hit index of potentially damaged part - * 3: New damage done to part - * 4: Information about hitpoint - * 5: Person who caused damage + * 0: Vehicle + * 1: Hit point + * 2: Hit index + * 3: Added damage to part + * 4: Projectile + * 5: Source of damage + * 6: Person who caused damage * * Return Value: - * None + * Whether or not to continue handling last frame's damage * * Example: - * [myVehicle, projectile, 5, 0.663] call ace_vehicle_damage_fnc_processHit; + * [cursorObject, "HitEngine", 1, 0.25, projectile, player, player] call ace_vehicle_damage_fnc_processHit * * Public: No */ -params ["_vehicle", "_projectile", "_hitIndex", "_newDamage", "_hitpointData", "_injurer"]; -_hitpointData params ["_hitArea", "_hitpointConfig", "_hitpointName"]; +params ["_vehicle", "_hitPoint", "_hitIndex", "_addedDamage", "_projectile", "_source", "_instigator"]; +TRACE_7("processHit",_vehicle,_hitPoint,_hitIndex,_addedDamage,_projectile,_source,_instigator); -private _return = true; - -if (_newDamage < 0) then { - _newDamage = -_newDamage; -}; +_addedDamage = abs _addedDamage; private _currentPartDamage = _vehicle getHitIndex _hitIndex; -private _nextPartDamage = _currentPartDamage + _newDamage; +private _newPartDamage = _currentPartDamage + _addedDamage; + +// Damage is high enough for immediate destruction +if (_addedDamage >= 15) exitWith { + TRACE_2("immediate destruction - high damage",_addedDamage,_currentPartDamage); -// damage is high enough for immediate destruction -if (_newDamage >= 15) exitWith { - TRACE_2("immediate destruction - high damage",_newDamage,_currentPartDamage); - [_vehicle] call FUNC(knockOut); - [_vehicle, 1] call FUNC(handleDetonation); // Kill everyone inside for very insane damage { - [QGVAR(medicalDamage), [_x, _injurer, _injurer, true], _x] call CBA_fnc_targetEvent; + [QGVAR(medicalDamage), [_x, _source, _instigator, true], _x] call CBA_fnc_targetEvent; } forEach (crew _vehicle); - _vehicle setDamage 1; - _return = false; - _return + + // setDamage triggers "Killed" EH in cookoff, which starts ammo cook-off + [QGVAR(setDamage), [_vehicle, [1, true, _source, _instigator]]] call CBA_fnc_serverEvent; + + false }; private _projectileConfig = _projectile call CBA_fnc_getObjectConfig; -private _warheadTypeStr = getText (_projectileConfig >> "warheadName"); -private _incendiary = [_projectileConfig >> QGVAR(incendiary), "NUMBER", -1] call CBA_fnc_getConfigEntry; -private _warheadType = ["HE", "AP", "HEAT", "TandemHEAT"] find _warheadTypeStr; // numerical index for warhead type for quicker checks. Numbers defined in script_macros.hpp -if (_warheadType < 0) then { - _warheadType = WARHEAD_TYPE_NONE; -}; -if (_incendiary < 0) then { - _incendiary = [0.3, 0.1, 1, 1, 0] select _warheadType; -}; +private _warheadTypeStr = toLowerANSI getText (_projectileConfig >> "warheadName"); +private _warheadType = ["he", "ap", "heat", "tandemheat"] find _warheadTypeStr; // numerical index for warhead type for quicker checks. Numbers defined in script_macros.hpp -private _minDamage = [_hitpointConfig >> "minimalHit", "NUMBER", 0] call CBA_fnc_getConfigEntry; -if (_minDamage < 0) then { - _minDamage = -_minDamage; -}; +private _incendiary = [_projectileConfig >> QGVAR(incendiary), "NUMBER", [0.3, 0.1, 1, 1, 0] select _warheadType] call CBA_fnc_getConfigEntry; -private _ammoEffectiveness = 0; -private _projectileExplosive = [_projectileConfig >> "explosive", "NUMBER", 0] call CBA_fnc_getConfigEntry; -private _indirectHit = [_projectileConfig >> "indirectHit", "NUMBER", 0] call CBA_fnc_getConfigEntry; +private _hitPointHash = GVAR(vehicleClassesHitPointHash) getOrDefault [typeOf _vehicle, createHashMap]; +(_hitPointHash getOrDefault [_hitPoint, []]) params ["_hitArea", "_minDamage"]; -if (_warheadType isEqualTo WARHEAD_TYPE_AP) then { - // change damage based on projectile speed (doesn't do this in vanilla ARMA believe it or not) - if !(isNull _injurer) then { - private _airFriction = [_projectileConfig >> "airFriction", "NUMBER", 0] call CBA_fnc_getConfigEntry; - private _distance = _injurer distance _vehicle; - _newDamage = (1 - _projectileExplosive) * _newDamage * exp(_airFriction * _distance); +private _projectileExplosive = getNumber (_projectileConfig >> "explosive"); +private _indirectHit = getNumber (_projectileConfig >> "indirectHit"); + +if (_warheadType == WARHEAD_TYPE_AP) then { + // Change damage based on projectile speed (doesn't do this in vanilla Arma believe it or not) + if (!isNull _source) then { + private _airFriction = getNumber (_projectileConfig >> "airFriction"); + private _distance = _source distance _vehicle; + _addedDamage = (1 - _projectileExplosive) * _addedDamage * exp (_airFriction * _distance); }; }; private _penChance = 1; -if (_newDamage < _minDamage) then { - _penChance = _newDamage / _minDamage; - TRACE_5("minimum damage modifying hit",_newDamage,_penChance,abs _minDamage,_warheadTypeStr,_hitArea); + +// Added damage can't be 0, so don't need to worry about 0 division here +if (_addedDamage < _minDamage) then { + _penChance = _addedDamage / _minDamage; + + TRACE_5("minimum damage modifying hit",_addedDamage,_penChance,_minDamage,_warheadTypeStr,_hitArea); }; if (_penChance < random 1) exitWith { TRACE_1("didn't penetrate",_penChance); - _return + + true }; if (_minDamage == 0) then { _minDamage = 1; }; -if (_warheadType isEqualTo WARHEAD_TYPE_HE) then { +if (_warheadType == WARHEAD_TYPE_HE) then { private _modifiedIndirectHit = _indirectHit / 100; - if (_newDamage > _modifiedIndirectHit) then { - _newDamage = _newDamage / 2; + + if (_addedDamage > _modifiedIndirectHit) then { + _addedDamage = _addedDamage / 2; }; - _newDamage = (_newDamage * (_newDamage / _modifiedIndirectHit)) min _newDamage; + + _addedDamage = (_addedDamage * (_addedDamage / _modifiedIndirectHit)) min _addedDamage; }; -_ammoEffectiveness = if (_warheadType isEqualTo WARHEAD_TYPE_AP) then { - 0.15 max _newDamage +private _ammoEffectiveness = if (_warheadType == WARHEAD_TYPE_AP) then { + 0.15 max _addedDamage } else { - if (_warheadType isEqualTo WARHEAD_TYPE_HE) then { - (_newDamage / (_minDamage + (_indirectHit / 100)) * 0.2) + if (_warheadType == WARHEAD_TYPE_HE) then { + (_addedDamage / (_minDamage + (_indirectHit / 100)) * 0.2) } else { - ((_newDamage / _minDamage) * 0.4) min 1 + ((_addedDamage / _minDamage) * 0.4) min 1 }; }; -TRACE_4("ammo effectiveness",_ammoEffectiveness,_newDamage,_minDamage,_warheadTypeStr); + +TRACE_4("ammo effectiveness",_ammoEffectiveness,_addedDamage,_minDamage,_warheadTypeStr); _incendiary = _incendiary * _ammoEffectiveness; -private _isCar = (_vehicle isKindOf "Car" && { !(_vehicle isKindOf "Wheeled_APC_F") }); +private _isCar = _vehicle isKindOf "Car" && {!(_vehicle isKindOf "Wheeled_APC_F")}; + if (_isCar) then { - _ammoEffectiveness = (_ammoEffectiveness + (_ammoEffectiveness * 0.5)) min 1; + _ammoEffectiveness = (_ammoEffectiveness * 1.5) min 1; }; -private _currentVehicleAmmo = _vehicle call EFUNC(cookoff,getVehicleAmmo); +(_vehicle call EFUNC(cookoff,getVehicleAmmo)) params ["_magazines", "_totalAmmo"]; private _chanceOfDetonation = 0; private _explosiveAmmoCount = 0; -private _nonExplosiveAmmoCount = 0; -if ((_currentVehicleAmmo select 0) isNotEqualTo []) then { +if (_magazines isNotEqualTo []) then { private _magConfig = configFile >> "CfgMagazines"; private _ammoConfig = configFile >> "CfgAmmo"; private _countOfExplodableAmmo = 0; + { _x params ["_magazineClassname", "_currentAmmoCount"]; + private _initialAmmoCount = getNumber (_magConfig >> _magazineClassname >> "count"); _chanceOfDetonation = _chanceOfDetonation + (_currentAmmoCount / _initialAmmoCount); _countOfExplodableAmmo = _countOfExplodableAmmo + 1; @@ -135,215 +134,241 @@ if ((_currentVehicleAmmo select 0) isNotEqualTo []) then { private _ammoClassname = getText (_magConfig >> _magazineClassname >> "ammo"); private _explosive = getNumber (_ammoConfig >> _ammoClassname >> "explosive"); private _hit = getNumber (_ammoConfig >> _ammoClassname >> "hit"); - if (_explosive > 0.5 || _hit > 50) then { + + if (_explosive > 0.5 || {_hit > 50}) then { _explosiveAmmoCount = _explosiveAmmoCount + 1; - } else { - _nonExplosiveAmmoCount = _nonExplosiveAmmoCount + 1; }; - } forEach (_currentVehicleAmmo select 0); + } forEach _magazines; + if (_countOfExplodableAmmo != 0) then { _chanceOfDetonation = _chanceOfDetonation / _countOfExplodableAmmo; }; }; -private _chanceToDetonate = 0; -private _chanceOfFire = 0; -private _currentFuel = fuel _vehicle; -private _vehicleConfig = _vehicle call CBA_fnc_getObjectConfig; + +private _return = true; + switch (_hitArea) do { case "engine": { - _chanceToDetonate = ([_vehicleConfig >> QGVAR(engineDetonationProb), "NUMBER", 0] call CBA_fnc_getConfigEntry) * _incendiary * _currentFuel * _penChance; - _chanceOfFire = ([_vehicleConfig >> QGVAR(engineFireProb), "NUMBER", 0] call CBA_fnc_getConfigEntry) * _incendiary * _currentFuel * _penChance; + private _vehicleConfig = configOf _vehicle; + private _currentFuel = fuel _vehicle; + private _chanceToDetonate = getNumber (_vehicleConfig >> QGVAR(engineDetonationProb)) * _incendiary * _currentFuel * _penChance; - private _cookoffIntensity = 4 * _currentFuel; - TRACE_6("hit engine",_chanceToDetonate,_chanceOfFire,_incendiary,_chanceOfDetonation,_currentFuel,_cookoffIntensity); + TRACE_4("hit engine",_chanceToDetonate,_incendiary,_chanceOfDetonation,_currentFuel); - if (_isCar) then { - _chanceOfFire = 0; // no cookoff for cars + // Knock out and detonate vehicle if necessary + if ([_vehicle, _chanceToDetonate, _explosiveAmmoCount > 0, _totalAmmo > 0, _source, _instigator] call FUNC(handleDetonation)) exitWith {}; + + // Cap damage at 0.9 to avoid hard coded blow up + _newPartDamage = 0.9 min _newPartDamage; + + // Fatal engine/drive system damage (engine and tracks stop working at 0.9) + if (0.8 * _ammoEffectiveness > random 1) then { + _newPartDamage = 0.9; }; - if ([_vehicle, _chanceToDetonate, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { - [_vehicle] call FUNC(knockOut); - }; - - // cap damage at 0.9 to avoid hard coded blow up - _nextPartDamage = (0.9 min _nextPartDamage); - - // fatal engine/drive system damage - if (_nextPartDamage == 0.9 || { 0.8 * _ammoEffectiveness > random 1 }) then { - [_vehicle, _hitIndex, _hitpointName, 0.9 * _penChance] call FUNC(addDamage); + if (_newPartDamage == 0.9) then { _vehicle setVariable [QGVAR(canMove), false]; - } else { - [_vehicle, _hitIndex, _hitpointName, _nextPartDamage * _penChance] call FUNC(addDamage); }; - [_vehicle, _chanceOfFire, _cookoffIntensity, _injurer, _hitArea, false] call FUNC(handleCookoff); + [_vehicle, _hitPoint, _hitIndex, _newPartDamage * _penChance, _source, _instigator] call FUNC(setDamage); + + // No cookoff for cars + if (_isCar) exitWith {}; + + private _chanceOfFire = getNumber (_vehicleConfig >> QGVAR(engineFireProb)) * _incendiary * _currentFuel * _penChance; + private _cookoffIntensity = 4 * _currentFuel; + + [_vehicle, _chanceOfFire, _cookoffIntensity, _source, _instigator, "engine", false, false] call FUNC(handleCookoff); }; case "hull": { - _chanceToDetonate = ([_vehicleConfig >> QGVAR(hullDetonationProb), "NUMBER", 0] call CBA_fnc_getConfigEntry) * _incendiary * ((_chanceOfDetonation + _currentFuel) / 2) * _penChance; - _chanceOfFire = ([_vehicleConfig >> QGVAR(hullFireProb), "NUMBER", 0] call CBA_fnc_getConfigEntry) * _incendiary * ((_chanceOfDetonation + _currentFuel) / 2) * _penChance; + private _vehicleConfig = configOf _vehicle; + private _currentFuel = fuel _vehicle; + private _chanceToDetonate = getNumber (_vehicleConfig >> QGVAR(hullDetonationProb)) * _incendiary * ((_chanceOfDetonation + _currentFuel) / 2) * _penChance; - private _cookoffIntensity = 1.5 + (_explosiveAmmoCount * _chanceOfFire); - TRACE_6("hit hull",_chanceToDetonate,_chanceOfFire,_incendiary,_chanceOfDetonation,_currentFuel,_cookoffIntensity); + TRACE_4("hit hull",_chanceToDetonate,_incendiary,_chanceOfDetonation,_currentFuel); - if (_isCar) then { - _chanceOfFire = 0; // no cookoff for cars + // Knock out and detonate vehicle if necessary + if ([_vehicle, _chanceToDetonate, _explosiveAmmoCount > 0, _totalAmmo > 0, _source, _instigator] call FUNC(handleDetonation)) exitWith { + [_vehicle, _hitPoint, _hitIndex, 0.89 * _penChance, _source, _instigator] call FUNC(setDamage); }; - if ([_vehicle, _chanceToDetonate, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { - [_vehicle, _hitIndex, _hitpointName, 0.89 * _penChance] call FUNC(addDamage); - [_vehicle] call FUNC(knockOut); - }; - - private _hash = _vehicle getVariable [QGVAR(hitpointHash), []]; - private _hashKeys = [_hash] call CBA_fnc_hashKeys; - // 25% chance of jamming turret - 25% of mobility kill - 25% of both - 75% chance of critical hull damage private _rand = random 1; + TRACE_2("rolling hull damage",_ammoEffectiveness,_rand); + private _partKill = []; + if (_ammoEffectiveness > _rand) then { _rand = random 1; + TRACE_2("damaged hull part",_ammoEffectiveness,_rand); + switch (true) do { case (_rand < 0.25): { - [_vehicle, _hitIndex, _hitpointName, 0.89 * _penChance] call FUNC(addDamage); - // iterate through all keys and find appropriate turret - [_hash, { - if (_value#0 isEqualTo "turret") then { - _partKill pushBack _key; + [_vehicle, _hitPoint, _hitIndex, 0.89 * _penChance, _source, _instigator] call FUNC(setDamage); + + // Iterate through all keys and find appropriate turret + { + if ((_y select 0) == "turret") then { + _partKill pushBack _x; }; - }] call CBA_fnc_hashEachPair; + } forEach _hitPointHash; + _vehicle setVariable [QGVAR(canShoot), false]; }; case (_rand < 0.5): { - [_vehicle, _hitIndex, _hitpointName, 0.89 * _penChance] call FUNC(addDamage); - _partKill = _partKill + ENGINE_HITPOINTS#0; + [_vehicle, _hitPoint, _hitIndex, 0.89 * _penChance, _source, _instigator] call FUNC(setDamage); + + _partKill append (ENGINE_HITPOINTS select 0); + if !(_vehicle isKindOf "Wheeled_APC_F") then { - _partKill = _partKill + TRACK_HITPOINTS#0; + _partKill append (TRACK_HITPOINTS select 0); }; _vehicle setVariable [QGVAR(canMove), false]; }; case (_rand < 0.75): { - [_vehicle, _hitIndex, _hitpointName, 0.89 * _penChance] call FUNC(addDamage); - _partKill = _partKill + ENGINE_HITPOINTS#0; + [_vehicle, _hitPoint, _hitIndex, 0.89 * _penChance, _source, _instigator] call FUNC(setDamage); + + _partKill append (ENGINE_HITPOINTS select 0); + if !(_vehicle isKindOf "Wheeled_APC_F") then { - _partKill = _partKill + TRACK_HITPOINTS#0; + _partKill append (TRACK_HITPOINTS select 0); }; - // iterate through all keys and find appropriate turret - [_hash, { - if (_value#0 isEqualTo "turret") then { - _partKill pushBack _key; + // Iterate through all keys and find appropriate turret + { + if ((_y select 0) == "turret") then { + _partKill pushBack _x; }; - }] call CBA_fnc_hashEachPair; + } forEach _hitPointHash; _vehicle setVariable [QGVAR(canMove), false]; _vehicle setVariable [QGVAR(canShoot), false]; }; - default{}; }; }; { + [_vehicle, _x, -1, _penChance, _source, _instigator] call FUNC(setDamage); + TRACE_1("doing damage to hitpoint",_x); - [_vehicle, -1, _x, 1 * _penChance] call FUNC(addDamage); } forEach _partKill; - [_vehicle, _chanceOfFire, _cookoffIntensity, _injurer, "", true] call FUNC(handleCookoff); + // No cookoff for cars + if (_isCar) exitWith {}; + + private _chanceOfFire = getNumber (_vehicleConfig >> QGVAR(hullFireProb)) * _incendiary * ((_chanceOfDetonation + _currentFuel) / 2) * _penChance; + private _cookoffIntensity = 1.5 + (_explosiveAmmoCount * _chanceOfFire); + + [_vehicle, _chanceOfFire, _cookoffIntensity, _source, _instigator] call FUNC(handleCookoff); }; case "turret": { - _chanceToDetonate = ([_vehicleConfig >> QGVAR(turretDetonationProb), "NUMBER", 0] call CBA_fnc_getConfigEntry) * _incendiary * _chanceOfDetonation * _penChance; - _chanceOfFire = ([_vehicleConfig >> QGVAR(turretFireProb), "NUMBER", 0] call CBA_fnc_getConfigEntry) * _incendiary * _chanceOfDetonation * _penChance; + private _vehicleConfig = configOf _vehicle; + private _chanceToDetonate = getNumber (_vehicleConfig >> QGVAR(turretDetonationProb)) * _incendiary * _chanceOfDetonation * _penChance; - private _cookoffIntensity = _explosiveAmmoCount * _chanceOfFire; - TRACE_6("hit turret",_chanceToDetonate,_chanceOfFire,_incendiary,_chanceOfDetonation,_currentFuel,_cookoffIntensity); + TRACE_3("hit turret",_chanceToDetonate,_incendiary,_chanceOfDetonation); - if (_isCar) then { - _chanceOfFire = 0; // no cookoff for cars - }; - - if ([_vehicle, _chanceToDetonate, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { - [_vehicle] call FUNC(knockOut); - }; + if ([_vehicle, _chanceToDetonate, _explosiveAmmoCount > 0, _totalAmmo > 0, _source, _instigator] call FUNC(handleDetonation)) exitWith {}; if (0.8 * _ammoEffectiveness > random 1) then { TRACE_1("damaged turret",_ammoEffectiveness * 0.8); - [_vehicle, _hitIndex, _hitpointName, 1 * _penChance] call FUNC(addDamage); + + [_vehicle, _hitPoint, _hitIndex, _penChance, _source, _instigator] call FUNC(setDamage); + _vehicle setVariable [QGVAR(canShoot), false]; }; - [_vehicle, _chanceOfFire, _cookoffIntensity, _injurer, "", true] call FUNC(handleCookoff); + // No cookoff for cars + if (_isCar) exitWith {}; + + private _chanceOfFire = getNumber (_vehicleConfig >> QGVAR(turretFireProb)) * _incendiary * _chanceOfDetonation * _penChance; + private _cookoffIntensity = _explosiveAmmoCount * _chanceOfFire; + + [_vehicle, _chanceOfFire, _cookoffIntensity, _source, _instigator] call FUNC(handleCookoff); }; case "gun": { - TRACE_5("hit gun",_chanceToDetonate,_chanceOfFire,_incendiary,_chanceOfDetonation,_currentFuel); + TRACE_2("hit gun",_addedDamage,_minDamage); + if (0.8 * _ammoEffectiveness > random 1) then { TRACE_1("damaged gun",_ammoEffectiveness * 0.8); - [_vehicle, _hitIndex, _hitpointName, 1 * _penChance] call FUNC(addDamage); + + [_vehicle, _hitPoint, _hitIndex, _penChance, _source, _instigator] call FUNC(setDamage); + _vehicle setVariable [QGVAR(canShoot), false]; }; }; case "track": { - private _damage = (0.1 max (0.1 * _newDamage / _minDamage)) min 1; - [_vehicle, _hitIndex, _hitpointName, (_currentPartDamage + _damage) * _penChance] call FUNC(addDamage); - TRACE_3("damaged track",_damage,_newDamage,_minDamage); + private _damage = (0.1 max (0.1 * _addedDamage / _minDamage)) min 1; + + [_vehicle, _hitPoint, _hitIndex, (_currentPartDamage + _damage) * _penChance] call FUNC(setDamage); + + TRACE_3("damaged track",_damage,_addedDamage,_minDamage); if ((_vehicle getHitIndex _hitIndex) >= 1) then { _vehicle setVariable [QGVAR(canMove), false]; }; }; case "wheel": { - [_vehicle, _hitIndex, _hitpointName, (_currentPartDamage + _newDamage) * _penChance] call FUNC(addDamage); - TRACE_1("damaged wheel",_newDamage); + [_vehicle, _hitPoint, _hitIndex, (_currentPartDamage + _addedDamage) * _penChance, _source, _instigator] call FUNC(setDamage); + + TRACE_1("damaged wheel",_addedDamage); }; case "fuel": { - _chanceOfFire = (_incendiary * _currentFuel * _penChance) / 2; + private _damage = (0.1 max (0.1 * _addedDamage / _minDamage)) min 1; + [_vehicle, _hitPoint, _hitIndex, (_currentPartDamage + _damage) * _penChance, _source, _instigator] call FUNC(setDamage); + + // No cookoff for cars + if (_isCar) exitWith {}; + + private _currentFuel = fuel _vehicle; + private _chanceOfFire = (_incendiary * _currentFuel * _penChance) / 2; private _cookoffIntensity = _currentFuel * 5; - TRACE_2("damaged fuel",_chanceOfFire,_cookoffIntensity); - if (_isCar) then { - _chanceOfFire = 0; // no cookoff for cars - }; + TRACE_4("damaged fuel",_chanceOfFire,_incendiary,_cookoffIntensity,_currentFuel); - [_vehicle, _chanceOfFire, _cookoffIntensity, _injurer, "", false] call FUNC(handleCookoff); - - private _damage = (0.1 max (0.1 * _newDamage / _minDamage)) min 1; - [_vehicle, _hitIndex, _hitpointName, (_currentPartDamage + _damage) * _penChance] call FUNC(addDamage); + [_vehicle, _chanceOfFire, _cookoffIntensity, _source, _instigator, "", false, false] call FUNC(handleCookoff); }; case "slat": { TRACE_2("hit slat",_warheadType,_warheadTypeStr); - // incredibly small chance of AP destroying SLAT - if (_warheadType in [WARHEAD_TYPE_HE, WARHEAD_TYPE_AP, WARHEAD_TYPE_HEAT, WARHEAD_TYPE_TANDEM] || { 0.01 > random 1 }) then { + + // Incredibly small chance of AP destroying SLAT + if (_warheadType in [WARHEAD_TYPE_HE, WARHEAD_TYPE_AP, WARHEAD_TYPE_HEAT, WARHEAD_TYPE_TANDEM] || {0.01 > random 1}) then { private _currentDamage = _vehicle getHitIndex _hitIndex; + TRACE_3("damaged slat",_warheadType,_warheadTypeStr,_currentDamage); if (_warheadType in [WARHEAD_TYPE_HEAT, WARHEAD_TYPE_TANDEM, WARHEAD_TYPE_AP]) then { - [_vehicle, _hitIndex, _hitpointName, 1] call FUNC(addDamage); + [_vehicle, _hitPoint, _hitIndex, 1, _source, _instigator] call FUNC(setDamage); } else { - [_vehicle, _hitIndex, _hitpointName, _currentDamage + (0.5 max random 1)] call FUNC(addDamage); + [_vehicle, _hitPoint, _hitIndex, _currentDamage + (0.5 max random 1), _source, _instigator] call FUNC(setDamage); }; - if (_currentDamage < 1 && _warheadType isEqualTo WARHEAD_TYPE_HEAT) then { + if (_currentDamage < 1 && {_warheadType == WARHEAD_TYPE_HEAT}) then { _return = false; }; }; }; case "era": { TRACE_2("hit era",_warheadType,_warheadTypeStr); - if (_warheadType in [WARHEAD_TYPE_AP, WARHEAD_TYPE_HEAT, WARHEAD_TYPE_TANDEM] || { 0.05 > random 1 }) then { - private _currentDamage = _vehicle getHitIndex _hitIndex; - TRACE_3("damaged era",_warheadType,_warheadTypeStr,_currentDamage); - [_vehicle, _hitIndex, _hitpointName, 1] call FUNC(addDamage); - // dont process anymore damage if this is HEAT - shouldnt happen anyway but ARMA says it does so you know - if (_currentDamage < 1 && _warheadType isEqualTo WARHEAD_TYPE_HEAT) then { + if (_warheadType in [WARHEAD_TYPE_AP, WARHEAD_TYPE_HEAT, WARHEAD_TYPE_TANDEM] || {0.05 > random 1}) then { + private _currentDamage = _vehicle getHitIndex _hitIndex; + + TRACE_3("damaged era",_warheadType,_warheadTypeStr,_currentDamage); + + [_vehicle, _hitPoint, _hitIndex, 1, _source, _instigator] call FUNC(setDamage); + + // Don't process anymore damage if this is HEAT - shouldn't happen anyway but Arma says it does so you know + if (_currentDamage < 1 && {_warheadType == WARHEAD_TYPE_HEAT}) then { _return = false; }; }; }; default { TRACE_1("hit unknown hitpoint??",_hitArea); - } + }; }; _return diff --git a/addons/vehicle_damage/functions/fnc_setDamage.sqf b/addons/vehicle_damage/functions/fnc_setDamage.sqf new file mode 100644 index 0000000000..8b75bff1f7 --- /dev/null +++ b/addons/vehicle_damage/functions/fnc_setDamage.sqf @@ -0,0 +1,45 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Sets vehicle damage based on HitIndex. Failing that it falls back to HitPoint name. + * + * Arguments: + * 0: Vehicle + * 1: Hit point + * 2: Hit index + * 3: Damage + * 4: Source of damage + * 5: Person who caused damage + * + * Return Value: + * None + * + * Example: + * [cursorObject, "HitEngine", 1, 0.25, player, player] call ace_vehicle_damage_fnc_setDamage + * + * Public: No + */ + +params ["_vehicle", "_hitPoint", "_hitIndex", "_damage", "_source", "_instigator"]; +TRACE_6("setDamage",_vehicle,_hitPoint,_hitIndex,_damage,_source,_instigator); + +private _currentDamage = _vehicle getHitPointDamage _hitPoint; + +if (_damage < _currentDamage) exitWith { + TRACE_3("capping damage at current",_damage,_currentDamage,_hitPoint); +}; + +if (_hitPoint == "#structural") then { + _hitPoint = "hithull"; + _hitIndex = -1; +}; + +if (_hitIndex >= 0) then { + _vehicle setHitIndex [_hitIndex, _damage, true, _source, _instigator]; +} else { + _vehicle setHitPointDamage [_hitPoint, _damage, true, _source, _instigator]; +}; + +if (_hitPoint == "HitEngine" && {_damage >= 0.9}) then { + [QEGVAR(cookoff,engineFireServer), _vehicle] call CBA_fnc_serverEvent; +}; diff --git a/addons/vehicle_damage/initSettings.inc.sqf b/addons/vehicle_damage/initSettings.inc.sqf index 0d3f324af2..3a1bcf568a 100644 --- a/addons/vehicle_damage/initSettings.inc.sqf +++ b/addons/vehicle_damage/initSettings.inc.sqf @@ -1,19 +1,21 @@ [ - QGVAR(enabled), "CHECKBOX", + QGVAR(enabled), + "CHECKBOX", [ELSTRING(common,Enabled), LSTRING(setting_description)], LSTRING(category_displayName), - false, // default value - true, // isGlobal + false, + 1, {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, true // Needs mission restart -] call CBA_settings_fnc_init; +] call CBA_fnc_addSetting; [ - QGVAR(enableCarDamage), "CHECKBOX", + QGVAR(enableCarDamage), + "CHECKBOX", [LSTRING(carDamage_setting_enable), LSTRING(carDamage_setting_description)], LSTRING(category_displayName), - false, // default value - true, // isGlobal + false, + 1, {[QGVAR(enableCarDamage), _this] call EFUNC(common,cbaSettings_settingChanged)}, true // Needs mission restart -] call CBA_settings_fnc_init; +] call CBA_fnc_addSetting; diff --git a/addons/vehicle_damage/script_macros.hpp b/addons/vehicle_damage/script_macros.hpp index 84f3120ac1..43bac7e2f8 100644 --- a/addons/vehicle_damage/script_macros.hpp +++ b/addons/vehicle_damage/script_macros.hpp @@ -7,21 +7,23 @@ #define IS_EXPLOSIVE_AMMO(ammo) (getNumber (ammo call CBA_fnc_getObjectConfig >> "explosive") > 0.5) #define ENGINE_HITPOINTS [["hitengine"], "engine"] -#define HULL_HITPOINTS [["hithull", "hitbody", "#structural"],"hull"] +#define HULL_HITPOINTS [["hithull", "hitbody", "#structural"], "hull"] #define TRACK_HITPOINTS [["hitltrack", "hitrtrack"], "track"] #define WHEEL_HITPOINTS [["hitlbwheel", "hitlmwheel", "hitlfwheel", "hitlf2wheel", "hitrbwheel", "hitrmwheel", "hitrlwheel", "hitrfwheel", "hitrf2wheel"], "wheel"] #define FUEL_HITPOINTS [["hitfuel"], "fuel"] #define ALL_HITPOINTS [ENGINE_HITPOINTS, HULL_HITPOINTS, TRACK_HITPOINTS, WHEEL_HITPOINTS, FUEL_HITPOINTS] -#define CRITICAL_HITPOINTS ["hithull", 0.89, "hitbody", 0.89, "#structural", 0.89, "hitengine", 0.9] +#define CRITICAL_HITPOINTS ["hithull", "hitbody", "#structural", "hitengine"] +#define CRITICAL_HITPOINTS_THRESHOLDS [0.89, 0.89, 0.89, 0.9] #define WARHEAD_TYPE_HE 0 #define WARHEAD_TYPE_AP 1 #define WARHEAD_TYPE_HEAT 2 #define WARHEAD_TYPE_TANDEM 3 -#define WARHEAD_TYPE_NONE 4 #define EJECT_IF_DESTROYED_VEHICLES ["Boat_Transport_02_base_F", "Rubber_duck_base_F"] - -#define CREATE_INCENDIARY_AMMO(ammo,base,inc) class ammo: base { GVAR(incendiary) = inc; } +#define CREATE_INCENDIARY_AMMO(ammo,base,inc)\ +class ammo: base {\ + GVAR(incendiary) = inc;\ +} diff --git a/addons/vehicle_damage/stringtable.xml b/addons/vehicle_damage/stringtable.xml index 8e0bb6fe70..a2d9a9232f 100644 --- a/addons/vehicle_damage/stringtable.xml +++ b/addons/vehicle_damage/stringtable.xml @@ -15,43 +15,33 @@ ACE Dano avançãdo de veículos - Enable/Disable advanced vehicle damage - アドバンスドビークルダメージを有効/無効にする + Enable advanced vehicle damage Active les dégâts de véhicule avancés. - Aktiviert/Deaktiviert den Erweiterten Fahrzeugsschaden + Aktiviert den Erweiterten Fahrzeugsschaden Abilità danni avanzati ai veicoli - Włącz/Wyłącz zaawansowane uszkodzenia pojazdów - 启用/禁用高级载具损坏 - 고급 차량 피해 활성화/비활성화 - Включить/выключить продвинутое повреждение техники - Habilitar/Deshabilitar el daño avanzado de vehículos - Ativar/Desativar dano avançado de veículo - - - Enable/Disable advanced car damage (Experimental) - アドバンスド車ダメージを有効/無効にする (試験的) - Active les dégâts avancés sur les voitures (expérimental). - Aktiviert/Deaktiviert den Erweiterten Fahrzeugsschaden (Experimentell) - Abilita danni avanzati ai veicoli (sperimentale) - Włącz/Wyłącz zaawansowane uszkodzenia w samochodach (eksperymentalne) - 启用/禁用高级车辆损坏(实验性) - 고급 차량 피해(실험용) 활성화/비활성화 - Включить/выключить продвинутое повреждение машин (экспериментальное) - Habilita/Deshabilita el daño avanzado de coche (Experimental) - Ativar/Desativar dano avançado de carro (Experimental) + Włącz zaawansowane uszkodzenia pojazdów + Включить продвинутое повреждение техники + Habilitar el daño avanzado de vehículos + Ativar dano avançado de veículo - Enable/Disable advanced car damage - アドバンスド車ダメージを有効/無効にする + Enable advanced car damage Dégâts de voiture avancés - Aktiviert/Deaktiviert erweiterten Autoschaden + Aktiviert erweiterten Autoschaden Abilita danni avanzati alle macchine - Włącz/Wyłącz zaawansowane uszkodzenia w samochodach - 启用/禁用高级车辆损坏 - 고급 차량 피해 활성화/비활성화 - Продвинутое повреждение машин - Habilitar/Deshabilitar daño avanzado de coche (Experimental) - Ativar/Desativar dano avançado de carro + Włącz zaawansowane uszkodzenia w samochodach + Habilitar daño avanzado de coche + Habilitar dano avançado para carros + + + Enable advanced car damage (Experimental) + Active les dégâts avancés sur les voitures (expérimental). + Aktiviert den Erweiterten Fahrzeugsschaden (Experimentell) + Abilita danni avanzati ai veicoli (sperimentale) + Włącz zaawansowane uszkodzenia w samochodach (eksperymentalne) + Включить продвинутое повреждение машин (экспериментальное) + Habilitar daño avanzado de coche (Experimental) + Habilitar dano avançado para carros (Experimental) Wreck (Turret) diff --git a/docs/wiki/feature/vehicledamage.md b/docs/wiki/feature/vehicledamage.md index 12dd1d4a19..a457e663f4 100644 --- a/docs/wiki/feature/vehicledamage.md +++ b/docs/wiki/feature/vehicledamage.md @@ -19,7 +19,7 @@ Removes hit-point based damage on armoured vehicles. ### 1.1 Differences from vanilla -Vehicle damage is component based in this system. Rather than catastrophically exploding when an arbitrary amount of damage is recieved, the system calculates what warhead hit you, if it hit SLAT/ERA, and what components it hits. +Vehicle damage is component based in this system. Rather than catastrophically exploding when an arbitrary amount of damage is received, the system calculates what warhead hit you, if it hit SLAT/ERA, and what components it hits. When you are hit, a calculation takes place and determines which people inside the vehicle should get hurt. ### 1.2 How is damage calculated @@ -116,20 +116,3 @@ When hit, HEAT warheads will be defeated and no damage will be applied. If hit w - Can cook-off [N] - Can injure occupants [N] - -## 3. Addon Options - -### 3.1 Enable - -- Enables/Disables the vehicle damage simulation -- Default: On - -### 3.2 Enable/Disable Ammo Removal During Cook-Off - -- Enables/Disables whether or not vehicle ammo will be fully removed upon cooking-off -- Default: On - -### 3.3 Enable/Disable advanced car damage (Experimental) - -- Enable experimental car damage. System will apply vehicle damage simulation to "car" types (trucks, SUVs, Humvees, etc.). Not fully tested and could be immbalanced causing weird behaviours. -- Default: Off diff --git a/docs/wiki/framework/vehicledamage-framework.md b/docs/wiki/framework/vehicledamage-framework.md index 04137e9c73..afda3f82f7 100644 --- a/docs/wiki/framework/vehicledamage-framework.md +++ b/docs/wiki/framework/vehicledamage-framework.md @@ -73,7 +73,7 @@ Default: 0 Whether or not this vehicle can spawn a `jet` effect (Boolean value: 0 or 1) -Default: 0 +Default: 1 #### 1.1.10 `ace_vehicle_damage_slatHitpoints` @@ -89,9 +89,9 @@ Default: {} #### 1.1.12 `ace_vehicle_damage_turret` -String for turret classname to spawn when catastrophically destroyed. Turret will pop-off and this is the class spawned +String for turret classname to spawn when catastrophically destroyed, followed by offset the object should spawn with. Turret will pop-off and this is the class spawned -Default: "" +Default: {} ### 1.2 Defined Hitpoints From c292f0ed313afe8896a55391b9841b8232ea43d6 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Tue, 20 Aug 2024 21:44:33 +0200 Subject: [PATCH 06/26] Interaction - Improve interaction anims locations for bags (#10230) Improve interaction anims locations --- addons/interaction/CfgVehicles.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/interaction/CfgVehicles.hpp b/addons/interaction/CfgVehicles.hpp index b3a0c1d37e..e3663cdee8 100644 --- a/addons/interaction/CfgVehicles.hpp +++ b/addons/interaction/CfgVehicles.hpp @@ -439,7 +439,7 @@ class CfgVehicles { class GVAR(anims): GVAR(anims) { class showBags { phase = 0; - selections[] = {"vhc_bags"}; + positions[] = {"_target selectionPosition ['vhc_bags', 'FireGeometry', 'AveragePoint']"}; items[] = {"B_Carryall_cbr"}; name = "$STR_BACKPACK_CONTAINER_NAME"; text = "$STR_BACKPACK_CONTAINER_NAME"; @@ -450,7 +450,7 @@ class CfgVehicles { class GVAR(anims) { class showBags { phase = 0; - selections[] = {"vhc_bags"}; + positions[] = {"_target selectionPosition ['vhc_bags', 'FireGeometry', 'AveragePoint']"}; items[] = {"B_Carryall_cbr", "B_Carryall_cbr"}; name = "$STR_a3_cfgvehicleclasses_backpacks0"; text = "$STR_a3_cfgvehicleclasses_backpacks0"; @@ -490,13 +490,13 @@ class CfgVehicles { class GVAR(anims) { class showBags { phase = 0; - selections[] = {"vhc_bags"}; + positions[] = {"_target selectionPosition ['vhc_bags', 'FireGeometry', 'AveragePoint']"}; items[] = {"B_Carryall_cbr"}; name = "$STR_BACKPACK_CONTAINER_NAME"; text = "$STR_BACKPACK_CONTAINER_NAME"; }; class showBags2: showBags { - selections[] = {"vhc_bags2"}; + positions[] = {"_target selectionPosition ['vhc_bags2', 'FireGeometry', 'AveragePoint']"}; }; }; }; From 0643ca6fd96b14be8878aed8bcdcc2a07c56ef05 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Tue, 20 Aug 2024 21:44:47 +0200 Subject: [PATCH 07/26] Repair - Improve some locations for interaction anims (#10224) Improve some locations for interaction anims --- addons/repair/CfgVehicles.hpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/addons/repair/CfgVehicles.hpp b/addons/repair/CfgVehicles.hpp index 6172b72679..011a038f91 100644 --- a/addons/repair/CfgVehicles.hpp +++ b/addons/repair/CfgVehicles.hpp @@ -434,7 +434,8 @@ class CfgVehicles { class EGVAR(interaction,anims) { class showTracks { phase = 0; - positions[] = {{-1.7, -3.875, -0.7}, {1.7, -3.875, -0.7}}; + selections[] = {"vhc_tracks"}; + positions[] = {"private _pos = _target selectionPosition 'vhc_tracks'; _pos set [0, -(_pos select 0)]; _pos"}; // Mirror position to other side of vehicle items[] = {"ACE_Track", "ACE_Track", "ACE_Track"}; name = CSTRING(RemoveTrack); text = CSTRING(RemovingTrack); @@ -448,7 +449,7 @@ class CfgVehicles { class Offroad_02_base_F: Car_F { class EGVAR(interaction,anims) { class hideSpareWheel { - selections[] = {"spare_wheel"}; + positions[] = {"_target selectionPosition ['spare_wheel', 'ViewGeometry', 'AveragePoint']"}; items[] = {"ACE_Wheel"}; name = CSTRING(RemoveWheel); text = CSTRING(RemovingWheel); @@ -505,7 +506,7 @@ class CfgVehicles { class Van_02_base_F: Truck_F { class EGVAR(interaction,anims) { class spare_tyre_hide { - positions[] = {"[[-1.2, -3.7, -0.4], [-0.45, -3.5, -0.4]] select (_target animationPhase 'Door_4_source' == 0)"}; + positions[] = {"_target selectionPosition ['spare_tyre', 'ViewGeometry', 'AveragePoint']"}; items[] = {"ACE_Wheel"}; name = CSTRING(RemoveWheel); text = CSTRING(RemovingWheel); From 52c19d53af9fbdcbd56eac528eedbefe40c78488 Mon Sep 17 00:00:00 2001 From: Mike-MF Date: Tue, 20 Aug 2024 23:24:58 +0100 Subject: [PATCH 08/26] Magazine Repack - Add ability to disable repacking via class (#10232) * Magazine Repack - Add ability to disable repacking via class * Update addons/magazinerepack/functions/fnc_getMagazineChildren.sqf Co-authored-by: PabstMirror * Bretts suggestion * Documentation * Apply suggestions from code review Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> * Review missed a line * Fix getting number instead of config & microoptimisation --------- Co-authored-by: PabstMirror Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- .../functions/fnc_canRepackMagazine.sqf | 3 +++ .../functions/fnc_getMagazineChildren.sqf | 10 ++++--- .../framework/magazine-repack-framework.md | 26 +++++++++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 docs/wiki/framework/magazine-repack-framework.md diff --git a/addons/magazinerepack/functions/fnc_canRepackMagazine.sqf b/addons/magazinerepack/functions/fnc_canRepackMagazine.sqf index d6d8f3b827..2c32ec5727 100644 --- a/addons/magazinerepack/functions/fnc_canRepackMagazine.sqf +++ b/addons/magazinerepack/functions/fnc_canRepackMagazine.sqf @@ -18,6 +18,9 @@ params ["_unit", "_magazine"]; +// Exit if repack is disabled for this magazine. +if (getNumber (configFile >> "CfgMagazines" >> _magazine >> "ace_disableRepacking") == 1) exitWith {false}; + private _maxAmmoCount = getNumber (configFile >> "CfgMagazines" >> _magazine >> "count"); { diff --git a/addons/magazinerepack/functions/fnc_getMagazineChildren.sqf b/addons/magazinerepack/functions/fnc_getMagazineChildren.sqf index b4cf8b16ef..09d6974fef 100644 --- a/addons/magazinerepack/functions/fnc_getMagazineChildren.sqf +++ b/addons/magazinerepack/functions/fnc_getMagazineChildren.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: PabstMirror, commy2, esteldunedain, Ruthberg - * Gets magazine children for interaciton menu. + * Gets magazine children for interaction menu. * * Arguments: * 0: Target @@ -18,16 +18,20 @@ params ["_target", "_player"]; +private _cfgMagazines = configFile >> "CfgMagazines"; + // get all mags and ammo count private _unitMagazines = []; private _unitMagCounts = []; { _x params ["_xClassname", "_xCount", "_xLoaded", "_xType"]; - private _xFullMagazineCount = getNumber (configFile >> "CfgMagazines" >> _xClassname >> "count"); + private _configMagazine = _cfgMagazines >> _xClassname; + private _xFullMagazineCount = getNumber (_configMagazine >> "count"); + private _isRepackDisabled = getNumber (_configMagazine >> "ace_disableRepacking") == 1; //for every partial magazine, that is either in inventory or can be moved there - if ((_xCount < _xFullMagazineCount) && {_xCount > 0} && {(!_xLoaded) || {GVAR(repackLoadedMagazines) && {[_player, _xClassname] call CBA_fnc_canAddItem}}}) then { + if ((!_isRepackDisabled) && {_xCount < _xFullMagazineCount} && {_xCount > 0} && {(!_xLoaded) || {GVAR(repackLoadedMagazines) && {[_player, _xClassname] call CBA_fnc_canAddItem}}}) then { private _index = _unitMagazines find _xClassname; if (_index == -1) then { _unitMagazines pushBack _xClassname; diff --git a/docs/wiki/framework/magazine-repack-framework.md b/docs/wiki/framework/magazine-repack-framework.md new file mode 100644 index 0000000000..b14272227e --- /dev/null +++ b/docs/wiki/framework/magazine-repack-framework.md @@ -0,0 +1,26 @@ +--- +layout: wiki +title: Magazine Repack Framework +description: Explains how to disable repacking. +group: framework +order: 5 +parent: wiki +mod: ace +version: + major: 3 + minor: 18 + patch: 0 +--- + +## 1. Config Values + +### 1.1 Disable Magazine Repacking + +```cpp +class CfgMagazines { + class MyMagazine { + // Disables the ability to repack this magazine + ace_disableRepacking = 1; + }; +}; +``` From ffba6120112d49fa1206a45856e77cb0e0aee425 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Wed, 21 Aug 2024 00:27:28 +0200 Subject: [PATCH 09/26] Interaction - Add distance to interaction anims (#10233) --- addons/interaction/CfgVehicles.hpp | 6 +----- addons/interaction/functions/fnc_initAnimActions.sqf | 10 ++++++++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/addons/interaction/CfgVehicles.hpp b/addons/interaction/CfgVehicles.hpp index e3663cdee8..b178ed3050 100644 --- a/addons/interaction/CfgVehicles.hpp +++ b/addons/interaction/CfgVehicles.hpp @@ -420,15 +420,11 @@ class CfgVehicles { class GVAR(anims) { class showBags { phase = 0; - // Rotate interactions with turret rotation - positions[] = { - "[0, -1.6, 0] vectorAdd ([[1, -1, 0.1], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)", - "[0, -1.6, 0] vectorAdd ([[-1, -1, 0.1], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)" - }; selections[] = {"vhc_bags"}; items[] = {"B_Carryall_cbr", "B_Carryall_cbr"}; name = "$STR_a3_cfgvehicleclasses_backpacks0"; text = "$STR_a3_cfgvehicleclasses_backpacks0"; + distance = 3; }; }; }; diff --git a/addons/interaction/functions/fnc_initAnimActions.sqf b/addons/interaction/functions/fnc_initAnimActions.sqf index 673946a2e1..fcd183cd75 100644 --- a/addons/interaction/functions/fnc_initAnimActions.sqf +++ b/addons/interaction/functions/fnc_initAnimActions.sqf @@ -180,13 +180,19 @@ private _config = configOf _object; private _icon = [_animConfig >> "icon", "TEXT", "\A3\ui_f\data\igui\cfg\actions\take_ca.paa"] call CBA_fnc_getConfigEntry; private _duration = [_animConfig >> "duration", "NUMBER", 10] call CBA_fnc_getConfigEntry; private _text = getText (_animConfig >> "text"); + private _distance = [_animConfig >> "distance", "NUMBER", 2] call CBA_fnc_getConfigEntry; { private _action = [ format [QGVAR(anim_%1_%2), _anim, _forEachIndex], - _name, _icon, _statement, _condition, {}, + _name, + _icon, + _statement, + _condition, + {}, [_anim, _phase, _duration, _text], - _x + _x, + _distance ] call EFUNC(interact_menu,createAction); [_class, 0, [], _action] call EFUNC(interact_menu,addActionToClass); TRACE_3("add anim",_class,_anim,_x); From b2091f0e4d7f75d3694d6ed16fa106923f333745 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Thu, 22 Aug 2024 02:55:42 +0200 Subject: [PATCH 10/26] RHS Compats - Improve some locations for interaction anims (#10235) --- .../compat_rhs_afrf3_repair/CfgVehicles.hpp | 14 +++++++------- .../compat_rhs_usf3_repair/CfgVehicles.hpp | 13 +++++++------ 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_repair/CfgVehicles.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_repair/CfgVehicles.hpp index 1acd977b99..6cd2237a6f 100644 --- a/addons/compat_rhs_afrf3/compat_rhs_afrf3_repair/CfgVehicles.hpp +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_repair/CfgVehicles.hpp @@ -43,7 +43,7 @@ class CfgVehicles { class rhs_truck: Truck_F { class EGVAR(interaction,anims) { class spare_hide { - selections[] = {"spare"}; + positions[] = {"_target selectionPosition ['spare', 'ViewGeometry', 'AveragePoint']"}; items[] = {"ACE_Wheel"}; name = ECSTRING(repair,RemoveWheel); text = ECSTRING(repair,RemovingWheel); @@ -54,7 +54,7 @@ class CfgVehicles { class RHS_Ural_BaseTurret: Truck_F { class EGVAR(interaction,anims) { class spare_hide { - selections[] = {"spare"}; + positions[] = {"_target selectionPosition ['spare', 'ViewGeometry', 'AveragePoint']"}; items[] = {"ACE_Wheel"}; name = ECSTRING(repair,RemoveWheel); text = ECSTRING(repair,RemovingWheel); @@ -65,7 +65,7 @@ class CfgVehicles { class rhs_zil131_base: Truck_F { class EGVAR(interaction,anims) { class spare_hide { - selections[] = {"spare"}; + positions[] = {"_target selectionPosition ['spare', 'ViewGeometry', 'AveragePoint']"}; items[] = {"ACE_Wheel"}; name = ECSTRING(repair,RemoveWheel); text = ECSTRING(repair,RemovingWheel); @@ -77,7 +77,7 @@ class CfgVehicles { class rhs_kraz255b1_base: rhs_kraz255_base { class EGVAR(interaction,anims) { class spare_hide { - selections[] = {"spare"}; + positions[] = {"_target selectionPosition ['spare', 'FireGeometry', 'AveragePoint']"}; items[] = {"ACE_Wheel"}; name = ECSTRING(repair,RemoveWheel); text = ECSTRING(repair,RemovingWheel); @@ -89,7 +89,7 @@ class CfgVehicles { class rhs_kamaz5350: O_Truck_02_covered_F { class EGVAR(interaction,anims) { class spare_hide { - selections[] = {"spare"}; + positions[] = {"_target selectionPosition ['spare', 'FireGeometry', 'AveragePoint']"}; items[] = {"ACE_Wheel"}; name = ECSTRING(repair,RemoveWheel); text = ECSTRING(repair,RemovingWheel); @@ -101,7 +101,7 @@ class CfgVehicles { class rhs_tigr_base: MRAP_02_base_F { class EGVAR(interaction,anims) { class spare_hide { - selections[] = {"spare"}; + positions[] = {"_target selectionPosition ['spare', 'ViewGeometry', 'AveragePoint']"}; items[] = {"ACE_Wheel"}; name = ECSTRING(repair,RemoveWheel); text = ECSTRING(repair,RemovingWheel); @@ -113,7 +113,7 @@ class CfgVehicles { class RHS_UAZ_Base: Offroad_01_base_f { class EGVAR(interaction,anims) { class spare_hide { - selections[] = {"spare"}; + positions[] = {"_target selectionPosition ['spare', 'ViewGeometry', 'AveragePoint']"}; items[] = {"ACE_Wheel"}; name = ECSTRING(repair,RemoveWheel); text = ECSTRING(repair,RemovingWheel); diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_repair/CfgVehicles.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_repair/CfgVehicles.hpp index 26341db1da..91bed1dc5a 100644 --- a/addons/compat_rhs_usf3/compat_rhs_usf3_repair/CfgVehicles.hpp +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_repair/CfgVehicles.hpp @@ -60,10 +60,11 @@ class CfgVehicles { class rhsusf_HEMTT_A4_base: Truck_01_base_F { class EGVAR(interaction,anims) { class hide_spare { - positions[] = {"_target selectionPosition 'sparewheel' vectorAdd [0.6, 0.6, -0.4]"}; + positions[] = {"_target selectionPosition ['sparewheel', 'FireGeometry', 'AveragePoint']"}; items[] = {"ACE_Wheel"}; name = ECSTRING(repair,RemoveWheel); text = ECSTRING(repair,RemovingWheel); + distance = 2.5; }; }; }; @@ -72,7 +73,7 @@ class CfgVehicles { class rhsusf_m1151_base: MRAP_01_base_F { class EGVAR(interaction,anims) { class hide_spare { - positions[] = {"_target selectionPosition 'sparewheel' vectorAdd [-0.465, 0, 0]"}; + positions[] = {"_target selectionPosition ['sparewheel', 'FireGeometry', 'AveragePoint']"}; items[] = {"ACE_Wheel"}; name = ECSTRING(repair,RemoveWheel); text = ECSTRING(repair,RemovingWheel); @@ -83,7 +84,7 @@ class CfgVehicles { class rhsusf_M1165A1_GMV_SAG2_base: rhsusf_m1151_base { class EGVAR(interaction,anims) { class hide_spare { - positions[] = {"_target selectionPosition 'sparewheel_gmv' vectorAdd [0, -0.44, 0]"}; + positions[] = {"_target selectionPosition ['sparewheel_gmv', 'Geometry', 'AveragePoint']"}; items[] = {"ACE_Wheel"}; name = ECSTRING(repair,RemoveWheel); text = ECSTRING(repair,RemovingWheel); @@ -94,7 +95,7 @@ class CfgVehicles { class rhsusf_rg33_base: MRAP_01_base_F { class EGVAR(interaction,anims) { class hide_spare { - selections[] = {"sparewheel"}; + positions[] = {"_target selectionPosition ['sparewheel', 'FireGeometry', 'AveragePoint']"}; items[] = {"ACE_Wheel"}; name = ECSTRING(repair,RemoveWheel); text = ECSTRING(repair,RemovingWheel); @@ -105,7 +106,7 @@ class CfgVehicles { class rhsusf_M1239_base: MRAP_01_base_F { class EGVAR(interaction,anims) { class hide_spare { - selections[] = {"sparewheel"}; + positions[] = {"_target selectionPosition ['sparewheel', 'FireGeometry', 'AveragePoint']"}; items[] = {"ACE_Wheel"}; name = ECSTRING(repair,RemoveWheel); text = ECSTRING(repair,RemovingWheel); @@ -116,7 +117,7 @@ class CfgVehicles { class rhsusf_MATV_base: MRAP_01_base_F { class EGVAR(interaction,anims) { class hide_spare { - selections[] = {"sparewheel"}; + positions[] = {"_target selectionPosition ['sparewheel', 'Geometry', 'AveragePoint']"}; items[] = {"ACE_Wheel"}; name = ECSTRING(repair,RemoveWheel); text = ECSTRING(repair,RemovingWheel); From abced51bb0659e9f593edbf503b9cf5ade715ad0 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Thu, 22 Aug 2024 02:56:30 +0200 Subject: [PATCH 11/26] WS Compat - Add interaction anims to WS vehicles (#10229) --- addons/compat_ws/CfgVehicles.hpp | 45 +++++++++++++++++++ .../compat_ws_repair/CfgVehicles.hpp | 34 ++++++++++++++ addons/compat_ws/compat_ws_repair/config.cpp | 20 +++++++++ .../compat_ws_repair/script_component.hpp | 3 ++ addons/compat_ws/config.cpp | 3 +- 5 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 addons/compat_ws/CfgVehicles.hpp create mode 100644 addons/compat_ws/compat_ws_repair/CfgVehicles.hpp create mode 100644 addons/compat_ws/compat_ws_repair/config.cpp create mode 100644 addons/compat_ws/compat_ws_repair/script_component.hpp diff --git a/addons/compat_ws/CfgVehicles.hpp b/addons/compat_ws/CfgVehicles.hpp new file mode 100644 index 0000000000..9c2f3184c0 --- /dev/null +++ b/addons/compat_ws/CfgVehicles.hpp @@ -0,0 +1,45 @@ +class CfgVehicles { + // Vehicle animation interactions + class Offroad_01_base_lxWS; + class Offroad_01_armor_base_lxWS: Offroad_01_base_lxWS { + class EGVAR(interaction,anims) { + class HideBackpacks { + positions[] = {{-1.15, -1.15, -0.7}, {1.1, -1.15, -0.7}, {1.1, -2.5, -0.7}}; + items[] = {"B_TacticalPack_blk", "B_TacticalPack_blk", "B_Carryall_khk", "B_Carryall_khk"}; + name = "$STR_a3_cfgvehicleclasses_backpacks0"; + text = "$STR_a3_cfgvehicleclasses_backpacks0"; + }; + }; + }; + + class I_G_Offroad_01_AT_F; + class Offroad_01_AT_lxWS: I_G_Offroad_01_AT_F { + class EGVAR(interaction,anims) { + class HideBackpacks { + positions[] = {{-1.15, -1.25, -0.2}, {1.1, -1.25, -0.2}, {1.1, -2.6, -0.2}}; + items[] = {"B_TacticalPack_blk", "B_TacticalPack_blk", "B_Carryall_khk", "B_Carryall_khk"}; + name = "$STR_a3_cfgvehicleclasses_backpacks0"; + text = "$STR_a3_cfgvehicleclasses_backpacks0"; + }; + }; + }; + class Offroad_01_armor_AT_lxWS: Offroad_01_AT_lxWS { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class HideBackpacks: HideBackpacks { + positions[] = {{-1.15, -1.25, -0.7}, {1.1, -1.25, -0.7}, {1.1, -2.6, -0.7}}; + }; + }; + }; + + class I_G_Offroad_01_armed_F; + class Offroad_01_armed_lxWS: I_G_Offroad_01_armed_F { + class EGVAR(interaction,anims) { + class HideBackpacks { + positions[] = {{-1.15, -1.03, -0.8}, {1.1, -1.03, -0.8}, {1.1, -2.38, -0.8}}; + items[] = {"B_TacticalPack_blk", "B_TacticalPack_blk", "B_Carryall_khk", "B_Carryall_khk"}; + name = "$STR_a3_cfgvehicleclasses_backpacks0"; + text = "$STR_a3_cfgvehicleclasses_backpacks0"; + }; + }; + }; +}; diff --git a/addons/compat_ws/compat_ws_repair/CfgVehicles.hpp b/addons/compat_ws/compat_ws_repair/CfgVehicles.hpp new file mode 100644 index 0000000000..d7fcbc7cd9 --- /dev/null +++ b/addons/compat_ws/compat_ws_repair/CfgVehicles.hpp @@ -0,0 +1,34 @@ +class CfgVehicles { + // Vehicle animation interactions + class Truck_02_base_F; + class Truck_02_aa_base_lxWS: Truck_02_base_F { + class EGVAR(interaction,anims) { + class hideSpareWheel { + positions[] = {{1, 1.93, -0.85}}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + class Truck_02_cargo_base_lxWS: Truck_02_base_F { + class EGVAR(interaction,anims) { + class hideSpareWheel { + positions[] = {{1, 1.93, -0.35}}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + class Truck_02_box_base_lxWS: Truck_02_base_F { + class EGVAR(interaction,anims) { + class hideSpareWheel { + positions[] = {{1, 1.7, -0.35}}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; +}; diff --git a/addons/compat_ws/compat_ws_repair/config.cpp b/addons/compat_ws/compat_ws_repair/config.cpp new file mode 100644 index 0000000000..4f37c831cb --- /dev/null +++ b/addons/compat_ws/compat_ws_repair/config.cpp @@ -0,0 +1,20 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"data_f_lxWS_Loadorder", "ace_repair"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_ws/compat_ws_repair/script_component.hpp b/addons/compat_ws/compat_ws_repair/script_component.hpp new file mode 100644 index 0000000000..1af928486c --- /dev/null +++ b/addons/compat_ws/compat_ws_repair/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT repair +#define SUBCOMPONENT_BEAUTIFIED Repair +#include "..\script_component.hpp" diff --git a/addons/compat_ws/config.cpp b/addons/compat_ws/config.cpp index 32a3f6f73c..54a6df99ee 100644 --- a/addons/compat_ws/config.cpp +++ b/addons/compat_ws/config.cpp @@ -6,7 +6,7 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"data_f_lxWS_Loadorder"}; + requiredAddons[] = {"data_f_lxWS_Loadorder", "ace_common"}; skipWhenMissingDependencies = 1; author = ECSTRING(common,ACETeam); authors[] = {"Mike"}; @@ -15,4 +15,5 @@ class CfgPatches { }; }; +#include "CfgVehicles.hpp" #include "CfgWeapons.hpp" From e798050a002a5df91302cde87bd7534d5484c2a3 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Thu, 22 Aug 2024 02:57:30 +0200 Subject: [PATCH 12/26] SOG Compat - Add interaction anims to SOG vehicles (#10223) --- addons/compat_sog/CfgVehicles/tracked.hpp | 56 ++++- .../compat_sog_refuel/CfgVehicles.hpp | 163 +++++++++++++++ .../compat_sog/compat_sog_refuel/config.cpp | 18 ++ .../compat_sog_refuel/script_component.hpp | 3 + .../compat_sog_repair/CfgVehicles.hpp | 141 +++++++++++++ .../compat_sog/compat_sog_repair/config.cpp | 18 ++ .../compat_sog_repair/script_component.hpp | 3 + .../compat_sog_trenches/CfgVehicles.hpp | 195 ++++++++++++++++++ 8 files changed, 590 insertions(+), 7 deletions(-) create mode 100644 addons/compat_sog/compat_sog_refuel/CfgVehicles.hpp create mode 100644 addons/compat_sog/compat_sog_refuel/config.cpp create mode 100644 addons/compat_sog/compat_sog_refuel/script_component.hpp create mode 100644 addons/compat_sog/compat_sog_repair/CfgVehicles.hpp create mode 100644 addons/compat_sog/compat_sog_repair/config.cpp create mode 100644 addons/compat_sog/compat_sog_repair/script_component.hpp diff --git a/addons/compat_sog/CfgVehicles/tracked.hpp b/addons/compat_sog/CfgVehicles/tracked.hpp index e2832796a9..7adc0193c6 100644 --- a/addons/compat_sog/CfgVehicles/tracked.hpp +++ b/addons/compat_sog/CfgVehicles/tracked.hpp @@ -1,18 +1,55 @@ +// M113A1 https://man.fas.org/dod-101/sys/land/m113.htm +class Tank_F; +class APC_Tracked_01_base_F: Tank_F { + class ACE_Actions; +}; +class vn_armor_m113_base: APC_Tracked_01_base_F { + EGVAR(refuel,fuelCapacity) = 360; + class ACE_Actions: ACE_Actions { + class ACE_MainActions; + }; +}; +class vn_armor_m577_base: vn_armor_m113_base { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0, 3.5, -1]"; + }; + }; +}; + // M41 class vn_armor_tank_base; class vn_armor_m41_base: vn_armor_tank_base { EGVAR(refuel,fuelCapacity) = 530; }; -// Type 63 -class vn_armor_type63_base: vn_armor_tank_base { - EGVAR(refuel,fuelCapacity) = 545; +// M48 +class vn_armor_m48_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_mainturret_backpacks { + // Rotate interactions with turret rotation + positions[] = { + "[[-1.3, -0.7, -0.4], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D", + "[[0.1, -2, -0.2], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D" + }; + items[] = {"vn_b_pack_02_02", "vn_b_pack_04_02"}; + name = "$STR_a3_cfgvehicleclasses_backpacks0"; + text = "$STR_a3_cfgvehicleclasses_backpacks0"; + }; + }; }; -// M113A1 https://man.fas.org/dod-101/sys/land/m113.htm -class APC_Tracked_01_base_F; -class vn_armor_m113_base: APC_Tracked_01_base_F { - EGVAR(refuel,fuelCapacity) = 360; +// T-54 +class vn_armor_t54_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_mainturret_backpacks { + // Rotate interactions with turret rotation + positions[] = {"[0, -0.2, 0] vectorAdd ([[-1.1, -0.85, -1.3], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)"}; + items[] = {"vn_o_pack_01", "vn_o_pack_02"}; + name = "$STR_a3_cfgvehicleclasses_backpacks0"; + text = "$STR_a3_cfgvehicleclasses_backpacks0"; + }; + }; }; // PT-76A https://en.wikipedia.org/wiki/PT-76 @@ -24,3 +61,8 @@ class vn_armor_pt76_base: vn_armor_tank_base { class vn_armor_pt76b_base: vn_armor_pt76_base { EGVAR(refuel,fuelCapacity) = 400; }; + +// Type 63 +class vn_armor_type63_base: vn_armor_tank_base { + EGVAR(refuel,fuelCapacity) = 545; +}; diff --git a/addons/compat_sog/compat_sog_refuel/CfgVehicles.hpp b/addons/compat_sog/compat_sog_refuel/CfgVehicles.hpp new file mode 100644 index 0000000000..c3dcfb719e --- /dev/null +++ b/addons/compat_sog/compat_sog_refuel/CfgVehicles.hpp @@ -0,0 +1,163 @@ +class CfgVehicles { + // Vehicle animation interactions + // BTR-40 + class vn_wheeled_car_base; + class vn_wheeled_btr40_base: vn_wheeled_car_base { + class EGVAR(interaction,anims) { + class refuel_can_hide { + positions[] = {{0.7, -2.35, -0.9}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + class vn_wheeled_btr40_01_base: vn_wheeled_btr40_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class refuel_can_hide: refuel_can_hide { + positions[] = {{0.72, -2.35, -0.45}}; + }; + }; + }; + class vn_wheeled_btr40_ambulance_base: vn_wheeled_btr40_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class refuel_can_hide: refuel_can_hide { + positions[] = {{0.72, -2.35, -0.45}}; + }; + }; + }; + class vn_wheeled_btr40_mg_01_base: vn_wheeled_btr40_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class refuel_can_hide: refuel_can_hide { + positions[] = {{0.72, -2.35, -0.9}}; + }; + }; + }; + class vn_wheeled_btr40_mg_03_base: vn_wheeled_btr40_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class refuel_can_hide: refuel_can_hide { + positions[] = {{0.82, -2.35, -1.25}}; + }; + }; + }; + class vn_wheeled_btr40_mg_04_base: vn_wheeled_btr40_mg_01_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class refuel_can_hide: refuel_can_hide { + positions[] = {{0.72, -2.35, -1}}; + }; + }; + }; + class vn_wheeled_btr40_mg_05_base: vn_wheeled_btr40_mg_04_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class refuel_can_hide: refuel_can_hide { + positions[] = {{0.65, -2.25, -1}}; + }; + }; + }; + + // M151 + class vn_wheeled_m151_base: vn_wheeled_car_base { + class EGVAR(interaction,anims) { + class user_refuel_can_hide { + positions[] = {{-0.48, -1.5, -1.1}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + class vn_wheeled_m151_mg_03_base: vn_wheeled_m151_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class user_refuel_can_hide: user_refuel_can_hide { + positions[] = {{-0.75, -1.5, -1}}; + }; + }; + }; + class vn_wheeled_m151_mg_05_base: vn_wheeled_m151_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class user_refuel_can_hide: user_refuel_can_hide { + positions[] = {{0.9, -0.1, -1.1}}; + }; + }; + }; + class vn_wheeled_m151_mg_06_base: vn_wheeled_m151_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class user_refuel_can_hide: user_refuel_can_hide { + positions[] = {{0.3, 0.1, -1.1}}; + }; + }; + }; + class vn_wheeled_m151_01_base: vn_wheeled_m151_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class user_refuel_can_hide: user_refuel_can_hide { + positions[] = {{-0.4, -1.5, -0.7}}; + }; + }; + }; + + // M577 + class vn_armor_m113_base; + class vn_armor_m577_base: vn_armor_m113_base { + class EGVAR(interaction,anims) { + class hide_fuel_cans { + selections[] = {"hide_fuel_cans"}; + positions[] = {{1.07, 1.05, -1}}; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + + // M48 + class vn_armor_tank_base; + class vn_armor_m48_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_mainturret_jerrycan { + positions[] = {"_target selectionPosition ['hide_jerrycan', 'FireGeometry', 'AveragePoint']"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + + // BTR-50PK + class vn_armor_btr50pk_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_barrels { + selections[] = {"hide_barrels"}; + positions[] = {"private _pos = _target selectionPosition 'hide_barrels'; _pos set [0, -(_pos select 0)]; _pos"}; // Mirror position to other side of vehicle + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + + // PT-76 + class vn_armor_pt76_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_barrels { + selections[] = {"hide_barrels"}; + positions[] = {"private _pos = _target selectionPosition 'hide_barrels'; _pos set [0, -(_pos select 0)]; _pos"}; // Mirror position to other side of vehicle + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + + // Type 63 + class vn_armor_type63_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_barrels { + selections[] = {"hide_barrels"}; + positions[] = {"private _pos = _target selectionPosition 'hide_barrels'; _pos set [0, -(_pos select 0)]; _pos"}; // Mirror position to other side of vehicle + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; +}; diff --git a/addons/compat_sog/compat_sog_refuel/config.cpp b/addons/compat_sog/compat_sog_refuel/config.cpp new file mode 100644 index 0000000000..793cf90fc4 --- /dev/null +++ b/addons/compat_sog/compat_sog_refuel/config.cpp @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"loadorder_f_vietnam", "ace_refuel"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_sog/compat_sog_refuel/script_component.hpp b/addons/compat_sog/compat_sog_refuel/script_component.hpp new file mode 100644 index 0000000000..af997fb8d4 --- /dev/null +++ b/addons/compat_sog/compat_sog_refuel/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT refuel +#define SUBCOMPONENT_BEAUTIFIED refuel +#include "..\script_component.hpp" diff --git a/addons/compat_sog/compat_sog_repair/CfgVehicles.hpp b/addons/compat_sog/compat_sog_repair/CfgVehicles.hpp new file mode 100644 index 0000000000..de93243251 --- /dev/null +++ b/addons/compat_sog/compat_sog_repair/CfgVehicles.hpp @@ -0,0 +1,141 @@ +class CfgVehicles { + // Vehicle animation interactions + // M39 / M54 / M49 + class vn_wheeled_truck_base; + class vn_wheeled_m54_base: vn_wheeled_truck_base { + class EGVAR(interaction,anims) { + class user_sparewheel_hide { + positions[] = {"_target selectionPosition ['hide_spare_wheel', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + class vn_wheeled_m54_mg_01_base: vn_wheeled_m54_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class user_sparewheel_hide: user_sparewheel_hide { + items[] = {"ACE_Wheel", "ACE_Wheel", "ACE_Wheel", "ACE_Wheel"}; + }; + }; + }; + + // M151 + class vn_wheeled_car_base; + class vn_wheeled_m151_base: vn_wheeled_car_base { + class EGVAR(interaction,anims) { + class user_sparewheel_hide { + positions[] = {"_target selectionPosition ['hide_sparewheel', 'ViewGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + // Dirt Ranger + class vn_wheeled_lr2a_base: vn_wheeled_car_base { + class EGVAR(interaction,anims) { + class hide_sparewheel { + positions[] = {"_target selectionPosition ['hide_sparewheel', 'ViewGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + // BTR-40 + class vn_wheeled_btr40_base: vn_wheeled_car_base { + class EGVAR(interaction,anims) { + class sparewheel_hide { + positions[] = {"_target selectionPosition ['hide_sparewheel', 'ViewGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + // M48 + class vn_armor_tank_base; + class vn_armor_m48_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_mainturret_tracks { + // Rotate interactions with turret rotation + positions[] = { + "[[1.3, 0.2, -0.5], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D", + "[[-1.3, 0.2, -0.5], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D" + }; + items[] = {"ACE_Track", "ACE_Track", "ACE_Track", "ACE_Track", "ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + }; + }; + + // BTR-50PK + class vn_armor_btr50pk_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_tracks { + positions[] = {{1.35, 2.5, -0.5}}; + items[] = {"ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + }; + }; + class vn_armor_btr50pk_01_base: vn_armor_btr50pk_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tracks: hide_tracks { + positions[] = {{1.35, 2.5, -0.8}}; + }; + }; + }; + + class vn_armor_btr50pk_02_base: vn_armor_btr50pk_01_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tracks: hide_tracks { + positions[] = {{1.35, 2.9, -0.8}}; + }; + }; + }; + + // T-54 + class vn_armor_t54_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_tracks { + positions[] = {{1.4, 2.1, -1.7}}; + items[] = {"ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + }; + }; + + // PT-76 + class vn_armor_pt76_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_tracks { + // Rotate interactions with turret rotation + positions[] = {"[0, 0.9, 0] vectorAdd ([[-0.6, -0.9, -0.3], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)"}; + items[] = {"ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + }; + }; + + // Type 63 + class vn_armor_type63_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_tracks { + // Rotate interactions with turret rotation + positions[] = {"[0, 0.7, 0] vectorAdd ([[0.4, -1.1, -0.4], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)"}; + items[] = {"ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + }; + }; +}; diff --git a/addons/compat_sog/compat_sog_repair/config.cpp b/addons/compat_sog/compat_sog_repair/config.cpp new file mode 100644 index 0000000000..b2cffd8a36 --- /dev/null +++ b/addons/compat_sog/compat_sog_repair/config.cpp @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"loadorder_f_vietnam", "ace_repair"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_sog/compat_sog_repair/script_component.hpp b/addons/compat_sog/compat_sog_repair/script_component.hpp new file mode 100644 index 0000000000..1af928486c --- /dev/null +++ b/addons/compat_sog/compat_sog_repair/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT repair +#define SUBCOMPONENT_BEAUTIFIED Repair +#include "..\script_component.hpp" diff --git a/addons/compat_sog/compat_sog_trenches/CfgVehicles.hpp b/addons/compat_sog/compat_sog_trenches/CfgVehicles.hpp index bb222eaed1..3a826d0139 100644 --- a/addons/compat_sog/compat_sog_trenches/CfgVehicles.hpp +++ b/addons/compat_sog/compat_sog_trenches/CfgVehicles.hpp @@ -60,4 +60,199 @@ class CfgVehicles { class EGVAR(compat_sog,spiderhole_03_nogeo): vn_o_vc_spiderhole_03 { scope = 1; }; + + // Vehicle animation interactions + // BTR-40 + class vn_wheeled_car_base; + class vn_wheeled_btr40_base: vn_wheeled_car_base { + class EGVAR(interaction,anims) { + class shovel_hide { + positions[] = {{0.95, -1.5, -0.75}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + class vn_wheeled_btr40_01_base: vn_wheeled_btr40_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class shovel_hide: shovel_hide { + positions[] = {{0.95, -1.5, -0.3}}; + }; + }; + }; + class vn_wheeled_btr40_ambulance_base: vn_wheeled_btr40_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class shovel_hide: shovel_hide { + positions[] = {{0.95, -1.5, -0.3}}; + }; + }; + }; + class vn_wheeled_btr40_mg_01_base: vn_wheeled_btr40_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class shovel_hide: shovel_hide { + positions[] = {{0.95, -1.5, -0.8}}; + }; + }; + }; + class vn_wheeled_btr40_mg_03_base: vn_wheeled_btr40_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class shovel_hide: shovel_hide { + positions[] = {{1.05, -1.55, -1.1}}; + }; + }; + }; + class vn_wheeled_btr40_mg_04_base: vn_wheeled_btr40_mg_01_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class shovel_hide: shovel_hide { + positions[] = {{0.95, -1.5, -0.85}}; + }; + }; + }; + class vn_wheeled_btr40_mg_05_base: vn_wheeled_btr40_mg_04_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class shovel_hide: shovel_hide { + positions[] = {{0.9, -1.4, -0.85}}; + }; + }; + }; + + // Dirt Ranger + class vn_wheeled_lr2a_base: vn_wheeled_car_base { + class EGVAR(interaction,anims) { + class hide_shovel { + positions[] = {"_target selectionPosition ['hide_shovel', 'ViewGeometry', 'AveragePoint']"}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + + // M151 + class vn_wheeled_m151_base: vn_wheeled_car_base { + class EGVAR(interaction,anims) { + class user_shovel_hide { + positions[] = {{0.65, 0.2, -1.4}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + class vn_wheeled_m151_mg_03_base: vn_wheeled_m151_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class user_shovel_hide: user_shovel_hide { + positions[] = {{0.35, 0.2, -1.27}}; + }; + }; + }; + class vn_wheeled_m151_mg_05_base: vn_wheeled_m151_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class user_shovel_hide: user_shovel_hide { + enabled = 0; + }; + }; + }; + class vn_wheeled_m151_mg_06_base: vn_wheeled_m151_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class user_shovel_hide: user_shovel_hide { + enabled = 0; + }; + }; + }; + class vn_wheeled_m151_01_base: vn_wheeled_m151_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class user_shovel_hide: user_shovel_hide { + positions[] = {{0.72, 0.2, -0.92}}; + }; + }; + }; + + // M113 + class APC_Tracked_01_base_F; + class vn_armor_m113_base: APC_Tracked_01_base_F { + class EGVAR(interaction,anims) { + class hide_shovel { + positions[] = {{0.2, 2.2, -0.5}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + class vn_armor_m113_01_base: vn_armor_m113_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_shovel: hide_shovel {}; + }; + }; + class vn_armor_m132_base: vn_armor_m113_01_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_shovel: hide_shovel { + positions[] = {{0.2, 2.2, -0.35}}; + }; + }; + }; + + // Don't inherit, as it's easier for the refuel compat + // M577 + class vn_armor_m577_base: vn_armor_m113_base { + class EGVAR(interaction,anims) { + class hide_shovel { + positions[] = {{0.2, 5.05, -0.57}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + + // M48 + class vn_armor_tank_base; + class vn_armor_m48_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_mainturret_tools { + positions[] = {"_target selectionPosition ['hide_tools', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + + // BTR-50PK + class vn_armor_btr50pk_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_shovel { + positions[] = {"_target selectionPosition ['hide_shovel', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_EntrenchingTool", "ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + + // PT-76 + class vn_armor_pt76_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_shovel { + positions[] = {"_target selectionPosition ['hide_shovel', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + + // Type 63 + class vn_armor_type63_base: vn_armor_tank_base { + class EGVAR(interaction,anims) { + class hide_shovel { + positions[] = {"_target selectionPosition ['hide_shovel', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; }; From b4700aeffcb3874fcf7099aa2fdcb4189d3488b6 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Wed, 21 Aug 2024 20:13:29 -0500 Subject: [PATCH 13/26] Interaction - Add action to drop distant units from group (#10228) Co-authored-by: Dystopian Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com> --- addons/interaction/CfgVehicles.hpp | 6 +++++ addons/interaction/XEH_PREP.hpp | 2 ++ .../fnc_canGroupDropDistantUnits.sqf | 20 +++++++++++++++ .../functions/fnc_groupDropDistantUnits.sqf | 25 +++++++++++++++++++ addons/interaction/stringtable.xml | 3 +++ 5 files changed, 56 insertions(+) create mode 100644 addons/interaction/functions/fnc_canGroupDropDistantUnits.sqf create mode 100644 addons/interaction/functions/fnc_groupDropDistantUnits.sqf diff --git a/addons/interaction/CfgVehicles.hpp b/addons/interaction/CfgVehicles.hpp index b178ed3050..8671ecf9ce 100644 --- a/addons/interaction/CfgVehicles.hpp +++ b/addons/interaction/CfgVehicles.hpp @@ -316,6 +316,12 @@ class CfgVehicles { statement = QUOTE(_player call FUNC(renameGroupUI)); showDisabled =1; }; + class ACE_groupDropDistantUnits { + displayName = CSTRING(groupDropDistantUnits); + condition = QUOTE(call FUNC(canGroupDropDistantUnits)); + exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting", "isNotOnLadder", "isNotRefueling"}; + statement = QUOTE(call FUNC(groupDropDistantUnits)); + }; }; class ACE_Equipment { diff --git a/addons/interaction/XEH_PREP.hpp b/addons/interaction/XEH_PREP.hpp index 26d4cf4d00..2369570278 100644 --- a/addons/interaction/XEH_PREP.hpp +++ b/addons/interaction/XEH_PREP.hpp @@ -36,6 +36,8 @@ PREP(pullOutBody); PREP(canRenameGroup); PREP(renameGroupUI); PREP(renameGroup); +PREP(canGroupDropDistantUnits); +PREP(groupDropDistantUnits); // Weapon Attachments PREP(getWeaponAttachmentsActions); diff --git a/addons/interaction/functions/fnc_canGroupDropDistantUnits.sqf b/addons/interaction/functions/fnc_canGroupDropDistantUnits.sqf new file mode 100644 index 0000000000..b13abc1039 --- /dev/null +++ b/addons/interaction/functions/fnc_canGroupDropDistantUnits.sqf @@ -0,0 +1,20 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Checks if the unit can drop distant units from their group + * + * Arguments: + * 0: Unit + * + * Return Value: + * Unit can drop distant units + * + * Example: + * [player] call ace_interaction_fnc_canGroupDropDistantUnits + * + * Public: No + */ + +params ["_unit"]; + +(_unit == leader _unit) && {missionNamespace getVariable [QGVAR(groupDropUnitDistance), 100] > 0} diff --git a/addons/interaction/functions/fnc_groupDropDistantUnits.sqf b/addons/interaction/functions/fnc_groupDropDistantUnits.sqf new file mode 100644 index 0000000000..40875b8580 --- /dev/null +++ b/addons/interaction/functions/fnc_groupDropDistantUnits.sqf @@ -0,0 +1,25 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Drops distant units from their group + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [player] call ace_interaction_fnc_groupDropDistantUnits + * + * Public: No + */ + +params ["_unit"]; + +{ + if ((_x distance _unit) > (missionNamespace getVariable [QGVAR(groupDropUnitDistance), 100])) then { + TRACE_1("drop",_x); + [_x] joinSilent grpNull; + }; +} forEach (units group _unit); diff --git a/addons/interaction/stringtable.xml b/addons/interaction/stringtable.xml index 3d1daf9c3c..7c80a9d932 100644 --- a/addons/interaction/stringtable.xml +++ b/addons/interaction/stringtable.xml @@ -582,6 +582,9 @@ 小隊管理 Takım Yönetimi + + Drop Distant Members + Red Rot From 6304a9e5f3eab03c20b87abbf02383c83d8a4dea Mon Sep 17 00:00:00 2001 From: Hexo <130893962+Alfred-Neuman@users.noreply.github.com> Date: Thu, 22 Aug 2024 04:16:43 +0200 Subject: [PATCH 14/26] Translation French (#10236) * Update translate Hearing french * update map tools * trad fr * correction * Translate realisticnames * compat_ws translate fr * translate FR * Update stringtable.xml * Update addons/cookoff/stringtable.xml space correction --------- --- addons/aircraft/stringtable.xml | 2 + .../compat_cup_weapons_csw/stringtable.xml | 6 ++ .../compat_rf_realisticnames/stringtable.xml | 76 +++++++++++++++++++ .../compat_ws_realisticnames/stringtable.xml | 46 +++++++++++ addons/cookoff/stringtable.xml | 11 +++ addons/grenades/stringtable.xml | 1 + addons/hitreactions/stringtable.xml | 2 + addons/interaction/stringtable.xml | 1 + addons/killtracker/stringtable.xml | 2 + addons/medical_treatment/stringtable.xml | 6 +- addons/overpressure/stringtable.xml | 6 +- addons/realisticnames/stringtable.xml | 11 ++- addons/zeus/stringtable.xml | 7 ++ 13 files changed, 173 insertions(+), 4 deletions(-) diff --git a/addons/aircraft/stringtable.xml b/addons/aircraft/stringtable.xml index 041653fe2b..bcec121106 100644 --- a/addons/aircraft/stringtable.xml +++ b/addons/aircraft/stringtable.xml @@ -182,6 +182,7 @@ Distanza di seguimento Folge-Entfernung 따라가는 거리 + Distance de suivi 追跡距離 @@ -189,6 +190,7 @@ Seguendo unità entro %1m Folgt Einheit bis zu %1m %1m 이내로 유닛을 따라갑니다 + Suivre l'unité jusqu'à %1m %1m 間隔で 目標を追跡します diff --git a/addons/compat_cup_weapons/compat_cup_weapons_csw/stringtable.xml b/addons/compat_cup_weapons/compat_cup_weapons_csw/stringtable.xml index 89b025d647..86e56ee3d9 100644 --- a/addons/compat_cup_weapons/compat_cup_weapons_csw/stringtable.xml +++ b/addons/compat_cup_weapons/compat_cup_weapons_csw/stringtable.xml @@ -10,6 +10,7 @@ [CSW] Cinta de AGS30 [CSW] Nastro AGS30 [CSW] Cinto de AGS30 + [CSW] Ceinture AGS30 [CSW] MK19 Belt @@ -20,6 +21,7 @@ [CSW] Cinta de MK19 [CSW] Nastro MK19 [CSW] Cinto de MK19 + [CSW] Ceinture MK19 [CSW] TOW Tube @@ -30,6 +32,7 @@ [CSW] Tubo de TOW [CSW] Tubo TOW [CSW] Tubo de TOW + [CSW] Tube TOW [CSW] TOW2 Tube @@ -40,6 +43,7 @@ [CSW] Tubo de TOW2 [CSW] Tubo TOW2 [CSW] Tubo de TOW2 + [CSW] Tube TOW2 [CSW] PG-9 Round @@ -50,6 +54,7 @@ [CSW] Carga de PG-9 [CSW] Razzo PG-9 [CSW] Cartucho PG-9 + [CSW] Projectile PG-9 [CSW] OG-9 Round @@ -60,6 +65,7 @@ [CSW] Carga de OG-9 [CSW] Razzo OG-9 [CSW] Cartucho OG-9 + [CSW] Projectile OG-9. [CSW] M1 HE diff --git a/addons/compat_rf/compat_rf_realisticnames/stringtable.xml b/addons/compat_rf/compat_rf_realisticnames/stringtable.xml index 03d5003a62..16a6e92789 100644 --- a/addons/compat_rf/compat_rf_realisticnames/stringtable.xml +++ b/addons/compat_rf/compat_rf_realisticnames/stringtable.xml @@ -7,6 +7,7 @@ 이오텍 MRDS (카키) EOTech MRDS (Khaki) EOTech MRDS (Cachi) + EOTech MRDS (Khaki) EOTech MRDS (Tan) @@ -14,6 +15,7 @@ 이오텍 MRDS (황갈) EOTech MRDS (Hellbraun) EOTech MRDS (Marroncino) + EOTech MRDS (Marron) C-More Railway (Green, Desert) @@ -21,6 +23,7 @@ 씨모어 레일웨이 (녹색, 사막) C-More Railway (Grün, Wüste) C-More Railway (Verde, Deserto) + C-More Railway (Vert, Désert) C-More Railway (Green, Woodland) @@ -28,6 +31,7 @@ 씨모어 레일웨이 (녹색, 수풀 위장) C-More Railway (Grün, Grünes Tarnmuster) C-More Railway (Verde, Boschivo) + C-More Railway (Vert, Woodland) C-More Railway (Red, Desert) @@ -35,6 +39,7 @@ 씨모어 레일웨이 (빨강, 사막) C-More Railway (Rot, Wüste) C-More Railway (Rosso, Desert) + C-More Railway (Rouge, Désert) C-More Railway (Red, Woodland) @@ -42,6 +47,7 @@ 씨모어 레일웨이 (빨강, 수풀) C-More Railway (Rot, Grünes Tarnmuster) C-More Railway (Rosso, Boschivo) + C-More Railway (Rouge, Woodland) Aimpoint Micro R-1 @@ -49,6 +55,7 @@ 에임포인트 마이크로 R-1 Aimpoint Micro R-1 Aimpoint Micro R-1 + Aimpoint Micro R-1 Vortex Spitfire Prism @@ -56,6 +63,7 @@ 버텍스 스핏파이어 프리즘 Vortex Spitfire Prism Vortex Spitfire Prism + Vortex Spitfire Prism Vortex Spitfire Prism (Tan) @@ -63,6 +71,7 @@ 버텍스 스핏파이어 프리즘 (황갈) Vortex Spitfire Prism (Hellbraun) Vortex Spitfire Prism (Marroncino) + Vortex Spitfire Prism (Marron) Vortex Spitfire Prism (Khaki) @@ -70,6 +79,7 @@ 버텍스 스핏파이어 프리즘 (카키) Vortex Spitfire Prism (Khaki) Vortex Spitfire Prism (Cachi) + Vortex Spitfire Prism (Khaki) Vortex Spitfire Prism (Pistol) @@ -77,6 +87,7 @@ 버텍스 스핏파이어 프리즘 (권총용) Vortex Spitfire Prism (Pistole) Vortex Spitfire Prism (Pistola) + Vortex Spitfire Prism (Pistol) Glock 19X @@ -84,6 +95,7 @@ 글록 19X Glock 19X Glock 19X + Glock 19X Glock 19X (Khaki) @@ -91,6 +103,7 @@ 글록 19X (카키) Glock 19X (Khaki) Glock 19X (Cachi) + Glock 19X (Khaki) Glock 19X (Tan) @@ -98,6 +111,7 @@ 글록 19X (황갈) Glock 19X (Hellbraun) Glock 19X (Marroncino) + Glock 19X (Marron) Glock 19X Auto @@ -105,6 +119,7 @@ 글록 19X 기관권총 Glock 19X Auto Glock 19X Auto + Glock 19X Auto Glock 19X Auto (Khaki) @@ -112,6 +127,7 @@ 글록 19X 기관권총 (카키) Glock 19X Auto (Khaki) Glock 19X Auto (Cachi) + Glock 19X Auto (Khaki) Glock 19X Auto (Tan) @@ -119,6 +135,7 @@ 글록 19X 기관권총 (황갈) Glock 19X Auto (Hellbraun) Glock 19X Auto (Marroncino) + Glock 19X Auto (Marron) Desert Eagle Mark XIX L5 @@ -126,6 +143,7 @@ 데저트 이글 마크 XIX L5 Desert Eagle Mark XIX L5 Desert Eagle Mark XIX L5 + Desert Eagle Mark XIX L5 Desert Eagle Mark XIX L5 (Classic) @@ -133,6 +151,7 @@ 데저트 이글 마크 XIX L5 (클래식) Desert Eagle Mark XIX L5 (Klassisch) Desert Eagle Mark XIX L5 (Classico) + Desert Eagle Mark XIX L5 (Classique) Desert Eagle Mark XIX L5 (Bronze) @@ -140,6 +159,7 @@ 데저트 이글 마크 XIX L5 (브론즈) Desert Eagle Mark XIX L5 (Bronze) Desert Eagle Mark XIX L5 (Bronzo) + Desert Eagle Mark XIX L5 (Bronze) Desert Eagle Mark XIX L5 (Copper) @@ -147,6 +167,7 @@ 데저트 이글 마크 XIX L5 (구리) Desert Eagle Mark XIX L5 (Kupfer) Desert Eagle Mark XIX L5 (Rame) + Desert Eagle Mark XIX L5 (Cuivre) Desert Eagle Mark XIX L5 (Gold) @@ -154,6 +175,7 @@ 데저트 이글 마크 XIX L5 (금색) Desert Eagle Mark XIX L5 (Gold) Desert Eagle Mark XIX L5 (Oro) + Desert Eagle Mark XIX L5 (Or) HERA H6 (Tan) @@ -161,6 +183,7 @@ 헤라 H6 (황갈) HERA H6 (Hellbraun) HERA H6 (Marroncino) + HERA H6 (Marron) HERA H6 (Olive) @@ -168,6 +191,7 @@ 헤라 H6 (올리브) HERA H6 (Olivgrün) HERA H6 (Oliva) + HERA H6 (Olive) HERA H6 (Black) @@ -175,6 +199,7 @@ 헤라 H6 (검정) HERA H6 (Schwarz) HERA H6 (Nero) + HERA H6 (Noir) HERA H6 (Digital) @@ -182,6 +207,7 @@ 헤라 H6 (AAF 디지털) HERA H6 (Digital) HERA H6 (Digitale) + HERA H6 (Digital) HERA H6 (Gold) @@ -189,6 +215,7 @@ 헤라 H6 (금색) HERA H6 (Gold) HERA H6 (Oro) + HERA H6 (Or) VS-121 (Black) @@ -196,6 +223,7 @@ VS-121 (검정) VS-121 (Schwarz) VS-121 (Nero) + VS-121 (Noir) VS-121 (Tan) @@ -203,6 +231,7 @@ VS-121 (황갈) VS-121 (Hellbraun) VS-121 (Marroncino) + VS-121 (Marron) Vector SMG (Black) @@ -210,6 +239,7 @@ 벡터 SMG (검정) Vector SMG (Schwarz) Vector SMG (Nero) + Vector SMG (Noir) ASh-12 (Black) @@ -217,6 +247,7 @@ ASh-12 (검정) ASh-12 (Schwarz) ASh-12 (Nero) + ASh-12 (Noir) ASh-12 (Desert) @@ -224,6 +255,7 @@ ASh-12 (사막) ASh-12 (Wüste) ASh-12 (Deserto) + ASh-12 (Désert ) ASh-12 (Urban) @@ -231,6 +263,7 @@ ASh-12 (도심) ASh-12 (Urban) ASh-12 (Urbano) + ASh-12 (Urbain) ASh-12 (Woodland) @@ -238,6 +271,7 @@ ASh-12 (수풀) ASh-12 (Grünes Tarnmuster) ASh-12 (Boschivo) + ASh-12 (Woodland) ASh-12 GL (Black) @@ -245,6 +279,7 @@ ASh-12 GL (검정) ASh-12 GL (Schwarz) ASh-12 GL (Nero) + ASh-12 GL (Noir) ASh-12 GL (Desert) @@ -252,6 +287,7 @@ ASh-12 GL (사막) ASh-12 GL (Wüste) ASh-12 GL (Deserto) + ASh-12 GL (Désert) ASh-12 GL (Urban) @@ -259,6 +295,7 @@ ASh-12 GL (도심) ASh-12 GL (Urban) ASh-12 GL (Urbano) + ASh-12 GL (Urbain) ASh-12 GL (Woodland) @@ -266,6 +303,7 @@ ASh-12 GL (수풀) ASh-12 GL (Grünes Tarnmuster) ASh-12 GL (Boschivo) + ASh-12 GL (Woodland) ASh-12 LR (Black) @@ -273,6 +311,7 @@ ASh-12 LR (검정) ASh-12 LR (Schwarz) ASh-12 LR (Nero) + ASh-12 LR (Noir) ASh-12 LR (Desert) @@ -280,6 +319,7 @@ ASh-12 LR (사막) ASh-12 LR (Wüste) ASh-12 LR (Deserto) + ASh-12 LR (Désert) ASh-12 LR (Urban) @@ -287,6 +327,7 @@ ASh-12 LR (도심) ASh-12 LR (Urban) ASh-12 LR (Urbano) + ASh-12 LR (Urbain) ASh-12 LR (Woodland) @@ -294,6 +335,7 @@ ASh-12 LR (수풀) ASh-12 LR (Grünes Tarnmuster) ASh-12 LR (Boschivo) + ASh-12 LR (Woodland) AW159 Wildcat ASW @@ -301,6 +343,7 @@ AW159 와일드캣 ASW AW159 Wildcat ASW AW159 Wildcat ASW + AW159 Wildcat ASW AW159 Wildcat ASW (Unarmed) @@ -308,6 +351,7 @@ AW159 와일드캣 ASW (비무장) AW159 Wildcat ASW (Unbewaffnet) AW159 Wildcat ASW (Disarmato) + AW159 Wildcat ASW (non armé) H225 Super Puma (Transport) @@ -315,6 +359,7 @@ H225 슈퍼 퓨마 (비무장) H225 Super Puma (Transport) H225 Super Puma (Trasporto) + H225 Super Puma (Transport ) H225 Super Puma (Civilian) @@ -322,6 +367,7 @@ H225 슈퍼 퓨마 (비무장) H225 Super Puma (Zivil) H225 Super Puma (Civile) + H225 Super Puma (Civil) H215 Super Puma (Transport) @@ -329,6 +375,7 @@ H215 슈퍼 퓨마 (비무장) H215 Super Puma (Transport) H215 Super Puma (Trasporto) + H215 Super Puma (Transport) H215 Super Puma (Civilian) @@ -336,6 +383,7 @@ H215 슈퍼 퓨마 (비무장) H215 Super Puma (Zivil) H215 Super Puma (Civile) + H215 Super Puma (Civil) H215 Super Puma (Unarmed) @@ -343,6 +391,7 @@ H215 슈퍼 퓨마 (비무장) H215 Super Puma (Unbewaffnet) H215 Super Puma (Disarmato) + H215 Super Puma (non armé) H225M Super Cougar SOCAT @@ -350,6 +399,7 @@ H225M 슈퍼 쿠거 SOCAT H225M Super Cougar SOCAT H225M Super Cougar SOCAT + H225M Super Cougar SOCAT H225M Super Cougar SOCAT @@ -357,6 +407,7 @@ H225M 슈퍼 쿠거 SOCAT H225M Super Cougar SOCAT H225M Super Cougar SOCAT + H225M Super Cougar SOCAT H225M Super Cougar @@ -364,6 +415,7 @@ H225M 슈퍼 쿠거 H225M Super Cougar H225M Super Cougar + H225M Super Cougar H225 Super Puma SAR @@ -371,6 +423,7 @@ H225 슈퍼 퓨마 SAR H225 Super Puma SAR H225 Super Puma SAR + H225 Super Puma SAR H225M Super Cougar (Unarmed) @@ -378,6 +431,7 @@ H225M Super Cougar (Unbewaffnet) H225M Super Cougar (Disarmato) H225M 슈퍼 쿠거 (비무장) + H225M Super Cougar (Non armé) HEMTT Fire Truck @@ -398,6 +452,7 @@ 타이푼 급수 Typhoon Water Typhoon Acqua + Typhoon Water Ram 1500 @@ -405,6 +460,7 @@ 램 1500 Ram 1500 Ram 1500 + Ram 1500 Ram 1500 (Fuel) @@ -412,6 +468,7 @@ 램 1500 (연료) Ram 1500 (Treibstoff) Ram 1500 (Carburante) + Ram 1500 (Carburant) Ram 1500 (Services) @@ -419,6 +476,7 @@ 램 1500 (서비스) Ram 1500 (Pannenhilfe) Ram 1500 (Servizi) + Ram 1500 (Dépannage) Ram 1500 (Repair) @@ -426,6 +484,7 @@ 램 1500 (정비) Ram 1500 (Instandsetzung) Ram 1500 (Riparazioni) + Ram 1500 (Réparation) Ram 1500 (Comms) @@ -433,6 +492,7 @@ 램 1500 (통신) Ram 1500 (Kommunikation) Ram 1500 (Comunicazioni) + Ram 1500 (Communication) Ram 1500 (HMG) @@ -440,6 +500,7 @@ 램 1500 (중기관총) Ram 1500 (HMG) Ram 1500 (HMG) + Ram 1500 (HMG) Ram 1500 (MMG) @@ -447,6 +508,7 @@ 램 1500 (중형기관총) Ram 1500 (MMG) Ram 1500 (MMG) + Ram 1500 (MMG) Ram 1500 (MRL) @@ -454,6 +516,7 @@ 램 1500 (다연장로켓) Ram 1500 (MRL) Ram 1500 (MRL) + Ram 1500 (MRL) Ram 1500 (AA) @@ -461,6 +524,7 @@ 램 1500 (대공) Ram 1500 (AA) Ram 1500 (AA) + Ram 1500 (AA) Ram 1500 (Covered) @@ -468,6 +532,7 @@ 램 1500 (커버) Ram 1500 (Abgedeckt) Ram 1500 (Coperto) + Ram 1500 (couvert) Ram 1500 (Water) @@ -475,6 +540,7 @@ 램 1500 (급수) Ram 1500 (Wasser) Ram 1500 (Acqua) + Ram 1500 (eau) RSG60 @@ -482,6 +548,7 @@ RSG60 RSG60 RSG60 + RSG60 AMOS Container @@ -489,6 +556,7 @@ AMOS 컨테이너 AMOS Container AMOS Container + AMOS Container Drone40 @@ -496,6 +564,7 @@ 드론40 Drone40 Drone40 + Drone40 Drone40 Scout @@ -503,6 +572,7 @@ 드론40 정찰 Drone40 Scout Drone40 Scout + Drone40 Scout Drone40 HE @@ -510,6 +580,7 @@ 드론40 고폭 Drone40 HE Drone40 HE + Drone40 HE Drone40 Smoke (White) @@ -517,6 +588,7 @@ 드론40 연막 (백색) Drone40 Smoke (Weiß) Drone40 Smoke (Bianco) + Drone40 Fumée (Blanc) Drone40 Smoke (Blue) @@ -524,6 +596,7 @@ 드론40 연막 (청색) Drone40 Smoke (Blau) Drone40 Smoke (Blu) + Drone40 Fumée (Bleu) Drone40 Smoke (Red) @@ -531,6 +604,7 @@ 드론40 연막 (적색) Drone40 Smoke (Rot) Drone40 Smoke (Rosso) + Drone40 Fumée (Rouge) Drone40 Smoke (Green) @@ -538,6 +612,7 @@ 드론40 연막 (녹색) Drone40 Smoke (Grün) Drone40 Smoke (Verde) + Drone40 Fumée (Vert) Drone40 Smoke (Orange) @@ -545,6 +620,7 @@ 드론40 연막 (주황색) Drone40 Smoke (Orange) Drone40 Smoke (Arancione) + Drone40 Fumée (Orange) diff --git a/addons/compat_ws/compat_ws_realisticnames/stringtable.xml b/addons/compat_ws/compat_ws_realisticnames/stringtable.xml index 606bbb7932..66c1791f9c 100644 --- a/addons/compat_ws/compat_ws_realisticnames/stringtable.xml +++ b/addons/compat_ws/compat_ws_realisticnames/stringtable.xml @@ -29,6 +29,7 @@ AA12 (ヘビ柄迷彩) AA12 (Змея) AA12 (Serpiente) + AA12 (Sable) Galil ARM @@ -68,6 +69,7 @@ GLX 160 (ヘビ柄迷彩) GLX 160 (Змея) GLX 160 (Serpiente) + GLX 160 GLX 160 (Hex) @@ -127,6 +129,7 @@ Mk14 Mod 1 EBR (ヘビ柄迷彩) Mk14 Mod 1 EBR (Змея) Mk14 Mod 1 EBR (Serpiente) + Mk14 Mod 1 EBR (Serpent) Vektor SS-77 @@ -195,6 +198,7 @@ ヴェクター SS-77 コンパクト (ヘビ柄迷彩) Vektor SS-77 Compact (змея) Vektor SS-77 Compacta (Serpiente) + Vektor SS-77 Compacte (Serpent) FN FAL 50.00 (Wood) @@ -262,6 +266,7 @@ FN FAL OSW 파라 FN FAL OSW Fallschirmjäger FN FAL OSW Para + FN FAL OSW Para FN FAL OSW Para (Snake) @@ -269,6 +274,7 @@ FN FAL OSW 파라 (뱀 위장) FN FAL OSW Fallschirmjäger (Schlange) FN FAL OSW Para (Serpe) + FN FAL OSW Para (Serpent) Vektor R4 @@ -308,6 +314,7 @@ ヴェクター R5 カービン (ヘビ柄迷彩) Vektor R5 Carbine (Змея) Vektor R5 Carabina (Serpiente) + Vektor R5 Carbine (Serpent) Vektor R5 Carbine GL (Snake) @@ -317,6 +324,7 @@ ヴェクター R5 カービン GL (ヘビ柄迷彩) Vektor R5 Carbine GL (Змея) Vektor R5 Carabina GL (Serpiente) + Vektor R5 Carbine GL (Serpent) XMS @@ -468,6 +476,7 @@ GM6 링스 (뱀 위장) GM6 Lynx (Schlange) GM6 Lynx (Serpe) + GM6 Lynx (Serpent) RPG-32 (Sand) @@ -475,6 +484,7 @@ RPG-32 (모래) RPG-32 (Sand) RPG-32 (Sabbia) + RPG-32 (Sable) ELCAN SpecterOS (Hex) @@ -482,6 +492,7 @@ 엘칸 스펙터OS (육각) ELCAN SpecterOS (Hex) ELCAN SpecterOS (Hex) + ELCAN SpecterOS (Hex) EOTech XPS3 (Snake) @@ -489,6 +500,7 @@ 이오텍 XPS3 (뱀 위장) EOTech XPS3 (Schlange) EOTech XPS3 (Serpe) + EOTech XPS3 (Serpent) EOTech XPS3 SMG (Snake) @@ -496,6 +508,7 @@ 이오텍 XPS3 SMG (뱀 위장) EOTech XPS3 SMG (Schlange) EOTech XPS3 SMG (Serpe) + EOTech XPS3 SMG (Serpent) Leupold Mark 4 HAMR (Arid) @@ -503,6 +516,7 @@ 류폴드 마크 4 HAMR (건조) Leupold Mark 4 HAMR (Trocken) Leupold Mark 4 HAMR (Arido) + Leupold Mark 4 HAMR (Aride) Leupold Mark 4 HAMR (Lush) @@ -510,6 +524,7 @@ 류폴드 마크 4 HAMR (초목) Leupold Mark 4 HAMR (Grün) Leupold Mark 4 HAMR (Verdeggiante) + Leupold Mark 4 HAMR (Vert) Leupold Mark 4 HAMR (Sand) @@ -517,6 +532,7 @@ 류폴드 마크 4 HAMR (모래) Leupold Mark 4 HAMR (Sand) Leupold Mark 4 HAMR (Sabbia) + Leupold Mark 4 HAMR (Sable) Leupold Mark 4 HAMR (Snake) @@ -524,6 +540,7 @@ 류폴드 마크 4 HAMR (뱀 위장) Leupold Mark 4 HAMR (Schlange) Leupold Mark 4 HAMR (Serpe) + Leupold Mark 4 HAMR (Serpent) Aimpoint Micro R-1 (High, Black) @@ -531,6 +548,7 @@ 에임포인트 마이크로 R-1 (높음, 검정) Aimpoint Micro R-1 (Hoch, Schwarz) Aimpoint Micro R-1 (Alto, Nero) + Aimpoint Micro R-1 (Haut, Noir) Aimpoint Micro R-1 (High, Khaki) @@ -538,6 +556,7 @@ 에임포인트 마이크로 R-1 (높음, 카키) Aimpoint Micro R-1 (Hoch, Khaki) Aimpoint Micro R-1 (Alto, Cachi) + Aimpoint Micro R-1 (Haut, Kaki) Aimpoint Micro R-1 (High, Sand) @@ -545,6 +564,7 @@ 에임포인트 마이크로 R-1 (높음, 모래) Aimpoint Micro R-1 (Hoch, Sand) Aimpoint Micro R-1 (Alto, Sabbia) + Aimpoint Micro R-1 (Haut, Sable) Aimpoint Micro R-1 (High, Snake) @@ -552,6 +572,7 @@ 에임포인트 마이크로 R-1 (높음, 뱀 위장) Aimpoint Micro R-1 (Hoch, Schlange) Aimpoint Micro R-1 (Alto, Serpe) + Aimpoint Micro R-1 (Haut, Serpent) Aimpoint Micro R-1 (High, Arid) @@ -559,6 +580,7 @@ 에임포인트 마이크로 R-1 (높음, 건조) Aimpoint Micro R-1 (Hoch, Trocken) Aimpoint Micro R-1 (Alto, Arido) + Aimpoint Micro R-1 (Hoch, Arid Aimpoint Micro R-1 (High, Lush) @@ -566,6 +588,7 @@ 에임포인트 마이크로 R-1 (높음, 초목) Aimpoint Micro R-1 (Hoch, Grün) Aimpoint Micro R-1 (Alto, Verdeggiante) + Aimpoint Micro R-1 (Haute, Vert) Aimpoint Micro R-1 (High, Black/Sand) @@ -573,6 +596,7 @@ 에임포인트 마이크로 R-1 (높음, 검정/모래) Aimpoint Micro R-1 (Hoch, Schwarz/Sand) Aimpoint Micro R-1 (Alto, Nero/Sabbia) + Aimpoint Micro R-1 (Haut, Noir/Sable) Aimpoint Micro R-1 (Low, Black) @@ -580,6 +604,7 @@ 에임포인트 마이크로 R-1 (낮음, 검정) Aimpoint Micro R-1 (Tief, Schwarz) Aimpoint Micro R-1 (Basso, Nero) + Aimpoint Micro R-1 (Bas, Noir) Aimpoint Micro R-1 (Low, Khaki) @@ -587,6 +612,7 @@ 에임포인트 마이크로 R-1 (낮음, 카키) Aimpoint Micro R-1 (Tief, Khaki) Aimpoint Micro R-1 (Basso, Cachi) + Aimpoint Micro R-1 (Bas, Kaki) Aimpoint Micro R-1 (Low, Sand) @@ -594,6 +620,7 @@ 에임포인트 마이크로 R-1 (낮음, 모래) Aimpoint Micro R-1 (Tief, Sand) Aimpoint Micro R-1 (Basso, Sabbia) + Aimpoint Micro R-1 ( Bas, Sable ) Aimpoint Micro R-1 (Low, Snake) @@ -601,6 +628,7 @@ 에임포인트 마이크로 R-1 (낮음, 뱀 위장) Aimpoint Micro R-1 (Tief, Schlange) Aimpoint Micro R-1 (Basso, Serpe) + Aimpoint Micro R-1 (Bas, Serpent) Aimpoint Micro R-1 (Low, Arid) @@ -608,6 +636,7 @@ 에임포인트 마이크로 R-1 (낮음, 건조) Aimpoint Micro R-1 (Tief, Trocken) Aimpoint Micro R-1 (Basso, Arido) + Aimpoint Micro R-1 (Bas, Arid) Aimpoint Micro R-1 (Low, Lush) @@ -615,6 +644,7 @@ 에임포인트 마이크로 R-1 (낮음, 초목) Aimpoint Micro R-1 (Tief, Grün) Aimpoint Micro R-1 (Basso, Verdeggiante) + Aimpoint Micro R-1 (Bas, Vert) Burris XTR II (Snake) @@ -622,6 +652,7 @@ 버리스 XTR II (뱀 위장) Burris XTR II (Schlange) Burris XTR II (Serpe) + Burris XTR II (Serpent) Badger IFV (ATGM) @@ -629,6 +660,7 @@ 뱃져 보병전투차 (대전차미사일) Badger IFV (PzAbw) Badger IFV (ATGM) + Badger IFV (ATGM) Badger IFV (Command) @@ -636,6 +668,7 @@ 뱃져 보병전투차 (지휘) Badger IFV (Kommando) Badger IFV (Comando) + Badger IFV (Commandement) Badger IFV (Mortar) @@ -643,6 +676,7 @@ 뱃져 보병전투차 (자주박격포) Badger IFV (Mörser) Badger IFV (Mortaio) + Badger IFV (mortier) KamAZ (Zu-23-2) @@ -650,6 +684,7 @@ 카마즈 (ZU-23-2) KamAZ (Zu-23-2) KamAZ (Zu-23-2) + KamAZ (Zu-23-2) KamAZ Cargo @@ -657,6 +692,7 @@ 카마즈 화물 KamAZ Fracht KamAZ Carico + KamAZ Cargo KamAZ Repair @@ -664,6 +700,7 @@ 카마즈 정비 KamAZ Instandsetzung KamAZ Riparazione + KamAZ Réparation KamAZ Racing @@ -671,6 +708,7 @@ 카마즈 경주용 KamAZ Rennlaster KamAZ da corsa + KamAZ de course KamAZ Ammo @@ -678,6 +716,7 @@ 카마즈 탄약 KamAZ Munition KamAZ Munizioni + KamAZ Munitions KamAZ Flatbed @@ -685,6 +724,7 @@ 카마즈 플랫베드 KamAZ Flachbett KamAZ Pianale + KamAZ Flatbed AW101 Merlin @@ -692,6 +732,7 @@ AW101 멀린 AW101 Merlin AW101 Merlin + AW101 Merlin BM-2T Stalker (Bumerang-BM) @@ -699,6 +740,7 @@ BM-2T 스토커 (부메랑-BM) BM-2T Stalker (Bumerang-BM) BM-2T Stalker (Bumerang-BM) + BM-2T Stalker (Boomerang-BM) Otokar ARMA (HMG) @@ -706,6 +748,7 @@ 오토카르 아르마 APC (중기관총) Otokar ARMA (HMG) Otokar ARMA (HMG) + Otokar ARMA (HMG) Otokar ARMA (Unarmed) @@ -713,6 +756,7 @@ 오토카르 아르마 APC (비무장) Otokar ARMA (Unbewaffnet) Otokar ARMA (Disarmato) + Otokar ARMA (non armé) Ka-60 Kasatka (UP) @@ -720,6 +764,7 @@ Ka-60 카사트카 (UP) Ka-60 Kasatka (UP) Ka-60 Kasatka (UP) + Ka-60 Kasatka (UP) Ka-60 Kasatka (UP, Unarmed) @@ -727,6 +772,7 @@ Ka-60 카사트카 (UP, 비무장)) Ka-60 Kasatka (UP, Unbewaffnet) Ka-60 Kasatka (UP, Disarmato) + Ka-60 Kasatka (UP, non armé) diff --git a/addons/cookoff/stringtable.xml b/addons/cookoff/stringtable.xml index 15d2d2adec..838b3490bb 100644 --- a/addons/cookoff/stringtable.xml +++ b/addons/cookoff/stringtable.xml @@ -23,6 +23,7 @@ 차량 유폭 화재를 활성화합니다 Abilita incendio dei veicoli Aktiviert Fahrzeug Munitionsbrand + Permettre l'incendie du véhicule Enables vehicle cook-off fire effects.\nThis doesn't include ammunition detonations. @@ -31,6 +32,7 @@ 차량 유폭 효과를 활성화합니다.\n여기엔 탄약 유폭이 포함되지 않습니다. Abilita effetti di incendio del veicolo dovuto all'esplosione delle munizioni.\nQuesto non include gli effetti di esplosione. Aktiviert Fahrzeug Brandeffekte durch Durchzündung.\nExplosionseffekte sind nicht mit einbegriffen. + Permet d'obtenir des effets de feu de véhicule à partir de munitions qui explosent.\nCela n'inclut pas les effets d'explosion. Vehicle cook-off fire duration multiplier @@ -39,6 +41,7 @@ 차량 유폭 화재 지속 시간 계수 Coefficiente di durata incendio dei veicoli Fahrzeugbrand Dauer-Multiplikator + Coefficient de durée d'incendie du véhicule Multiplier for how long vehicle cook-off fire lasts.\nSetting to 0 will disable vehicle cook-off fire. @@ -47,6 +50,7 @@ 차량 유폭 화재가 지속되는 시간에 대한 계수입니다.\n0으로 설정하면 차량 쿸오프 화재가 비활성화됩니다. Coefficiente di durata degli incendi dei veicoli.\nImpostarlo su 0 disabilita incendi dei veicoli. Multiplikator der Fahrzeugbrand Dauer.\nIhn auf 0 zu setzen wird Munitionsbrände deaktivieren. + Coefficient de durée des feux de véhicules.\nLa valeur 0 désactive les feux de véhicules. Vehicle cook-off fire probability multiplier @@ -55,6 +59,7 @@ 차량 유폭 화재 확률 계수 Probabilità di incendio dei veicoli Fahrzeug Munitionsbrand Wahrscheinlichkeit-Multiplikator + Probabilité d'incendies de véhicules Multiplier for vehicle cook-off fire probability. Higher value results in higher cook-off probability.\nSetting to 0 will disable vehicle cook-off fire. @@ -63,6 +68,7 @@ 차량 유폭 화재 확률에 대한 계수입니다. 값이 높을 수록 유폭 확률이 높아집니다.\n0으로 설정하면 차량 유폭 화재가 비활성화됩니다. Coefficiente di probabilità degli incendi dei veicoli.\nValori maggiori aumentano la probabilità di incendi.\nImpostarlo su 0 disabilita incendi dei veicoli. Multiplikator der Fahrzeugbrand Wahrscheinlichkeit.\nHöhere Werte erhöhen die Wahrscheinlichkeit.\nEin Null-Wert wird Munitionsbrände deaktivieren. + Coefficient de probabilité des incendies de véhicules.\nLes valeurs élevées augmentent la probabilité des incendies.\nLa valeur 0 désactive les incendies de véhicules. Destroy vehicles after cook-off @@ -96,6 +102,7 @@ 차량 내 탄약 유폭 활성화 Abilita esplosioni delle munizioni dei veicoli Aktiviert Fahrzeug Munitionsdurchzündung + Permet l'explosion des munitions des véhicules Enables cooking off of vehicle ammunition. Fires ammunition projectiles while vehicle has ammunition remaining.\nThis doesn't include fire effects. @@ -104,6 +111,7 @@ 차량 내 탄약 유폭을 활성화합니다. 차량에 탄약이 남아 있는 동안 탄약 발사체를 발사합니다.\n여기엔 화재 효과가 포함되지 않습니다. Abilita l'esplosione delle munizioni dei veicoli. Spara via pezzi di munizioni se il veicolo ha ancora munizioni rimanenti.\nNon include gli effetti di fuoco. Aktiviert Durchzündung von Fahrzeugmunition. Schleudert Munitionsfragmente umher wenn das Fahrzeug noch Munition an Bord hat.\nBrandeffekte sind nicht mit einbegriffen. + Permet l'explosion des munitions du véhicule. Tire des morceaux de munitions si le véhicule a encore des munitions restantes.\nIl n'y a pas d'effets de feu. Enable ammo box cook-off @@ -127,6 +135,7 @@ 탄약 상자 유폭을 활성화합니다.\n여기엔 화재 효과가 포함되지 않습니다. Abilita esplosioni delle casse di munizioni.\nNon include effetti di fuoco. Aktiviert Munitionskisten Durchzündung.\nBrandeffekte sind nicht mit einbegriffen. + Permet l'explosion des caisses de munitions.\nN'inclut pas les effets de feu. Ammo cook-off duration multiplier @@ -135,6 +144,7 @@ 탄약 유폭 시간 계수 Coefficiente di durata esplisioni di munizioni Fahrzeug Munitionsdurchzündung Dauer-Multiplikator + Coefficient de durée d'explosion des munitions Multiplier for how long ammunition cook-off lasts, for both vehicles and ammo boxes.\nSetting to 0 will disable ammo cook-off for both vehicles and ammo boxes. @@ -143,6 +153,7 @@ 차량과 탄약 상자 모두에 대해 탄약 유폭이 지속되는 시간에 대한 계수입니다.\n0으로 설정하면 차량과 탄약 상자 모두에 대해 탄약 유폭이 비활성화됩니다. Coefficiente della durata di esplosioni delle munizioni, sia per veicoli che casse.\nImpostarlo su 0 disabilita esplosioni di veicoli e casse. Multiplikator der Munitionsdurchzündungs-Dauer, gilt für Fahrzeuge und Munitionskisten.\nIhn auf 0 zu setzen wird Durchzünden deaktivieren. + Coefficient de durée d'explosion des munitions pour les véhicules et les caisses.\nLa valeur 0 désactive les explosions des véhicules et des caisses. Enable ammo removal during cook-off diff --git a/addons/grenades/stringtable.xml b/addons/grenades/stringtable.xml index b0630e3a43..1a6243464f 100644 --- a/addons/grenades/stringtable.xml +++ b/addons/grenades/stringtable.xml @@ -110,6 +110,7 @@ 이 수류탄은 굴릴 수 없습니다. %1(으)로 전환되었습니다. Granate kann nicht rollen, zu %1 gewechselt Granata non può rotolare, cambiato a %1 + Grenade ne peut pas rouler, passé à %1 M84 Stun Grenade diff --git a/addons/hitreactions/stringtable.xml b/addons/hitreactions/stringtable.xml index 251cd437bc..e60be5b353 100644 --- a/addons/hitreactions/stringtable.xml +++ b/addons/hitreactions/stringtable.xml @@ -24,6 +24,7 @@ 플레이어가 무기를 떨굴 확률 (팔 피격) Spieler Wahrscheinlichkeit, die Waffe fallen zu lassen (Arm Treffer) Probabilità dei giocatori di far cadere l'arma (colpo al braccio) + Probabilité de lâcher l'arme (coup au bras) Probabilidade do jogador de largar a arma após tiro no braço @@ -33,6 +34,7 @@ 인공지능이 무기를 떨굴 확률 (팔 피격) KI-Wahrscheinlichkeit, die Waffe fallen zu lassen (Arm Treffer) Probabilità dell'IA di far cadere l'arma (colpo al braccio) + Probabilité de l'IA de lâcher l'arme (coup au bras) Probabilidade da IA de largar a arma após tiro no braço diff --git a/addons/interaction/stringtable.xml b/addons/interaction/stringtable.xml index 7c80a9d932..f9bf842bd9 100644 --- a/addons/interaction/stringtable.xml +++ b/addons/interaction/stringtable.xml @@ -1330,6 +1330,7 @@ Interaction with animations Взаимодействие с анимациями + Interaction avec les animations diff --git a/addons/killtracker/stringtable.xml b/addons/killtracker/stringtable.xml index 64b9ee764d..9ab1423f1f 100644 --- a/addons/killtracker/stringtable.xml +++ b/addons/killtracker/stringtable.xml @@ -126,6 +126,7 @@ Mostra uccisioni del veicolo a membri dell'equipaggio 車両でのキルを乗員全員に表示する 다른 승무원에게 차량 처치 표시 + Montrer les véhicules tués aux membres de l'équipage Show kills from a vehicle to driver, gunner and commander @@ -134,6 +135,7 @@ Mostra uccisioni del veicolo al pilota, artigliere e comandante 車両でのキルを操縦手、砲手、車長で共有して表示する 차량 처치를 운전수, 사수, 지휘관에게 보여줍니다 + Montrer les véhicules tués au pilote, à l'artilleur et au commandant. diff --git a/addons/medical_treatment/stringtable.xml b/addons/medical_treatment/stringtable.xml index 6211a05359..10ac97af78 100644 --- a/addons/medical_treatment/stringtable.xml +++ b/addons/medical_treatment/stringtable.xml @@ -85,6 +85,7 @@ 활성화 및 사망/심정지 진찰 가능 [직접] Aktiviert & kann Tod/Herzstillstand diagnostizieren [Direkt] Abilitato e può diagnosticare Morte/Arresto Cardiaco [Esplicito] + Activé & peut diagnostiquer la mort/l'arrêt cardiaque [Direct]. Advanced Medication @@ -4197,7 +4198,7 @@ %1 is not responsive %1 не реагирует на раздражители - %1 est inconscient. + %1 ne répond pas aux stimuli %1 no reacciona %1 jest nieprzytomny %1 ist nicht ansprechbar @@ -4218,6 +4219,7 @@ %1은(는) 의식불명입니다 %1 ist bewusstlos %1 è privo di sensi + %1 est inconscient %1 is not responsive, taking shallow gasps and convulsing @@ -4239,6 +4241,7 @@ %1은(는) 심정지 상태입니다 %1 ist im Herzstillstand %1 è in arresto cardiaco + %1 est en arrêt cardiaque %1 is not responsive, motionless and cold @@ -4260,6 +4263,7 @@ %1은(는) 사망했습니다 %1 ist tod %1 è morto + %1 est mort You checked %1 diff --git a/addons/overpressure/stringtable.xml b/addons/overpressure/stringtable.xml index 2ce7615ad4..c8a0aa895d 100644 --- a/addons/overpressure/stringtable.xml +++ b/addons/overpressure/stringtable.xml @@ -52,6 +52,7 @@ Coefficiente distanza di svampata 後方噴射の距離係数 후폭풍 거리 계수 + Multiplicateur de distance de réflexion Scales the backblast effect @@ -60,6 +61,7 @@ Scala l'effetto delle svampate dei lanciarazzi 無反動砲による後方噴射の影響範囲の大きさ 후폭풍 효과의 스케일을 조정합니다 + Multiplicateur de distance de réflexion Backblast range @@ -72,7 +74,7 @@ Дальность реактивной струи Alcance do Sopro de Disparo Utóhatás távolsága - Portée du backblast + Portée du souffle Dosah zpětné tlakové vlny (backblast) Alcance del cono de fuego 후폭풍 거리 @@ -88,7 +90,7 @@ Угол реактивной струи Ângulo do Sopro de Disparo Utóhatás aránya - Angle du backblast + Angle du souffle Úhel zpětné tlakové vlny (backblast) Ángulo del cono de fuego 후폭풍 각도 diff --git a/addons/realisticnames/stringtable.xml b/addons/realisticnames/stringtable.xml index 89c4775d1b..bf5110de7a 100644 --- a/addons/realisticnames/stringtable.xml +++ b/addons/realisticnames/stringtable.xml @@ -706,6 +706,7 @@ 카마즈 급수 KamAS Wasser KamAZ Acqua + KamAZ Eau KamAZ MRL @@ -1674,6 +1675,7 @@ CZ 581 CZ 581 CZ 581 + CZ 581 CZ 581 (Sawed-Off) @@ -1683,6 +1685,7 @@ CZ 581 (소드오프) CZ 581 (Abgesägt) CZ 581 (Canne mozze) + CZ 581 (canon scié) FNX-45 Tactical (Green) @@ -2733,7 +2736,7 @@ ASP-1 Kir (Tan) ASP-1 Kir (Žlutohnědá) - ASP-1 Kir (Tan) + ASP-1 Kir (Marron) ASP-1 Kir (Tan) ASP-1 Kir (пустынный) ASP-1 Kir (Hellbraun) @@ -3093,6 +3096,7 @@ 115식 보총 (검정) Type 115 (Schwarz) Type 115 (Nero) + Type 115 (Noir) Type 115 (Green Hex) @@ -3102,6 +3106,7 @@ 115식 보총 (초록육각) Type 115 (Hex Grün) Type 115 (Hex Verde) + Type 115 (Hew Vert) Type 115 (Hex) @@ -3111,6 +3116,7 @@ 115식 보총 (육각) Type 115 (Hex) Type 115 (Hex) + Type 115 (Hex) QBZ-95-1 (Black) @@ -3904,6 +3910,7 @@ UTG 디펜더 126 UTG Defender 126 UTG Defender 126 + UTG Defender 126 EOTech MRDS @@ -3913,6 +3920,7 @@ 이오텍 MRDS EOTech MRDS EOTech MRDS + EOTech MRDS EOTech MRDS (Black) @@ -3922,6 +3930,7 @@ 이오텍 MRDS (검정) EOTech MRDS (Schwarz) EOTech MRDS (Nero) + EOTech MRDS (Noir) Leupold Mark 4 HAMR diff --git a/addons/zeus/stringtable.xml b/addons/zeus/stringtable.xml index a6eaaac158..7a285f2d6a 100644 --- a/addons/zeus/stringtable.xml +++ b/addons/zeus/stringtable.xml @@ -2016,6 +2016,7 @@ 플레이어가 Esc 키로 관전자 인터페이스를 닫지 못하도록 강제로 관전자 인터페이스를 설정합니다. Erzwingt die Zuschauer-Ansicht und verhindert dass der Spieler sie mit der Esc-Taste schließen kann Forza l'interfaccia di spettatore, impedendo al giocatore di chiuderla con il tasto Esc + Force le mode spectateur en empêchant le joueur de la fermer avec la touche Echap. Hide player @@ -2024,6 +2025,7 @@ 플레이어 숨기기 Spieler ausblenden Nascondi giocatore + Cacher le joueur Hides the player by making them invisible, invulnerable, muted, and removing them from their group @@ -2032,6 +2034,7 @@ 플레이어를 투명, 무적, 음소거화하고 그룹에서 제거하여 숨깁니다. Blendet den Spieler aus, macht ihn unsichtbar, unverwundbar, stumm und entfernt ihn von seiner Gruppe Nasconde il giocatore, rendendolo invisibile, invulnerabile, muto e lo rimuove dal proprio gruppo + Cache le joueur en le rendant invisible, invulnérable, muet et en le retirant de son groupe. Sets the sides that are available to spectate @@ -2040,6 +2043,7 @@ 관전 가능한 진영을 설정합니다. Bestimmt die Seiten denen man zuschauen kann Imposta le fazioni che lo spettatore può osservare + Définit les côtés disponibles pour le mode spectateur White Hot @@ -2048,6 +2052,7 @@ 백색 열원 Weiß-Schwarz Bianco-caldo + Blanc-noir Black Hot @@ -2056,6 +2061,7 @@ 흑색 열원 Schwarz-Weiß Nero-caldo + Noir et blanc Toggle All @@ -2064,6 +2070,7 @@ 전부 토글 Alle wechseln Cambia tutti + Tout afficher From 1dae884fff9c0e9f477b9aafdae08345000f0d1a Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Thu, 22 Aug 2024 05:48:36 +0200 Subject: [PATCH 15/26] General - Add replacement items for editor inventory management (#10216) Add replacement items for editor inventory management --- addons/intelitems/CfgWeapons.hpp | 17 +++++++++++++++++ addons/intelitems/XEH_postInit.sqf | 3 +++ addons/intelitems/config.cpp | 3 ++- addons/medical_treatment/CfgWeapons.hpp | 13 +++++++++++++ addons/medical_treatment/XEH_postInit.sqf | 3 +++ addons/medical_treatment/config.cpp | 2 +- addons/overheating/CfgWeapons.hpp | 10 ++++++---- 7 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 addons/intelitems/CfgWeapons.hpp diff --git a/addons/intelitems/CfgWeapons.hpp b/addons/intelitems/CfgWeapons.hpp new file mode 100644 index 0000000000..727b163de2 --- /dev/null +++ b/addons/intelitems/CfgWeapons.hpp @@ -0,0 +1,17 @@ +class CfgWeapons { + class ACE_ItemCore; + class CBA_MiscItem_ItemInfo; + + // Since base game doesn't support misc. items, this is needed to filling inventories in the editor + class GVAR(notepad_Item): ACE_ItemCore { + displayName = CSTRING(Notepad_DisplayName); + author = ECSTRING(common,ACETeam); + scope = 2; + scopeArsenal = 0; + descriptionShort = CSTRING(Notepad_Description); + picture = QPATHTOF(ui\notepad_ca.paa); + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 0.1; + }; + }; +}; diff --git a/addons/intelitems/XEH_postInit.sqf b/addons/intelitems/XEH_postInit.sqf index f416b3667e..f79ae9f636 100644 --- a/addons/intelitems/XEH_postInit.sqf +++ b/addons/intelitems/XEH_postInit.sqf @@ -1,5 +1,8 @@ #include "script_component.hpp" +// Notepad item to magazine +[QGVAR(notepad_Item), QXGVAR(notepad)] call EFUNC(common,registerItemReplacement); + // Only handle loadout change when on map or have open controls ["loadout", { if (!visibleMap && {GVAR(controlsGroups) isEqualTo []}) exitWith {}; diff --git a/addons/intelitems/config.cpp b/addons/intelitems/config.cpp index 3b9b37b5b6..1eafb3fe86 100644 --- a/addons/intelitems/config.cpp +++ b/addons/intelitems/config.cpp @@ -8,7 +8,7 @@ class CfgPatches { QXGVAR(document), QXGVAR(photo) }; - weapons[] = {}; + weapons[] = {QGVAR(notepad_Item)}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_interact_menu", "ace_zeus"}; author = ECSTRING(common,ACETeam); @@ -23,5 +23,6 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgEditorSubcategories.hpp" #include "CfgMagazines.hpp" +#include "CfgWeapons.hpp" #include "CfgVehicles.hpp" #include "gui.hpp" diff --git a/addons/medical_treatment/CfgWeapons.hpp b/addons/medical_treatment/CfgWeapons.hpp index 7b31e10bee..aae3fbb69c 100644 --- a/addons/medical_treatment/CfgWeapons.hpp +++ b/addons/medical_treatment/CfgWeapons.hpp @@ -310,4 +310,17 @@ class CfgWeapons { hiddenSelectionsTextures[] = {QPATHTOF(data\bodybagItem_white_co.paa)}; GVAR(bodyBagObject) = "ACE_bodyBagObject_white"; }; + + // Since base game doesn't support misc. items, this is needed to filling inventories in the editor + class ACE_painkillers_Item: ACE_ItemCore { + displayName = CSTRING(painkillers_Display); + author = ECSTRING(common,ACETeam); + scope = 2; + scopeArsenal = 0; + descriptionShort = CSTRING(painkillers_Desc_Short); + picture = QPATHTOF(ui\painkillers_ca.paa); + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 1; + }; + }; }; diff --git a/addons/medical_treatment/XEH_postInit.sqf b/addons/medical_treatment/XEH_postInit.sqf index 4c7a780fc3..0752e67ddf 100644 --- a/addons/medical_treatment/XEH_postInit.sqf +++ b/addons/medical_treatment/XEH_postInit.sqf @@ -1,5 +1,8 @@ #include "script_component.hpp" +// Pain killers item to magazine +["ACE_painkillers_Item", "ACE_painkillers"] call EFUNC(common,registerItemReplacement); + [QEGVAR(medical_status,initialized), { params ["_unit"]; diff --git a/addons/medical_treatment/config.cpp b/addons/medical_treatment/config.cpp index 3782645019..7b340d0109 100644 --- a/addons/medical_treatment/config.cpp +++ b/addons/medical_treatment/config.cpp @@ -12,7 +12,7 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; units[] = {"ACE_fieldDressingItem","ACE_packingBandageItem","ACE_elasticBandageItem","ACE_tourniquetItem","ACE_splintItem","ACE_painkillersItem","ACE_morphineItem","ACE_adenosineItem","ACE_epinephrineItem","ACE_plasmaIVItem","ACE_bloodIVItem","ACE_salineIVItem","ACE_quikClotItem","ACE_personalAidKitItem","ACE_surgicalKitItem","ACE_sutureItem","ACE_bodyBagItem","ACE_medicalSupplyCrate","ACE_medicalSupplyCrate_advanced"}; - weapons[] = {"ACE_fieldDressing","ACE_packingBandage","ACE_elasticBandage","ACE_tourniquet","ACE_splint","ACE_painkillers","ACE_morphine","ACE_adenosine","ACE_epinephrine","ACE_plasmaIV","ACE_plasmaIV_500","ACE_plasmaIV_250","ACE_bloodIV","ACE_bloodIV_500","ACE_bloodIV_250","ACE_salineIV","ACE_salineIV_500","ACE_salineIV_250","ACE_quikclot","ACE_personalAidKit","ACE_surgicalKit","ACE_suture","ACE_bodyBag","ACE_bodyBag_blue","ACE_bodyBag_white"}; + weapons[] = {"ACE_fieldDressing","ACE_packingBandage","ACE_elasticBandage","ACE_tourniquet","ACE_splint","ACE_painkillers","ACE_morphine","ACE_adenosine","ACE_epinephrine","ACE_plasmaIV","ACE_plasmaIV_500","ACE_plasmaIV_250","ACE_bloodIV","ACE_bloodIV_500","ACE_bloodIV_250","ACE_salineIV","ACE_salineIV_500","ACE_salineIV_250","ACE_quikclot","ACE_personalAidKit","ACE_surgicalKit","ACE_suture","ACE_bodyBag","ACE_bodyBag_blue","ACE_bodyBag_white","ACE_painkillers_Item"}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_medical_status", "ace_medical_damage", "ace_apl"}; author = ECSTRING(common,ACETeam); diff --git a/addons/overheating/CfgWeapons.hpp b/addons/overheating/CfgWeapons.hpp index 9232fa3249..0b8087cc13 100644 --- a/addons/overheating/CfgWeapons.hpp +++ b/addons/overheating/CfgWeapons.hpp @@ -97,17 +97,19 @@ class CfgWeapons { GVAR(closedBolt) = 1; GVAR(jamTypesAllowed)[] = {"Fire", "Dud"}; }; + class ACE_ItemCore; class CBA_MiscItem_ItemInfo; - // Deprecated, 3.16.0 Arsenal supports showing magazines as misc items + // Deprecated, 3.16.0 Arsenal supports showing magazines as misc. items + // However, since base game doesn't support misc. items, it's still needed to filling inventories in the editor class ACE_SpareBarrel_Item: ACE_ItemCore { displayName = CSTRING(SpareBarrelName); author = ECSTRING(common,ACETeam); - scope = 1; + scope = 2; scopeArsenal = 0; - descriptionshort = CSTRING(SpareBarrelDescription); - picture = QUOTE(PATHTOF(UI\spare_barrel_ca.paa)); + descriptionShort = CSTRING(SpareBarrelDescription); + picture = QPATHTOF(UI\spare_barrel_ca.paa); class ItemInfo: CBA_MiscItem_ItemInfo { mass = 25; }; From 15a5e74649315aa196c860e6c9591582ccc77c4e Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Thu, 22 Aug 2024 05:49:06 +0200 Subject: [PATCH 16/26] GM Compat - Add interaction anims to GM vehicles (#10234) Add interaction anims to GM --- addons/compat_gm/CfgVehicles.hpp | 422 ++++++++++++++++-- .../compat_gm_refuel/CfgVehicles.hpp | 336 ++++++++++++++ addons/compat_gm/compat_gm_refuel/config.cpp | 1 + .../compat_gm_repair/CfgVehicles.hpp | 100 +++++ addons/compat_gm/compat_gm_repair/config.cpp | 23 + .../compat_gm_repair/script_component.hpp | 3 + .../compat_gm_trenches/CfgVehicles.hpp | 47 ++ .../compat_gm/compat_gm_trenches/config.cpp | 23 + .../compat_gm_trenches/script_component.hpp | 3 + 9 files changed, 924 insertions(+), 34 deletions(-) create mode 100644 addons/compat_gm/compat_gm_refuel/CfgVehicles.hpp create mode 100644 addons/compat_gm/compat_gm_repair/CfgVehicles.hpp create mode 100644 addons/compat_gm/compat_gm_repair/config.cpp create mode 100644 addons/compat_gm/compat_gm_repair/script_component.hpp create mode 100644 addons/compat_gm/compat_gm_trenches/CfgVehicles.hpp create mode 100644 addons/compat_gm/compat_gm_trenches/config.cpp create mode 100644 addons/compat_gm/compat_gm_trenches/script_component.hpp diff --git a/addons/compat_gm/CfgVehicles.hpp b/addons/compat_gm/CfgVehicles.hpp index 6d03465cd7..d470e8a615 100644 --- a/addons/compat_gm/CfgVehicles.hpp +++ b/addons/compat_gm/CfgVehicles.hpp @@ -81,15 +81,242 @@ class CfgVehicles { class gm_brdm2_base: gm_wheeled_APC_base { EGVAR(refuel,fuelCapacity) = 290; + + class EGVAR(interaction,anims) { + class AmmoBox_01_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['ammobox_01', 'FireGeometry', 'AveragePoint']"}; + items[] = {"gm_AmmoBox_wood_04_empty"}; + name = "$STR_DN_gm_AmmoBox_wood_04_base"; + text = "$STR_DN_gm_AmmoBox_wood_04_base"; + }; + class AmmoBox_02_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['ammobox_02', 'FireGeometry', 'AveragePoint']"}; + items[] = {"gm_AmmoBox_wood_04_empty"}; + name = "$STR_DN_gm_AmmoBox_wood_04_base"; + text = "$STR_DN_gm_AmmoBox_wood_04_base"; + }; + class AmmoBox_03_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['ammobox_03', 'FireGeometry', 'AveragePoint']"}; + items[] = {"gm_AmmoBox_wood_04_empty"}; + name = "$STR_DN_gm_AmmoBox_wood_04_base"; + text = "$STR_DN_gm_AmmoBox_wood_04_base"; + }; + }; + }; + class gm_brdm2um_base: gm_brdm2_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class AmmoBox_01_unhide: AmmoBox_01_unhide { + positions[] = {{-0.1, -1.9, -0.5}}; + }; + class AmmoBox_02_unhide: AmmoBox_02_unhide { + positions[] = {{-0.55, -0.35, -0.35}}; + }; + class AmmoBox_03_unhide: AmmoBox_03_unhide { + positions[] = {{0.3, -1.85, -0.5}}; + }; + }; }; class gm_btr60_base: gm_wheeled_APC_base { EGVAR(refuel,fuelCapacity) = 290; EGVAR(cookoff,cookoffSelections)[] = {"commanderturret_hatch"}; + + class EGVAR(interaction,anims) { + class AmmoBox_01_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['ammobox_01', 'FireGeometry', 'AveragePoint']"}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_02_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['ammobox_02', 'FireGeometry', 'AveragePoint']"}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_03_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['ammobox_03', 'FireGeometry', 'AveragePoint']"}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_04_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['ammobox_04', 'FireGeometry', 'AveragePoint']"}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_05_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['ammobox_05', 'FireGeometry', 'AveragePoint']"}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_06_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['ammobox_06', 'FireGeometry', 'AveragePoint']"}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_07_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['ammobox_07', 'FireGeometry', 'AveragePoint']"}; + items[] = {"gm_AmmoBox_wood_04_empty"}; + name = "$STR_DN_gm_AmmoBox_wood_04_base"; + text = "$STR_DN_gm_AmmoBox_wood_04_base"; + }; + }; + }; + + class gm_ural375d_base: gm_wheeled_truck_base { + EGVAR(refuel,fuelCapacity) = 360; + + class EGVAR(interaction,anims) { + class AmmoBox_01_unhide { + phase = 0; + positions[] = {{-0.55, 1.83, 0.7}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + distance = 2.5; + }; + class AmmoBox_02_unhide { + phase = 0; + positions[] = {{0, 1.83, 0.7}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + distance = 3; + }; + class AmmoBox_03_unhide { + phase = 0; + positions[] = {{0.55, 1.83, 0.7}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + distance = 2.5; + }; + class AmmoBox_04_unhide { + phase = 0; + positions[] = {{-0.45, 1.83, 0.7}}; + items[] = {"gm_AmmoBox_wood_04_empty"}; + name = "$STR_DN_gm_AmmoBox_wood_04_base"; + text = "$STR_DN_gm_AmmoBox_wood_04_base"; + distance = 2.5; + }; + }; + }; + class gm_ural375d_mlrs_base: gm_ural375d_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class AmmoBox_01_unhide: AmmoBox_01_unhide { + positions[] = {{-0.55, 2, 0.5}}; + }; + class AmmoBox_02_unhide: AmmoBox_02_unhide { + positions[] = {{0, 2, 0.5}}; + }; + class AmmoBox_03_unhide: AmmoBox_03_unhide { + positions[] = {{0.55, 2, 0.5}}; + }; + class AmmoBox_04_unhide: AmmoBox_04_unhide { + positions[] = {{-0.45, 2, 0.5}}; + }; + }; + }; + class gm_ural375d_medic_base: gm_ural375d_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class AmmoBox_01_unhide: AmmoBox_01_unhide { + positions[] = {{-0.55, 2, 0.7}}; + }; + class AmmoBox_02_unhide: AmmoBox_02_unhide { + positions[] = {{0, 2, 0.7}}; + }; + class AmmoBox_03_unhide: AmmoBox_03_unhide { + positions[] = {{0.55, 2, 0.7}}; + }; + class AmmoBox_04_unhide: AmmoBox_04_unhide { + positions[] = {{-0.45, 2, 0.7}}; + }; + }; }; class gm_ural4320_base: gm_wheeled_truck_base { EGVAR(refuel,fuelCapacity) = 360; + + class EGVAR(interaction,anims) { + class AmmoBox_01_unhide { + phase = 0; + positions[] = {{-0.55, 1.47, 0.7}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + distance = 2.5; + }; + class AmmoBox_02_unhide { + phase = 0; + positions[] = {{0, 1.47, 0.7}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + distance = 3; + }; + class AmmoBox_03_unhide { + phase = 0; + positions[] = {{0.55, 1.47, 0.7}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + distance = 2.5; + }; + class AmmoBox_04_unhide { + phase = 0; + positions[] = {{-0.45, 1.47, 0.7}}; + items[] = {"gm_AmmoBox_wood_04_empty"}; + name = "$STR_DN_gm_AmmoBox_wood_04_base"; + text = "$STR_DN_gm_AmmoBox_wood_04_base"; + distance = 2.5; + }; + }; + }; + class gm_ural4320_repair_base: gm_ural4320_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class AmmoBox_01_unhide: AmmoBox_01_unhide { + positions[] = {{-0.55, 1.62, 0.7}}; + }; + class AmmoBox_02_unhide: AmmoBox_02_unhide { + positions[] = {{0, 1.62, 0.7}}; + }; + class AmmoBox_03_unhide: AmmoBox_03_unhide { + positions[] = {{0.55, 1.62, 0.7}}; + }; + class AmmoBox_04_unhide: AmmoBox_04_unhide { + positions[] = {{-0.45, 1.62, 0.7}}; + }; + }; + }; + class gm_ural44202_base: gm_ural4320_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class AmmoBox_01_unhide: AmmoBox_01_unhide { + positions[] = {{-0.55, 1.37, 0.7}}; + }; + class AmmoBox_02_unhide: AmmoBox_02_unhide { + positions[] = {{0, 1.37, 0.7}}; + }; + class AmmoBox_03_unhide: AmmoBox_03_unhide { + positions[] = {{0.55, 1.37, 0.7}}; + }; + class AmmoBox_04_unhide: AmmoBox_04_unhide { + positions[] = {{-0.45, 1.37, 0.7}}; + }; + }; }; class gm_ural4320_reammo_base: gm_ural4320_base { @@ -190,9 +417,103 @@ class CfgVehicles { EGVAR(refuel,fuelCapacity) = 460; EGVAR(cookoff,cookoffSelections)[] = {"mainturret_hatch","commanderturret_hatch"}; }; + class gm_bmp1sp2_base: gm_bmp1_base { + class EGVAR(interaction,anims) { + class AmmoBox_01_unhide { + phase = 0; + positions[] = {{-1.2, -2.52, -1.2}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_02_unhide { + phase = 0; + positions[] = {{-1.3, -2, -1.2}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_03_unhide { + phase = 0; + positions[] = {{-1.35, -1.43, -1.2}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_04_unhide { + phase = 0; + positions[] = {{1.2, -2.52, -1.2}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_05_unhide { + phase = 0; + positions[] = {{1.3, -2, -1.2}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_06_unhide { + phase = 0; + positions[] = {{1.35, -1.43, -1.2}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_07_unhide { + phase = 0; + positions[] = {{-1.45, 0.1, -1.3}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_08_unhide { + phase = 0; + positions[] = {{-1.45, 2, -1.3}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + class AmmoBox_09_unhide { + phase = 0; + positions[] = {{1.45, 2, -1.3}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + }; + }; + }; class gm_pt76_base: gm_tracked_Tank_base { EGVAR(refuel,fuelCapacity) = 250; + + class EGVAR(interaction,anims) { + class AmmoBox_01_unhide { + phase = 0; + positions[] = {{0.08, -1.75, -1}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + distance = 2.5; + }; + class AmmoBox_02_unhide { + phase = 0; + positions[] = {{0.08, -1.38, -1}}; + items[] = {"gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"}; + name = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + text = "$STR_DN_gm_AmmoBox_880Rnd_762x39mm_b_M43_ak47"; + distance = 2.5; + }; + class AmmoBox_03_unhide { + phase = 0; + positions[] = {{0.08, -2.15, -1}}; + items[] = {"gm_AmmoBox_wood_04_empty"}; + name = "$STR_DN_gm_AmmoBox_wood_04_base"; + text = "$STR_DN_gm_AmmoBox_wood_04_base"; + distance = 2.5; + }; + }; }; class gm_t55_base: gm_tracked_Tank_base { @@ -204,6 +525,21 @@ class CfgVehicles { EGVAR(refuel,fuelCapacity) = 812; }; + class gm_tracked_Artillery_base; + class gm_2s1_base: gm_tracked_Artillery_base { + class EGVAR(interaction,anims) { + class AmmoBox_01_unhide { + phase = 0; + // Rotate interactions with turret rotation + positions[] = {"[0, -1.3, 0] vectorAdd ([[0, -1.1, -0.35], [0, 0, 1], deg (_target animationPhase 'mainturret_trav_anim')] call CBA_fnc_vectRotate3D)"}; + items[] = {"gm_AmmoBox_wood_04_empty"}; + name = "$STR_DN_gm_AmmoBox_wood_04_base"; + text = "$STR_DN_gm_AmmoBox_wood_04_base"; + distance = 2.5; + }; + }; + }; + // WEST class gm_Leopard1_base; class gm_Leopard1a0_base: gm_Leopard1_base { @@ -211,6 +547,27 @@ class CfgVehicles { EGVAR(cookoff,cookoffSelections)[] = {"mainturret_hatch_1","commanderturret_hatch"}; }; + class gm_Leopard1a1_base: gm_Leopard1a0_base { + class EGVAR(interaction,anims) { + class AmmoBox_01_unhide { + phase = 0; + // Rotate interactions with turret rotation + positions[] = {"[0, -0.6, 0] vectorAdd ([[0.7, -2, -0.6], [0, 0, 1], deg (_target animationPhase 'mainturret_trav_anim')] call CBA_fnc_vectRotate3D)"}; + items[] = {"gm_AmmoBox_wood_04_empty"}; + name = "$STR_DN_gm_AmmoBox_wood_04_base"; + text = "$STR_DN_gm_AmmoBox_wood_04_base"; + }; + class AmmoBox_02_unhide { + phase = 0; + // Rotate interactions with turret rotation + positions[] = {"[0, -0.6, 0] vectorAdd ([[-0.3, -1.95, -0.6], [0, 0, 1], deg (_target animationPhase 'mainturret_trav_anim')] call CBA_fnc_vectRotate3D)"}; + items[] = {"gm_AmmoBox_wood_04_empty"}; + name = "$STR_DN_gm_AmmoBox_wood_04_base"; + text = "$STR_DN_gm_AmmoBox_wood_04_base"; + }; + }; + }; + class gm_Gepard_base: gm_Leopard1_base { EGVAR(refuel,fuelCapacity) = 985; }; @@ -257,42 +614,39 @@ class CfgVehicles { EGVAR(refuel,fuelCapacity) = 3700; EGVAR(fastroping,enabled) = 0; - // TODO: stringtables class UserActions { - class openDoor_L { - displayNameDefault = "Open left Door"; - displayName = "Open left Door"; - position = ""; - radius = 2.7; - onlyForPlayer = 1; - condition = QUOTE((this animationSourcePhase 'door_2_1_unhide' > 0.5) && (this doorPhase 'door_2_1_source' < 0.5) && {alive this} && {!(this getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)])}); - statement = "this animateDoor ['door_2_1_source',1]"; - }; - - class openDoor_R: openDoor_L { - displayNameDefault = "Open right Door"; - displayName = "Open right Door"; - condition = QUOTE((this animationSourcePhase 'door_2_2_unhide' > 0.5) && (this doorPhase 'door_2_2_source' < 0.5) && {alive this} && {!(this getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)])}); - statement = "this animateDoor ['door_2_2_source',1]"; - }; - - class closeDoor_L { - displayNameDefault = "Close left Door"; - displayName = "Close left Door"; - position = ""; - radius = 2.7; - onlyForPlayer = 1; - condition = QUOTE((this animationSourcePhase 'door_2_1_unhide' > 0.5) && (this doorPhase 'door_2_1_source' > 0.5) && {alive this} && {!(this getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)])}); - statement = "this animateDoor ['door_2_1_source',0]"; - }; - - class closeDoor_R: closeDoor_L { - displayNameDefault = "Close right Door"; - displayName = "Close right Door"; - condition = QUOTE((this animationSourcePhase 'door_2_2_unhide' > 0.5) && (this doorPhase 'door_2_2_source' > 0.5) && {alive this} && {!(this getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)])}); - statement = "this animateDoor ['door_2_2_source',0]"; - }; + class openDoor_L { + displayNameDefault = "$STR_a3_cfgvehicles_useractions_openldoor0"; + displayName = "$STR_a3_cfgvehicles_useractions_openldoor0"; + position = ""; + radius = 2.7; + onlyForPlayer = 1; + condition = QUOTE((this animationSourcePhase 'door_2_1_unhide' > 0.5) && (this doorPhase 'door_2_1_source' < 0.5) && {alive this} && {!(this getVariable [ARR_2(QQEGVAR(fastroping,doorsLocked),false)])}); + statement = "this animateDoor ['door_2_1_source',1]"; }; + class openDoor_R: openDoor_L { + displayNameDefault = "$STR_a3_cfgvehicles_useractions_openrdoor0"; + displayName = "$STR_a3_cfgvehicles_useractions_openrdoor0"; + condition = QUOTE((this animationSourcePhase 'door_2_2_unhide' > 0.5) && (this doorPhase 'door_2_2_source' < 0.5) && {alive this} && {!(this getVariable [ARR_2(QQEGVAR(fastroping,doorsLocked),false)])}); + statement = "this animateDoor ['door_2_2_source',1]"; + }; + + class closeDoor_L { + displayNameDefault = "$STR_a3_cfgvehicles_useractions_closeldoor0"; + displayName = "$STR_a3_cfgvehicles_useractions_closeldoor0"; + position = ""; + radius = 2.7; + onlyForPlayer = 1; + condition = QUOTE((this animationSourcePhase 'door_2_1_unhide' > 0.5) && (this doorPhase 'door_2_1_source' > 0.5) && {alive this} && {!(this getVariable [ARR_2(QQEGVAR(fastroping,doorsLocked),false)])}); + statement = "this animateDoor ['door_2_1_source',0]"; + }; + class closeDoor_R: closeDoor_L { + displayNameDefault = "$STR_a3_cfgvehicles_useractions_closerdoor0"; + displayName = "$STR_a3_cfgvehicles_useractions_closerdoor0"; + condition = QUOTE((this animationSourcePhase 'door_2_2_unhide' > 0.5) && (this doorPhase 'door_2_2_source' > 0.5) && {alive this} && {!(this getVariable [ARR_2(QQEGVAR(fastroping,doorsLocked),false)])}); + statement = "this animateDoor ['door_2_2_source',0]"; + }; + }; }; class gm_bo105p1m_vbh_base; class gm_bo105p1m_vbh_swooper_base: gm_bo105p1m_vbh_base { diff --git a/addons/compat_gm/compat_gm_refuel/CfgVehicles.hpp b/addons/compat_gm/compat_gm_refuel/CfgVehicles.hpp new file mode 100644 index 0000000000..aa51d46979 --- /dev/null +++ b/addons/compat_gm/compat_gm_refuel/CfgVehicles.hpp @@ -0,0 +1,336 @@ +class CfgVehicles { + class gm_typ2_base; + class gm_typ251_base: gm_typ2_base { + class EGVAR(interaction,anims) { + class canister_01_unhide { + phase = 0; + positions[] = {{-0.55, -0.17, 0.4}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class canister_02_unhide { + phase = 0; + positions[] = {{-0.55, -0.65, 0.4}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + class gm_typ253_base: gm_typ2_base { + class EGVAR(interaction,anims) { + class canister_01_unhide { + phase = 0; + positions[] = {{-0.55, -0.19, 0.4}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class canister_02_unhide { + phase = 0; + positions[] = {{-0.55, -0.68, 0.4}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + + class gm_wheeled_truck_base; + class gm_ural375d_base: gm_wheeled_truck_base { + class EGVAR(interaction,anims) { + class fuelcan_1_1_unhide { + phase = 0; + positions[] = {{-0.95, 3.15, -0.45}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class fuelcan_1_2_unhide { + phase = 0; + positions[] = {{0.9, 3.15, -0.45}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + class gm_ural375d_mlrs_base: gm_ural375d_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class fuelcan_1_1_unhide: fuelcan_1_1_unhide { + positions[] = {{-0.95, 3.35, -0.55}}; + }; + class fuelcan_1_2_unhide: fuelcan_1_2_unhide { + positions[] = {{0.9, 3.35, -0.55}}; + }; + }; + }; + class gm_ural375d_medic_base: gm_ural375d_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class fuelcan_1_1_unhide: fuelcan_1_1_unhide { + positions[] = {{-0.95, 3.35, -0.45}}; + }; + class fuelcan_1_2_unhide: fuelcan_1_2_unhide { + positions[] = {{0.9, 3.35, -0.45}}; + }; + }; + }; + + class gm_ural4320_base: gm_wheeled_truck_base { + class EGVAR(interaction,anims) { + class fuelcan_1_1_unhide { + phase = 0; + positions[] = {{-0.9, 3.1, -0.4}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class fuelcan_1_2_unhide { + phase = 0; + positions[] = {{0.9, 3.1, -0.4}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + class gm_ural4320_repair_base: gm_ural4320_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class fuelcan_1_1_unhide: fuelcan_1_1_unhide { + positions[] = {{-0.9, 3.25, -0.4}}; + }; + class fuelcan_1_2_unhide: fuelcan_1_2_unhide { + positions[] = {{0.9, 3.25, -0.4}}; + }; + }; + }; + class gm_ural44202_base: gm_ural4320_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class fuelcan_1_1_unhide: fuelcan_1_1_unhide { + positions[] = {{-0.9, 3, -0.4}}; + }; + class fuelcan_1_2_unhide: fuelcan_1_2_unhide { + positions[] = {{0.9, 3, -0.4}}; + }; + }; + }; + + class gm_wheeled_APC_base; + class gm_brdm2_base: gm_wheeled_APC_base { + class EGVAR(interaction,anims) { + class FuelCanister_01_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['fuelcanister_01', 'FireGeometry', 'AveragePoint']"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class FuelCanister_02_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['fuelcanister_02', 'FireGeometry', 'AveragePoint']"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class FuelCanister_03_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['fuelcanister_03', 'FireGeometry', 'AveragePoint']"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + class gm_brdm2um_base: gm_brdm2_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class FuelCanister_01_unhide: FuelCanister_01_unhide { + positions[] = {{0.87, -3, -1.2}}; + }; + class FuelCanister_02_unhide: FuelCanister_02_unhide { + positions[] = {{-0.87, -3, -1.2}}; + }; + class FuelCanister_03_unhide: FuelCanister_03_unhide { + positions[] = {{-0.4, -1.85, -0.5}}; + }; + }; + }; + + class gm_btr60_base: gm_wheeled_APC_base { + class EGVAR(interaction,anims) { + class FuelCanister_01_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['fuelcanister_01', 'FireGeometry', 'AveragePoint']"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class FuelCanister_02_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['fuelcanister_02', 'FireGeometry', 'AveragePoint']"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class FuelCanister_03_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['fuelcanister_03', 'FireGeometry', 'AveragePoint']"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class FuelCanister_04_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['fuelcanister_04', 'FireGeometry', 'AveragePoint']"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class FuelCanister_05_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['fuelcanister_05', 'FireGeometry', 'AveragePoint']"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class FuelCanister_06_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['fuelcanister_06', 'FireGeometry', 'AveragePoint']"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + class gm_btr60pa_base: gm_btr60_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class FuelCanister_05_unhide: FuelCanister_05_unhide { + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + }; + class FuelCanister_06_unhide: FuelCanister_06_unhide { + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + }; + }; + }; + class gm_btr60pb_base: gm_btr60_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class FuelCanister_03_unhide: FuelCanister_03_unhide { + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + }; + class FuelCanister_04_unhide: FuelCanister_04_unhide { + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + }; + }; + }; + class gm_btr60pu12_base: gm_btr60_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class FuelCanister_03_unhide: FuelCanister_03_unhide { + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + }; + class FuelCanister_04_unhide: FuelCanister_04_unhide { + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + }; + }; + }; + + class gm_bmp1_base; + class gm_bmp1sp2_base: gm_bmp1_base { + class EGVAR(interaction,anims) { + class FuelCanister_01_unhide { + phase = 0; + positions[] = {{-1.2, -2.52, -1.2}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class FuelCanister_02_unhide { + phase = 0; + positions[] = {{1.2, -2.52, -1.2}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + + class gm_zsu234_base; + class gm_zsu234v1_base: gm_zsu234_base { + class EGVAR(interaction,anims) { + class FuelCanister_01_unhide { + phase = 0; + // Rotate interactions with turret rotation + positions[] = {"[0, 0.2, 0] vectorAdd ([[-0.85, -2.2, -0.9], [0, 0, 1], deg (_target animationPhase 'mainturret_trav_anim')] call CBA_fnc_vectRotate3D)"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class FuelCanister_02_unhide { + phase = 0; + // Rotate interactions with turret rotation + positions[] = {"[0, 0.2, 0] vectorAdd ([[0.7, -2.25, -0.85], [0, 0, 1], deg (_target animationPhase 'mainturret_trav_anim')] call CBA_fnc_vectRotate3D)"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class FuelCanister_03_unhide { + phase = 0; + // Rotate interactions with turret rotation + positions[] = {"[0, 0.2, 0] vectorAdd ([[0.92, -2.25, -0.85], [0, 0, 1], deg (_target animationPhase 'mainturret_trav_anim')] call CBA_fnc_vectRotate3D)"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + + class gm_tracked_Tank_base; + class gm_pt76_base: gm_tracked_Tank_base { + class EGVAR(interaction,anims) { + class FuelTank_01_unhide { + phase = 0; + positions[] = {{-1, -2.85, -1}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class FuelTank_02_unhide { + phase = 0; + positions[] = {{1, -2.85, -1}}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + + class gm_Leopard1a0_base; + class gm_Leopard1a1_base: gm_Leopard1a0_base { + class EGVAR(interaction,anims) { + class FuelCanister_01_unhide { + phase = 0; + // Rotate interactions with turret rotation + positions[] = {"[0, -0.6, 0] vectorAdd ([[0.25, -1.9, -0.55], [0, 0, 1], deg (_target animationPhase 'mainturret_trav_anim')] call CBA_fnc_vectRotate3D)"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + distance = 2.5; + }; + class FuelCanister_02_unhide { + phase = 0; + // Rotate interactions with turret rotation + positions[] = {"[0, -0.6, 0] vectorAdd ([[-0.8, -1.65, -0.55], [0, 0, 1], deg (_target animationPhase 'mainturret_trav_anim')] call CBA_fnc_vectRotate3D)"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class FuelCanister_03_unhide { + phase = 0; + // Rotate interactions with turret rotation + positions[] = {"[0, -0.6, 0] vectorAdd ([[0.8, -1.8, -0.55], [0, 0, 1], deg (_target animationPhase 'mainturret_trav_anim')] call CBA_fnc_vectRotate3D)"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; +}; diff --git a/addons/compat_gm/compat_gm_refuel/config.cpp b/addons/compat_gm/compat_gm_refuel/config.cpp index 05688eff70..6becabe70a 100644 --- a/addons/compat_gm/compat_gm_refuel/config.cpp +++ b/addons/compat_gm/compat_gm_refuel/config.cpp @@ -21,3 +21,4 @@ class CfgPatches { }; #include "CfgEventHandlers.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/compat_gm/compat_gm_repair/CfgVehicles.hpp b/addons/compat_gm/compat_gm_repair/CfgVehicles.hpp new file mode 100644 index 0000000000..12f9253bba --- /dev/null +++ b/addons/compat_gm/compat_gm_repair/CfgVehicles.hpp @@ -0,0 +1,100 @@ +class CfgVehicles { + class gm_wheeled_car_base; + class gm_uaz469_base: gm_wheeled_car_base { + class EGVAR(interaction,anims) { + class spare_wheel_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['spare_wheel', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class gm_wheeled_APC_base; + class gm_brdm2_base: gm_wheeled_APC_base { + class EGVAR(interaction,anims) { + class SpareWheel_01_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['sparewheel_01', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + distance = 2.5; + }; + class SpareWheel_02_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['sparewheel_02', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + class gm_brdm2um_base: gm_brdm2_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class SpareWheel_01_unhide: SpareWheel_01_unhide { + positions[] = {{0.2, -0.7, -0.25}}; + distance = 2; + }; + class SpareWheel_02_unhide: SpareWheel_02_unhide { + positions[] = {{0, -1.6, -0.4}}; + }; + }; + }; + + class gm_btr60_base: gm_wheeled_APC_base { + class EGVAR(interaction,anims) { + class SpareWheel_01_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['sparewheel_01', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + distance = 3; + }; + class SpareWheel_02_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['sparewheel_02', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + class SpareWheel_03_unhide { + phase = 0; + positions[] = {"_target selectionPosition ['sparewheel_03', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class gm_bmp1_base; + class gm_bmp1sp2_base: gm_bmp1_base { + class EGVAR(interaction,anims) { + class spareTracks_1_1_unhide { + phase = 0; + positions[] = {"(_target selectionPosition ['door_1_1', 'FireGeometry', 'AveragePoint']) vectorAdd [0, 0, -0.15]"}; + items[] = {"ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + class spareTracks_1_2_unhide { + phase = 0; + positions[] = {"(_target selectionPosition ['door_1_2', 'FireGeometry', 'AveragePoint']) vectorAdd [0, 0, -0.15]"}; + items[] = {"ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + class spareTracks_2_1_unhide { + phase = 0; + positions[] = {{-1.1, -2.7, -1.3}, {1.1, -2.7, -1.3}}; + items[] = {"ACE_Track", "ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + }; + }; +}; diff --git a/addons/compat_gm/compat_gm_repair/config.cpp b/addons/compat_gm/compat_gm_repair/config.cpp new file mode 100644 index 0000000000..6fae9858b4 --- /dev/null +++ b/addons/compat_gm/compat_gm_repair/config.cpp @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "gm_core", + "ace_repair" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_gm/compat_gm_repair/script_component.hpp b/addons/compat_gm/compat_gm_repair/script_component.hpp new file mode 100644 index 0000000000..1af928486c --- /dev/null +++ b/addons/compat_gm/compat_gm_repair/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT repair +#define SUBCOMPONENT_BEAUTIFIED Repair +#include "..\script_component.hpp" diff --git a/addons/compat_gm/compat_gm_trenches/CfgVehicles.hpp b/addons/compat_gm/compat_gm_trenches/CfgVehicles.hpp new file mode 100644 index 0000000000..b5c32d8be1 --- /dev/null +++ b/addons/compat_gm/compat_gm_trenches/CfgVehicles.hpp @@ -0,0 +1,47 @@ +class CfgVehicles { + class gm_wheeled_truck_base; + class gm_ural375d_base: gm_wheeled_truck_base { + class EGVAR(interaction,anims) { + class tools_unhide { + phase = 0; + positions[] = {{0.9, 3.15, -0.5}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + class gm_ural375d_mlrs_base: gm_ural375d_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class tools_unhide: tools_unhide { + positions[] = {{0.9, 3.35, -0.65}}; + }; + }; + }; + class gm_ural375d_medic_base: gm_ural375d_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class tools_unhide: tools_unhide { + positions[] = {{0.9, 3.35, -0.5}}; + }; + }; + }; + + class gm_ural4320_base: gm_wheeled_truck_base { + class EGVAR(interaction,anims) { + class tools_unhide { + phase = 0; + positions[] = {{0.93, 2.7, -0.5}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + class gm_ural44202_base: gm_ural4320_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class tools_unhide: tools_unhide { + positions[] = {{0.9, 2.6, -0.5}}; + }; + }; + }; +}; diff --git a/addons/compat_gm/compat_gm_trenches/config.cpp b/addons/compat_gm/compat_gm_trenches/config.cpp new file mode 100644 index 0000000000..13c4dd0816 --- /dev/null +++ b/addons/compat_gm/compat_gm_trenches/config.cpp @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "gm_core", + "ace_trenches" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_gm/compat_gm_trenches/script_component.hpp b/addons/compat_gm/compat_gm_trenches/script_component.hpp new file mode 100644 index 0000000000..10b90eb71e --- /dev/null +++ b/addons/compat_gm/compat_gm_trenches/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT trenches +#define SUBCOMPONENT_BEAUTIFIED Trenches +#include "..\script_component.hpp" From 82f50194881ba9b5bebd386288bd39345a1323f3 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Thu, 22 Aug 2024 05:49:28 +0200 Subject: [PATCH 17/26] SPE Compat - Add interaction anims to SPE vehicles (#10226) Add interaction anims to SPE --- addons/compat_spe/CfgVehicles/wheeled.hpp | 72 ++++++++++- .../compat_spe_refuel/CfgVehicles.hpp | 61 +++++++-- .../compat_spe_repair/CfgVehicles.hpp | 106 ++++++++++++++++ .../compat_spe/compat_spe_repair/config.cpp | 27 ++++ .../compat_spe_repair/script_component.hpp | 3 + .../compat_spe_trenches/CfgVehicles.hpp | 119 ++++++++++++++++++ .../compat_spe/compat_spe_trenches/config.cpp | 27 ++++ .../compat_spe_trenches/script_component.hpp | 3 + 8 files changed, 409 insertions(+), 9 deletions(-) create mode 100644 addons/compat_spe/compat_spe_repair/CfgVehicles.hpp create mode 100644 addons/compat_spe/compat_spe_repair/config.cpp create mode 100644 addons/compat_spe/compat_spe_repair/script_component.hpp create mode 100644 addons/compat_spe/compat_spe_trenches/CfgVehicles.hpp create mode 100644 addons/compat_spe/compat_spe_trenches/config.cpp create mode 100644 addons/compat_spe/compat_spe_trenches/script_component.hpp diff --git a/addons/compat_spe/CfgVehicles/wheeled.hpp b/addons/compat_spe/CfgVehicles/wheeled.hpp index 6ed68dfbdf..534efcf490 100644 --- a/addons/compat_spe/CfgVehicles/wheeled.hpp +++ b/addons/compat_spe/CfgVehicles/wheeled.hpp @@ -56,8 +56,12 @@ class SPE_OpelBlitz_Ammo: SPE_OpelBlitz_base { EGVAR(rearm,defaultSupply) = 1200; }; -// WHEELED - ALLIED FORCES +class SPE_OpelBlitz_Fuel: SPE_OpelBlitz_base { + EGVAR(refuel,hooks)[] = {{-0.23, -2.58, -0.59}}; + EGVAR(refuel,fuelCargo) = 2000; +}; +// WHEELED - ALLIED FORCES class SPE_US_M3_Halftrack_Ambulance: SPE_Halftrack_base { EGVAR(medical,medicClass) = 1; }; @@ -69,3 +73,69 @@ class SPE_US_M3_Halftrack_Repair: SPE_Halftrack_base { class SPE_US_M3_Halftrack_Ammo: SPE_Halftrack_base { EGVAR(rearm,defaultSupply) = 1200; }; + +class SPE_US_M3_Halftrack_Fuel: SPE_Halftrack_base { + EGVAR(refuel,hooks)[] = {{-0.23, -2.58, -0.59}}; + EGVAR(refuel,fuelCargo) = 2000; +}; + +class SPE_Car_base; +class SPE_G503_MB_base: SPE_Car_base { + class EGVAR(interaction,anims) { + class hide_musette_source { + positions[] = {{0.8, -0.97, -0.6}, {-0.8, -0.92, -0.6}}; + items[] = {"B_SPE_US_M36", "B_SPE_US_M36"}; + name = "$STR_a3_cfgvehicleclasses_backpacks0"; + text = "$STR_a3_cfgvehicleclasses_backpacks0"; + }; + }; +}; +class SPE_US_G503_MB_M1919_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_musette_source: hide_musette_source { + positions[] = {{0.8, -0.5, -0.6}, {-0.8, -0.45, -0.6}}; + }; + }; +}; +class SPE_US_G503_MB_M1919_Armoured_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_musette_source: hide_musette_source { + positions[] = {{0.8, -0.5, -0.6}, {-0.8, -0.45, -0.6}}; + }; + }; +}; +class SPE_US_G503_MB_M1919_PATROL_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_musette_source: hide_musette_source { + positions[] = {{0.8, -0.5, -0.6}, {-0.8, -0.45, -0.6}}; + }; + }; +}; +class SPE_US_G503_MB_M2_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_musette_source: hide_musette_source { + positions[] = {{0.8, -0.5, -0.6}, {-0.8, -0.45, -0.6}}; + }; + }; +}; +class SPE_US_G503_MB_M2_Armoured_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_musette_source: hide_musette_source { + positions[] = {{0.8, -0.5, -0.6}, {-0.8, -0.45, -0.6}}; + }; + }; +}; +class SPE_US_G503_MB_M2_PATROL_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_musette_source: hide_musette_source { + positions[] = {{0.8, -0.5, -0.6}, {-0.8, -0.45, -0.6}}; + }; + }; +}; +class SPE_G503_MB_Ambulance_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_musette_source: hide_musette_source { + positions[] = {{0.8, -0.5, -0.6}, {-0.8, -0.45, -0.6}}; + }; + }; +}; diff --git a/addons/compat_spe/compat_spe_refuel/CfgVehicles.hpp b/addons/compat_spe/compat_spe_refuel/CfgVehicles.hpp index fc1ebc9b4e..8819f20559 100644 --- a/addons/compat_spe/compat_spe_refuel/CfgVehicles.hpp +++ b/addons/compat_spe/compat_spe_refuel/CfgVehicles.hpp @@ -1,12 +1,57 @@ class CfgVehicles { - class SPE_Halftrack_base; - class SPE_US_M3_Halftrack_Fuel: SPE_Halftrack_base { - EGVAR(refuel,hooks)[] = {{-0.23,-2.58,-0.59}}; - EGVAR(refuel,fuelCargo) = 2000; + // Vehicle animation interactions + class SPE_Car_base; + class SPE_G503_MB_base: SPE_Car_base { + class EGVAR(interaction,anims) { + class hide_jerry_can_source { + positions[] = {"_target selectionPosition ['hide_jerry_can', 'ViewGeometry', 'AveragePoint']"}; + items[] = {"Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; }; - class SPE_OpelBlitz_base; - class SPE_OpelBlitz_Fuel: SPE_OpelBlitz_base { - EGVAR(refuel,hooks)[] = {{-0.23,-2.58,-0.59}}; - EGVAR(refuel,fuelCargo) = 2000; + + class SPE_Truck_base; + class SPE_CCKW_353_Base: SPE_Truck_base { + class EGVAR(interaction,anims) { + class spare_fuel_hide_source { + positions[] = {{0.8, 1.8, -1}, {-0.8, 1.8, -1}, {0.8, 3.5, -1}, {-0.8, 3.5, -1}}; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + class SPE_CCKW_353_Ammo: SPE_CCKW_353_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class spare_fuel_hide_source: spare_fuel_hide_source { + positions[] = {{0.8, 1.8, -0.85}, {-0.8, 1.8, -0.85}, {0.8, 3.5, -0.85}, {-0.8, 3.5, -0.85}}; + }; + }; + }; + class SPE_CCKW_353_Repair: SPE_CCKW_353_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class spare_fuel_hide_source: spare_fuel_hide_source { + positions[] = {{0.8, 1.9, -0.85}, {-0.8, 1.9, -0.85}, {0.8, 3.6, -0.85}, {-0.8, 3.6, -0.85}}; + }; + }; + }; + class SPE_CCKW_353_Fuel: SPE_CCKW_353_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class spare_fuel_hide_source: spare_fuel_hide_source { + positions[] = {{0.8, 1.25, -0.8}, {-0.8, 1.25, -0.8}, {0.8, 2.95, -0.8}, {-0.8, 2.95, -0.8}, {0.8, -1, -0.3}, {-0.8, -1, -0.3}}; + items[] = { // 32x + "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", + "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", + "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", + "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", + "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", + "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", + "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", + "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F" + }; + }; + }; }; }; diff --git a/addons/compat_spe/compat_spe_repair/CfgVehicles.hpp b/addons/compat_spe/compat_spe_repair/CfgVehicles.hpp new file mode 100644 index 0000000000..5b245eebbc --- /dev/null +++ b/addons/compat_spe/compat_spe_repair/CfgVehicles.hpp @@ -0,0 +1,106 @@ +class CfgVehicles { + // Vehicle animation interactions + class SPE_Car_base; + class SPE_G503_MB_base: SPE_Car_base { + class EGVAR(interaction,anims) { + class hide_spare_wheel_source { + positions[] = {"_target selectionPosition ['hide_spare_wheel', 'ViewGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class SPE_Truck_base; + class SPE_CCKW_353_Base: SPE_Truck_base { + class EGVAR(interaction,anims) { + class spare_wheel_hide_source { + positions[] = {{-0.9, 0.35, -0.95}}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + class SPE_CCKW_353_Ammo: SPE_CCKW_353_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class spare_wheel_hide_source: spare_wheel_hide_source { + positions[] = {{-0.9, 0.35, -0.8}}; + }; + }; + }; + + class SPE_R200_base: SPE_Car_base { + class EGVAR(interaction,anims) { + class hide_spare_wheel_source { + positions[] = {"_target selectionPosition ['hide_sparetire', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class SPE_Tank_base; + class SPE_M18_Hellcat_Base: SPE_Tank_base { + class EGVAR(interaction,anims) { + class hull_armour_hide_source { + positions[] = {"_target selectionPosition ['spare_track_hull', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Track", "ACE_Track", "ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + }; + }; + + class SPE_PzKpfwV_base: SPE_Tank_base { + class EGVAR(interaction,anims) { + class spare_tracks_hide_source { + selections[] = {"spare_tracks"}; + positions[] = {"private _pos = _target selectionPosition 'spare_tracks'; _pos set [0, -(_pos select 0)]; _pos"}; // Mirror position to other side of vehicle + items[] = {"ACE_Track", "ACE_Track", "ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + }; + }; + + class SPE_PzKpfwVI_H1_base: SPE_Tank_base { + class EGVAR(interaction,anims) { + class hull_armour_hide_source { + positions[] = {{-1.3, 1.7, -0.75}, {1.1, 1.7, -0.75}, {-0.05, 2.35, -1.5}}; + items[] = {"ACE_Track", "ACE_Track", "ACE_Track", "ACE_Track", "ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + class turret_armour_hide_source { + // Rotate interactions with turret rotation + positions[] = { + "[0, -0.6, 0] vectorAdd ([[1.2, 0, -0.2], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)", + "[0, -0.6, 0] vectorAdd ([[-1.3, -0.3, -0.2], [0, 0, 1], deg (_target animationPhase 'MainTurret')] call CBA_fnc_vectRotate3D)" + }; + items[] = {"ACE_Track", "ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + }; + }; + + class SPE_Jagdpanther_G1_base: SPE_Tank_base { + class EGVAR(interaction,anims) { + class hide_spare_tracks_left_source { + positions[] = {"private _pos = _target selectionPosition ['hide_spare_tracks_right', 'FireGeometry', 'AveragePoint']; _pos set [0, -(_pos select 0)]; _pos vectorAdd [0, 0.335, 0]"}; + items[] = {"ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + class hide_spare_tracks_right_source { + positions[] = {"_target selectionPosition ['hide_spare_tracks_right', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Track", "ACE_Track"}; + name = ECSTRING(repair,RemoveTrack); + text = ECSTRING(repair,RemovingTrack); + }; + }; + }; +}; diff --git a/addons/compat_spe/compat_spe_repair/config.cpp b/addons/compat_spe/compat_spe_repair/config.cpp new file mode 100644 index 0000000000..356ef6a6be --- /dev/null +++ b/addons/compat_spe/compat_spe_repair/config.cpp @@ -0,0 +1,27 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "ww2_spe_assets_c_weapons_infantryweapons_c", + "ww2_spe_assets_c_vehicles_staticweapons_c", + "ww2_spe_assets_c_vehicles_weapons_c", + "ww2_spe_core_f_system_staticweapons_f", + "ww2_spe_core_c_core_c_eventhandlers", + "ace_repair" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_spe/compat_spe_repair/script_component.hpp b/addons/compat_spe/compat_spe_repair/script_component.hpp new file mode 100644 index 0000000000..1af928486c --- /dev/null +++ b/addons/compat_spe/compat_spe_repair/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT repair +#define SUBCOMPONENT_BEAUTIFIED Repair +#include "..\script_component.hpp" diff --git a/addons/compat_spe/compat_spe_trenches/CfgVehicles.hpp b/addons/compat_spe/compat_spe_trenches/CfgVehicles.hpp new file mode 100644 index 0000000000..bb4b78721d --- /dev/null +++ b/addons/compat_spe/compat_spe_trenches/CfgVehicles.hpp @@ -0,0 +1,119 @@ +class CfgVehicles { + // Vehicle animation interactions + class SPE_Car_base; + class SPE_G503_MB_base: SPE_Car_base { + class EGVAR(interaction,anims) { + class hide_tools_source { + positions[] = {{-0.7, 0, -0.9}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + class SPE_US_G503_MB_M1919_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tools_source: hide_tools_source { + positions[] = {{-0.7, 0.45, -0.9}}; + }; + }; + }; + class SPE_US_G503_MB_M1919_Armoured_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tools_source: hide_tools_source { + positions[] = {{-0.7, 0.45, -0.9}}; + }; + }; + }; + class SPE_US_G503_MB_M1919_PATROL_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tools_source: hide_tools_source { + positions[] = {{-0.7, 0.45, -0.9}}; + }; + }; + }; + class SPE_US_G503_MB_M2_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tools_source: hide_tools_source { + positions[] = {{-0.7, 0.45, -0.9}}; + }; + }; + }; + class SPE_US_G503_MB_M2_Armoured_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tools_source: hide_tools_source { + positions[] = {{-0.7, 0.45, -0.9}}; + }; + }; + }; + class SPE_US_G503_MB_M2_PATROL_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tools_source: hide_tools_source { + positions[] = {{-0.7, 0.45, -0.9}}; + }; + }; + }; + class SPE_G503_MB_Ambulance_base: SPE_G503_MB_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tools_source: hide_tools_source { + positions[] = {{-0.7, 0.45, -0.9}}; + }; + }; + }; + + class SPE_R200_base: SPE_Car_base { + class EGVAR(interaction,anims) { + class hide_shovel_source { + positions[] = {{0.5, 1.2, -1.05}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + + class SPE_Tank_base; + class SPE_PzKpfwV_base: SPE_Tank_base { + class EGVAR(interaction,anims) { + class tools_hide_source { + positions[] = {{-1.45, 0.7, -0.4}}; + items[] = {"ACE_EntrenchingTool", "ACE_wirecutter"}; + name = "$STR_a3_cfgeditorsubcategories_edsubcat_tools0"; + text = "$STR_a3_cfgeditorsubcategories_edsubcat_tools0"; + }; + }; + }; + + class SPE_PzKpfwVI_H1_base: SPE_Tank_base { + class EGVAR(interaction,anims) { + class tools_hide_source { + positions[] = {{0, 1, -0.6}, {1.1, 0.1, -0.6}}; + items[] = {"ACE_EntrenchingTool", "ACE_wirecutter"}; + name = "$STR_a3_cfgeditorsubcategories_edsubcat_tools0"; + text = "$STR_a3_cfgeditorsubcategories_edsubcat_tools0"; + }; + }; + }; + + class SPE_StuG_III_base: SPE_Tank_base { + class EGVAR(interaction,anims) { + class hide_tools_left_source { + positions[] = {{-1.4, -1.4, -0.7}, {-1, -2.2, -0.65}}; + items[] = {"ACE_EntrenchingTool", "ACE_wirecutter"}; + name = "$STR_a3_cfgeditorsubcategories_edsubcat_tools0"; + text = "$STR_a3_cfgeditorsubcategories_edsubcat_tools0"; + }; + }; + }; + + class SPE_Jagdpanther_G1_base: SPE_Tank_base { + class EGVAR(interaction,anims) { + class hide_tools_left_source { + positions[] = {{-1.4, 0.5, -0.7}}; + items[] = {"ACE_EntrenchingTool", "ACE_wirecutter"}; + name = "$STR_a3_cfgeditorsubcategories_edsubcat_tools0"; + text = "$STR_a3_cfgeditorsubcategories_edsubcat_tools0"; + }; + }; + }; +}; diff --git a/addons/compat_spe/compat_spe_trenches/config.cpp b/addons/compat_spe/compat_spe_trenches/config.cpp new file mode 100644 index 0000000000..1b742b5782 --- /dev/null +++ b/addons/compat_spe/compat_spe_trenches/config.cpp @@ -0,0 +1,27 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "ww2_spe_assets_c_weapons_infantryweapons_c", + "ww2_spe_assets_c_vehicles_staticweapons_c", + "ww2_spe_assets_c_vehicles_weapons_c", + "ww2_spe_core_f_system_staticweapons_f", + "ww2_spe_core_c_core_c_eventhandlers", + "ace_trenches" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_spe/compat_spe_trenches/script_component.hpp b/addons/compat_spe/compat_spe_trenches/script_component.hpp new file mode 100644 index 0000000000..10b90eb71e --- /dev/null +++ b/addons/compat_spe/compat_spe_trenches/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT trenches +#define SUBCOMPONENT_BEAUTIFIED Trenches +#include "..\script_component.hpp" From afde7264ba8ecd0d2ed7ccd8573091d6325926a3 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Thu, 22 Aug 2024 12:13:54 -0500 Subject: [PATCH 18/26] UI - Add keybind to hide all hud elements (#10227) * UI - Add keybind to hide all hud elements * Handle advFatigue stamina bar * Update stringtable.xml * Update docs/wiki/framework/ui-framework.md Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com> --------- Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com> --- addons/advanced_fatigue/XEH_PREP.hpp | 1 + addons/advanced_fatigue/XEH_postInit.sqf | 2 ++ .../functions/fnc_mainLoop.sqf | 2 +- .../functions/fnc_updateStaminaBar.sqf | 25 +++++++++++++++++++ addons/advanced_fatigue/initSettings.inc.sqf | 15 ++--------- addons/common/functions/fnc_showHud.sqf | 7 +++--- addons/ui/XEH_clientInit.sqf | 22 ++++++++++++++++ addons/ui/stringtable.xml | 3 +++ docs/wiki/framework/ui-framework.md | 9 +++++++ 9 files changed, 69 insertions(+), 17 deletions(-) create mode 100644 addons/advanced_fatigue/functions/fnc_updateStaminaBar.sqf diff --git a/addons/advanced_fatigue/XEH_PREP.hpp b/addons/advanced_fatigue/XEH_PREP.hpp index 22bb99617a..509c85e375 100644 --- a/addons/advanced_fatigue/XEH_PREP.hpp +++ b/addons/advanced_fatigue/XEH_PREP.hpp @@ -10,3 +10,4 @@ PREP(mainLoop); PREP(moduleSettings); PREP(removeDutyFactor); PREP(renderDebugLines); +PREP(updateStaminaBar); diff --git a/addons/advanced_fatigue/XEH_postInit.sqf b/addons/advanced_fatigue/XEH_postInit.sqf index 519d218b8c..e3b75a64a6 100644 --- a/addons/advanced_fatigue/XEH_postInit.sqf +++ b/addons/advanced_fatigue/XEH_postInit.sqf @@ -14,6 +14,8 @@ call FUNC(renderDebugLines); ["CBA_settingsInitialized", { if (!GVAR(enabled)) exitWith {}; + [QEGVAR(ui,hideHud), LINKFUNC(updateStaminaBar)] call CBA_fnc_addEventHandler; + ["baseline", { private _fatigue = ACE_player getVariable [QGVAR(aimFatigue), 0]; switch (stance ACE_player) do { diff --git a/addons/advanced_fatigue/functions/fnc_mainLoop.sqf b/addons/advanced_fatigue/functions/fnc_mainLoop.sqf index a07abae794..16d355a424 100644 --- a/addons/advanced_fatigue/functions/fnc_mainLoop.sqf +++ b/addons/advanced_fatigue/functions/fnc_mainLoop.sqf @@ -140,7 +140,7 @@ systemChat format ["---- velocity %1 - respiratoryRate: %2 ----", (vectorMagnitu [ACE_player, _perceivedFatigue, GVAR(anReserve) == 0, _fwdAngle, _sideAngle] call FUNC(handleEffects); -if (GVAR(enableStaminaBar)) then { +if (GVAR(enableStaminaBarRealized)) then { [GVAR(anReserve) / AN_MAXRESERVE] call FUNC(handleStaminaBar); }; diff --git a/addons/advanced_fatigue/functions/fnc_updateStaminaBar.sqf b/addons/advanced_fatigue/functions/fnc_updateStaminaBar.sqf new file mode 100644 index 0000000000..627430c820 --- /dev/null +++ b/addons/advanced_fatigue/functions/fnc_updateStaminaBar.sqf @@ -0,0 +1,25 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Updates the stamina bar state + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_advanced_fatigue_fnc_updateStaminaBar + * + * Public: No + */ + +GVAR(enableStaminaBarRealized) = GVAR(enabled) && GVAR(enableStaminaBar) && {!(missionNamespace getVariable [QEGVAR(ui,hideHud), false])}; +TRACE_1("updateStaminaBar",GVAR(enableStaminaBarRealized)); + +private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; +if (isNull _staminaBarContainer) exitWith {}; + +_staminaBarContainer ctrlSetFade ([1, 0] select GVAR(enableStaminaBarRealized)); +_staminaBarContainer ctrlCommit 0; diff --git a/addons/advanced_fatigue/initSettings.inc.sqf b/addons/advanced_fatigue/initSettings.inc.sqf index 01eba8652d..40d1d08f0d 100644 --- a/addons/advanced_fatigue/initSettings.inc.sqf +++ b/addons/advanced_fatigue/initSettings.inc.sqf @@ -6,12 +6,7 @@ true, 1, { - if (!_this) then { - private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; - _staminaBarContainer ctrlSetFade 1; - _staminaBarContainer ctrlCommit 0; - }; - + call FUNC(updateStaminaBar); [QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged) }, true // Needs mission restart @@ -24,13 +19,7 @@ LSTRING(DisplayName), true, 1, - { - if (!_this) then { - private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; - _staminaBarContainer ctrlSetFade 1; - _staminaBarContainer ctrlCommit 0; - }; - } + {call FUNC(updateStaminaBar)} ] call CBA_fnc_addSetting; [ diff --git a/addons/common/functions/fnc_showHud.sqf b/addons/common/functions/fnc_showHud.sqf index 5bb0153772..d74bed9cbd 100644 --- a/addons/common/functions/fnc_showHud.sqf +++ b/addons/common/functions/fnc_showHud.sqf @@ -6,8 +6,8 @@ * * Arguments: * 0: Source ID (default: "") - * 1: Show Hud Bool Array (8 to set, empty to remove) (default: []) - * - [hud, info, radar, compass, direction, menu, group, cursors] + * 1: Show Hud Bool Array (10 to set, empty to remove) (default: []) + * - [hud, info, radar, compass, direction, menu, group, cursors, panels, kills] * - hud: Boolean - show scripted HUD (same as normal showHUD true/false) * - info: Boolean - show vehicle + soldier info (hides weapon info from the HUD as well) * - radar: Boolean - show vehicle radar @@ -17,7 +17,8 @@ * - group: Boolean - show group info bar (hides squad leader info bar) * - cursors: Boolean - show HUD weapon cursors (connected with scripted HUD) * - panels: Boolean - show vehicle panels / GPS - * - ???: Boolean - Possibly related to changelog entry `Added: A new showKillConfirmations parameter for the showHud command` + * - kills: Boolean - show "x killed by y" systemChat messages + * - showIcon3D: is unsupported as it has inverted logic * * Return Value: * Resulting ShowHud Array diff --git a/addons/ui/XEH_clientInit.sqf b/addons/ui/XEH_clientInit.sqf index d9d3fa5717..5bf28bc58d 100644 --- a/addons/ui/XEH_clientInit.sqf +++ b/addons/ui/XEH_clientInit.sqf @@ -1,4 +1,5 @@ #include "script_component.hpp" +#include "\a3\ui_f\hpp\defineDIKCodes.inc" // Exit on Headless if (!hasInterface) exitWith {}; @@ -48,3 +49,24 @@ GVAR(elementsSet) = createHashMap; }] call CBA_fnc_addEventHandler; [QUOTE(ADDON), "AnimChanged", LINKFUNC(onAnimChanged), true] call EFUNC(common,addPlayerEH); + + +["ACE3 Common", QGVAR(hideHud), localize LSTRING(hideHud), { + GVAR(hideHud) = !(missionNamespace getVariable [QGVAR(hideHud), false]); + [QGVAR(hideHud), [GVAR(hideHud)]] call CBA_fnc_localEvent; + + private _mask = []; + if (GVAR(hideHud)) then { _mask resize [10, false] }; + [QGVAR(hideHud), _mask] call EFUNC(common,showHud); + + if (missionNamespace getVariable [QGVAR(hideHud_hideChat), true]) then { + showChat !GVAR(hideHud); + }; + + if (!isNil "diwako_dui_main_toggled_off") then { + diwako_dui_main_toggled_off = GVAR(hideHud); // ref https://github.com/diwako/diwako_dui/wiki/Hiding-DUI-for-cutscenes + }; + true +}, +{false}, +[DIK_F12, [false, true, false]], false] call CBA_fnc_addKeybind; // ctrl+f12 diff --git a/addons/ui/stringtable.xml b/addons/ui/stringtable.xml index 11089428c2..8f3d323a8a 100644 --- a/addons/ui/stringtable.xml +++ b/addons/ui/stringtable.xml @@ -722,5 +722,8 @@ Nasconde l'icona mostrata in automatico quando qualcosa è davanti al cursore. La modifica richiede un riavvio del gioco.\nAttenzione: Non rimuovere l'azione stessa! È consigliato rimuovere solo il tasto dall'assegnazione 'Usa Azione Standard' per impedire interazioni non volute. Esconde o ícone mostrado automaticamente quando algo está a frente do cursor. É preciso reiniciar o jogo.\nAviso: Não remove a ação em si! É recomendado desvincular a tecla de "Usar ação padrão" para previnir interações indesejadas. + + Hide all UI + diff --git a/docs/wiki/framework/ui-framework.md b/docs/wiki/framework/ui-framework.md index 3b6ec08951..095025ffe0 100644 --- a/docs/wiki/framework/ui-framework.md +++ b/docs/wiki/framework/ui-framework.md @@ -71,3 +71,12 @@ Adding new elements through scripting is currently not possible. | 1 | `true` | Set element, preventing others to change it (except config, which always has priority) | | 2 | `"ammoCount"` | Element name to modify | | 3 | `false` | Hide the element | + +### 2.2 Hide UI Keybind + +There is a keybind that will hide most UI elements (Ctrl-F12 by default). +It triggers an event that is listenable allowing other mods to hide their displays. + +| Event Key | Parameters | Locality | Type | Description | +|---------- |------------|----------|------|-------------| +| `ace_ui_hideHud` | `[_set]` | Local | Listen | _set=true means things should be hidden \ No newline at end of file From 53a42fc89e601cbfab8acbf62a2f27460e69b66f Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Thu, 22 Aug 2024 19:14:38 +0200 Subject: [PATCH 19/26] General - Improve backpack interaction anim names (#10239) Improve backpack interaction names --- addons/compat_spe/CfgVehicles/wheeled.hpp | 4 +-- addons/interaction/CfgVehicles.hpp | 32 +++++++++++------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/addons/compat_spe/CfgVehicles/wheeled.hpp b/addons/compat_spe/CfgVehicles/wheeled.hpp index 534efcf490..f645db29e6 100644 --- a/addons/compat_spe/CfgVehicles/wheeled.hpp +++ b/addons/compat_spe/CfgVehicles/wheeled.hpp @@ -85,8 +85,8 @@ class SPE_G503_MB_base: SPE_Car_base { class hide_musette_source { positions[] = {{0.8, -0.97, -0.6}, {-0.8, -0.92, -0.6}}; items[] = {"B_SPE_US_M36", "B_SPE_US_M36"}; - name = "$STR_a3_cfgvehicleclasses_backpacks0"; - text = "$STR_a3_cfgvehicleclasses_backpacks0"; + name = "$STR_CTH_B_SPE_US_M36"; + text = "$STR_CTH_B_SPE_US_M36"; }; }; }; diff --git a/addons/interaction/CfgVehicles.hpp b/addons/interaction/CfgVehicles.hpp index 8671ecf9ce..ab338c3f09 100644 --- a/addons/interaction/CfgVehicles.hpp +++ b/addons/interaction/CfgVehicles.hpp @@ -428,8 +428,8 @@ class CfgVehicles { phase = 0; selections[] = {"vhc_bags"}; items[] = {"B_Carryall_cbr", "B_Carryall_cbr"}; - name = "$STR_a3_cfgvehicleclasses_backpacks0"; - text = "$STR_a3_cfgvehicleclasses_backpacks0"; + name = "$STR_A3_B_Carryall_cbr0"; + text = "$STR_A3_B_Carryall_cbr0"; distance = 3; }; }; @@ -443,8 +443,8 @@ class CfgVehicles { phase = 0; positions[] = {"_target selectionPosition ['vhc_bags', 'FireGeometry', 'AveragePoint']"}; items[] = {"B_Carryall_cbr"}; - name = "$STR_BACKPACK_CONTAINER_NAME"; - text = "$STR_BACKPACK_CONTAINER_NAME"; + name = "$STR_A3_B_Carryall_cbr0"; + text = "$STR_A3_B_Carryall_cbr0"; }; }; }; @@ -454,8 +454,8 @@ class CfgVehicles { phase = 0; positions[] = {"_target selectionPosition ['vhc_bags', 'FireGeometry', 'AveragePoint']"}; items[] = {"B_Carryall_cbr", "B_Carryall_cbr"}; - name = "$STR_a3_cfgvehicleclasses_backpacks0"; - text = "$STR_a3_cfgvehicleclasses_backpacks0"; + name = "$STR_A3_B_Carryall_cbr0"; + text = "$STR_A3_B_Carryall_cbr0"; }; }; }; @@ -494,8 +494,8 @@ class CfgVehicles { phase = 0; positions[] = {"_target selectionPosition ['vhc_bags', 'FireGeometry', 'AveragePoint']"}; items[] = {"B_Carryall_cbr"}; - name = "$STR_BACKPACK_CONTAINER_NAME"; - text = "$STR_BACKPACK_CONTAINER_NAME"; + name = "$STR_A3_B_Carryall_cbr0"; + text = "$STR_A3_B_Carryall_cbr0"; }; class showBags2: showBags { positions[] = {"_target selectionPosition ['vhc_bags2', 'FireGeometry', 'AveragePoint']"}; @@ -513,8 +513,8 @@ class CfgVehicles { selections[] = {"vhc_bags"}; positions[] = {"private _pos = _target selectionPosition 'vhc_bags'; _pos set [0, -(_pos select 0)]; _pos"}; // Mirror position to other side of vehicle items[] = {"B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr"}; - name = "$STR_a3_cfgvehicleclasses_backpacks0"; - text = "$STR_a3_cfgvehicleclasses_backpacks0"; + name = "$STR_A3_B_Carryall_cbr0"; + text = "$STR_A3_B_Carryall_cbr0"; }; }; }; @@ -536,8 +536,8 @@ class CfgVehicles { phase = 0; selections[] = {"vhc_bags"}; items[] = {"B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr"}; - name = "$STR_a3_cfgvehicleclasses_backpacks0"; - text = "$STR_a3_cfgvehicleclasses_backpacks0"; + name = "$STR_A3_B_Carryall_cbr0"; + text = "$STR_A3_B_Carryall_cbr0"; }; }; }; @@ -548,8 +548,8 @@ class CfgVehicles { phase = 0; selections[] = {"vhc_bags"}; items[] = {"B_Carryall_cbr", "B_Carryall_cbr"}; - name = "$STR_a3_cfgvehicleclasses_backpacks0"; - text = "$STR_a3_cfgvehicleclasses_backpacks0"; + name = "$STR_A3_B_Carryall_cbr0"; + text = "$STR_A3_B_Carryall_cbr0"; }; }; }; @@ -564,8 +564,8 @@ class CfgVehicles { phase = 0; selections[] = {"vhc_bags"}; items[] = {"B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr", "B_Carryall_cbr"}; - name = "$STR_a3_cfgvehicleclasses_backpacks0"; - text = "$STR_a3_cfgvehicleclasses_backpacks0"; + name = "$STR_A3_B_Carryall_cbr0"; + text = "$STR_A3_B_Carryall_cbr0"; }; }; }; From f564016b4bacff68807e8647382e44babafecce2 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Thu, 22 Aug 2024 19:15:20 +0200 Subject: [PATCH 20/26] WS Compat - Rename WS weapon holders when realistic names is loaded (#10240) Rename WS weapon holders --- .../compat_ws_realisticnames/CfgVehicles.hpp | 169 ++++++++++++++++++ .../CfgVehiclesAttachments.hpp | 71 ++++++++ .../compat_ws_realisticnames/CfgWeapons.hpp | 2 +- ...achments.hpp => CfgWeaponsAttachments.hpp} | 1 + .../compat_ws_realisticnames/config.cpp | 2 + 5 files changed, 244 insertions(+), 1 deletion(-) create mode 100644 addons/compat_ws/compat_ws_realisticnames/CfgVehiclesAttachments.hpp rename addons/compat_ws/compat_ws_realisticnames/{Attachments.hpp => CfgWeaponsAttachments.hpp} (99%) diff --git a/addons/compat_ws/compat_ws_realisticnames/CfgVehicles.hpp b/addons/compat_ws/compat_ws_realisticnames/CfgVehicles.hpp index fe1aed7e17..5396b8f186 100644 --- a/addons/compat_ws/compat_ws_realisticnames/CfgVehicles.hpp +++ b/addons/compat_ws/compat_ws_realisticnames/CfgVehicles.hpp @@ -57,4 +57,173 @@ class CfgVehicles { class B_ION_Heli_Light_02_unarmed_lxWS: O_Heli_Light_02_unarmed_F { displayName = SUBCSTRING(heli_light_02_unarmed_Name); }; + + #include "CfgVehiclesAttachments.hpp" + + // AA12 + class Weapon_Base_F; + class Weapon_sgun_aa40_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(AA40_Name); + }; + class Weapon_sgun_aa40_tan_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(AA40_Tan_Name); + }; + class Weapon_sgun_aa40_snake_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(AA40_Snake_Name); + }; + + // Galil ARM + class Weapon_arifle_Galat_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(Galat_Name); + }; + class Weapon_arifle_Galat_worn_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(Galat_Old_Name); + }; + + // GLX 160 + class Weapon_glaunch_GLX_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(GLX_Name); + }; + class Weapon_glaunch_GLX_snake_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(GLX_Snake_Name); + }; + class Weapon_glaunch_GLX_hex_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(GLX_Hex_Name); + }; + class Weapon_glaunch_GLX_ghex_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(GLX_GreenHex_Name); + }; + class Weapon_glaunch_GLX_camo_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(GLX_Camo_Name); + }; + class Weapon_glaunch_GLX_tan_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(GLX_Tan_Name); + }; + + // Mk14 Mod 1 EBR + class Weapon_srifle_EBR_blk_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(EBR_Black_Name); + }; + class Weapon_srifle_EBR_snake_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(EBR_Snake_Name); + }; + + // Vektor SS-77 + class Weapon_LMG_S77_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(S77_Name); + }; + class Weapon_LMG_S77_AAF_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(S77_AAF_Name); + }; + class Weapon_LMG_S77_Hex_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(S77_Hex_Name); + }; + class Weapon_LMG_S77_GHex_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(S77_GreenHex_Name); + }; + class Weapon_LMG_S77_Desert_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(S77_Desert_Name); + }; + + // Vektor SS-77 (Compact) + class Weapon_LMG_S77_Compact_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(S77_Compact_Name); + }; + class Weapon_LMG_S77_Compact_Snakeskin_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(S77_Compact_Snake_Name); + }; + + // FN FAL (Wood) - Closest match is the 50.00 + class Weapon_arifle_SLR_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(SLR_Wood_Name); + }; + class Weapon_arifle_SLR_GL_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(SLR_GL_Wood_Name); + }; + + // FN FAL + class Weapon_arifle_SLR_V_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(SLR_Name); + }; + class Weapon_arifle_SLR_V_GL_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(SLR_GL_Name); + }; + class Weapon_arifle_SLR_D_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(SLR_Desert_Name); + }; + class Weapon_arifle_SLR_V_camo_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(SLR_Camo_Name); + }; + class Weapon_arifle_SLR_Para_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(SLR_Para_Name); + }; + class Weapon_arifle_SLR_Para_snake_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(SLR_Para_Snake_Name); + }; + + // Vektor R4/R5 + class Weapon_arifle_Velko_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(Velko_R4_Name); + }; + class Weapon_arifle_VelkoR5_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(Velko_R5_Name); + }; + class Weapon_arifle_VelkoR5_GL_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(Velko_R5_GL_Name); + }; + class Weapon_arifle_VelkoR5_snake_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(Velko_R5_Snake_Name); + }; + class Weapon_arifle_VelkoR5_GL_snake_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(Velko_R5_GL_Snake_Name); + }; + + // XMS has no realistic name as it's a make believe hybrid of the XM8/VHS-K2: XM8+VHS = XMS, this just removes the 5.56 mm from the name. + class Weapon_arifle_XMS_Base_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(XMS_Name); + }; + class Weapon_arifle_XMS_Base_khk_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(XMS_Khaki_Name); + }; + class Weapon_arifle_XMS_Base_Sand_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(XMS_Sand_Name); + }; + class Weapon_arifle_XMS_GL_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(XMS_GL_Name); + }; + class Weapon_arifle_XMS_GL_khk_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(XMS_GL_Khaki_Name); + }; + class Weapon_arifle_XMS_GL_Sand_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(XMS_GL_Sand_Name); + }; + class Weapon_arifle_XMS_Shot_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(XMS_SG_Name); + }; + class Weapon_arifle_XMS_Shot_khk_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(XMS_SG_Khaki_Name); + }; + class Weapon_arifle_XMS_Shot_Sand_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(XMS_SG_Sand_Name); + }; + class Weapon_arifle_XMS_M_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(XMS_SW_Name); + }; + class arifle_XMS_M_khk_lxWS: Weapon_Base_F { + diWeapon_splayName = SUBCSTRING(XMS_SW_Khaki_Name); + }; + class Weapon_arifle_XMS_M_Sand_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(XMS_SW_Sand_Name); + }; + + // GM6 Lynx + class Weapon_srifle_GM6_snake_lxWS: Weapon_Base_F { + displayName = SUBCSTRING(gm6_snake_Name); + }; + + // RPG-32 + class Launcher_Base_F; + class Weapon_launch_RPG32_tan_lxWS: Launcher_Base_F { + displayName = SUBCSTRING(rpg32_tan_Name); + }; }; diff --git a/addons/compat_ws/compat_ws_realisticnames/CfgVehiclesAttachments.hpp b/addons/compat_ws/compat_ws_realisticnames/CfgVehiclesAttachments.hpp new file mode 100644 index 0000000000..5dbeab9bc4 --- /dev/null +++ b/addons/compat_ws/compat_ws_realisticnames/CfgVehiclesAttachments.hpp @@ -0,0 +1,71 @@ +// Attachments +class Item_Base_F; +class Item_optic_arco_hex_lxWS: Item_Base_F { + displayName = SUBCSTRING(arco_hex_Name); +}; + +class Item_optic_Holosight_snake_lxWS: Item_Base_F { + displayName = SUBCSTRING(holosight_snake_Name); +}; + +class Item_optic_Holosight_smg_snake_lxWS: Item_Base_F { + displayName = SUBCSTRING(holosight_snake_smg_Name); +}; + +class Item_optic_Hamr_arid_lxWS: Item_Base_F { + displayName = SUBCSTRING(hamr_arid_Name); +}; +class Item_optic_Hamr_lush_lxWS: Item_Base_F { + displayName = SUBCSTRING(hamr_lush_Name); +}; +class Item_optic_Hamr_sand_lxWS: Item_Base_F { + displayName = SUBCSTRING(hamr_sand_Name); +}; +class Item_optic_Hamr_snake_lxWS: Item_Base_F { + displayName = SUBCSTRING(hamr_snake_Name); +}; + +class Item_optic_r1_high_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_high_black_Name); +}; +class Item_optic_r1_high_khaki_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_high_khaki_Name); +}; +class Item_optic_r1_high_sand_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_high_sand_Name); +}; +class Item_optic_r1_high_snake_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_high_snake_Name); +}; +class Item_optic_r1_high_arid_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_high_arid_Name); +}; +class Item_optic_r1_high_lush_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_high_lush_Name); +}; +class Item_optic_r1_high_black_sand_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_high_black_sand_Name); +}; + +class Item_optic_r1_low_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_low_black_Name); +}; +class Item_optic_r1_low_khaki_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_low_khaki_Name); +}; +class Item_optic_r1_low_sand_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_low_sand_Name); +}; +class Item_optic_r1_low_snake_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_low_snake_Name); +}; +class Item_optic_r1_low_arid_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_low_arid_Name); +}; +class Item_optic_r1_low_lush_lxWS: Item_Base_F { + displayName = SUBCSTRING(r1_low_lush_Name); +}; + +class Item_optic_DMS_snake_lxWS: Item_Base_F { + displayName = SUBCSTRING(dms_snake_Name); +}; diff --git a/addons/compat_ws/compat_ws_realisticnames/CfgWeapons.hpp b/addons/compat_ws/compat_ws_realisticnames/CfgWeapons.hpp index e9cf3c6934..b1929a4904 100644 --- a/addons/compat_ws/compat_ws_realisticnames/CfgWeapons.hpp +++ b/addons/compat_ws/compat_ws_realisticnames/CfgWeapons.hpp @@ -1,5 +1,5 @@ class CfgWeapons { - #include "Attachments.hpp" + #include "CfgWeaponsAttachments.hpp" // AA12 class sgun_aa40_base_lxWS; diff --git a/addons/compat_ws/compat_ws_realisticnames/Attachments.hpp b/addons/compat_ws/compat_ws_realisticnames/CfgWeaponsAttachments.hpp similarity index 99% rename from addons/compat_ws/compat_ws_realisticnames/Attachments.hpp rename to addons/compat_ws/compat_ws_realisticnames/CfgWeaponsAttachments.hpp index 95801e04e9..a805e82edc 100644 --- a/addons/compat_ws/compat_ws_realisticnames/Attachments.hpp +++ b/addons/compat_ws/compat_ws_realisticnames/CfgWeaponsAttachments.hpp @@ -1,3 +1,4 @@ +// Attachments class optic_Arco; class optic_arco_hex_lxWS: optic_Arco { displayName = SUBCSTRING(arco_hex_Name); diff --git a/addons/compat_ws/compat_ws_realisticnames/config.cpp b/addons/compat_ws/compat_ws_realisticnames/config.cpp index 0eb75926a8..167e83fa35 100644 --- a/addons/compat_ws/compat_ws_realisticnames/config.cpp +++ b/addons/compat_ws/compat_ws_realisticnames/config.cpp @@ -15,6 +15,8 @@ class CfgPatches { authors[] = {"Mike"}; url = ECSTRING(main,URL); VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); }; }; From 7790028aa73e2bcaeefae8e43d1717b3d00d73de Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Fri, 23 Aug 2024 02:59:48 +0200 Subject: [PATCH 21/26] RHS Compat - Add interaction anims for ammo boxes (#10242) * Add ammo boxes interaction anims to RHS * Fix bad inheritance --- addons/compat_rhs_afrf3/CfgVehicles.hpp | 496 ++++++++++++++++-- .../compat_rhs_usf3_refuel/CfgVehicles.hpp | 2 +- .../compat_rhs_usf3_trenches/CfgVehicles.hpp | 2 +- 3 files changed, 455 insertions(+), 45 deletions(-) diff --git a/addons/compat_rhs_afrf3/CfgVehicles.hpp b/addons/compat_rhs_afrf3/CfgVehicles.hpp index 1cf5029bc3..2ba6caf56f 100644 --- a/addons/compat_rhs_afrf3/CfgVehicles.hpp +++ b/addons/compat_rhs_afrf3/CfgVehicles.hpp @@ -60,6 +60,8 @@ class CfgVehicles { EGVAR(vehicle_damage,turretFireProb) = 0.7; EGVAR(vehicle_damage,engineFireProb) = 0.7; EGVAR(vehicle_damage,detonationDuringFireProb) = 0.5; + + class EGVAR(interaction,anims); }; class rhs_infantry_msv_base; @@ -156,68 +158,186 @@ class CfgVehicles { EGVAR(vehicle_damage,engineFireProb) = 0.8; EGVAR(vehicle_damage,detonationDuringFireProb) = 0.8; EGVAR(vehicle_damage,canHaveFireRing) = 1; - }; + }; class rhs_btr60_base: rhs_btr_base { EGVAR(refuel,fuelCapacity) = 290; + + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_l1_unhide { + positions[] = {{-1.1, 2, -0.3}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_l2_unhide { + positions[] = {{-1.1, 1.05, -0.3}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_l3_unhide { + positions[] = {{-1.1, -1.1, -0.3}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r1_unhide { + positions[] = {{1.1, 1.93, -0.3}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r2_unhide { + positions[] = {{1.1, 0.25, -0.3}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r3_unhide { + positions[] = {{1.1, -1.1, -0.3}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + }; }; class rhs_btr70_vmf: rhs_btr_base { EGVAR(refuel,fuelCapacity) = 350; + class ace_viewports { class view_0 { camLocation[] = {0.478394, -0.575, -0.145}; camAttach = 90; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; }; class view_1 { camLocation[] = {-1.38184, -0.575, -0.145}; camAttach = -90; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; + }; + }; + + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_l1_unhide { + positions[] = {{-1.7, 0.55, -0.4}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_l2_unhide { + positions[] = {{-1.7, -0.95, -0.4}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_l3_unhide { + positions[] = {{-1.7, -1.45, -0.4}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_l4_unhide { + positions[] = {{-1.7, -2.7, -0.4}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r1_unhide { + positions[] = {{0.8, 1, -0.4}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r2_unhide { + positions[] = {{0.8, 0.12, -0.4}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r3_unhide { + positions[] = {{0.8, -0.7, -0.4}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r4_unhide { + positions[] = {{0.8, -1.85, -0.4}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; }; }; }; - class rhs_btr70_msv: rhs_btr70_vmf {}; class rhs_btr80_msv: rhs_btr70_msv { EGVAR(refuel,fuelCapacity) = 300; + class ace_viewports { class view_0 { camLocation[] = {0.534424, -0.336914, 0.636819}; camAttach = 45; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; }; class view_1 { camLocation[] = {0.760254, -0.459473, 0.526328}; camAttach = 90; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; }; class view_2 { camLocation[] = {0.770508, -1.21924, 0.526954}; camAttach = 90; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; }; class view_3 { camLocation[] = {-1.13, -1.2085, 0.490339}; camAttach = -90; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; }; class view_4 { camLocation[] = {-1.14124, -0.416992, 0.460611}; camAttach = -90; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; }; class view_5 { camLocation[] = {-0.932983, -0.326172, 0.647666}; camAttach = -45; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; + }; + }; + + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_l1_unhide: crate_l1_unhide { + positions[] = {{-1.45, 0, 0.25}}; + }; + class crate_l2_unhide: crate_l2_unhide { + positions[] = {{-1.45, -1.68, 0.15}}; + }; + class crate_l3_unhide: crate_l3_unhide { + positions[] = {{-1.45, -2.87, 0.15}}; + }; + class crate_l4_unhide: crate_l4_unhide { + enabled = 0; + }; + class crate_r1_unhide: crate_r1_unhide { + positions[] = {{1.1, 0.97, 0.15}}; + }; + class crate_r2_unhide: crate_r2_unhide { + positions[] = {{1.1, -1.5, 0.15}}; + }; + class crate_r3_unhide: crate_r3_unhide { + enabled = 0; + }; + class crate_r4_unhide: crate_r4_unhide { + enabled = 0; }; }; }; @@ -226,38 +346,56 @@ class CfgVehicles { class view_0 { camLocation[] = {0.589844, -0.314941, 0.449678}; camAttach = 45; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; }; class view_1 { camLocation[] = {0.809082, -0.442871, 0.276865}; camAttach = 90; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; }; class view_2 { camLocation[] = {0.819092, -1.24414, 0.27857}; camAttach = 90; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; }; class view_3 { camLocation[] = {-1.1012, -1.22461, 0.341089}; camAttach = -90; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; }; class view_4 { camLocation[] = {-1.11597, -0.458984, 0.307256}; camAttach = -90; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; }; class view_5 { camLocation[] = {-0.869995, -0.304688, 0.461181}; camAttach = -45; - compartments[]={"Compartment1"}; - roles[]={"cargo"}; + compartments[] = {"Compartment1"}; + roles[] = {"cargo"}; + }; + }; + + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_l1_unhide: crate_l1_unhide { + positions[] = {{-1.45, 0, 0}}; + }; + class crate_l2_unhide: crate_l2_unhide { + positions[] = {{-1.45, -1.68, 0}}; + }; + class crate_l3_unhide: crate_l3_unhide { + positions[] = {{-1.45, -2.87, 0}}; + }; + class crate_r1_unhide: crate_l3_unhide { + positions[] = {{1.1, 0.97, 0}}; + }; + class crate_r2_unhide: crate_r2_unhide { + positions[] = {{1.1, -1.5, 0}}; }; }; }; @@ -279,11 +417,289 @@ class CfgVehicles { EGVAR(vehicle_damage,turretFireProb) = 0.5; EGVAR(vehicle_damage,engineFireProb) = 0.8; EGVAR(vehicle_damage,detonationDuringFireProb) = 0.5; + + class EGVAR(interaction,anims) { + class crate_l1_unhide { + positions[] = {{-1.45, 0.5, -0.65}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_l2_unhide { + positions[] = {{-1.45, -0.2, -0.65}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_l3_unhide { + positions[] = {{-1.45, -1.2, -0.65}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r1_unhide { + positions[] = {{1.45, 0.6, -0.65}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r2_unhide { + positions[] = {{1.45, -0.4, -0.65}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r3_unhide { + positions[] = {{1.45, -1.2, -0.65}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + }; }; + class rhs_bmd1_base: rhs_bmd_base {}; + class rhs_bmd1p: rhs_bmd1_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_l1_unhide: crate_l1_unhide { + positions[] = {{-1.45, 0.5, -0.8}}; + }; + class crate_l2_unhide: crate_l2_unhide { + positions[] = {{-1.45, -0.2, -0.8}}; + }; + class crate_l3_unhide: crate_l3_unhide { + positions[] = {{-1.45, -1.2, -0.8}}; + }; + class crate_r1_unhide: crate_l3_unhide { + positions[] = {{1.45, 0.6, -0.8}}; + }; + class crate_r2_unhide: crate_r2_unhide { + positions[] = {{1.45, -0.4, -0.8}}; + }; + class crate_r3_unhide: crate_r3_unhide { + positions[] = {{1.45, -1.2, -0.8}}; + }; + }; + }; + class rhs_bmd2_base: rhs_bmd_base {}; + class rhs_bmd2: rhs_bmd2_base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_l1_unhide: crate_l1_unhide { + positions[] = {{-1.45, 0.5, -0.8}}; + }; + class crate_l2_unhide: crate_l2_unhide { + positions[] = {{-1.45, -0.2, -0.8}}; + }; + class crate_l3_unhide: crate_l3_unhide { + positions[] = {{-1.45, -1.2, -0.8}}; + }; + class crate_r1_unhide: crate_l3_unhide { + positions[] = {{1.45, 0.6, -0.8}}; + }; + class crate_r2_unhide: crate_r2_unhide { + positions[] = {{1.45, -0.4, -0.8}}; + }; + class crate_r3_unhide: crate_r3_unhide { + positions[] = {{1.45, -1.2, -0.8}}; + }; + }; + }; + class rhs_bmd2m: rhs_bmd2 { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_l1_unhide: crate_l1_unhide { + positions[] = {{-1.45, 0.5, -0.7}}; + }; + class crate_l2_unhide: crate_l2_unhide { + positions[] = {{-1.45, -0.2, -0.7}}; + }; + class crate_l3_unhide: crate_l3_unhide { + positions[] = {{-1.45, -1.2, -0.7}}; + }; + class crate_r1_unhide: crate_l3_unhide { + positions[] = {{1.45, 0.6, -0.7}}; + }; + class crate_r2_unhide: crate_r2_unhide { + positions[] = {{1.45, -0.4, -0.7}}; + }; + class crate_r3_unhide: crate_r3_unhide { + positions[] = {{1.45, -1.2, -0.7}}; + }; + }; + }; + class rhs_bmp1tank_base: Tank_F { EGVAR(map,vehicleLightColor)[] = {0,1,0,0.1}; EGVAR(refuel,fuelCapacity) = 460; }; + class rhs_bmp_base: rhs_bmp1tank_base { + EGVAR(vehicle_damage,hullDetonationProb) = 0; + EGVAR(vehicle_damage,turretDetonationProb) = 0.2; + EGVAR(vehicle_damage,engineDetonationProb) = 0; + EGVAR(vehicle_damage,hullFireProb) = 0.8; + EGVAR(vehicle_damage,turretFireProb) = 0.5; + EGVAR(vehicle_damage,engineFireProb) = 0.8; + EGVAR(vehicle_damage,detonationDuringFireProb) = 0.5; + + class EGVAR(interaction,anims) { + class crate_l1_unhide { + positions[] = {{-1.55, 1.1, -0.55}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_l2_unhide { + positions[] = {{-1.55, 0.35, -0.55}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_l3_unhide { + positions[] = {{-1.55, -0.6, -0.55}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r1_unhide { + positions[] = {{1.55, 1.75, -0.55}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r2_unhide { + positions[] = {{1.55, -0.25, -0.55}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + class crate_r3_unhide { + positions[] = {{1.55, -1, -0.55}}; + items[] = {"rhs_3Ya40_1_single"}; + name = "3Ya40-1 Crate"; + text = "3Ya40-1 Crate"; + }; + }; + }; + class rhs_bmp1_vdv: rhs_bmp_base {}; + class rhs_bmp1d_vdv: rhs_bmp1_vdv { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_r3_unhide: crate_r3_unhide { + positions[] = {{1.5, -1.2, -0.55}}; + }; + }; + }; + class rhs_prp3_vdv: rhs_bmp1_vdv { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_l1_unhide: crate_l1_unhide { + enabled = 0; + }; + class crate_l2_unhide: crate_l2_unhide { + enabled = 0; + }; + class crate_l3_unhide: crate_l3_unhide { + enabled = 0; + }; + class crate_r1_unhide: crate_l3_unhide { + enabled = 0; + }; + class crate_r2_unhide: crate_r2_unhide { + enabled = 0; + }; + class crate_r3_unhide: crate_r3_unhide { + enabled = 0; + }; + }; + }; + + class rhs_bmp2e_vdv: rhs_bmp1_vdv { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_l1_unhide: crate_l1_unhide { + positions[] = {{-1.8, 1.05, -0.55}}; + }; + class crate_l2_unhide: crate_l2_unhide { + positions[] = {{-1.8, 0.35, -0.55}}; + }; + class crate_l3_unhide: crate_l3_unhide { + positions[] = {{-1.8, -0.65, -0.55}}; + }; + class crate_r1_unhide: crate_l3_unhide { + positions[] = {{1.4, 1.7, -0.55}}; + }; + class crate_r2_unhide: crate_r2_unhide { + positions[] = {{1.4, -0.25, -0.55}}; + }; + class crate_r3_unhide: crate_r3_unhide { + positions[] = {{1.4, -1.05, -0.55}}; + }; + }; + }; + class rhs_bmp2_vdv: rhs_bmp2e_vdv { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_l1_unhide: crate_l1_unhide { + positions[] = {{-1.8, 1.2, -0.55}}; + }; + class crate_l2_unhide: crate_l2_unhide { + positions[] = {{-1.8, 0.5, -0.55}}; + }; + class crate_l3_unhide: crate_l3_unhide { + positions[] = {{-1.8, -0.5, -0.55}}; + }; + class crate_r1_unhide: crate_l3_unhide { + positions[] = {{1.4, 1.85, -0.55}}; + }; + class crate_r2_unhide: crate_r2_unhide { + positions[] = {{1.4, -0.1, -0.55}}; + }; + class crate_r3_unhide: crate_r3_unhide { + positions[] = {{1.4, -0.9, -0.55}}; + }; + }; + }; + class rhs_bmp2e_msv: rhs_bmp2e_vdv {}; + class rhs_Ob_681_2: rhs_bmp2e_msv { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_l1_unhide: crate_l1_unhide { + positions[] = {{-1.8, 1.2, -0.55}}; + }; + class crate_l2_unhide: crate_l2_unhide { + positions[] = {{-1.8, 0.5, -0.55}}; + }; + class crate_l3_unhide: crate_l3_unhide { + positions[] = {{-1.8, -0.5, -0.55}}; + }; + class crate_r1_unhide: crate_l3_unhide { + positions[] = {{1.4, 1.85, -0.55}}; + }; + class crate_r2_unhide: crate_r2_unhide { + positions[] = {{1.4, -0.1, -0.55}}; + }; + class crate_r3_unhide: crate_r3_unhide { + positions[] = {{1.4, -0.9, -0.55}}; + }; + }; + }; + + class rhs_brm1k_base: rhs_bmp2e_vdv { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class crate_l1_unhide: crate_l1_unhide { + enabled = 0; + }; + class crate_l2_unhide: crate_l2_unhide { + enabled = 0; + }; + class crate_l3_unhide: crate_l3_unhide { + enabled = 0; + }; + class crate_r1_unhide: crate_l3_unhide { + enabled = 0; + }; + class crate_r2_unhide: crate_r2_unhide { + enabled = 0; + }; + class crate_r3_unhide: crate_r3_unhide { + enabled = 0; + }; + }; + }; + class rhs_bmp3tank_base: Tank_F { EGVAR(refuel,fuelCapacity) = 460; EGVAR(vehicle_damage,hullDetonationProb) = 0.2; @@ -293,37 +709,39 @@ class CfgVehicles { EGVAR(vehicle_damage,turretFireProb) = 0.2; EGVAR(vehicle_damage,engineFireProb) = 0.8; EGVAR(vehicle_damage,detonationDuringFireProb) = 0.5; + class ace_viewports { class view_0 { camLocation[] = {1.02881, -0.923828, -0.647231}; screenLocation[] = {1.12881, -0.653828, -1.08223}; camAttach = 50; maxDistance = 0.5; - roles[]={"cargo"}; + roles[] = {"cargo"}; }; class view_1 { camLocation[] = {1.01709, -1.55664, -0.647231}; screenLocation[] = {1.10709, -1.42664, -1.14223}; camAttach = 82; maxDistance = 0.5; - roles[]={"cargo"}; + roles[] = {"cargo"}; }; class view_2 { camLocation[] = {-0.871094, -1.55762, -0.647231}; screenLocation[] = {-0.981094, -1.42762, -1.13223}; camAttach = 285; maxDistance = 0.5; - roles[]={"cargo"}; + roles[] = {"cargo"}; }; class view_3 { camLocation[] = {-1.00879, -0.939941, -0.650259}; screenLocation[] = {-0.97879, -0.689941, -1.09526}; camAttach = 310; maxDistance = 0.5; - roles[]={"cargo"}; + roles[] = {"cargo"}; }; }; }; + class rhs_a3spruttank_base: Tank_F { EGVAR(refuel,fuelCapacity) = 400; EGVAR(vehicle_damage,hullDetonationProb) = 0.2; @@ -334,6 +752,7 @@ class CfgVehicles { EGVAR(vehicle_damage,engineFireProb) = 0.8; EGVAR(vehicle_damage,detonationDuringFireProb) = 0.5; }; + class rhs_a3t72tank_base: Tank_F { EGVAR(refuel,fuelCapacity) = 1200; EGVAR(vehicle_damage,hullDetonationProb) = 0.8; @@ -344,15 +763,6 @@ class CfgVehicles { EGVAR(vehicle_damage,engineFireProb) = 0.5; EGVAR(vehicle_damage,detonationDuringFireProb) = 0.2; }; - class rhs_bmp_base: rhs_bmp1tank_base { - EGVAR(vehicle_damage,hullDetonationProb) = 0; - EGVAR(vehicle_damage,turretDetonationProb) = 0.2; - EGVAR(vehicle_damage,engineDetonationProb) = 0; - EGVAR(vehicle_damage,hullFireProb) = 0.8; - EGVAR(vehicle_damage,turretFireProb) = 0.5; - EGVAR(vehicle_damage,engineFireProb) = 0.8; - EGVAR(vehicle_damage,detonationDuringFireProb) = 0.5; - }; class rhs_t72bd_tv: rhs_a3t72tank_base { EGVAR(vehicle_damage,eraHitpoints)[] = { "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", "era_5_hitpoint", "era_6_hitpoint", "era_7_hitpoint", diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgVehicles.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgVehicles.hpp index 445cab8226..10607ab6b5 100644 --- a/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgVehicles.hpp +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgVehicles.hpp @@ -26,7 +26,7 @@ class CfgVehicles { }; }; }; - class rhsusf_stryker_m1134_base: rhsusf_stryker_m1132_m2_base { + class rhsusf_stryker_m1134_base: rhsusf_stryker_m1126_m2_base { class EGVAR(interaction,anims): EGVAR(interaction,anims) { class Hide_FCans: Hide_FCans { positions[] = {{-0.7, -3, -0.7}}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_trenches/CfgVehicles.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_trenches/CfgVehicles.hpp index ba4dd16cd7..e914b24d60 100644 --- a/addons/compat_rhs_usf3/compat_rhs_usf3_trenches/CfgVehicles.hpp +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_trenches/CfgVehicles.hpp @@ -26,7 +26,7 @@ class CfgVehicles { }; }; }; - class rhsusf_stryker_m1134_base: rhsusf_stryker_m1132_m2_base { + class rhsusf_stryker_m1134_base: rhsusf_stryker_m1126_m2_base { class EGVAR(interaction,anims): EGVAR(interaction,anims) { class Hide_PioKit: Hide_PioKit { positions[] = {{-1, -2.2, -0.8}}; From dcf49d77ebf39d4182e28d758c27efedfffc2894 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Fri, 23 Aug 2024 03:00:15 +0200 Subject: [PATCH 22/26] CUP Compat - Add interaction anims to CUP vehicles (#10238) Add interaction anims to CUP --- addons/compat_cup_vehicles/CfgVehicles.hpp | 38 ++++ .../compat_cup_repair/CfgVehicles.hpp | 196 ++++++++++++++++++ .../compat_cup_repair/config.cpp | 23 ++ .../compat_cup_repair/script_component.hpp | 3 + .../compat_cup_trenches/CfgVehicles.hpp | 111 ++++++++++ .../compat_cup_trenches/config.cpp | 23 ++ .../compat_cup_trenches/script_component.hpp | 3 + .../compat_cup_vehicles_fastroping/config.cpp | 2 + .../CfgVehicles.hpp | 86 ++++++++ 9 files changed, 485 insertions(+) create mode 100644 addons/compat_cup_vehicles/compat_cup_repair/CfgVehicles.hpp create mode 100644 addons/compat_cup_vehicles/compat_cup_repair/config.cpp create mode 100644 addons/compat_cup_vehicles/compat_cup_repair/script_component.hpp create mode 100644 addons/compat_cup_vehicles/compat_cup_trenches/CfgVehicles.hpp create mode 100644 addons/compat_cup_vehicles/compat_cup_trenches/config.cpp create mode 100644 addons/compat_cup_vehicles/compat_cup_trenches/script_component.hpp diff --git a/addons/compat_cup_vehicles/CfgVehicles.hpp b/addons/compat_cup_vehicles/CfgVehicles.hpp index 5334987fff..ce502abad5 100644 --- a/addons/compat_cup_vehicles/CfgVehicles.hpp +++ b/addons/compat_cup_vehicles/CfgVehicles.hpp @@ -1,4 +1,31 @@ class CfgVehicles { + class CUP_nHMMWV_Base; + class CUP_nM1025_SOV_Base: CUP_nHMMWV_Base { + class EGVAR(interaction,anims) { + class hide_backpacks { + positions[] = { + "(_target selectionPosition ['vhc_backpacks', 'ViewGeometry', 'AveragePoint']) vectorAdd [-1, 0, 0]", + "(_target selectionPosition ['vhc_backpacks', 'ViewGeometry', 'AveragePoint']) vectorAdd [1.3, 0, 0]" + }; + items[] = {"CUP_B_USPack_Coyote", "CUP_B_USPack_Coyote", "CUP_B_AssaultPack_ACU", "CUP_B_AssaultPack_ACU", "CUP_B_AssaultPack_Coyote"}; + name = "$STR_a3_cfgvehicleclasses_backpacks0"; + text = "$STR_a3_cfgvehicleclasses_backpacks0"; + }; + }; + }; + + class Car_F; + class CUP_ECVHMMWV_Base: Car_F { + class EGVAR(interaction,anims) { + class hide_deploy2 { + positions[] = {"(_target selectionPosition ['vhc_rear_trunk_door', 'FireGeometry', 'AveragePoint']) vectorAdd [-0.7, 0, 0]"}; + items[] = {"CUP_B_USPack_Coyote", "CUP_B_AssaultPack_ACU"}; + name = "$STR_a3_cfgvehicleclasses_backpacks0"; + text = "$STR_a3_cfgvehicleclasses_backpacks0"; + }; + }; + }; + class CUP_MTVR_Base; class CUP_MTVR_Reammo_Base: CUP_MTVR_Base { EGVAR(rearm,defaultSupply) = 1200; @@ -106,6 +133,17 @@ class CfgVehicles { class CUP_BTR90_HQ_Base: CUP_BTR90_Base { delete ace_viewports; }; // no cargo seats class Tank_F; + class CUP_AAV_Base: Tank_F { + class EGVAR(interaction,anims) { + class Hide_Bags_Deployment { + positions[] = {{1.7, -0.7, -0.3}, {1.7, -2.55, -0.3}}; + items[] = {"CUP_B_USPack_Coyote", "CUP_B_USPack_Coyote"}; + name = "$STR_CUP_dn_USpack_coyote"; + text = "$STR_CUP_dn_USpack_coyote"; + }; + }; + }; + class CUP_M2Bradley_Base: Tank_F { ace_hunterkiller = 1; class ace_viewports { diff --git a/addons/compat_cup_vehicles/compat_cup_repair/CfgVehicles.hpp b/addons/compat_cup_vehicles/compat_cup_repair/CfgVehicles.hpp new file mode 100644 index 0000000000..29a471f451 --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_repair/CfgVehicles.hpp @@ -0,0 +1,196 @@ +class CfgVehicles { + class Car_F; + class CUP_Datsun_Base: Car_F { + class EGVAR(interaction,anims) { + class hideSpareTire { + positions[] = {{-0.23, -0.25, -0.8}}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + class CUP_Datsun_AA_Base: CUP_Datsun_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hideSpareTire: hideSpareTire { + enabled = 0; + }; + }; + }; + + class CUP_Tigr_Base: Car_F { + class EGVAR(interaction,anims) { + class hide_ReserveWheel { + positions[] = {{0.57, -2.3, -0.55}}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + class CUP_Tigr_STS_PK_Base: CUP_Tigr_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_ReserveWheel: hide_ReserveWheel {}; + }; + }; + class CUP_Tigr_233014_PK_Base: CUP_Tigr_STS_PK_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_ReserveWheel: hide_ReserveWheel { + positions[] = {{0.57, -2.3, -0.85}}; + }; + }; + }; + class CUP_Tigr_M_PK_Base: CUP_Tigr_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_ReserveWheel: hide_ReserveWheel {}; + }; + }; + class CUP_Tigr_233114_PK_Base: CUP_Tigr_M_PK_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_ReserveWheel: hide_ReserveWheel { + positions[] = {{0.57, -2.3, -0.85}}; + }; + }; + }; + + class CUP_LR_Base: Car_F { + class EGVAR(interaction,anims) { + class selection_wheelfront { + positions[] = {"_target selectionPosition ['selection_wheelfront', 'ViewGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + class selection_wheels { + positions[] = { + "(_target selectionPosition ['selection_wheels', 'ViewGeometry', 'AveragePoint']) vectorAdd [-1.1, 0, 0]", + "(_target selectionPosition ['selection_wheels', 'ViewGeometry', 'AveragePoint']) vectorAdd [1.1, 0, 0]" + }; + items[] = {"ACE_Wheel", "ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class CUP_nHMMWV_Base: Car_F { + class EGVAR(interaction,anims) { + class hide_spare_wheel { + positions[] = {"_target selectionPosition ['vhc_spare_wheel', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + // Don't inherit, as it's easier for the main compat + class CUP_nM1025_SOV_Base: CUP_nHMMWV_Base { + class EGVAR(interaction,anims) { + class hide_spare_wheel { + positions[] = {"_target selectionPosition ['vhc_spare_wheel', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class CUP_RG31_BASE: Car_F { + class EGVAR(interaction,anims) { + class left_spare { + positions[] = {"_target selectionPosition ['left_spare', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + class right_spare { + positions[] = {"_target selectionPosition ['right_spare', 'FireGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + + class CUP_UAZ_Base: Car_F { + class EGVAR(interaction,anims) { + class hide_spare_wheel { + positions[] = {"_target selectionPosition ['spare_wheel', 'ViewGeometry', 'AveragePoint']"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; + class CUP_UAZ_Armed_Base: CUP_UAZ_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare_wheel: hide_spare_wheel {}; + }; + }; + class CUP_UAZ_AA_Base: CUP_UAZ_Armed_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare_wheel: hide_spare_wheel { + positions[] = {{0.18, -1.8, 0.75}}; + }; + }; + }; + class CUP_UAZ_AGS30_Base: CUP_UAZ_Armed_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare_wheel: hide_spare_wheel { + positions[] = {{0.18, -1.9, 0.75}}; + }; + }; + }; + class CUP_UAZ_MG_Base: CUP_UAZ_Armed_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare_wheel: hide_spare_wheel { + positions[] = {{0.18, -1.9, 0.2}}; + }; + }; + }; + // Visual is bugged, but it works + class CUP_UAZ_METIS_Base: CUP_UAZ_Armed_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare_wheel: hide_spare_wheel { + positions[] = {{0.18, -1.9, 0.65}}; + }; + }; + }; + class CUP_UAZ_SPG9_Base: CUP_UAZ_Armed_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare_wheel: hide_spare_wheel { + positions[] = {{0.18, -1.9, 1.05}}; + }; + }; + }; + + class CUP_UAZ_Unarmed_Base: CUP_UAZ_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare_wheel: hide_spare_wheel {}; + }; + }; + class CUP_UAZ_Open_Base: CUP_UAZ_Unarmed_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_spare_wheel: hide_spare_wheel { + positions[] = {{0.135, -1.3, 0.7}}; + }; + }; + }; + + class CUP_ECVHMMWV_Base: Car_F { + class EGVAR(interaction,anims) { + class hide_spare_tire { + positions[] = {"(_target selectionPosition ['vhc_rear_trunk_door', 'FireGeometry', 'AveragePoint']) vectorAdd [0.05, -0.4, 0.2]"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + class hide_deploy1 { + positions[] = {"(_target selectionPosition ['vhc_rear_trunk_door', 'FireGeometry', 'AveragePoint']) vectorAdd [0.05, 0.5, 0.7]"}; + items[] = {"ACE_Wheel"}; + name = ECSTRING(repair,RemoveWheel); + text = ECSTRING(repair,RemovingWheel); + }; + }; + }; +}; diff --git a/addons/compat_cup_vehicles/compat_cup_repair/config.cpp b/addons/compat_cup_vehicles/compat_cup_repair/config.cpp new file mode 100644 index 0000000000..9a2785e7ef --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_repair/config.cpp @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "CUP_Vehicles_LoadOrder", + "ace_repair" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_cup_vehicles/compat_cup_repair/script_component.hpp b/addons/compat_cup_vehicles/compat_cup_repair/script_component.hpp new file mode 100644 index 0000000000..1af928486c --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_repair/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT repair +#define SUBCOMPONENT_BEAUTIFIED Repair +#include "..\script_component.hpp" diff --git a/addons/compat_cup_vehicles/compat_cup_trenches/CfgVehicles.hpp b/addons/compat_cup_vehicles/compat_cup_trenches/CfgVehicles.hpp new file mode 100644 index 0000000000..9d9bc2d62e --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_trenches/CfgVehicles.hpp @@ -0,0 +1,111 @@ +class CfgVehicles { + class Car_F; + class CUP_Tigr_Base: Car_F { + class EGVAR(interaction,anims) { + class hide_tools { + positions[] = {{1.15, -1.5, -0.68}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + class CUP_Tigr_STS_PK_Base: CUP_Tigr_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tools: hide_tools {}; + }; + }; + class CUP_Tigr_233014_PK_Base: CUP_Tigr_STS_PK_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tools: hide_tools { + positions[] = {{1.15, -1.5, -1}}; + }; + }; + }; + class CUP_Tigr_M_PK_Base: CUP_Tigr_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tools: hide_tools {}; + }; + }; + class CUP_Tigr_233114_PK_Base: CUP_Tigr_M_PK_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class hide_tools: hide_tools { + positions[] = {{1.15, -1.5, -1}}; + }; + }; + }; + + // Interaction added to both sides, as the whole vehicle is mirrored if in left/right side + class CUP_LR_Base: Car_F { + class EGVAR(interaction,anims) { + class selection_tool { + positions[] = {{-0.53, 1.65, -0.2}, {0.53, 1.65, -0.2}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + class CUP_LR_MG_Base: CUP_LR_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class selection_tool: selection_tool { + positions[] = {{-0.6, 1.4, 1.4}, {0.45, 1.4, 1.4}}; + }; + }; + }; + class CUP_LR_SPG9_Base: CUP_LR_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class selection_tool: selection_tool {}; + }; + }; + class CUP_LR_AA_Base: CUP_LR_SPG9_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class selection_tool: selection_tool { + positions[] = {{-0.55, 1.77, -0.75}, {0.55, 1.77, -0.75}}; + }; + }; + }; + class CUP_LR_Ambulance_Base: CUP_LR_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class selection_tool: selection_tool { + positions[] = {{-0.55, 2.1, -0.2}, {0.55, 2.1, -0.2}}; + }; + }; + }; + class CUP_LR_Special_Base: CUP_LR_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class selection_tool: selection_tool { + positions[] = {{-0.6, 1.4, 1.4}, {0.45, 1.4, 1.4}}; + }; + }; + }; + + class CUP_ECVHMMWV_Base: Car_F { + class EGVAR(interaction,anims) { + class hide_front_tool_rack { + positions[] = {"(_target selectionPosition ['vhc_rear_trunk_door', 'FireGeometry', 'AveragePoint']) vectorAdd [0.37, 4, 0.2]"}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; + + class Tank_F; + class CUP_leopard_1A3_base: Tank_F { + class EGVAR(interaction,anims) { + class hide_Tools_L { + positions[] = {{-2.2, 0, 0.2}, {-2.2, -1.8, 0.2}}; + items[] = {"ACE_EntrenchingTool", "ACE_wirecutter"}; + name = "$STR_a3_cfgeditorsubcategories_edsubcat_tools0"; + text = "$STR_a3_cfgeditorsubcategories_edsubcat_tools0"; + }; + class hide_Tools_R { + positions[] = {{0.9, -1.5, 0.23}}; + items[] = {"ACE_EntrenchingTool"}; + name = ECSTRING(trenches,EntrenchingToolName); + text = ECSTRING(trenches,EntrenchingToolName); + }; + }; + }; +}; diff --git a/addons/compat_cup_vehicles/compat_cup_trenches/config.cpp b/addons/compat_cup_vehicles/compat_cup_trenches/config.cpp new file mode 100644 index 0000000000..8f05885bd6 --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_trenches/config.cpp @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "CUP_Vehicles_LoadOrder", + "ace_trenches" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"johnb43"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_cup_vehicles/compat_cup_trenches/script_component.hpp b/addons/compat_cup_vehicles/compat_cup_trenches/script_component.hpp new file mode 100644 index 0000000000..10b90eb71e --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_trenches/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT trenches +#define SUBCOMPONENT_BEAUTIFIED Trenches +#include "..\script_component.hpp" diff --git a/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/config.cpp b/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/config.cpp index 1abe0de6ea..10eb5da69f 100644 --- a/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/config.cpp +++ b/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/config.cpp @@ -15,6 +15,8 @@ class CfgPatches { authors[] = {"Community Upgrade Project", "Mike"}; url = ECSTRING(main,URL); VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); }; }; diff --git a/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/CfgVehicles.hpp b/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/CfgVehicles.hpp index 1042c0eacf..60a83030df 100644 --- a/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/CfgVehicles.hpp +++ b/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/CfgVehicles.hpp @@ -28,4 +28,90 @@ class CfgVehicles { EGVAR(refuel,hooks)[] = {{-1.09, -0.01, -0.5},{1, -0.01, -0.5}}; EGVAR(refuel,fuelCargo) = 10000; }; + + class Car_F; + class CUP_LR_Base: Car_F { + class EGVAR(interaction,anims) { + class selection_jerry { + positions[] = {{-0.65, 2.7, -0.55}, {0.65, 2.7, -0.55}, {-1, -0.25, -0.75}, {1, -0.25, -0.75}}; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + class CUP_LR_MG_Base: CUP_LR_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class selection_jerry: selection_jerry { + positions[] = {{-0.55, 2.45, 1.05}, {0.55, 2.45, 1.05}, {-1, -0.53, 0.9}, {1, -0.53, 0.9}}; + }; + }; + }; + class CUP_LR_SPG9_Base: CUP_LR_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class selection_jerry: selection_jerry {}; + }; + }; + class CUP_LR_AA_Base: CUP_LR_SPG9_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class selection_jerry: selection_jerry { + positions[] = {{-0.65, 2.8, -1.1}, {0.65, 2.8, -1.1}, {-1, -0.15, -1.3}, {1, -0.15, -1.3}}; + }; + }; + }; + class CUP_LR_Ambulance_Base: CUP_LR_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class selection_jerry: selection_jerry { + positions[] = {{-0.65, 3.1, -0.55}, {0.65, 3.1, -0.55}}; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + }; + }; + }; + class CUP_LR_Special_Base: CUP_LR_Base { + class EGVAR(interaction,anims): EGVAR(interaction,anims) { + class selection_jerry: selection_jerry { + positions[] = {{-0.7, 2.45, 1.05}, {0.55, 2.45, 1.05}}; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + }; + }; + }; + + class CUP_nHMMWV_Base: Car_F { + class EGVAR(interaction,anims) { + class hide_jerrycans { + positions[] = {"(_target selectionPosition 'vhc_jerrycans') vectorAdd [0, 0, 0.15]"}; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + // Don't inherit, as it's easier for the main compat + class CUP_nM1025_SOV_Base: CUP_nHMMWV_Base { + class EGVAR(interaction,anims) { + class hide_jerrycans { + positions[] = {"(_target selectionPosition 'vhc_jerrycans') vectorAdd [0, 0, 0.15]"}; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + class hide_rear_rack_content { + positions[] = {"_target selectionPosition ['vhc_rear_rack_content', 'FireGeometry', 'AveragePoint']"}; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; + + class CUP_ECVHMMWV_Base: Car_F { + class EGVAR(interaction,anims) { + class hide_jerrycans { + positions[] = {"(_target selectionPosition ['vhc_rear_trunk_door', 'FireGeometry', 'AveragePoint']) vectorAdd [-0.85, -0.22, -0.1]"}; + items[] = {"Land_CanisterFuel_F", "Land_CanisterFuel_F"}; + name = ECSTRING(refuel,TakeFuelCanister); + text = ECSTRING(refuel,TakeFuelCanisterAction); + }; + }; + }; }; From 7cdafe1d10faa2dbdbb4a168332714d24428c909 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Fri, 23 Aug 2024 05:21:51 -0500 Subject: [PATCH 23/26] Interaction - Add setting for blocking interaction with enemy crew (#10237) --- .../functions/fnc_canInteractWithVehicleCrew.sqf | 3 +++ addons/interaction/initSettings.inc.sqf | 8 ++++++++ addons/interaction/stringtable.xml | 9 +++++++++ 3 files changed, 20 insertions(+) diff --git a/addons/interaction/functions/fnc_canInteractWithVehicleCrew.sqf b/addons/interaction/functions/fnc_canInteractWithVehicleCrew.sqf index a314a8b601..bc41152495 100644 --- a/addons/interaction/functions/fnc_canInteractWithVehicleCrew.sqf +++ b/addons/interaction/functions/fnc_canInteractWithVehicleCrew.sqf @@ -18,6 +18,9 @@ params ["_player", "_vehicle"]; +if (GVAR(interactWithEnemyCrew) == 2) exitWith { true }; +if ((GVAR(interactWithEnemyCrew) == 1) && {_vehicle isKindOf "StaticWeapon"}) exitWith { true }; + private _crew = crew _vehicle; // If vehicle is empty, quit diff --git a/addons/interaction/initSettings.inc.sqf b/addons/interaction/initSettings.inc.sqf index 4adc5a6daf..bba27769c0 100644 --- a/addons/interaction/initSettings.inc.sqf +++ b/addons/interaction/initSettings.inc.sqf @@ -55,3 +55,11 @@ false, true ] call CBA_fnc_addSetting; + +[ + QGVAR(interactWithEnemyCrew), "LIST", + [LSTRING(interactWithEnemyCrew_DisplayName), LSTRING(interactWithEnemyCrew_Description)], + format ["ACE %1", LLSTRING(DisplayName)], + [[0, 1, 2], [ELSTRING(common,Never), LSTRING(interactWithEnemyCrew_allowCSW), ELSTRING(common,Always)], 0], + true +] call CBA_fnc_addSetting; diff --git a/addons/interaction/stringtable.xml b/addons/interaction/stringtable.xml index f9bf842bd9..71666af381 100644 --- a/addons/interaction/stringtable.xml +++ b/addons/interaction/stringtable.xml @@ -1332,5 +1332,14 @@ Взаимодействие с анимациями Interaction avec les animations + + Interact With Enemy Crew + + + Limit some interactions on vehicles crewed by enemy factions. + + + Allow for Static Weapons + From 87333a1218a9fbc2c476bf08b0479f4e34ae6bc1 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Fri, 23 Aug 2024 12:22:19 +0200 Subject: [PATCH 24/26] CSW/Reload - Don't allow interactions with hostile CSWs (#10152) Don't allow interactions with hostile CSWs Co-authored-by: PabstMirror --- addons/csw/functions/fnc_getLoadActions.sqf | 3 ++- addons/csw/functions/fnc_getUnloadActions.sqf | 4 +++- .../functions/fnc_canInteractWithVehicleCrew.sqf | 2 +- addons/reload/functions/fnc_canCheckAmmo.sqf | 9 +++++---- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/addons/csw/functions/fnc_getLoadActions.sqf b/addons/csw/functions/fnc_getLoadActions.sqf index 2b28d2dbd6..59b368b368 100644 --- a/addons/csw/functions/fnc_getLoadActions.sqf +++ b/addons/csw/functions/fnc_getLoadActions.sqf @@ -32,7 +32,8 @@ private _condition = { params ["_target", "_player", "_args"]; _args params ["_carryMag", "_turretPath", "", "_magSource"]; - ([_target, _turretPath, _carryMag, _magSource] call FUNC(reload_canLoadMagazine)) select 0 + [_player, _target] call EFUNC(interaction,canInteractWithVehicleCrew) && + {([_target, _turretPath, _carryMag, _magSource] call FUNC(reload_canLoadMagazine)) select 0} }; private _cfgMagazines = configFile >> "CfgMagazines"; // Micro-optimization diff --git a/addons/csw/functions/fnc_getUnloadActions.sqf b/addons/csw/functions/fnc_getUnloadActions.sqf index dd119b0622..03f99cd65d 100644 --- a/addons/csw/functions/fnc_getUnloadActions.sqf +++ b/addons/csw/functions/fnc_getUnloadActions.sqf @@ -46,7 +46,9 @@ private _statement = { private _condition = { params ["_target", "_player", "_args"]; _args params ["_vehMag", "_turretPath", "_carryMag"]; - [_target, _turretPath, _player, _carryMag, _vehMag] call FUNC(reload_canUnloadMagazine) + + [_player, _target] call EFUNC(interaction,canInteractWithVehicleCrew) && + {[_target, _turretPath, _player, _carryMag, _vehMag] call FUNC(reload_canUnloadMagazine)} }; private _actions = []; diff --git a/addons/interaction/functions/fnc_canInteractWithVehicleCrew.sqf b/addons/interaction/functions/fnc_canInteractWithVehicleCrew.sqf index bc41152495..e8b7e47d75 100644 --- a/addons/interaction/functions/fnc_canInteractWithVehicleCrew.sqf +++ b/addons/interaction/functions/fnc_canInteractWithVehicleCrew.sqf @@ -11,7 +11,7 @@ * Unit can interact with vehicle crew * * Example: - * [cursorObject, player] call ace_interaction_fnc_canInteractWithVehicleCrew + * [player, cursorObject] call ace_interaction_fnc_canInteractWithVehicleCrew * * Public: No */ diff --git a/addons/reload/functions/fnc_canCheckAmmo.sqf b/addons/reload/functions/fnc_canCheckAmmo.sqf index 96b9f88d50..829e57e256 100644 --- a/addons/reload/functions/fnc_canCheckAmmo.sqf +++ b/addons/reload/functions/fnc_canCheckAmmo.sqf @@ -4,23 +4,24 @@ * Check if a unit can check the ammo of the target. * * Arguments: - * 0: Unit equipped with the weapon + * 0: Unit equipped with the weapon/CSW to check + * 1: Unit checking ammo * * Return Value: * Can check ammo * * Example: - * [cursorObject] call ace_reload_fnc_canCheckAmmo + * [cursorObject, player] call ace_reload_fnc_canCheckAmmo * * Public: No */ -params ["_target"]; +params ["_target", "_player"]; // Static weapons if (_target isKindOf "StaticWeapon") exitWith { // No check ammo action on destroyed static weapons - if (!alive _target) exitWith {false}; + if (!alive _target || {!([_player, _target] call EFUNC(interaction,canInteractWithVehicleCrew))}) exitWith {false}; if (currentMagazine _target != "") exitWith {true}; From 1f67058ddab3af14558b312d1af508db3770ef42 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Fri, 23 Aug 2024 09:12:53 -0500 Subject: [PATCH 25/26] Interaction - Give some feedback if action is disabled (#10244) --- addons/interaction/functions/fnc_initAnimActions.sqf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/addons/interaction/functions/fnc_initAnimActions.sqf b/addons/interaction/functions/fnc_initAnimActions.sqf index fcd183cd75..e47f80008b 100644 --- a/addons/interaction/functions/fnc_initAnimActions.sqf +++ b/addons/interaction/functions/fnc_initAnimActions.sqf @@ -119,6 +119,8 @@ private _statement = { }; }; } forEach _items; + } else { + [LELSTRING(common,disabled)] call EFUNC(common,displayTextStructured); }; if (!_success) exitWith {}; From 8ac2d09c31a674aaa6d9a2c1bca6025679c5b273 Mon Sep 17 00:00:00 2001 From: Bailey Danyluk Date: Fri, 23 Aug 2024 08:21:31 -0600 Subject: [PATCH 26/26] Missileguidance -- rewrite to use real-world guidance principles, general refactor (#10019) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update todo with list of weapons * Add AIM-120 with ARH. Change AHR to not always seek all targets * Implement some generic modes of flight * implement augmented proportional navigation * Add zero-effort miss. Seeker now feeds data to navigation * Fix bug with ZEM * remove placeholder * Change out missile types to reflect navigation scheme they use IRL * remove uneeded sets * chane navigation profiles to go for attack direction instead of target * multiple changes * SALH: only update seeker pos if it within small error * IR seeker and AIM-9M * small tweaks * more tweaks * todo: fix nlaw * update todo * implement course state machine * Improve radar simulation * enable chaff decoy * add config entries * Implement optical mavericks * Allow for debug info to be displayed via variable * Change AIM-9 agility * update dragon to not use new guidance * Tweak flight parameters. Add R-77 * Add AIM-120A * add ASRAAM * add R-73/4 * Add all GBU-12s that exist for all planes * update todo * update todo for ground based weapons * Add GPS selector dialog for GPS munitions * add TOO TGP * Add SDB and JDAM * update todo * fix gimbal lock via rotating with quaternions * tweak JDAM guidance * Better attack angle calculation. Does not get exactly right, but works for all cases. Need to implement a PID controller navigation type to get a correct attack angle * Fix SACLOS missiles * Fix NLAW and PLOS The missile pitches up due to initial angle stuff. I don't know if this is behaviour we want to fix or not? * update todo * update todo * Add Vikhr ATGM * Add long range SAMs * fix SAM animations * Add all ground based missiles. Tweak AIM-9 flare angle * remove debugh print * Fix Wiesel ATGM animation. Tweak SACLOS values * Add action to get into jdam settings * fix all script components * Add paremter to allow weathervaning Weapons usually tend toward the velocity vector due to aerodynamics - calculate side slip and use calculation to do this * Add new navigation profile. Tweak javelin mid-course guidance * Process all navigation onFired. Send the correct array to function * fix missing semicolons * Add hellfire mid course guidance * Tweak hellfire attack profile * change how IR seeker performs The angle check is better now. Relative velocites guarenteed * tabs -> spaces * localise aim120 * localise aim9 * localise gbu * fix IR tracker losing lock immediately due to being blocked by launcher * localise manpad * actually localise manpad * localise maverick * localise missile guidance * localise sam * localise sdb * localise vikhr * tabs -> spaces again * init commit 9m14 * update stringtables so they are in titlecase * crash on load * perplexed * fix game crashing on load * Add joystick model * Add realistic 9m14 behaviour the 9m14 control joystick can attach 4 9m14 launchers at a time. Replicate that here * add MCLOS guidance * add the ability to see a light trail * tweak HOT guidance params * tweak metis guidance params * tweak Vikhr guidance * add trail to vikhr * Add Iron Dome interceptor API * Optimise iron dome * Only launch if we are above a threshold angle * add local event for mission makers * change events to allow for any number of arguments * avoid making un-needed calls to the server * Update doppler seeker to allow the tracking and killing of projectiles * Avoid overshooting target * Add settings for various things * Add missile hiding for malyutka * init commit of cruise missile * Various - Add missing units/weapons to cfgPatches (#8175) * Various - Add missing units/weapons to cfgPatches * Update config.cpp * Documentation - Add Mikero binarization note (#8172) * Bump is-svg from 4.2.1 to 4.3.1 in /docs/src (#8177) Bumps [is-svg](https://github.com/sindresorhus/is-svg) from 4.2.1 to 4.3.1. - [Release notes](https://github.com/sindresorhus/is-svg/releases) - [Commits](https://github.com/sindresorhus/is-svg/compare/v4.2.1...v4.3.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Adjust "New issue" link to lead to template selection page (#8182) We want people to choose a template when creating a new issue * Update linguist settings (#8151) * Typo in usage example (#8201) * Mk6 Mortar - Fix README.md typo (#8205) * Overhaul CSW docs (#8206) * Medical - Add Alternative Survival Chance (#8192) Co-authored-by: TyroneMF Co-authored-by: Filip Maciejewski Co-authored-by: Kyle Mckay <5459452+kymckay@users.noreply.github.com> * Fix make.py temp files cleanup (#8189) * Fix Injured Sounds Not Playing At Altitudes Above 70 (#8212) * Particles - Fix macro (#8214) * initial push * Update script_component.hpp * Update script_component.hpp * Update script_component.hpp * Map - Fix stuck map compass size (add 0.1 zoom duration) (#8176) Co-authored-by: jonpas * Medical - Allow unconscious unit in Taru pods (#8168) Co-authored-by: Filip Maciejewski * Name Tags - Add ability to set custom rank icon (#8174) * Tools - Add script to update HEMTT include folder (#8134) * Tools - Add script to check sqf/config with sqfvm (#8137) * Medical - Add Vehicle Crashes setting (#8149) Co-authored-by: jonpas * Dragging - Add new dragging animations (#7950) * New custom animation added * Adjusted CfgMoves and the script components * New drop animation and key handler * CBA settings and new ManActions added * Adjustments to the drop animation * Added translations and fixed some stuff * Update CfgMovesBasic.hpp * Fix translations Co-authored-by: Elgin675 Co-authored-by: Blutze <37950828+Blutze@users.noreply.github.com> * Use the same key to drop object * Update addons/dragging/stringtable.xml Co-authored-by: Jo David * Fix French translation Co-authored-by: Elgin675 * Lower the weapon accuracy of the drag animations * Removed auto-switch to handgun * Update fnc_startDrag.sqf - Holding a launcher breaks the firing animation. - Now the unit has to hold either a primary weapon or handgun. * Handle the unit's current weapon Co-authored-by: BaerMitUmlaut * Update addons/dragging/functions/fnc_handlePlayerWeaponChanged.sqf Co-authored-by: Filip Maciejewski * Update addons/dragging/initSettings.sqf Co-authored-by: Elgin675 Co-authored-by: Blutze <37950828+Blutze@users.noreply.github.com> Co-authored-by: Jo David Co-authored-by: BaerMitUmlaut Co-authored-by: Filip Maciejewski Co-authored-by: jonpas * Dragging - Fix build issue (#8219) * Documentation - Remove DeTex requirement (#8220) DeTex is subscriber-only now, not required for building ACE3. * User Interface - Add setting for Development Build watermark (#8140) Co-authored-by: jonpas * RHS USAF Compat - Nightforce NXS scopes updated (#8222) * Interact Menu - Make List default (#8217) * Markers - Add scale slider (#8059) Co-authored-by: commy2 Co-authored-by: PabstMirror Co-authored-by: jonpas * Initial push (#8225) * MicroDAGR - Add mode switching keybinds (#8216) * Initial push * Mode cycling * Use defines * RHS ARF Compat - Fix RPK74M wrong ammo bug (#8223) * Fixed RPK74M wrong ammo bug * Fix wrong deleted lines of code * Edit rjs_weap_rpk74_base to rhs_weap_rpk_base Co-authored-by: Dabako Co-authored-by: PabstMirror * Extensions - Various Improvments (#8227) * Translations - Spanish (#8229) Complete to date spanish translation. * Attach - Added attached/detaching events (#8193) * Added ace_attach attached/detach events * Apply suggestions from code review Co-authored-by: Jo David * Apply suggestions from code review Co-authored-by: jonpas Co-authored-by: Jo David Co-authored-by: jonpas * Markers - Fix marker scale (#8233) * Cargo - paradrop fixes (#8203) * Small fixes in ace_cargo Makes paradropItem and unloadItem invoke event "ace_cargoUnloaded" with parameters _itemObject, _vehicle and "paradrop" or "unload" respectivelty. paradropItem invoked said event but if item was classname it would send classname to event which is not particularly useful. * Update XEH_postInit.sqf Moved event invocation to unloadItem, this provides ability to always pass object to eventhandlers. * code refactor refactored according to https://github.com/acemod/ACE3/pull/8203#discussion_r610394484 * Update fnc_paradropItem.sqf apply new fix * Revert "Update fnc_paradropItem.sqf" This reverts commit 3db5cc191082a4d8e3cb0c39f0a5c791e2874f0e. * Update fnc_paradropItem.sqf fixed hint that was broken by previous fixes * style check Co-authored-by: commy2 * style check Co-authored-by: commy2 * naming convention replaced object references called _item with _object. * Update fnc_paradropItem.sqf Co-authored-by: commy2 * Parachute - Add failure chance (#8226) * Initial push * disable forgotten define * Improve exitWith check * Requested/suggested changes * Requested changes * Requested changes * Bump lodash from 4.17.20 to 4.17.21 in /docs/src (#8244) Bumps [lodash](https://github.com/lodash/lodash) from 4.17.20 to 4.17.21. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.20...4.17.21) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump grunt from 1.0.4 to 1.3.0 in /docs/src (#8246) Bumps [grunt](https://github.com/gruntjs/grunt) from 1.0.4 to 1.3.0. - [Release notes](https://github.com/gruntjs/grunt/releases) - [Changelog](https://github.com/gruntjs/grunt/blob/main/CHANGELOG) - [Commits](https://github.com/gruntjs/grunt/compare/v1.0.4...v1.3.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump hosted-git-info from 2.5.0 to 2.8.9 in /docs/src (#8247) Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.5.0 to 2.8.9. - [Release notes](https://github.com/npm/hosted-git-info/releases) - [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md) - [Commits](https://github.com/npm/hosted-git-info/compare/v2.5.0...v2.8.9) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Markers - Fix JIP scale (#8248) * Night Vision - Add color variants to all generations (#8209) * Fix wrong shot size in birdshot strings (#8253) * Patachute - Add sound effect when cutting (#8239) * Changes poisson disc to centered random. (#8257) It looks nicer and distributes more realistically. I don't know what I was thinking when I first put in poisson disc. * Fix tabs and manpad UBC * fix tabs in aim9 * progress update: tercom now flies to acquisition basket * add TERCOM state defines * work on parsing heightmap * Change GBU navigation * remove testing constants * remove TERCOM guidance * better JDAM simulation Attack heading and impact angle now are followed better * Better flare decoy calculation * Update 9m14_joystick.p3d removed p:\ part from proxy path: was: `\p:\a3\data_f\proxies\gunner_static_low01\gunner.p3d` * Destroy projectile on all clients The projectile needs to be destroyed on all clients to stop it from being simulated. If not destroyed where projectile is local, it will still explode when hitting the ground. If not destroyed on remote clients, the projectile will still be visible but deal no damage * fix NLAW navigation profile * fix uninitialised values * make over-fly trajectory over-fly * remove malyutka * SACLOS tweaks * small changes * fix bug in laser * make pronav use the correct units * change back * add dev function to get ammo which has MG class data * improve lin navigation * Minor style * add spike ATGM * Allow multiple cameras to exist at once. Fix script error * fix bug with angles close to 0 * remove debug * misc updates * Handle pre-tracking * Tweak target acquisition. Reset target after shooting * Tweak how targets are acquired. Fix velocity calculation * tweak navigation to allow for <200m shots * enhance target designation * Stringtable addition * Config changes * more SACLOS tweaks * Some minor fixes * fix undefined array * Only play sound when Spike is launcher. Change onFired to missileguidance * Tweak IR seeker. Fix MCLOS fired from vehicles * Remove debug sets * Update all Line guidance missiles * remove debug sets * tweak javelin to make minimum ranges more realistic * cut spike * add better error messaging * better debug info * Rewrite documentation * Add ability to disable iron dome (disabled by default) * Change name * fix typo * Remove null projectiles from iron dome nonTrackingProjectiles * HEMTT v10 Compatibility * Update addons/field_rations/CfgUIGrids.hpp Co-authored-by: PabstMirror * fix PabstMirror review * optionals * Change configs to enclose strings for calculations * Fix NLAW guidance that was causing massive overfly * make tweaks for PLOS movement path * fix NLAW overfly * Fix hemmit merge * fix header * Update fnc_seekerType_SACLOS.sqf * Update to new include paths * Update fnc_midCourseTransition.sqf * initSettings.inc.sqf * Remove weapon additions * revert old weapons, pt1 * revert pt2 * readd javelin * split iron dome * cleanup laser * remove GPS files * remove gps definitions * remove IR * remove MCLOS * remove doppler * final cleanup * restore final final i promise * cleanup arbitrary files * small cleanup * fix hemtt warnings * cleanup unused var * fix preping some missing files (jdam/doppler) * move cam func --------- Co-authored-by: PabstMirror Co-authored-by: jonpas Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jo David Co-authored-by: Filip Maciejewski Co-authored-by: Pascal Dunaj <32539404+t-zilla@users.noreply.github.com> Co-authored-by: BaerMitUmlaut Co-authored-by: Brett Co-authored-by: TyroneMF Co-authored-by: Kyle Mckay <5459452+kymckay@users.noreply.github.com> Co-authored-by: Dystopian Co-authored-by: commy2 Co-authored-by: R3voA3 Co-authored-by: Steve Zhao Co-authored-by: Kyle J. McKeown Co-authored-by: Salluci <69561145+Salluci@users.noreply.github.com> Co-authored-by: Dániel Boros <43353942+Malbryn@users.noreply.github.com> Co-authored-by: Elgin675 Co-authored-by: Blutze <37950828+Blutze@users.noreply.github.com> Co-authored-by: Laid3acK Co-authored-by: frankplow Co-authored-by: JoramD Co-authored-by: Dabako Co-authored-by: Dabako Co-authored-by: Abogado Co-authored-by: Dedmen Miller Co-authored-by: Lupus the Canine Co-authored-by: Drofseh Co-authored-by: LorenLuke Co-authored-by: SzwedzikPL Co-authored-by: BrettMayson --- addons/missileguidance/ACE_GuidanceConfig.hpp | 51 +++- addons/missileguidance/XEH_PREP.hpp | 26 +- addons/missileguidance/XEH_postInit.sqf | 6 +- addons/missileguidance/XEH_preInit.sqf | 11 + .../missileguidance/dev/getAmmoProperties.sqf | 26 ++ .../functions/fnc_SACLOS_onFired.sqf | 1 - .../functions/fnc_attackProfile_BEAM.sqf | 29 +- .../functions/fnc_attackProfile_DIR.sqf | 7 +- .../functions/fnc_attackProfile_HI.sqf | 21 -- .../functions/fnc_attackProfile_LIN.sqf | 36 +-- .../functions/fnc_attackProfile_LOFT.sqf | 53 ++++ .../functions/fnc_attackProfile_MID.sqf | 21 -- .../functions/fnc_attackProfile_WIRE.sqf | 36 +-- .../functions/fnc_changeMissileDirection.sqf | 9 +- .../functions/fnc_checkLos.sqf | 1 - .../fnc_cycleAttackProfileKeyDown.sqf | 2 +- .../functions/fnc_dev_ProjectileCamera.sqf | 61 +++++ .../functions/fnc_doAttackProfile.sqf | 9 +- .../functions/fnc_doSeekerSearch.sqf | 12 +- .../functions/fnc_guidancePFH.sqf | 249 +++++++++++++----- .../functions/fnc_line_onFired.sqf | 35 +++ ...nc_ahr_onFired.sqf => fnc_mwr_onFired.sqf} | 6 +- .../fnc_navigationType_augmentedProNav.sqf | 50 ++++ .../functions/fnc_navigationType_direct.sqf | 21 ++ .../functions/fnc_navigationType_line.sqf | 52 ++++ .../fnc_navigationType_lineOfSight.sqf | 48 ++++ .../functions/fnc_navigationType_proNav.sqf | 46 ++++ .../fnc_navigationType_zeroEffortMiss.sqf | 38 +++ .../missileguidance/functions/fnc_onFired.sqf | 127 +++++++-- .../functions/fnc_proNav_onFired.sqf | 36 +++ ...kerType_ARH.sqf => fnc_seekerType_MWR.sqf} | 36 ++- .../functions/fnc_seekerType_Optic.sqf | 13 +- .../functions/fnc_seekerType_SACLOS.sqf | 15 +- .../functions/fnc_seekerType_SALH.sqf | 51 +++- .../functions/fnc_wire_onFired.sqf | 1 - addons/missileguidance/script_component.hpp | 4 +- .../framework/missile-guidance-framework.md | 71 +++-- 37 files changed, 1030 insertions(+), 287 deletions(-) create mode 100644 addons/missileguidance/dev/getAmmoProperties.sqf delete mode 100644 addons/missileguidance/functions/fnc_attackProfile_HI.sqf create mode 100644 addons/missileguidance/functions/fnc_attackProfile_LOFT.sqf delete mode 100644 addons/missileguidance/functions/fnc_attackProfile_MID.sqf create mode 100644 addons/missileguidance/functions/fnc_dev_ProjectileCamera.sqf create mode 100644 addons/missileguidance/functions/fnc_line_onFired.sqf rename addons/missileguidance/functions/{fnc_ahr_onFired.sqf => fnc_mwr_onFired.sqf} (92%) create mode 100644 addons/missileguidance/functions/fnc_navigationType_augmentedProNav.sqf create mode 100644 addons/missileguidance/functions/fnc_navigationType_direct.sqf create mode 100644 addons/missileguidance/functions/fnc_navigationType_line.sqf create mode 100644 addons/missileguidance/functions/fnc_navigationType_lineOfSight.sqf create mode 100644 addons/missileguidance/functions/fnc_navigationType_proNav.sqf create mode 100644 addons/missileguidance/functions/fnc_navigationType_zeroEffortMiss.sqf create mode 100644 addons/missileguidance/functions/fnc_proNav_onFired.sqf rename addons/missileguidance/functions/{fnc_seekerType_ARH.sqf => fnc_seekerType_MWR.sqf} (82%) diff --git a/addons/missileguidance/ACE_GuidanceConfig.hpp b/addons/missileguidance/ACE_GuidanceConfig.hpp index 3628c9eec0..131beee339 100644 --- a/addons/missileguidance/ACE_GuidanceConfig.hpp +++ b/addons/missileguidance/ACE_GuidanceConfig.hpp @@ -6,6 +6,11 @@ class GVAR(AttackProfiles) { functionName = QFUNC(attackProfile_LIN); }; + // empty classes for backwards compat + class MID: LIN { + }; + class HI: LIN { + }; class DIR { name = ""; visualName = ""; @@ -13,21 +18,14 @@ class GVAR(AttackProfiles) { functionName = QFUNC(attackProfile_DIR); }; - class MID { + class LOFT { name = ""; visualName = ""; description = ""; - functionName = QFUNC(attackProfile_MID); + functionName = QFUNC(attackProfile_LOFT); }; - class HI { - name = ""; - visualName = ""; - description = ""; - - functionName = QFUNC(attackProfile_HI); - }; - class JAV_DIR { + class JAV_DIR { name = ""; visualName = ""; description = ""; @@ -82,12 +80,39 @@ class GVAR(SeekerTypes) { functionName = QFUNC(seekerType_SACLOS); onFired = QFUNC(SACLOS_onFired); }; - class ARH { + class MillimeterWaveRadar { name = ""; visualName = ""; description = ""; - functionName = QFUNC(seekerType_ARH); - onFired = QFUNC(ahr_onFired); + functionName = QFUNC(seekerType_MWR); + onFired = QFUNC(mwr_onFired); + }; +}; + +class GVAR(NavigationTypes) { + class Direct { + functionName = QFUNC(navigationType_direct); + onFired = ""; + }; + class Line { + functionName = QFUNC(navigationType_line); + onFired = QFUNC(line_onFired); + }; + class LineOfSight { + functionName = QFUNC(navigationType_lineOfSight); + onFired = QFUNC(proNav_onFired); + }; + class ProportionalNavigation { + functionName = QFUNC(navigationType_proNav); + onFired = QFUNC(proNav_onFired); + }; + class AugmentedProportionalNavigation { + functionName = QFUNC(navigationType_augmentedProNav); + onFired = QFUNC(proNav_onFired); + }; + class ZeroEffortMiss { + functionName = QFUNC(navigationType_zeroEffortMiss); + onFired = QFUNC(proNav_onFired); }; }; diff --git a/addons/missileguidance/XEH_PREP.hpp b/addons/missileguidance/XEH_PREP.hpp index 075f2f03c5..d0c6b0af11 100644 --- a/addons/missileguidance/XEH_PREP.hpp +++ b/addons/missileguidance/XEH_PREP.hpp @@ -6,6 +6,8 @@ PREP(changeMissileDirection); PREP(checkSeekerAngle); PREP(checkLos); +PREP(dev_ProjectileCamera); + PREP(onFired); PREP(onIncomingMissile); @@ -16,28 +18,44 @@ PREP(doSeekerSearch); PREP(doHandoff); PREP(handleHandoff); +//re-enable after feature merge - PREP(shouldFilterRadarHit); + // Attack Profiles PREP(attackProfile_AIR); PREP(attackProfile_DIR); -PREP(attackProfile_HI); PREP(attackProfile_LIN); -PREP(attackProfile_MID); +PREP(attackProfile_LOFT); PREP(attackProfile_WIRE); PREP(attackProfile_BEAM); +//re-enable after feature merge - PREP(attackProfile_JDAM); // Javelin profiles PREP(attackProfile_JAV_DIR); PREP(attackProfile_JAV_TOP); +// Navigation Profiles +PREP(navigationType_zeroEffortMiss); +PREP(navigationType_augmentedProNav); +PREP(navigationType_proNav); +PREP(navigationType_lineOfSight); +PREP(navigationType_line); +PREP(navigationType_direct); + // Seeker search functions PREP(seekerType_SALH); PREP(seekerType_Optic); PREP(seekerType_SACLOS); -PREP(seekerType_ARH); +//re-enable after feature merge - PREP(seekerType_Doppler); +PREP(seekerType_MWR); // Attack Profiles OnFired PREP(wire_onFired); // Seeker OnFired PREP(SACLOS_onFired); -PREP(ahr_onFired); +PREP(mwr_onFired); + +// Navigation OnFired +PREP(proNav_onFired); +PREP(line_onFired); + diff --git a/addons/missileguidance/XEH_postInit.sqf b/addons/missileguidance/XEH_postInit.sqf index eb0fb60abf..e0fc98ba1b 100644 --- a/addons/missileguidance/XEH_postInit.sqf +++ b/addons/missileguidance/XEH_postInit.sqf @@ -2,12 +2,10 @@ [QGVAR(handoff), LINKFUNC(handleHandoff)] call CBA_fnc_addEventHandler; -["ACE3 Weapons", QGVAR(cycleFireMode), localize LSTRING(CycleFireMode), -{ +["ACE3 Weapons", QGVAR(cycleFireMode), localize LSTRING(CycleFireMode), { [] call FUNC(cycleAttackProfileKeyDown); false -}, -{ +}, { false }, [15, [false, true, false]], false] call CBA_fnc_addKeybind; //Ctrl+Tab Key diff --git a/addons/missileguidance/XEH_preInit.sqf b/addons/missileguidance/XEH_preInit.sqf index 0798fed2e4..9b1a85e37c 100644 --- a/addons/missileguidance/XEH_preInit.sqf +++ b/addons/missileguidance/XEH_preInit.sqf @@ -11,4 +11,15 @@ PREP_RECOMPILE_END; // As weapons take config changes, there is little point in being able to disable guidance if (isNil QGVAR(enabled)) then { GVAR(enabled) = 2; }; +GVAR(debug_enableMissileCamera) = false; +GVAR(debug_drawGuidanceInfo) = false; + +#ifdef DRAW_GUIDANCE_INFO +GVAR(debug_drawGuidanceInfo) = true; +#endif + +#ifdef ENABLE_PROJECTILE_CAMERA +GVAR(debug_enableMissileCamera) = true; +#endif + ADDON = true; diff --git a/addons/missileguidance/dev/getAmmoProperties.sqf b/addons/missileguidance/dev/getAmmoProperties.sqf new file mode 100644 index 0000000000..9c416c228f --- /dev/null +++ b/addons/missileguidance/dev/getAmmoProperties.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" + +private _configs = configProperties [configFile >> "CfgAmmo", QUOTE((isClass _x) && { isClass (_x >> QUOTE(QUOTE(ADDON)))})]; + +private _seekerTypes = createHashMap; +private _navigationTypes = createHashMap; +private _attackProfiles = createHashMap; +{ + private _seekerType = getText (_x >> QUOTE(ADDON) >> "defaultSeekerType"); + private _navigationType = getText (_x >> QUOTE(ADDON) >> "defaultNavigationType"); + private _attackProfile = getText (_x >> QUOTE(ADDON) >> "defaultAttackProfile"); + + private _seekers = _seekerTypes getOrDefault [_seekerType, []]; + private _navigations = _navigationTypes getOrDefault [_navigationType, []]; + private _attacks = _attackProfiles getOrDefault [_attackProfile, []]; + + _seekers pushBack configName _x; + _navigations pushBack configName _x; + _attacks pushBack configName _x; + + _seekerTypes set [_seekerType, _seekers]; + _navigationTypes set [_navigationType, _navigations]; + _attackProfiles set [_attackProfile, _attacks]; +} forEach _configs; + +[_seekerTypes, _navigationTypes, _attackProfiles] diff --git a/addons/missileguidance/functions/fnc_SACLOS_onFired.sqf b/addons/missileguidance/functions/fnc_SACLOS_onFired.sqf index 299ec6f236..f48b4a9571 100644 --- a/addons/missileguidance/functions/fnc_SACLOS_onFired.sqf +++ b/addons/missileguidance/functions/fnc_SACLOS_onFired.sqf @@ -32,4 +32,3 @@ _seekerStateParams set [2, _animationSourceGun]; _seekerStateParams set [3, _usePilotCamera || { (_shooter isKindOf "Plane") && hasPilotCamera _shooter }]; if ((_shooter isKindOf "Plane") && !hasPilotCamera _shooter) then { WARNING("SACLOS fired from planes without pilot camera unsupported!"); }; - diff --git a/addons/missileguidance/functions/fnc_attackProfile_BEAM.sqf b/addons/missileguidance/functions/fnc_attackProfile_BEAM.sqf index 5aaff9d7f8..fd86b57104 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_BEAM.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_BEAM.sqf @@ -17,31 +17,26 @@ * Public: No */ params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; -_args params ["_firedEH"]; +_args params ["_firedEH", "", "", "", "", "_targetData"]; _firedEH params ["_shooter","","","","","","_projectile"]; -_attackProfileStateParams params["_maxCorrectableDistance", "_wireCut", "_randomVector", "_crosshairOffset", "_seekerMaxRangeSqr", "_seekerMinRangeSqr", "_wireCutSource", "_distanceAheadOfMissile"]; +_attackProfileStateParams params ["_maxCorrectableDistance", "_wireCut", "_lastInput", "_crosshairOffset", "_seekerMaxRangeSqr", "_seekerMinRangeSqr", "_wireCutSource", "_distanceAheadOfMissile"]; private _projectilePos = getPosASL _projectile; private _shooterPos = getPosASL _shooter; -private _shooterDir = vectorNormalized(_seekerTargetPos vectorDiff _shooterPos); private _distanceToProjectile = _shooterPos vectorDistanceSqr _projectilePos; -if (_distanceToProjectile > _seekerMaxRangeSqr || { _seekerTargetPos isEqualTo [0, 0, 0] } || { _distanceToProjectile < _seekerMinRangeSqr }) exitWith { - // return position 50m infront of projectile - _projectilePos vectorAdd (_projectile vectorModelToWorld [0, 50, 0]) +if ((_distanceToProjectile > _seekerMaxRangeSqr) || { _wireCut }) exitWith { + // wire snap, random direction + if !(_wireCut) then { + _attackProfileStateParams set [1, true]; + }; + _lastInput }; -private _relativeCorrection = _projectile vectorWorldToModel (_projectilePos vectorDiff _seekerTargetPos); -_relativeCorrection = _relativeCorrection vectorDiff _crosshairOffset; +private _final = _seekerTargetPos vectorAdd _crosshairOffset; +_attackProfileStateParams set [2, _final]; -private _magnitude = vectorMagnitude [_relativeCorrection select 0, 0, _relativeCorrection select 2]; -private _fovImpulse = 1 min (_magnitude / _maxCorrectableDistance); // the simulated impulse for the missile being close to the center of the crosshair +_targetData set [0, _projectilePos vectorFromTo _final]; -// Adjust the impulse due to near-zero values creating wobbly missiles? -private _correction = _fovImpulse; - - -_relativeCorrection = (vectorNormalized _relativeCorrection) vectorMultiply _correction; -private _returnPos = _projectilePos vectorDiff (_projectile vectorModelToWorld _relativeCorrection); -_returnPos vectorAdd (_shooterDir vectorMultiply _distanceAheadOfMissile) +_final diff --git a/addons/missileguidance/functions/fnc_attackProfile_DIR.sqf b/addons/missileguidance/functions/fnc_attackProfile_DIR.sqf index 80499a85da..d2a2c0616c 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_DIR.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_DIR.sqf @@ -1,8 +1,8 @@ #include "..\script_component.hpp" /* - * Author: jaynus / nou + * Author: tcvm * Attack profile: DIR - * TODO: falls back to Linear + * Returns target position with no modifications * * Arguments: * 0: Seeker Target PosASL @@ -18,4 +18,5 @@ * Public: No */ -_this call FUNC(attackProfile_LIN); +params ["_seekerTargetPos"]; +_seekerTargetPos diff --git a/addons/missileguidance/functions/fnc_attackProfile_HI.sqf b/addons/missileguidance/functions/fnc_attackProfile_HI.sqf deleted file mode 100644 index 92413f59d0..0000000000 --- a/addons/missileguidance/functions/fnc_attackProfile_HI.sqf +++ /dev/null @@ -1,21 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: jaynus / nou - * Attack profile: HI - * TODO: falls back to Linear - * - * Arguments: - * 0: Seeker Target PosASL - * 1: Guidance Arg Array - * 2: Attack Profile State - * - * Return Value: - * Missile Aim PosASL - * - * Example: - * [[1,2,3], [], []] call ace_missileguidance_fnc_attackProfile_HI; - * - * Public: No - */ - -_this call FUNC(attackProfile_LIN); diff --git a/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf b/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf index e346b16eb6..5462a80a75 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf @@ -18,8 +18,10 @@ */ params ["_seekerTargetPos", "_args"]; -_args params ["_firedEH"]; +_args params ["_firedEH", "_launchParams"]; _firedEH params ["_shooter","","","","","","_projectile"]; +_launchParams params ["","_targetLaunchParams"]; +_targetLaunchParams params ["", "", "_launchPos"]; if (_seekerTargetPos isEqualTo [0,0,0]) exitWith {_seekerTargetPos}; @@ -30,27 +32,29 @@ private _distanceToTarget = _projectilePos vectorDistance _seekerTargetPos; private _distanceToShooter = _projectilePos vectorDistance _shooterPos; private _distanceShooterToTarget = _shooterPos vectorDistance _seekerTargetPos; +private _ttgo = _distanceToTarget / (vectorMagnitude velocity _projectile); + TRACE_2("",_distanceToTarget,_distanceToShooter); // Add height depending on distance for compensate private _addHeight = [0,0,0]; -// Always climb an arc on initial launch if we are close to the round -if ((((ASLtoAGL _projectilePos) select 2) < 5) && {_distanceToShooter < 15}) then { - _addHeight = _addHeight vectorAdd [0,0,_distanceToTarget]; - TRACE_1("climb - near shooter",_addHeight); -} else { - // If we are below the target, increase the climbing arc - if (((_projectilePos select 2) < (_seekerTargetPos select 2)) && {_distanceToTarget > 100}) then { - _addHeight = _addHeight vectorAdd [0,0, ((_seekerTargetPos select 2) - (_projectilePos select 2))]; - TRACE_1("climb - below target and far",_addHeight); - }; -}; +private _2dDistance = (800 + (_projectilePos distance2D _launchPos)) / (_projectilePos distance2D _seekerTargetPos); -// Projectile above target -if ((_projectilePos select 2) > (_seekerTargetPos select 2)) then { - TRACE_1("above - far",_addHeight); - _addHeight = _addHeight vectorAdd [0,0, _distanceToTarget / 50]; +if (_2dDistance <= 1) then { + _addHeight = [0, 0, (_projectilePos#2) + 8]; +} else { + // Always climb an arc on initial launch if we are close to the round + if ((((ASLtoAGL _projectilePos) select 2) < 5) && {_distanceToShooter < 15}) then { + _addHeight = _addHeight vectorAdd [0,0,_distanceToTarget]; + TRACE_1("climb - near shooter",_addHeight); + } else { + // If we are below the target, increase the climbing arc + if (((_projectilePos select 2) < (_seekerTargetPos select 2)) && {_distanceToTarget > 100}) then { + _addHeight = _addHeight vectorAdd [0,0, ((_seekerTargetPos select 2) - (_projectilePos select 2))]; + TRACE_1("climb - below target and far",_addHeight); + }; + }; }; private _returnTargetPos = _seekerTargetPos vectorAdd _addHeight; diff --git a/addons/missileguidance/functions/fnc_attackProfile_LOFT.sqf b/addons/missileguidance/functions/fnc_attackProfile_LOFT.sqf new file mode 100644 index 0000000000..1fff2ef8c5 --- /dev/null +++ b/addons/missileguidance/functions/fnc_attackProfile_LOFT.sqf @@ -0,0 +1,53 @@ +#include "..\script_component.hpp" +/* + * Author: jaynus / nou + * Attack profile: AIR + * TODO: falls back to Linear + * + * Arguments: + * 0: Seeker Target PosASL + * 1: Guidance Arg Array + * 2: Seeker State + * + * Return Value: + * Missile Aim PosASL + * + * Example: + * [[1,2,3], [], []] call ace_missileguidance_fnc_attackProfile_AIR; + * + * Public: No + */ + +params ["_seekerTargetPos", "_args"]; +_args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams"]; +_firedEH params ["_shooter","","","","_ammo","","_projectile"]; +_launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo","_navigationType"]; +_targetLaunchParams params ["_target", "_targetPos", "_launchPos", "_launchDir", "_launchTime"]; +_flightParams params ["_pitchRate", "_yawRate", "_isBangBangGuidance"]; +_stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState","_navigationParams"]; +_seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"]; + +if (_seekerTargetPos isEqualTo [0, 0, 0]) exitWith { + _seekerTargetPos +}; + +private _projectilePos = getPosASLVisual _projectile; +private _distanceToTarget2d = _projectilePos distance2d _seekerTargetPos; + +private _closingRate = vectorMagnitude velocity _projectile; +private _timeToGo = (_projectilePos distance _seekerTargetPos) / _closingRate; + +// we could do stuff like desired attack angle, but I'm not going that far today +private _los = vectorNormalized (_seekerTargetPos vectorDiff _projectilePos); + +private _angleToTarget = acos ((vectorDir _projectile) vectorCos _los); +private _atMinRotationAngle = _angleToTarget >= (0.5 * _pitchRate * _timeToGo); + +private _returnTargetPos = _seekerTargetPos; + +if (!_atMinRotationAngle && _distanceToTarget2d >= 500 && _timeToGo >= 10) then { + // 10 degree pitch up + _returnTargetPos = _seekerTargetPos vectorAdd [0, 0, (_projectilePos distance _seekerTargetPos) * sin 10]; +}; + +_returnTargetPos diff --git a/addons/missileguidance/functions/fnc_attackProfile_MID.sqf b/addons/missileguidance/functions/fnc_attackProfile_MID.sqf deleted file mode 100644 index 2ca9eef77f..0000000000 --- a/addons/missileguidance/functions/fnc_attackProfile_MID.sqf +++ /dev/null @@ -1,21 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: jaynus / nou - * Attack profile: MID - * TODO: falls back to Linear - * - * Arguments: - * 0: Seeker Target PosASL - * 1: Guidance Arg Array - * 2: Attack Profile State - * - * Return Value: - * Missile Aim PosASL - * - * Example: - * [[1,2,3], [], []] call ace_missileguidance_fnc_attackProfile_MID; - * - * Public: No - */ - -_this call FUNC(attackProfile_LIN); diff --git a/addons/missileguidance/functions/fnc_attackProfile_WIRE.sqf b/addons/missileguidance/functions/fnc_attackProfile_WIRE.sqf index 443fe1bb97..361b0d8fcf 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_WIRE.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_WIRE.sqf @@ -17,47 +17,27 @@ * Public: No */ params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; -_args params ["_firedEH"]; +_args params ["_firedEH", "", "", "", "", "_targetData"]; _firedEH params ["_shooter","","","","","","_projectile"]; -_attackProfileStateParams params["_maxCorrectableDistance", "_wireCut", "_randomVector", "_crosshairOffset", "_seekerMaxRangeSqr", "_seekerMinRangeSqr", "_wireCutSource", "_distanceAheadOfMissile"]; +_attackProfileStateParams params ["_maxCorrectableDistance", "_wireCut", "_lastInput", "_crosshairOffset", "_seekerMaxRangeSqr", "_seekerMinRangeSqr", "_wireCutSource", "_distanceAheadOfMissile"]; private _projectilePos = getPosASL _projectile; private _shooterPos = getPosASL _shooter; -private _shooterDir = vectorNormalized(_seekerTargetPos vectorDiff _shooterPos); private _distanceToProjectile = _shooterPos vectorDistanceSqr _projectilePos; if ((_distanceToProjectile > _seekerMaxRangeSqr) || { _wireCut }) exitWith { // wire snap, random direction - if (_randomVector isEqualTo [0, 0, 0]) then { - _randomVector = RANDOM_VECTOR_3D vectorMultiply 300; + if !(_wireCut) then { _attackProfileStateParams set [1, true]; - _attackProfileStateParams set [2, _randomVector]; - playSound3D ["a3\sounds_f\air\sfx\SL_rope_break.wss", objNull, false, AGLtoASL (_shooter modelToWorld _wireCutSource), 5, 1, 150]; }; - _projectilePos vectorAdd _randomVector + _lastInput }; -if (_seekerTargetPos isEqualTo [0, 0, 0] || { _distanceToProjectile < _seekerMinRangeSqr }) exitWith { - // cut wire if its caught on terrain - /*if (lineIntersectsSurfaces [getPosASL _shooter, _projectilePos, _shooter] isNotEqualTo []) then { - _attackProfileStateParams set [1, true]; - };*/ - // return position 50m infront of projectile - _projectilePos vectorAdd (_projectile vectorModelToWorld [0, 50, 0]) -}; +private _final = _seekerTargetPos vectorAdd _crosshairOffset; +_attackProfileStateParams set [2, _final]; -private _relativeCorrection = _projectile vectorWorldToModel (_projectilePos vectorDiff _seekerTargetPos); -_relativeCorrection = _relativeCorrection vectorDiff _crosshairOffset; +_targetData set [0, _projectilePos vectorFromTo _final]; -private _magnitude = vectorMagnitude [_relativeCorrection select 0, 0, _relativeCorrection select 2]; -private _fovImpulse = 1 min (_magnitude / _maxCorrectableDistance); // the simulated impulse for the missile being close to the center of the crosshair - -// Adjust the impulse due to near-zero values creating wobbly missiles? -private _correction = _fovImpulse; - - -_relativeCorrection = (vectorNormalized _relativeCorrection) vectorMultiply _correction; -private _returnPos = _projectilePos vectorDiff (_projectile vectorModelToWorld _relativeCorrection); -_returnPos vectorAdd (_shooterDir vectorMultiply _distanceAheadOfMissile) +_final diff --git a/addons/missileguidance/functions/fnc_changeMissileDirection.sqf b/addons/missileguidance/functions/fnc_changeMissileDirection.sqf index 21884c1693..f9a2493955 100644 --- a/addons/missileguidance/functions/fnc_changeMissileDirection.sqf +++ b/addons/missileguidance/functions/fnc_changeMissileDirection.sqf @@ -16,10 +16,9 @@ * Public: No */ -params ["_projectile", "_v"]; +params ["_projectile", "_pitch", "_yaw", "_roll"]; -private _l = sqrt ((_v select 0) ^ 2 + (_v select 1) ^ 2); -private _r = -(_v select 2) / _l; +private _dir = [sin _yaw * cos _pitch, cos _yaw * cos _pitch, sin _pitch]; +private _up = [[sin _roll, -sin _pitch, cos _roll * cos _pitch], -_yaw] call BIS_fnc_rotateVector2D; -_projectile setVectorDirAndUp [ _v, [(_v select 0) * _r,(_v select 1) * _r, _l] ]; -_projectile setVelocity (_v vectorMultiply (vectorMagnitude (velocity _projectile))); +_projectile setVectorDirAndUp [_dir, _up]; diff --git a/addons/missileguidance/functions/fnc_checkLos.sqf b/addons/missileguidance/functions/fnc_checkLos.sqf index 1fadc5510e..4ec1ebac10 100644 --- a/addons/missileguidance/functions/fnc_checkLos.sqf +++ b/addons/missileguidance/functions/fnc_checkLos.sqf @@ -43,4 +43,3 @@ if (!((terrainIntersectASL [_seekerPos, _targetPos]) && {terrainIntersectASL [_s }; _return - diff --git a/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf b/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf index 2263716724..f8494e474c 100644 --- a/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf +++ b/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf @@ -76,7 +76,7 @@ private _nextFireMode = _attackProfiles select _index; TRACE_4("",_currentFireMode,_nextFireMode,_index,_attackProfiles); -private _currentFireMode = if (_useModeForAttackProfile) then { +if (_useModeForAttackProfile) then { TRACE_2("setting fire mode",_weaponStateToken,_nextFireMode); { _x params ["_xIndex", "", "_xWeapon", "", "_xMode"]; diff --git a/addons/missileguidance/functions/fnc_dev_ProjectileCamera.sqf b/addons/missileguidance/functions/fnc_dev_ProjectileCamera.sqf new file mode 100644 index 0000000000..5073709a27 --- /dev/null +++ b/addons/missileguidance/functions/fnc_dev_ProjectileCamera.sqf @@ -0,0 +1,61 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * tracks a projectile until it explodes + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: No + */ +params ["_projectile"]; + +private _camera = "camera" camCreate getPosATL _projectile; +_camera camPrepareFOV 0.7; +_camera cameraEffect ["internal", "back"]; + +_camera camCommitPrepared 0; + +GVAR(debug_camera_close) = false; +private _displayEH = (findDisplay 46) displayAddEventHandler ["KeyDown", { + params ["_displayorcontrol", "_key", "_shift", "_ctrl", "_alt"]; + GVAR(debug_camera_close) = (_key == 1); + true +}]; + +[{ + params ["_args", "_pfh"]; + _args params ["_projectile", "_camera", "_projectilePos", "_displayEH"]; + if (!alive _projectile || GVAR(debug_camera_close)) exitWith { + private _delay = 1.5; + if (GVAR(debug_camera_close)) then { + _delay = 0; + }; + + (findDisplay 46) displayRemoveEventHandler ["KeyDown", _displayEH]; + + [{ + params ["_camera"]; + + _camera cameraEffect ["terminate", "back"]; + _camera camCommitPrepared 0; + camDestroy _camera; + }, [_camera], _delay] call CBA_fnc_waitAndExecute; + + _camera camPrepareTarget _projectilePos; + _camera camCommitPrepared 0; + + [_pfh] call CBA_fnc_removePerFrameHandler; + }; + + private _currentProjectilePos = getPosATLVisual _projectile; + + _camera camPrepareTarget _projectile; + _camera camPrepareRelPos [0, -5, 1]; + _camera camCommitPrepared 0; + + _args set [2, getPosATL _projectile]; +}, 0, [_projectile, _camera, getPosATL _projectile, _displayEH]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/missileguidance/functions/fnc_doAttackProfile.sqf b/addons/missileguidance/functions/fnc_doAttackProfile.sqf index cafbadf69c..731d18d18d 100644 --- a/addons/missileguidance/functions/fnc_doAttackProfile.sqf +++ b/addons/missileguidance/functions/fnc_doAttackProfile.sqf @@ -22,7 +22,6 @@ _args params ["", "_launchParams"]; _launchParams params ["", "", "", "_attackProfileName"]; private _attackProfileFunction = getText (configFile >> QGVAR(AttackProfiles) >> _attackProfileName >> "functionName"); - private _attackProfilePos = _this call (missionNamespace getVariable _attackProfileFunction); if ((isNil "_attackProfilePos") || {_attackProfilePos isEqualTo [0,0,0]}) exitWith { @@ -30,10 +29,10 @@ if ((isNil "_attackProfilePos") || {_attackProfilePos isEqualTo [0,0,0]}) exitWi [0,0,0] }; -#ifdef DRAW_GUIDANCE_INFO -drawLine3D [(ASLtoAGL _attackProfilePos), (ASLtoAGL _seekerTargetPos), [0,1,1,1]]; -drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0,0,1,1], ASLtoAGL _attackProfilePos, 0.5, 0.5, 0, _attackProfileName, 1, 0.025, "TahomaB"]; -#endif +if (GVAR(debug_drawGuidanceInfo)) then { + drawLine3D [(ASLtoAGL _attackProfilePos), (ASLtoAGL _seekerTargetPos), [0,1,1,1]]; + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0,0,1,1], ASLtoAGL _attackProfilePos, 0.5, 0.5, 0, _attackProfileName, 1, 0.025, "TahomaB"]; +}; TRACE_2("return",_attackProfilePos,_attackProfileName); _attackProfilePos; diff --git a/addons/missileguidance/functions/fnc_doSeekerSearch.sqf b/addons/missileguidance/functions/fnc_doSeekerSearch.sqf index 6008725b4c..b6fd158ce0 100644 --- a/addons/missileguidance/functions/fnc_doSeekerSearch.sqf +++ b/addons/missileguidance/functions/fnc_doSeekerSearch.sqf @@ -30,9 +30,9 @@ if ((isNil "_seekerTargetPos") || {_seekerTargetPos isEqualTo [0,0,0]}) then { / if (_seekLastTargetPos && {_lastKnownPos isNotEqualTo [0,0,0]}) then { // if enabled for the ammo, use last known position if we have one stored TRACE_2("seeker returned bad pos - using last known",_seekLastTargetPos,_lastKnownPos); _seekerTargetPos = _lastKnownPos; - #ifdef DRAW_GUIDANCE_INFO - drawIcon3D ["\A3\ui_f\data\map\markers\military\unknown_CA.paa", [1,1,0,1], ASLtoAGL _lastKnownPos, 0.25, 0.25, 0, "LastKnownPos", 1, 0.02, "TahomaB"]; - #endif + if (GVAR(debug_drawGuidanceInfo)) then { + drawIcon3D ["\A3\ui_f\data\map\markers\military\unknown_CA.paa", [1,1,0,1], ASLtoAGL _lastKnownPos, 0.25, 0.25, 0, "LastKnownPos", 1, 0.02, "TahomaB"]; + }; } else { TRACE_1("seeker returned no pos",_seekerTargetPos); _seekerTargetPos = [0,0,0]; @@ -44,9 +44,9 @@ if ((isNil "_seekerTargetPos") || {_seekerTargetPos isEqualTo [0,0,0]}) then { / }; }; -#ifdef DRAW_GUIDANCE_INFO -drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0,1,0,1], ASLtoAGL _seekerTargetPos, 0.5, 0.5, 0, _seekerTypeName, 1, 0.025, "TahomaB"]; -#endif +if (GVAR(debug_drawGuidanceInfo)) then { + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0,1,0,1], ASLtoAGL _seekerTargetPos, 0.5, 0.5, 0, _seekerTypeName, 1, 0.025, "TahomaB"]; +}; TRACE_2("return",_seekerTargetPos,_seekerTypeName); _seekerTargetPos; diff --git a/addons/missileguidance/functions/fnc_guidancePFH.sqf b/addons/missileguidance/functions/fnc_guidancePFH.sqf index 0620e9e3c0..3c67b4b126 100644 --- a/addons/missileguidance/functions/fnc_guidancePFH.sqf +++ b/addons/missileguidance/functions/fnc_guidancePFH.sqf @@ -15,100 +15,215 @@ * * Public: No */ +#define TRAIL_COLOUR(multiplier) [1 * multiplier, 1 * multiplier, 0.3 * multiplier, 0.7 * multiplier] BEGIN_COUNTER(guidancePFH); -#define TIMESTEP_FACTOR 0.01 - params ["_args", "_pfID"]; -_args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams"]; +_args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams", "_targetData", "_navigationStateParams"]; _firedEH params ["_shooter","","","","_ammo","","_projectile"]; -_launchParams params ["","_targetLaunchParams"]; -_stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState"]; +_launchParams params ["","_targetLaunchParams","","","","","_navigationType"]; +_stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState", "_navigationParameters", "_guidanceParameters"]; +_navigationStateParams params ["_currentState", "_navigationStateData"]; +_flightParams params ["_pitchRate", "_yawRate", "_isBangBangGuidance", "_stabilityCoefficient", "_showTrail"]; if (!alive _projectile || isNull _projectile || isNull _shooter) exitWith { [_pfID] call CBA_fnc_removePerFrameHandler; END_COUNTER(guidancePFH); }; -private _runtimeDelta = diag_tickTime - _lastRunTime; -private _adjustTime = 1; - -if (accTime > 0) then { - _adjustTime = 1/accTime; - _adjustTime = _adjustTime * (_runtimeDelta / TIMESTEP_FACTOR); - TRACE_4("Adjust timing",1/accTime,_adjustTime,_runtimeDelta,(_runtimeDelta / TIMESTEP_FACTOR)); -} else { - _adjustTime = 0; +if (_showTrail) then { + drop [ + "\a3\data_f\kouleSvetlo", "", "Billboard", + 100, + 0.03, + _projectile modelToWorld [0, 0, 0], + [0, 0, 0], + 0, + 1.25, + 1, + 0.05, + [0.5], + [TRAIL_COLOUR(1)], + [0], + 0, + 0, + "", + "", + "", + 0, + false, + -1, + [TRAIL_COLOUR(10000)] + ]; }; -private _minDeflection = ((_flightParams select 0) - ((_flightParams select 0) * _adjustTime)) max 0; -private _maxDeflection = (_flightParams select 1) * _adjustTime; -// private _incDeflection = _flightParams select 2; // todo - -private _projectilePos = getPosASL _projectile; +private _timestep = diag_deltaTime * accTime; // Run seeker function: -private _seekerTargetPos = [[0,0,0], _args, _seekerStateParams, _lastKnownPosState] call FUNC(doSeekerSearch); - +private _seekerTargetPos = [[0,0,0], _args, _seekerStateParams, _lastKnownPosState, _timestep] call FUNC(doSeekerSearch); // Run attack profile function: -private _profileAdjustedTargetPos = [_seekerTargetPos, _args, _attackProfileStateParams] call FUNC(doAttackProfile); +_seekerTargetPos = AGLtoASL ASLToAGL _seekerTargetPos; +private _profileAdjustedTargetPos = [_seekerTargetPos, _args, _attackProfileStateParams, _timestep] call FUNC(doAttackProfile); + +private _projectilePos = getPosASLVisual _projectile; +_targetData set [1, _projectilePos vectorFromTo _profileAdjustedTargetPos]; // If we have no seeker target, then do not change anything // If there is no deflection on the missile, this cannot change and therefore is redundant. Avoid calculations for missiles without any deflection -if ((_minDeflection != 0 || {_maxDeflection != 0}) && {_profileAdjustedTargetPos isNotEqualTo [0,0,0]}) then { - - private _targetVector = _projectilePos vectorFromTo _profileAdjustedTargetPos; - private _adjustVector = _targetVector vectorDiff (vectorDir _projectile); - _adjustVector params ["_adjustVectorX", "_adjustVectorY", "_adjustVectorZ"]; - - private _yaw = 0; - private _pitch = 0; - private _roll = 0; - - if (_adjustVectorX < 0) then { - _yaw = - ( (_minDeflection max ((abs _adjustVectorX) min _maxDeflection) ) ); - } else { - if (_adjustVectorX > 0) then { - _yaw = ( (_minDeflection max (_adjustVectorX min _maxDeflection) ) ); +if ((_pitchRate != 0 || {_yawRate != 0})) then { + private _navigationFunction = getText (configFile >> QGVAR(NavigationTypes) >> _navigationType >> "functionName"); + if (_navigationStateData isNotEqualTo []) then { + (_navigationStateData select _currentState) params ["_transitionCondition"]; + private _transition = (_args call (missionNamespace getVariable [_transitionCondition, { false }])); + if (_transition) then { + _currentState = _currentState + 1; + _navigationStateParams set [0, _currentState]; }; - }; - if (_adjustVectorY < 0) then { - _roll = - ( (_minDeflection max ((abs _adjustVectorY) min _maxDeflection) ) ); - } else { - if (_adjustVectorY > 0) then { - _roll = ( (_minDeflection max (_adjustVectorY min _maxDeflection) ) ); - }; - }; - if (_adjustVectorZ < 0) then { - _pitch = - ( (_minDeflection max ((abs _adjustVectorZ) min _maxDeflection) ) ); - } else { - if (_adjustVectorZ > 0) then { - _pitch = ( (_minDeflection max (_adjustVectorZ min _maxDeflection) ) ); - }; - }; - private _finalAdjustVector = [_yaw, _roll, _pitch]; - TRACE_3("",_pitch,_yaw,_roll); - TRACE_3("",_targetVector,_adjustVector,_finalAdjustVector); + _navigationType = (_navigationStateData select _currentState) select 1; + _navigationFunction = getText (configFile >> QGVAR(NavigationTypes) >> _navigationType >> "functionName"); - if (accTime > 0) then { - private _changeVector = (vectorDir _projectile) vectorAdd _finalAdjustVector; - TRACE_2("",_projectile,_changeVector); - [_projectile, _changeVector] call FUNC(changeMissileDirection); + _navigationParameters = (_navigationStateData select _currentState) select 2; + _stateParams set [4, _navigationParameters]; }; + private _commandedAcceleration = [_args, _timestep, _seekerTargetPos, _profileAdjustedTargetPos, _targetData, _navigationParameters] call (missionNamespace getVariable _navigationFunction); + + if (isNil "_commandedAcceleration") exitWith { + systemChat format ["Error in %1 Missile Type %2 Seeker Pos %3", _navigationFunction, typeOf _projectile, _seekerTargetPos]; + ERROR_MSG_3("_commandedAcceleration is nil! Guidance cancelled [%1 %2 %3]",_navigationFunction,typeOf _projectile,_seekerTargetPos); + }; + + if (GVAR(debug_drawGuidanceInfo)) then { + private _projectilePosAGL = ASLToAGL _projectilePos; + private _cmdAccelLocal = _projectile vectorWorldToModelVisual _commandedAcceleration; + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], _projectilePosAGL vectorAdd [0, 0, 1], 0.75, 0.75, 0, format ["cmdPitch: %1 cmdYaw %2", _cmdAccelLocal#2, _cmdAccelLocal#0], 1, 0.025, "TahomaB"]; + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,1,0,1], _projectilePosAGL vectorAdd [0, 0, 2], 0.75, 0.75, 0, _navigationType, 1, 0.025, "TahomaB"]; + drawLine3D [_projectilePosAGL, _projectilePosAGL vectorAdd _commandedAcceleration, [1, 0, 1, 1]]; + }; + + // activate missile servos and change direction + if (!isGamePaused && accTime > 0) then { + _guidanceParameters params ["_yaw", "_roll", "_pitch"]; + + _commandedAcceleration = _projectile vectorWorldToModelVisual _commandedAcceleration; + _commandedAcceleration params ["_yawChange", "", "_pitchChange"]; + + if (isNil "_yawChange") then { + _yawChange = 0; + }; + if (isNil "_pitchChange") then { + _pitchChange = 0; + }; + + private _clampedPitch = (_pitchChange min _pitchRate) max -_pitchRate; + private _clampedYaw = (_yawChange min _yawRate) max -_yawRate; + + // controls are either on or off, no proportional + if (_isBangBangGuidance) then { + private _pitchSign = if (_clampedPitch == 0) then { + 0 + } else { + _clampedPitch / abs _clampedPitch + }; + private _yawSign = if (_clampedYaw == 0) then { + 0 + } else { + _clampedYaw / abs _clampedYaw + }; + _clampedPitch = _pitchSign * _pitchRate; + _clampedYaw = _yawSign * _yawRate; + }; + + TRACE_9("pitch/yaw/roll",_pitch,_yaw,_roll,_yawChange,_pitchChange,_pitchRate,_yawRate,_clampedPitch,_clampedYaw); + // directional stability + private _localVelocity = _projectile vectorWorldToModelVisual (velocity _projectile); + + private _velocityAngleYaw = (_localVelocity#0) atan2 (_localVelocity#1); + private _velocityAnglePitch = (_localVelocity#2) atan2 (_localVelocity#1); + + // bastardized version of direction stability https://en.wikipedia.org/wiki/Directional_stability#Steering_forces + private _forceYaw = _stabilityCoefficient * _velocityAngleYaw + _clampedYaw; + private _forcePitch = _stabilityCoefficient * _velocityAnglePitch + _clampedPitch; + + _pitch = _pitch + _forcePitch * _timestep; + _yaw = _yaw + _forceYaw * _timestep; + + TRACE_3("new pitch/yaw/roll",_pitch,_yaw,_roll); + + private _multiplyQuat = { + params ["_qLHS", "_qRHS"]; + _qLHS params ["_lhsX", "_lhsY", "_lhsZ", "_lhsW"]; + _qRHS params ["_rhsX", "_rhsY", "_rhsZ", "_rhsW"]; + + private _lhsImaginary = [_lhsX, _lhsY, _lhsZ]; + private _rhsImaginary = [_rhsX, _rhsY, _rhsZ]; + + private _scalar = _lhsW * _rhsW - (_lhsImaginary vectorDotProduct _rhsImaginary); + private _imginary = (_rhsImaginary vectorMultiply _lhsW) vectorAdd (_lhsImaginary vectorMultiply _rhsW) vectorAdd (_lhsImaginary vectorCrossProduct _rhsImaginary); + + _imginary + [_scalar] + }; + + private _multiplyVector = { + params ["_quaternion", "_vector"]; + + private _real = _quaternion#3; + private _imaginary = [ + _quaternion#0, + _quaternion#1, + _quaternion#2 + ]; + + private _vectorReturn = _vector vectorAdd (( + _imaginary vectorCrossProduct ( + (_imaginary vectorCrossProduct _vector) vectorAdd ( + _vector vectorMultiply _real + ) + ) + ) vectorMultiply 2); + + _vectorReturn + }; + + private _quaternion = [0, 0, 0, 1]; + + private _temp = [0, 0, sin (-_yaw / 2), cos (-_yaw / 2)]; + _quaternion = [_quaternion, _temp] call _multiplyQuat; + + _temp = [sin (_pitch / 2), 0, 0, cos (_pitch / 2)]; + _quaternion = [_quaternion, _temp] call _multiplyQuat; + + private _dir = [_quaternion, [0, 1, 0]] call _multiplyVector; + private _up = [_quaternion, [0, 0, 1]] call _multiplyVector; + + _projectile setVectorDirAndUp [_dir, _up]; + + //[_projectile, _pitch, _yaw, 0] call FUNC(changeMissileDirection); + + _guidanceParameters set [0, _yaw]; + _guidanceParameters set [2, _pitch]; + + _stateParams set [5, _guidanceParameters]; + }; + + _stateParams set [4, _navigationParameters]; + _args set [4, _stateParams]; }; -#ifdef DRAW_GUIDANCE_INFO -TRACE_3("",_projectilePos,_seekerTargetPos,_profileAdjustedTargetPos); -drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], ASLtoAGL _projectilePos, 0.75, 0.75, 0, _ammo, 1, 0.025, "TahomaB"]; +if (GVAR(debug_drawGuidanceInfo)) then { + TRACE_3("",_projectilePos,_seekerTargetPos,_profileAdjustedTargetPos); + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], ASLtoAGL _projectilePos, 0.75, 0.75, 0, _ammo, 1, 0.025, "TahomaB"]; -private _ps = "#particlesource" createVehicleLocal (ASLtoAGL _projectilePos); -_PS setParticleParams [["\A3\Data_f\cl_basic", 8, 3, 1], "", "Billboard", 1, 3.0141, [0, 0, 2], [0, 0, 0], 1, 1.275, 1, 0, [1, 1], [[1, 0, 0, 1], [1, 0, 0, 1], [1, 0, 0, 1]], [1], 1, 0, "", "", nil]; -_PS setDropInterval 3.0; -#endif + if (!isGamePaused && accTime > 0) then { + private _ps = "#particlesource" createVehicleLocal (ASLtoAGL _projectilePos); + _PS setParticleParams [["\A3\Data_f\cl_basic", 8, 3, 1], "", "Billboard", 1, 3.0141, [0, 0, 0], [0, 0, 0], 1, 1.275, 1, 0, [1, 1], [[1, 0, 0, 1], [1, 0, 0, 1], [1, 0, 0, 1]], [1], 1, 0, "", "", nil]; + _PS setDropInterval 1.0; + }; + + drawLine3D [ASLtoAGL _projectilePos, (ASLtoAGL _projectilePos) vectorAdd velocity _projectile, [1, 1, 1, 1]]; +}; _stateParams set [0, diag_tickTime]; END_COUNTER(guidancePFH); - diff --git a/addons/missileguidance/functions/fnc_line_onFired.sqf b/addons/missileguidance/functions/fnc_line_onFired.sqf new file mode 100644 index 0000000000..6093dc2738 --- /dev/null +++ b/addons/missileguidance/functions/fnc_line_onFired.sqf @@ -0,0 +1,35 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Sets up line state arrays (called from missileGuidance's onFired). + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * None + * + * Example: + * [] call ace_missileguidance_fnc_line_onFired + * + * Public: No + */ +params ["_firedEH", "", "", "", "_stateParams"]; +_firedEH params ["","","","","","","_projectile"]; + +private _ammoConfig = configOf _projectile; +private _p = getNumber (_ammoConfig >> QUOTE(ADDON) >> "lineGainP"); +private _d = getNumber (_ammoConfig >> QUOTE(ADDON) >> "lineGainD"); +private _correctionDistance = getNumber (_ammoConfig >> QUOTE(ADDON) >> "correctionDistance"); + +if (_correctionDistance == 0) then { + _correctionDistance = 1; +}; + +private _navigationParams = [ + _p, 0, _d, + 0, + 0, + _correctionDistance +]; +_navigationParams diff --git a/addons/missileguidance/functions/fnc_ahr_onFired.sqf b/addons/missileguidance/functions/fnc_mwr_onFired.sqf similarity index 92% rename from addons/missileguidance/functions/fnc_ahr_onFired.sqf rename to addons/missileguidance/functions/fnc_mwr_onFired.sqf index 0618c046ad..845b81cda6 100644 --- a/addons/missileguidance/functions/fnc_ahr_onFired.sqf +++ b/addons/missileguidance/functions/fnc_mwr_onFired.sqf @@ -10,7 +10,7 @@ * None * * Example: - * [] call ace_missileguidance_fnc_ahr_onFired + * [] call ace_missileguidance_fnc_mwr_onFired * * Public: No */ @@ -38,6 +38,8 @@ private _activeRadarDistance = [_config >> "activeRadarEngageDistance", "NUMBER" private _projectileThrust = [_projectileConfig >> "thrust", "NUMBER", 0] call CBA_fnc_getConfigEntry; private _projectileThrustTime = [_projectileConfig >> "thrustTime", "NUMBER", 0] call CBA_fnc_getConfigEntry; +private _lockTypes = [_config >> "lockableTypes", "ARRAY", ["Air", "LandVehicle", "Ship"]] call CBA_fnc_getConfigEntry; + private _velocityAtImpact = _projectileThrust * _projectileThrustTime; private _timeToActive = 0; if (!isNil "_target" && _velocityAtImpact > 0) then { @@ -70,4 +72,4 @@ _seekerStateParams set [6, false]; _seekerStateParams set [7, [0, 0, 0]]; _seekerStateParams set [8, CBA_missionTime]; _seekerStateParams set [9, isNull _target]; - +_seekerStateParams set [10, _lockTypes]; diff --git a/addons/missileguidance/functions/fnc_navigationType_augmentedProNav.sqf b/addons/missileguidance/functions/fnc_navigationType_augmentedProNav.sqf new file mode 100644 index 0000000000..f8f1e6c0f4 --- /dev/null +++ b/addons/missileguidance/functions/fnc_navigationType_augmentedProNav.sqf @@ -0,0 +1,50 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Determine path for projectile to take in accordance to proportional navigation, takes target acceleration into account + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * Commanded acceleration normal to LOS in world space + * + * Example: + * [] call ace_missileguidance_fnc_navigationType_augmentedProNav + * + * Public: No + */ +params ["_args", "_timestep", "_seekerTargetPos", "_profileAdjustedTargetPos"]; +_args params ["_firedEH", "", "", "", "_stateParams", "_targetData"]; +_firedEH params ["","","","","","","_projectile"]; +_stateParams params ["", "", "", "","_navigationParams"]; +_navigationParams params ["_lastMissileFrame", "_navigationGain"]; +_lastMissileFrame params ["_lastLineOfSight"]; +_targetData params ["_targetDirection", "_attackProfileDirection", "", "_targetVelocity", "_targetAcceleration"]; + +// Proportional navigation implemented via "Fundamentals of proportional navigation" by Stephen Murtaugh and Harry Criel +private _closingVelocity = _targetVelocity vectorDiff velocity _projectile; + +private _targetAccelerationProjected = _attackProfileDirection vectorMultiply (_targetAcceleration vectorDotProduct _attackProfileDirection); +_targetAcceleration = _targetAcceleration vectorDiff _targetAccelerationProjected; + +private _losDelta = (vectorNormalized _attackProfileDirection) vectorDiff (vectorNormalized _lastLineOfSight); +private _losRate = if (_timestep == 0) then { + 0 +} else { + 1 * (vectorMagnitude _losDelta) / _timestep; +}; + +private _lateralAcceleration = _navigationGain * _losRate; +private _commandedAcceleration = _closingVelocity vectorMultiply _lateralAcceleration; +_commandedAcceleration = _commandedAcceleration vectorAdd (_losDelta vectorMultiply (0.5 * _navigationGain * vectorMagnitude _targetAcceleration)); + +// we need acceleration normal to our LOS +private _commandedAccelerationProjected = _attackProfileDirection vectorMultiply (_commandedAcceleration vectorDotProduct _attackProfileDirection); +_commandedAcceleration = _commandedAcceleration vectorDiff _commandedAccelerationProjected; + +if (accTime > 0) then { + _navigationParams set [0, [_seekerTargetPos, _targetVelocity, _attackProfileDirection]]; +}; + +_commandedAcceleration vectorMultiply _timestep diff --git a/addons/missileguidance/functions/fnc_navigationType_direct.sqf b/addons/missileguidance/functions/fnc_navigationType_direct.sqf new file mode 100644 index 0000000000..7b4763b44e --- /dev/null +++ b/addons/missileguidance/functions/fnc_navigationType_direct.sqf @@ -0,0 +1,21 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Points directly toward attack profile positon + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * Commanded acceleration normal to LOS in world space + * + * Example: + * [] call ace_missileguidance_fnc_navigationType_direct + * + * Public: No + */ +params ["_args", "", "", "_profileAdjustedTargetPos"]; +_args params ["_firedEH"]; +_firedEH params ["","","","","","","_projectile"]; + +_profileAdjustedTargetPos vectorDiff getPosASLVisual _projectile diff --git a/addons/missileguidance/functions/fnc_navigationType_line.sqf b/addons/missileguidance/functions/fnc_navigationType_line.sqf new file mode 100644 index 0000000000..c9a3870c58 --- /dev/null +++ b/addons/missileguidance/functions/fnc_navigationType_line.sqf @@ -0,0 +1,52 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Assumes targetDir is pointing toward line we want to stay on + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * Commanded acceleration normal to LOS in world space + * + * Example: + * [] call ace_missileguidance_fnc_navigationType_line + * + * Public: No + */ +params ["_args", "_timestep", "_seekerTargetPos", "_profileAdjustedTargetPos", "_targetData", "_navigationParams"]; +_args params ["", "", "_flightParams"]; +_targetData params ["", "_targetDir", "_distance"]; +_flightParams params ["_pitchRate", "_yawRate"]; + +_navigationParams params ["_proportionalGain", "", "_derivativeGain", "_lastErrorX", "_lastErrorY", "_correctionDistance"]; +private _relativeTargetDirection = [0, (velocityModelSpace _projectile) select 1, 0] vectorAdd (_projectile vectorWorldToModelVisual (_targetDir vectorMultiply _distance)); + +private _angleX = ((_relativeTargetDirection select 0) atan2 (_relativeTargetDirection select 1)); +private _angleY = ((_relativeTargetDirection select 2) atan2 (_relativeTargetDirection select 1)); + +private _pX = _proportionalGain * _angleX; +private _dX = 0; +if (_timestep > 0) then { + _dX = _derivativeGain * (_angleX - _lastErrorX) / _timestep; +}; + +private _pY = _proportionalGain * _angleY; +private _dY = 0; +if (_timestep > 0) then { + _dY = _derivativeGain * (_angleY - _lastErrorY) / _timestep; +}; + +private _accelerationX = _pX + _dX; +private _accelerationY = _pY + _dY; + +private _commandedAcceleration = [ + _accelerationX, + 0, + _accelerationY +]; + +_navigationParams set [3, _angleX]; +_navigationParams set [4, _angleY]; + +_projectile vectorModelToWorldVisual _commandedAcceleration; diff --git a/addons/missileguidance/functions/fnc_navigationType_lineOfSight.sqf b/addons/missileguidance/functions/fnc_navigationType_lineOfSight.sqf new file mode 100644 index 0000000000..5056d83722 --- /dev/null +++ b/addons/missileguidance/functions/fnc_navigationType_lineOfSight.sqf @@ -0,0 +1,48 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Accelerates toward LOS + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * Commanded acceleration normal to LOS in world space + * + * Example: + * [] call ace_missileguidance_fnc_navigationType_lineOfSight + * + * Public: No + */ +params ["_args", "_timestep", "_seekerTargetPos", "_profileAdjustedTargetPos"]; +_args params ["_firedEH", "", "", "", "_stateParams", "_targetData"]; +_firedEH params ["","","","","","","_projectile"]; +_stateParams params ["", "", "", "","_navigationParams"]; +_navigationParams params ["_onLaunch"]; +_onLaunch params ["_lastLineOfSight"]; +_targetData params ["_targetDirection", "_attackProfileDirection", "", "_targetVelocity", ""]; + +// Semi-proportional navigation implemented via "Fundamentals of proportional navigation" by Stephen Murtaugh and Harry Criel + +// the los rate is tiny, so we multiply by a constant of a power of ten to get more aggressive acceleration +// this is just due to how we measure our LOS delta, the vectors involved are _tiny_ +private _losDelta = _attackProfileDirection vectorDiff _lastLineOfSight; +private _losRate = if (_timestep == 0) then { + 0 +} else { + 10 * (vectorMagnitude _losDelta) / _timestep; +}; + +private _closingVelocity = _targetVelocity vectorDiff (velocity _projectile); + +private _commandedAcceleration = _closingVelocity vectorMultiply _losRate; + +// we need acceleration normal to our LOS +private _commandedAccelerationProjected = _attackProfileDirection vectorMultiply (_commandedAcceleration vectorDotProduct _attackProfileDirection); +_commandedAcceleration = _commandedAcceleration vectorDiff _commandedAccelerationProjected; + +if (accTime > 0) then { + _navigationParams set [0, [_attackProfileDirection]]; +}; + +_targetDirection diff --git a/addons/missileguidance/functions/fnc_navigationType_proNav.sqf b/addons/missileguidance/functions/fnc_navigationType_proNav.sqf new file mode 100644 index 0000000000..45052689b0 --- /dev/null +++ b/addons/missileguidance/functions/fnc_navigationType_proNav.sqf @@ -0,0 +1,46 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Determine path for projectile to take in accordance to proportional navigation + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * Commanded acceleration normal to LOS in world space + * + * Example: + * [] call ace_missileguidance_fnc_navigationType_proNav + * + * Public: No + */ +params ["_args", "_timestep", "_seekerTargetPos", "_profileAdjustedTargetPos"]; +_args params ["_firedEH", "", "", "", "_stateParams", "_targetData"]; +_firedEH params ["","","","","","","_projectile"]; +_stateParams params ["", "", "", "","_navigationParams"]; +_navigationParams params ["_lastMissileFrame", "_navigationGain"]; +_lastMissileFrame params ["_lastLineOfSight"]; +_targetData params ["_targetDirection", "_attackProfileDirection", "", "_targetVelocity", ""]; + +// Proportional navigation implemented via "Fundamentals of proportional navigation" by Stephen Murtaugh and Harry Criel +private _closingVelocity = _targetVelocity vectorDiff velocity _projectile; + +private _losDelta = (vectorNormalized _attackProfileDirection) vectorDiff (vectorNormalized _lastLineOfSight); +private _losRate = if (_timestep == 0) then { + 0 +} else { + 1 * (vectorMagnitude _losDelta) / _timestep; +}; + +private _lateralAcceleration = _navigationGain * _losRate; +private _commandedAcceleration = _closingVelocity vectorMultiply _lateralAcceleration; + +// we need acceleration normal to our LOS +private _commandedAccelerationProjected = _attackProfileDirection vectorMultiply (_commandedAcceleration vectorDotProduct _attackProfileDirection); +_commandedAcceleration = _commandedAcceleration vectorDiff _commandedAccelerationProjected; + +if (accTime > 0) then { + _navigationParams set [0, [_seekerTargetPos, _targetVelocity, _attackProfileDirection]]; +}; + +_commandedAcceleration vectorMultiply _timestep diff --git a/addons/missileguidance/functions/fnc_navigationType_zeroEffortMiss.sqf b/addons/missileguidance/functions/fnc_navigationType_zeroEffortMiss.sqf new file mode 100644 index 0000000000..293bede8bf --- /dev/null +++ b/addons/missileguidance/functions/fnc_navigationType_zeroEffortMiss.sqf @@ -0,0 +1,38 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Determine path for projectile to take in accordance to zero-effort miss pro-nav, takes target acceleration into account. Super deadly + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * Commanded acceleration normal to LOS in world space + * + * Example: + * [] call ace_missileguidance_fnc_navigationType_zeroEffortMiss + * + * Public: No + */ +params ["_args", "_timestep", "_seekerTargetPos", "_profileAdjustedTargetPos"]; +_args params ["_firedEH", "", "", "", "_stateParams", "_targetData"]; +_firedEH params ["","","","","","","_projectile"]; +_stateParams params ["", "", "", "","_navigationParams"]; +_navigationParams params ["", "_navigationGain"]; +_targetData params ["_targetDirection", "_attackProfileDirection", "_targetRange", "_targetVelocity", "_targetAcceleration"]; + +private _vectorToTarget = _attackProfileDirection vectorMultiply _targetRange; +private _closingVelocity = _targetVelocity vectorDiff velocity _projectile; +private _timeToGo = _targetRange / vectorMagnitude _closingVelocity; + +if (_timeToGo == 0) then { + _timeToGo = 0.001; +}; + +private _zeroEffortMiss = _vectorToTarget vectorAdd (_closingVelocity vectorMultiply _timeToGo); +private _zeroEffortMissProjectiled = _attackProfileDirection vectorMultiply (_zeroEffortMiss vectorDotProduct _attackProfileDirection); +private _zeroEffortMissNormal = _zeroEffortMiss vectorDiff _zeroEffortMissProjectiled; + +private _commandedAcceleration = _zeroEffortMissNormal vectorMultiply (_navigationGain / (_timeToGo * _timeToGo)); + +_commandedAcceleration diff --git a/addons/missileguidance/functions/fnc_onFired.sqf b/addons/missileguidance/functions/fnc_onFired.sqf index 1d63d120a9..9cc91f300a 100644 --- a/addons/missileguidance/functions/fnc_onFired.sqf +++ b/addons/missileguidance/functions/fnc_onFired.sqf @@ -19,9 +19,6 @@ params ["_shooter","_weapon","","_mode","_ammo","","_projectile"]; -// Bail on not missile -if !(_ammo isKindOf "MissileBase") exitWith {}; - // Bail if guidance is disabled for this ammo if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "enabled")) != 1) exitWith {}; @@ -44,6 +41,7 @@ private _target = _shooter getVariable [QGVAR(target), nil]; private _targetPos = _shooter getVariable [QGVAR(targetPosition), nil]; private _seekerType = _shooter getVariable [QGVAR(seekerType), nil]; private _attackProfile = _shooter getVariable [QGVAR(attackProfile), nil]; +private _navigationType = _shooter getVariable [QGVAR(navigationType), nil]; if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "useModeForAttackProfile")) == 1) then { _attackProfile = getText (configFile >> "CfgWeapons" >> _weapon >> _mode >> QGVAR(attackProfile)) }; @@ -52,7 +50,7 @@ private _lockMode = _shooter getVariable [QGVAR(lockMode), nil]; private _laserCode = _shooter getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; private _laserInfo = [_laserCode, ACE_DEFAULT_LASER_WAVELENGTH, ACE_DEFAULT_LASER_WAVELENGTH]; -TRACE_6("getVars",_target,_targetPos,_seekerType,_attackProfile,_lockMode,_laserCode); +TRACE_7("getVars",_target,_targetPos,_seekerType,_attackProfile,_lockMode,_laserCode,_navigationType); private _launchPos = getPosASL (vehicle _shooter); @@ -65,6 +63,14 @@ if (isNil "_attackProfile" || {!(_attackProfile in (getArray (_config >> "attack if (isNil "_lockMode" || {!(_lockMode in (getArray (_config >> "seekerLockModes")))}) then { _lockMode = getText (_config >> "defaultSeekerLockMode"); }; +if (isNil "_navigationType" || {!(_navigationType in (getArray (_config >> "navigationTypes")))}) then { + _navigationType = getText (_config >> "defaultNavigationType"); +}; + +if (isNil "_navigationType" || _navigationType isEqualTo "") then { + // most missiles use ProNav by default + _navigationType = "ProportionalNavigation"; +}; // If we didn't get a target, try to fall back on tab locking if (isNil "_target") then { @@ -76,7 +82,7 @@ if (isNil "_target") then { private _canUseLock = getNumber (_config >> "canVanillaLock"); // @TODO: Get vanilla target if (_canUseLock > 0 || difficulty < 1) then { - private _vanillaTarget = cursorTarget; + private _vanillaTarget = missileTarget _projectile; TRACE_1("Using Vanilla Locking",_vanillaTarget); if (!isNil "_vanillaTarget") then { @@ -85,6 +91,7 @@ if (isNil "_target") then { }; }; }; +_targetPos = getPosASLVisual _target; // Array for seek last target position private _seekLastTargetPos = (getNumber ( _config >> "seekLastTargetPos")) == 1; @@ -95,19 +102,66 @@ if (_seekLastTargetPos && {!isNil "_target"}) then { _lastKnownPosState set [1, [0,0,0]]; }; -TRACE_4("Beginning ACE guidance system",_target,_ammo,_seekerType,_attackProfile); +private _navigationParameters = [ + // set up in navigation type onFired function +]; + +// default config values to make sure there is backwards compat +private _pitchRate = 30; +private _yawRate = 30; +private _bangBang = false; +if (isNumber (_config >> "pitchRate")) then { + _pitchRate = getNumber ( _config >> "pitchRate" ); + _yawRate = getNumber ( _config >> "yawRate" ); + _bangBang = (1 == getNumber (_config >> "bangBangGuidance")); +}; + +// How much this projectile likes to stay toward current velocity +private _stabilityCoefficient = getNumber (_config >> "stabilityCoefficient"); + +// show a light trail in flight +private _showTrail = (1 == getNumber (_config >> "showTrail")); + +private _navigationStateSubclass = _config >> "navigationStates"; +private _states = getArray (_navigationStateSubclass >> "states"); + +private _navigationStateData = []; +private _initialState = ""; + +if (_states isNotEqualTo []) then { + _initialState = _states select 0; + { + private _stateClass = _navigationStateSubclass >> _x; + _navigationStateData pushBack [ + getText (_stateClass >> "transitionCondition"), + getText (_stateClass >> "navigationType"), + [] + ]; + } forEach _states; +}; + +private _initialRoll = getNumber (_config >> "initialRoll"); +private _initialYaw = getNumber (_config >> "initialYaw"); +private _initialPitch = getNumber (_config >> "initialPitch"); + +private _yawRollPitch = (vectorDir _projectile) call CBA_fnc_vect2Polar; + +TRACE_5("Beginning ACE guidance system",_target,_ammo,_seekerType,_attackProfile,_navigationType); private _args = [_this, [ _shooter, - [_target, _targetPos, _launchPos], + [_target, _targetPos, _launchPos, vectorDirVisual vehicle _shooter, CBA_missionTime], _seekerType, _attackProfile, _lockMode, - _laserInfo + _laserInfo, + _navigationType ], [ - getNumber ( _config >> "minDeflection" ), - getNumber ( _config >> "maxDeflection" ), - getNumber ( _config >> "incDeflection" ) + _pitchRate, + _yawRate, + _bangBang, + _stabilityCoefficient, + _showTrail ], [ getNumber ( _config >> "seekerAngle" ), @@ -115,37 +169,70 @@ private _args = [_this, getNumber ( _config >> "seekerMaxRange" ), getNumber ( _config >> "seekerMinRange" ) ], - [ diag_tickTime, [], [], _lastKnownPosState] + [ diag_tickTime, [], [], _lastKnownPosState, _navigationParameters, [_initialYaw + (_yawRollPitch select 1), _initialRoll, _initialPitch + (_yawRollPitch select 2)]], + [ + // target data from missile. Must be filled by seeker for navigation to work + [0, 0, 0], // direction to target + [0, 0, 0], // direction to attack profile + 0, // range to target + [0, 0, 0], // target velocity + [0, 0, 0] // target acceleration + ], + [0, _navigationStateData] ]; private _onFiredFunc = getText (configFile >> QGVAR(SeekerTypes) >> _seekerType >> "onFired"); -TRACE_1("",_onFiredFunc); +TRACE_1("seeker on fired",_onFiredFunc); if (_onFiredFunc != "") then { _args call (missionNamespace getVariable _onFiredFunc); }; _onFiredFunc = getText (configFile >> QGVAR(AttackProfiles) >> _attackProfile >> "onFired"); -TRACE_1("",_onFiredFunc); +TRACE_1("attack on fired",_onFiredFunc); if (_onFiredFunc != "") then { _args call (missionNamespace getVariable _onFiredFunc); }; +if (_states isEqualTo []) then { + _onFiredFunc = getText (configFile >> QGVAR(NavigationTypes) >> _navigationType >> "onFired"); + TRACE_1("navigation on fired",_onFiredFunc); + if (_onFiredFunc != "") then { + private _navState = (_args call (missionNamespace getVariable _onFiredFunc)); + (_args select 4) set [4, _navState]; + }; +} else { + { + _onFiredFunc = getText (configFile >> QGVAR(NavigationTypes) >> _x >> "onFired"); + TRACE_1("navigation on fired",_onFiredFunc); + if (_onFiredFunc != "") then { + private _navState = (_args call (missionNamespace getVariable _onFiredFunc)); + (_navigationStateData select _forEachIndex) set [2, _navState]; + }; + } forEach getArray (_config >> "navigationTypes"); +}; + // Run the "onFired" function passing the full guidance args array _onFiredFunc = getText (_config >> "onFired"); -TRACE_1("",_onFiredFunc); +TRACE_1("general on fired",_onFiredFunc); if (_onFiredFunc != "") then { _args call (missionNamespace getVariable _onFiredFunc); }; // Reverse: -// _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams"]; +// _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams", "_targetData", "_navigationStateData"]; // _firedEH params ["_shooter","","","","_ammo","","_projectile"]; -// _launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo"]; -// _targetLaunchParams params ["_target", "_targetPos", "_launchPos"]; -// _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState"]; +// _launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo","_navigationType"]; +// _targetLaunchParams params ["_target", "_targetPos", "_launchPos", "_launchDir", "_launchTime"]; +// _flightParams params ["_pitchRate", "_yawRate", "_isBangBangGuidance"]; +// _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState", "_navigationParams", "_guidanceParameters"]; // _seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"]; +// _targetData params ["_targetDirection", "_attackProfileDirection", "_targetRange", "_targetVelocity", "_targetAcceleration"]; -[LINKFUNC(guidancePFH), 0, _args ] call CBA_fnc_addPerFrameHandler; +[LINKFUNC(guidancePFH),0, _args ] call CBA_fnc_addPerFrameHandler; + +if (GVAR(debug_enableMissileCamera)) then { + [_projectile] call FUNC(dev_ProjectileCamera); +}; /* Clears locking settings diff --git a/addons/missileguidance/functions/fnc_proNav_onFired.sqf b/addons/missileguidance/functions/fnc_proNav_onFired.sqf new file mode 100644 index 0000000000..c297d3ce59 --- /dev/null +++ b/addons/missileguidance/functions/fnc_proNav_onFired.sqf @@ -0,0 +1,36 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Sets up proportional navigation state arrays (called from missileGuidance's onFired). + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * None + * + * Example: + * [] call ace_missileguidance_fnc_proNav_onFired + * + * Public: No + */ +params ["_firedEH", "", "", "", "_stateParams"]; +_firedEH params ["_shooter","","","","_ammo","","_projectile"]; +_launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo","_navigationType"]; +_targetLaunchParams params ["_target", "_targetPos", "_launchPos"]; +_stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState"]; +_seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"]; + +private _ammoConfig = configOf _projectile; +private _navigationGain = getNumber (_ammoConfig >> QUOTE(ADDON) >> "navigationGain"); +if (_navigationGain == 0) then { + _navigationGain = 3; +}; + +private _navigationParams = [ + [ // Last Missile Frame + [0, 0, 0] // Last line of sight + ], + _navigationGain // navigation gain of missile. Set in the navigation onFired function +]; +_navigationParams diff --git a/addons/missileguidance/functions/fnc_seekerType_ARH.sqf b/addons/missileguidance/functions/fnc_seekerType_MWR.sqf similarity index 82% rename from addons/missileguidance/functions/fnc_seekerType_ARH.sqf rename to addons/missileguidance/functions/fnc_seekerType_MWR.sqf index 54e487a9a0..df51acdd8c 100644 --- a/addons/missileguidance/functions/fnc_seekerType_ARH.sqf +++ b/addons/missileguidance/functions/fnc_seekerType_MWR.sqf @@ -11,16 +11,16 @@ * Seeker Pos * * Example: - * [] call call ace_missileguidance_fnc_seekerType_ARH; + * [] call call ace_missileguidance_fnc_seekerType_MWR; * * Public: No */ -params ["", "_args", "_seekerStateParams"]; -_args params ["_firedEH", "_launchParams", "", "_seekerParams", "_stateParams"]; +params ["", "_args", "_seekerStateParams", "", "_timestep"]; +_args params ["_firedEH", "_launchParams", "", "_seekerParams", "_stateParams", "_targetData"]; _firedEH params ["_shooter","","","","","","_projectile"]; _launchParams params ["_target","","","",""]; _seekerParams params ["_seekerAngle", "", "_seekerMaxRange"]; -_seekerStateParams params ["_isActive", "_activeRadarEngageDistance", "_timeWhenActive", "_expectedTargetPos", "_lastTargetPollTime", "_shooterHasRadar", "_wasActive", "_lastKnownVelocity", "_lastTimeSeen", "_doesntHaveTarget"]; +_seekerStateParams params ["_isActive", "_activeRadarEngageDistance", "_timeWhenActive", "_expectedTargetPos", "_lastTargetPollTime", "_shooterHasRadar", "_wasActive", "_lastKnownVelocity", "_lastTimeSeen", "_doesntHaveTarget", "_lockTypes"]; if (_isActive || { CBA_missionTime >= _timeWhenActive }) then { if !(_isActive) then { @@ -60,8 +60,7 @@ if (_isActive || { CBA_missionTime >= _timeWhenActive }) then { _seekerBaseRadiusAdjusted = _seekerBaseRadiusAtGround; }; // Look in front of seeker for any targets - private _nearestObjects = nearestObjects [ASLtoAGL _searchPos, ["Air", "LandVehicle", "Ship"], _seekerBaseRadiusAdjusted, false]; - + private _nearestObjects = nearestObjects [ASLtoAGL _searchPos, _lockTypes, _seekerBaseRadiusAdjusted, false]; _nearestObjects = _nearestObjects apply { // I check both Line of Sight versions to make sure that a single bush doesnt make the target lock dissapear but at the same time ensure that this can see through smoke. Should work 80% of the time if ([_projectile, getPosASL _x, _seekerAngle] call FUNC(checkSeekerAngle) && { ([_projectile, _x, true] call FUNC(checkLOS)) || { ([_projectile, _x, false] call FUNC(checkLOS)) } }) then { @@ -74,6 +73,7 @@ if (_isActive || { CBA_missionTime >= _timeWhenActive }) then { // Select closest object to the expected position to be the current radar target if (_nearestObjects isEqualTo []) exitWith { _projectile setMissileTarget objNull; + _seekerStateParams set [3, _searchPos]; _searchPos }; private _closestDistance = _seekerBaseRadiusAtGround; @@ -89,9 +89,9 @@ if (_isActive || { CBA_missionTime >= _timeWhenActive }) then { _projectile setMissileTarget _target; } else { - #ifdef DRAW_GUIDANCE_INFO - _seekerTypeName = "AHR - EXT"; - #endif + if (GVAR(debug_drawGuidanceInfo)) then { + _seekerTypeName = "MWR - EXT"; + }; // External radar homing // if the target is in the remote targets for the side, whoever the donor is will "datalink" the target for the hellfire. private _remoteTargets = listRemoteTargets side _shooter; @@ -104,16 +104,30 @@ if (_isActive || { CBA_missionTime >= _timeWhenActive }) then { }; }; +if (GVAR(debug_drawGuidanceInfo)) then { + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], ASLtoAGL _expectedTargetPos, 0.75, 0.75, 0, "expected target pos", 1, 0.025, "TahomaB"]; +}; + if !(isNull _target) then { private _centerOfObject = getCenterOfMass _target; - private _targetAdjustedPos = _target modelToWorldWorld _centerOfObject; + private _targetAdjustedPos = _target modelToWorldVisualWorld _centerOfObject; _expectedTargetPos = _targetAdjustedPos; - _seekerStateParams set [3, _expectedTargetPos]; _seekerStateParams set [7, velocity _target]; _seekerStateParams set [8, CBA_missionTime]; _seekerStateParams set [9, false]; + + _targetData set [2, _projectile distance _target]; + _targetData set [3, velocity _target]; + + if (_timestep != 0) then { + private _acceleration = ((velocity _target) vectorDiff _lastKnownVelocity) vectorMultiply (1 / _timestep); + _targetData set [4, _acceleration]; + }; }; +_targetData set [0, (getPosASLVisual _projectile) vectorFromTo _expectedTargetPos]; + +_seekerStateParams set [3, _expectedTargetPos]; _launchParams set [0, _target]; _expectedTargetPos diff --git a/addons/missileguidance/functions/fnc_seekerType_Optic.sqf b/addons/missileguidance/functions/fnc_seekerType_Optic.sqf index bac01d05b4..0507bc2c11 100644 --- a/addons/missileguidance/functions/fnc_seekerType_Optic.sqf +++ b/addons/missileguidance/functions/fnc_seekerType_Optic.sqf @@ -17,7 +17,7 @@ */ params ["", "_args"]; -_args params ["_firedEH", "_launchParams", "", "_seekerParams", "_stateParams"]; +_args params ["_firedEH", "_launchParams", "", "_seekerParams", "_stateParams", "_targetData"]; _firedEH params ["","","","","","","_projectile"]; _launchParams params ["", "_targetParams"]; _targetParams params ["_target"]; @@ -25,7 +25,7 @@ _seekerParams params ["_seekerAngle", "", "_seekerMaxRange"]; if (isNil "_target") exitWith {[0,0,0]}; -private _foundTargetPos = aimPos _target; +private _foundTargetPos = _target modelToWorldVisualWorld getCenterOfMass _target; // @TODO: This is seeker LOS and angle checks for LOAL only; LOBL does not need visual private _angleOkay = [_projectile, _foundTargetPos, _seekerAngle] call FUNC(checkSeekerAngle); @@ -40,14 +40,11 @@ TRACE_2("",_angleOkay,_losOkay); if (!_angleOkay || !_losOkay) exitWith {[0,0,0]}; TRACE_2("",_target,_foundTargetPos); -// @TODO: Configurable lead for seekers -private _projectileSpeed = (vectorMagnitude velocity _projectile); private _distanceToTarget = (getPosASL _projectile) vectorDistance _foundTargetPos; -private _eta = _distanceToTarget / _projectileSpeed; -private _adjustDistance = (velocity _target) vectorMultiply _eta; -TRACE_3("leading target",_distanceToTarget,_eta,_adjustDistance); -_foundTargetPos = _foundTargetPos vectorAdd _adjustDistance; +_targetData set [0, (getPosASL _projectile) vectorFromTo _foundTargetPos]; +_targetData set [2, _distanceToTarget]; +_targetData set [3, velocity _target]; TRACE_2("return",_foundTargetPos,(aimPos _target) distance _foundTargetPos); _foundTargetPos; diff --git a/addons/missileguidance/functions/fnc_seekerType_SACLOS.sqf b/addons/missileguidance/functions/fnc_seekerType_SACLOS.sqf index da9549c3ae..1641ff4a7d 100644 --- a/addons/missileguidance/functions/fnc_seekerType_SACLOS.sqf +++ b/addons/missileguidance/functions/fnc_seekerType_SACLOS.sqf @@ -16,13 +16,13 @@ * Public: No */ params ["", "_args"]; -_args params ["_firedEH", "", "", "_seekerParams", "_stateParams"]; +_args params ["_firedEH", "", "", "_seekerParams", "_stateParams", "_targetData"]; _firedEH params ["_shooter","_weapon","","","","","_projectile"]; _seekerParams params ["_seekerAngle"]; _stateParams params ["", "_seekerStateParams"]; _seekerStateParams params ["_memoryPointGunnerOptics", "_animationSourceBody", "_animationSourceGun", "_usePilotCamera"]; -private _shooterPos = AGLToASL (_shooter modelToWorld(_shooter selectionPosition _memoryPointGunnerOptics)); +private _shooterPos = AGLToASL (_shooter modelToWorldVisual (_shooter selectionPosition _memoryPointGunnerOptics)); private _projPos = getPosASL _projectile; private _lookDirection = if !(_shooter isKindOf "CAManBase" || {_shooter isKindOf "StaticWeapon"}) then { @@ -37,8 +37,9 @@ private _lookDirection = if !(_shooter isKindOf "CAManBase" || {_shooter isKindO _shooter vectorModelToWorldVisual getPilotCameraDirection _shooter; }; } else { - private _gBody = -deg(_shooter animationPhase _animationSourceBody); - private _gGun = deg(_shooter animationPhase _animationSourceGun); + // use animationSourcePhase + private _gBody = -deg(_shooter animationSourcePhase _animationSourceBody); + private _gGun = deg(_shooter animationSourcePhase _animationSourceGun); _shooter vectorModelToWorldVisual ([1, _gBody, _gGun] call CBA_fnc_polar2vect); }; _finalLookDirection @@ -58,5 +59,9 @@ if ((_testDotProduct < (cos _seekerAngle)) || {_testIntersections isNotEqualTo [ [0, 0, 0] }; -_shooterPos vectorAdd (_lookDirection vectorMultiply _distanceToProj); +private _returnPos = _shooterPos vectorAdd (_lookDirection vectorMultiply _distanceToProj); +_targetData set [0, _projPos vectorFromTo _returnPos]; +_targetData set [2, _returnPos vectorDistance getPosASLVisual _projectile]; + +_returnPos diff --git a/addons/missileguidance/functions/fnc_seekerType_SALH.sqf b/addons/missileguidance/functions/fnc_seekerType_SALH.sqf index a16c58ce5f..8772d73178 100644 --- a/addons/missileguidance/functions/fnc_seekerType_SALH.sqf +++ b/addons/missileguidance/functions/fnc_seekerType_SALH.sqf @@ -16,17 +16,58 @@ * * Public: No */ +#define MAX_AVERAGES 15 +#define MINIMUM_DISTANCE_UNTIL_NEW_POS 1 -params ["", "_args"]; -_args params ["_firedEH", "_launchParams", "", "_seekerParams"]; +params ["", "_args", "", "", "_timestep"]; +_args params ["_firedEH", "_launchParams", "", "_seekerParams", "", "_targetData"]; _firedEH params ["","","","","","","_projectile"]; _launchParams params ["","","","","","_laserParams"]; -_seekerParams params ["_seekerAngle", "", "_seekerMaxRange"]; +_seekerParams params ["_seekerAngle", "", "_seekerMaxRange", "", ["_lastPositions", []], ["_lastPositionIndex", 0], ["_lastPositionSum", [0, 0, 0]]]; _laserParams params ["_code", "_wavelengthMin", "_wavelengthMax"]; - private _laserResult = [(getPosASL _projectile), (velocity _projectile), _seekerAngle, _seekerMaxRange, [_wavelengthMin, _wavelengthMax], _code, _projectile] call EFUNC(laser,seekerFindLaserSpot); private _foundTargetPos = _laserResult select 0; TRACE_1("Search",_laserResult); -_foundTargetPos; +if (isNil "_foundTargetPos") exitWith { + [0, 0, 0] +}; + +// average out any error from laser jump +private _positionSum = [0, 0, 0]; +{ + _positionSum = _positionSum vectorAdd _x; +} forEach _lastPositions; + +if (_foundTargetPos isNotEqualTo [0, 0, 0]) then { + _lastPositions set [_lastPositionIndex % MAX_AVERAGES, _foundTargetPos]; + _seekerParams set [4, _lastPositions]; + _seekerParams set [5, _lastPositionIndex + 1]; +}; + +private _aproximateVelocity = [0, 0, 0]; +_positionSum = _positionSum vectorAdd _foundTargetPos; +if (MAX_AVERAGES == count _lastPositions) then { + _positionSum = _positionSum vectorMultiply (1 / (1 + count _lastPositions)); + + // if we are within a meter of the previous average, just use the previous average + if (_positionSum distanceSqr _lastPositionSum < MINIMUM_DISTANCE_UNTIL_NEW_POS * MINIMUM_DISTANCE_UNTIL_NEW_POS) then { + _positionSum = _lastPositionSum; + }; + + if (_timestep != 0) then { + _aproximateVelocity = (_positionSum vectorDiff _lastPositionSum) vectorMultiply (1 / _timestep); + }; +} else { + _positionSum = _positionSum vectorMultiply (1 / count _lastPositions); +}; + +_seekerParams set [6, _positionSum]; + +_targetData set [0, (getPosASL _projectile) vectorFromTo _positionSum]; +_targetData set [3, _aproximateVelocity]; + +TRACE_3("laser target found",_foundTargetPos,_positionSum,count _lastPositions); + +_positionSum diff --git a/addons/missileguidance/functions/fnc_wire_onFired.sqf b/addons/missileguidance/functions/fnc_wire_onFired.sqf index 0cfa90ff99..870754c509 100644 --- a/addons/missileguidance/functions/fnc_wire_onFired.sqf +++ b/addons/missileguidance/functions/fnc_wire_onFired.sqf @@ -45,4 +45,3 @@ _attackProfileStateParams set [4, _maxDistanceSqr]; // max distance squared used _attackProfileStateParams set [5, _minDistanceSqr]; _attackProfileStateParams set [6, _wireCutSource]; _attackProfileStateParams set [7, _distanceAheadOfMissile]; - diff --git a/addons/missileguidance/script_component.hpp b/addons/missileguidance/script_component.hpp index 2b43be42f3..2ffb589e77 100644 --- a/addons/missileguidance/script_component.hpp +++ b/addons/missileguidance/script_component.hpp @@ -3,8 +3,9 @@ #include "\z\ace\addons\main\script_mod.hpp" // #define DRAW_GUIDANCE_INFO +// #define ENABLE_PROJECTILE_CAMERA // #define DEBUG_MODE_FULL -// #define DISABLE_COMPILE_CACHE + #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_MISSILEGUIDANCE @@ -28,4 +29,3 @@ #define DEFAULT_LEAD_DISTANCE 5 #define ACTIVE_RADAR_POLL_FREQUENCY (1 / 7) #define ACTIVE_RADAR_MINIMUM_SCAN_AREA 30 - diff --git a/docs/wiki/framework/missile-guidance-framework.md b/docs/wiki/framework/missile-guidance-framework.md index ff6859d735..df83559996 100644 --- a/docs/wiki/framework/missile-guidance-framework.md +++ b/docs/wiki/framework/missile-guidance-framework.md @@ -27,10 +27,10 @@ Finally, flight profiles and mechanics for realistic missile simulations are als ## 2. Components -The framework is broken up into 3 major components: Locking Types, Seeker Types and Attack Profiles. In combination, these components build out the entire process of launching, locking and going terminal flight against targets. +The framework is broken up into 3 major components: Navigation Types, Seeker Types and Attack Profiles. In combination, these components build out the entire process of launching, locking and going terminal flight against targets. -#### 2.1 Locking Types -Locking types provide the basic functionality of targeting which will be based to a seeker type, providing target acquisition for seekers. This provides the basic functionality for providing pre-determined targets for a seeker, or allowing the seeker to perform its own target acquisition and locking. Additionally, the seeker may reference back into the locking type in order to re-perform target acquisition. +#### 2.1 Navigation Types +Navigation types define how the missile flies to the designated target. ACE 3 implements the most common ones in use, Proportional Navigation, Augmented Proportional Navigation, and Zero-Effort Miss. These navigation types give an acceleration command to the missile who attempts to satisfy the command by adjusting its pitch and yaw to fly to the target. #### 2.2 Seeker Types Each seeker is generally assumed to be the logic for the seeker head unit within any given munition. Seekers within this framework provide the basic targeting functionality for the entire framework. The locking type will provide a generic target to the seeker, or the seeker may aquire a target on its own. The seeker then provides a target, either an object or a ASL position, which is then passed further into the framework. This target (or position) should be the actual current target position for the missiles flight. Seekers are required to perform all limitations and checks within their systems, although various limitations have been provided in this framework such as LOS FOV, laser guidance, etc. @@ -42,9 +42,9 @@ An attack profile adjusts the current target flight location to create the actua ## 3. How it all ties together -The system is executed in a linear series of calls to each step of the process, and feeding back the return from that step to the next step. Execution is conducted using Locking -> Seeker -> Profile, iteratively every frame of execution. Flight times are adjusted to `accTime` values and FPS lag, giving consistent flight. +The system is executed in a linear series of calls to each step of the process, and feeding back the return from that step to the next step. Execution is conducted using Seeker -> Profile -> Navigation, iteratively every frame of execution. Flight times are adjusted to `accTime` values and FPS lag, giving consistent flight. -On each step of execution, a target specification array `[targetObj, targetPos]` is passed to the locking type, which then will return a possible modified target array. Next, this modified data is passed to the seeker type - which then, in turn, returns a position vector to the current "seeked" target position (ASL). Last, this target position is passed to the attack profile, which then returns an "adjusted attack position" (ASL), which is the location the missile should *currently* be homing on for flight. +On each step of execution, the seeker finds and returns the position of its target (ASL) and, optionally, sets target data specifying the target's direction from the missile, range, velocity and acceleration (if able). Then, this data is passed to the attack profile, which then returns an "adjusted attack position" (ASL), which is the location the missile should *currently* be homing on for flight. Finally, the navigation system processes the seeker's data about the target and returns a "Commanded Acceleration" vector which the missile attempts to satisfy. In the simplest sense, the entire system provides the flight trajectory of the missile homing directly on the "adjusted attack position"; thus, an attack profile would ajust this position to direct the missile. For example, top down attacks return the adjusted attack position high above the target, until entering their terminal stages, which then changes the position to be directly on top of the target - thus "walking the missile" along its flight path and to the impact. @@ -60,28 +60,47 @@ class CfgAmmo { // Begin ACE guidance Configs class ace_missileguidance { - enabled = 1; // Enable missile guidance (0-disabled, 1-enabled) + enabled = 1; // Explicit enabling of the system - minDeflection = 0.00025; // Minimum flap deflection for guidance - maxDeflection = 0.001; // Maximum flap deflection for guidance - incDeflection = 0.0005; // The increment in which deflection adjusts + pitchRate = 30; // How many degrees/second the missile can pitch + yawRate = 30; // How many degrees/second this missile can yaw - canVanillaLock = 0; // Enable vanilla lock, only applicable to non-cadet modes, 'recruit' always uses vanilla locking (0-disabled, 1-enabled) + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode - defaultSeekerType = "SALH"; // Default seeker type - seekerTypes[] = {"SALH", "LIDAR", "SARH", "Optic", "Thermal", "GPS", "SACLOS", "MCLOS"}; // Seeker types available + // Guidance type for munitions + defaultSeekerType = "SALH"; // Default seeker type + seekerTypes[] = { "SALH", "LIDAR", "SARH", "Optic", "Thermal", "GPS", "SACLOS", "MCLOS" }; - defaultSeekerLockMode = "LOAL"; // Default seeker lock mode - seekerLockModes[] = {"LOAL", "LOBL"}; // Seeker lock modes available + defaultSeekerLockMode = "LOAL"; // Default lock mode + seekerLockModes[] = { "LOAL", "LOBL" }; - seekerAngle = 90; // Angle in front of the missile which can be searched - seekerAccuracy = 1; // Seeker accuracy multiplier + defaultNavigationType = "Direct"; // Default navigation type + navigationTypes[] = { "Direct", "ZeroEffortMiss" }; // Navigation types this missile can use - seekerMinRange = 1; // Minimum range from the missile which the seeker can visually search - seekerMaxRange = 2500; // Maximum from the missile which the seeker can visually search + seekLastTargetPos = 1; // seek last target position [if seeker loses LOS of target, continue to last known pos] + seekerAngle = 70; // Angle in front of the missile which can be searched + seekerAccuracy = 1; // seeker accuracy multiplier - defaultAttackProfile = "LIN"; // Default attack profile - attackProfiles[] = {"LIN", "DIR", "MID", "HI"}; // Attack profiles available + seekerMinRange = 1; // Minimum range from the missile which the seeker can visually search + seekerMaxRange = 8000; // Maximum range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "hellfire"; // Default attack profile + attackProfiles[] = {"hellfire", "hellfire_hi", "hellfire_lo"}; // Possible attack profiles + + // State machine defining what navigation type to use in this missiles phase + class navigationStates { + class initial { + transitionCondition = "my_fnc_navigationTransition"; // Condition needed to transition to next state + navigationType = "Direct"; // Navigation type to use in this state + }; + class terminal { + transitionCondition = ""; + navigationType = "ZeroEffortMiss"; + }; + // transitions from initial -> termimal + states[] = {"initial", "terminal"}; + }; }; ``` @@ -95,6 +114,7 @@ class ace_missileguidance_seekerTypes { description = ""; // Description functionName = "my_fnc_doSeekerType"; // Function that handles the seeker type + onFired = "my_fnc_onFired"; // Function that runs when the missile is fired using this seeker }; }; ``` @@ -109,6 +129,17 @@ class ace_missileguidance_attackProfiles { description = ""; // Description functionName = "my_fnc_doAttackProfile"; // Function that handles the attack profile + onFired = "my_fnc_onFired"; // Function that runs when missile is fired using this attack profile + }; +}; +``` + +### 4.4 Custom Navigation Type +```cpp +class ace_missileguidance_navigationTypes { + class MyNavigationProfile { + functionName = "my_fnc_navigation"; // Function to run for navigation + onFired = "my_fnc_onFired"; // Function to run when the missile is fired with this navigation type }; }; ```