From 6c212ca377d509a02576c365b2ade94ccfafe132 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 8 Jan 2024 15:21:32 -0600 Subject: [PATCH 001/282] Initial commit or frag & spall rewrite --- .gitignore | 1 + addons/frag/CfgAmmo.hpp | 583 +++++++++++++++++++++++++- addons/frag/README.md | 2 +- addons/frag/initSettings.inc.sqf | 40 +- addons/frag/initSettingsDebug.inc.sqf | 54 +++ addons/frag/script_component.hpp | 2 +- addons/frag/stringtable.xml | 9 + 7 files changed, 655 insertions(+), 36 deletions(-) create mode 100644 addons/frag/initSettingsDebug.inc.sqf diff --git a/.gitignore b/.gitignore index 8a7e6945a63..44f28e560a0 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ CHANGELOG.md sqfvm.exe ArmaScriptCompiler.exe *.sqfc +addons/frag/dev \ No newline at end of file diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index 7a124833b3c..eb524e5c184 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -10,6 +10,7 @@ class CfgAmmo { GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; + GVAR(fragCount) = 17500; GVAR(metal) = 140000; GVAR(charge) = 87000; GVAR(gurney_c) = 2320; @@ -18,7 +19,8 @@ class CfgAmmo { class Bomb_04_F: ammo_Bomb_LaserGuidedBase { GVAR(enabled) = 1; - GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; + GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large ), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; + GVAR(fragCount) = 17500; GVAR(metal) = 140000; GVAR(charge) = 87000; GVAR(gurney_c) = 2320; @@ -29,6 +31,7 @@ class CfgAmmo { GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; + GVAR(fragCount) = 17500; GVAR(metal) = 140000; GVAR(charge) = 87000; GVAR(gurney_c) = 2320; @@ -43,12 +46,12 @@ class CfgAmmo { GVAR(skip) = 0; GVAR(force) = 1; - // This is a good high-drag frag type for grenades. - GVAR(classes)[] = {QGVAR(tiny_HD)}; /* These values are based on the M67 Grenade, should be tweaked for individual grenades. */ + GVAR(classes)[] = {QGVAR(tiny)}; + GVAR(fragCount) = 1000; GVAR(metal) = 210; // metal in grams GVAR(charge) = 185; // explosive in grams GVAR(gurney_c) = 2843; // Gurney velocity constant for explosive type. See: http://en.wikipedia.org/wiki/Gurney_equations @@ -65,17 +68,19 @@ class CfgAmmo { GVAR(enabled) = 1; GVAR(force) = 1; - GVAR(classes)[] = {QGVAR(tiny_HD)}; + GVAR(classes)[] = {QGVAR(small)}; + GVAR(fragCount) = 800; // guess based on probability hit of 1% GVAR(metal) = 200; GVAR(charge) = 32; GVAR(gurney_c) = 2700; - GVAR(gurney_k) = "1/2"; + GVAR(gurney_k) = "3/5"; // interior fragmenter/charge is a sphere }; class G_40mm_HEDP: G_40mm_HE { // Source: http://www.inetres.com/gp/military/infantry/grenade/40mm_ammo.html#M433 GVAR(enabled) = 1; - GVAR(classes)[] = {QGVAR(tiny_HD)}; + GVAR(classes)[] = {QGVAR(small_HD)}; + GVAR(fragCount) = 270; // seems to have greater framentation ability, but lower range per source GVAR(metal) = 200; GVAR(charge) = 45; GVAR(gurney_c) = 2830; @@ -89,6 +94,7 @@ class CfgAmmo { GVAR(force) = 0; EGVAR(vehicle_damage,incendiary) = 0; }; + // What is this even? class ACE_G40mm_HE_VOG25P: G_40mm_HE { GVAR(skip) = 0; GVAR(force) = 1; @@ -98,13 +104,14 @@ class CfgAmmo { // ~~~~ RPGs: class MissileBase; class R_PG32V_F; - class R_TBG32V_F: R_PG32V_F { // HE + class R_TBG32V_F: R_PG32V_F { // Thermobaric GVAR(enabled) = 1; + GVAR(fragCount) = 200; GVAR(metal) = 400; GVAR(charge) = 210; GVAR(gurney_c) = 2800; GVAR(gurney_k) = "3/5"; - GVAR(classes)[] = {"ACE_frag_medium_HD"}; + GVAR(classes)[] = {QGVAR(medium_HD)}; }; class M_Titan_AA: MissileBase { GVAR(skip) = 1; @@ -114,12 +121,13 @@ class CfgAmmo { }; class M_Titan_AP: M_Titan_AT { // "anti personnel" GVAR(skip) = 0; + GVAR(fragCount) = 800; // guesstimate / provides ~80 m frag range GVAR(enabled) = 1; GVAR(metal) = 400; GVAR(charge) = 210; GVAR(gurney_c) = 2800; GVAR(gurney_k) = "3/5"; - GVAR(classes)[] = {"ACE_frag_medium_HD"}; + GVAR(classes)[] = {QGVAR(medium_HD)}; }; // https://ofb.gov.in/product/products/product-details/84-mm-he-round-ffv-441-b @@ -127,11 +135,12 @@ class CfgAmmo { class R_MRAAWS_HEAT_F; class R_MRAAWS_HE_F: R_MRAAWS_HEAT_F { GVAR(enabled) = 1; + GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) GVAR(metal) = 2300; GVAR(charge) = 590; GVAR(gurney_c) = 2800; GVAR(gurney_k) = "1/2"; - GVAR(classes)[] = {"ACE_frag_small"}; + GVAR(classes)[] = {QGVAR(small)}; }; @@ -142,6 +151,7 @@ class CfgAmmo { GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) GVAR(metal) = 3850; GVAR(charge) = 1040; GVAR(gurney_c) = 2700; @@ -156,6 +166,7 @@ class CfgAmmo { GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(fragCount) = 1600; // guesstimate / provides ~112 m frag range (1% chance to hit) GVAR(metal) = 56250; GVAR(charge) = 39000; GVAR(gurney_c) = 2700; @@ -164,6 +175,7 @@ class CfgAmmo { class Rocket_04_HE_F: MissileBase { // Shrieker (Hydra 70) GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) GVAR(metal) = 3850; GVAR(charge) = 1040; GVAR(gurney_c) = 2700; @@ -171,7 +183,8 @@ class CfgAmmo { }; class M_Scalpel_AT: MissileBase { // 9K121 Vikhr GVAR(enabled) = 1; - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium_HD)}; + GVAR(fragCount) = 800; // guesstimate based on frag jacket, provides ~80 m frag range (1% chance to hit) GVAR(metal) = 10000; GVAR(charge) = 3000; GVAR(gurney_c) = 2700; @@ -182,6 +195,7 @@ class CfgAmmo { GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(fragCount) = 350; // guesstimate based on frag jacket, provides ~50 m frag range (1% chance to hit) GVAR(metal) = 8000; GVAR(charge) = 2400; GVAR(gurney_c) = 2700; @@ -202,18 +216,20 @@ class CfgAmmo { GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; + GVAR(fragCount) = 3250; // http://18.195.19.6/bitstream/handle/20.500.12242/1200/15-01916.pdf?sequence=1&isAllowed=y GVAR(metal) = 36000; GVAR(charge) = 9979; GVAR(gurney_c) = 2440; GVAR(gurney_k) = "1/2"; }; class Sh_82mm_AMOS: Sh_155mm_AMOS { - // Source: http://www.arsenal-bg.com/defense_police/mortar_bombs_82mm.htm + //http://65.175.100.54/uxofiles/mulvaney/techdatasheets/81mm-HE-M821.pdf GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(metal) = 3200; - GVAR(charge) = 420; + GVAR(fragCount) = 1600; // based on mass and fragment energy/count + GVAR(metal) = 2500; + GVAR(charge) = 726; GVAR(gurney_c) = 2440; GVAR(gurney_k) = "1/2"; }; @@ -230,6 +246,7 @@ class CfgAmmo { GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(fragCount) = 1600; // based on mass and fragment energy/count GVAR(metal) = 11400; GVAR(charge) = 7100; GVAR(gurney_c) = 2800; @@ -239,6 +256,7 @@ class CfgAmmo { GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(fragCount) = 2000; GVAR(metal) = 23000; GVAR(charge) = 3148; GVAR(gurney_c) = 2830; @@ -262,13 +280,18 @@ class CfgAmmo { GVAR(gurney_c) = 2320; GVAR(gurney_k) = "1/2"; }; - + // Special + class Default; + class Laserbeam : Default { + GVAR(skip) = 1; + }; class B_65x39_Caseless; class GVAR(base): B_65x39_Caseless { ACE_damageType = "grenade"; // compatibility with medical_damage, shrapnel should produce grenade wounds - timeToLive = 12; - typicalSpeed = 1500; + timeToLive = 4; + typicalSpeed = 800; + maxSpeed = 1500; deflecting = 65; }; @@ -341,11 +364,11 @@ class CfgAmmo { }; class GVAR(spall_small): GVAR(small) { - timeToLive = 0.1; + timeToLive = 0.2; }; class GVAR(spall_medium): GVAR(medium) { - timeToLive = 0.15; + timeToLive = 0.2; }; class GVAR(spall_large): GVAR(large) { @@ -356,5 +379,523 @@ class CfgAmmo { timeToLive = 0.3; }; - #include "CfgAmmoReflections.hpp" -}; + + // format fragType_spawn_n_range + /********************* ***************************/ + class GVAR(spawnbase) : B_65x39_Caseless { + access = 2; + deleteParentWhenTriggered = 1; + submunitionConeType[] = {"random", 25}; + submunitionAmmo[] = {QGVAR(tiny), 3, QGVAR(tiny_HD), 3, QGVAR(small), 4, QGVAR(small_HD), 4, QGVAR(medium_HD), 5}; + submunitionDirectionType = "SubmunitionModelDirection"; + submunitionConeAngleHorizontal = 15; + submunitionConeAngle = 87; + submunitionInitialOffset[] = {0,0,0}; + submunitionInitSpeed = 1000; + submunitionParentSpeedCoef = 1; + triggerSpeedCoef[] = {0.75, 1.5}; + triggerTime = 0; + }; + + /********************* ***************************/ + class GVAR(def_10) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 10}; + }; + class GVAR(def_10_lo) : GVAR(def_10) { + submunitionConeAngle = 85; + }; + class GVAR(def_10_mid) : GVAR(def_10) { + submunitionConeAngle = 85; + triggerSpeedCoef[] = {-1.5, 1.5}; + }; + class GVAR(def_10_hi) : GVAR(def_10) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + class GVAR(def_10_top) : GVAR(def_10) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + + /********************* ***************************/ + class GVAR(def_15) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 15}; + }; + class GVAR(def_15_lo) : GVAR(def_15) { + submunitionConeAngle = 85; + }; + class GVAR(def_15_mid) : GVAR(def_15) { + submunitionConeAngle = 85; + triggerSpeedCoef[] = {-1.5, 1.5}; + }; + class GVAR(def_15_hi) : GVAR(def_15) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + class GVAR(def_15_top) : GVAR(def_15) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + + /********************* ***************************/ + class GVAR(def_5) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 5}; + }; + class GVAR(def_5_lo) : GVAR(def_5) { + submunitionConeAngle = 85; + }; + class GVAR(def_5_mid) : GVAR(def_5) { + submunitionConeAngle = 85; + triggerSpeedCoef[] = {-1.5, 1.5}; + }; + class GVAR(def_5_hi) : GVAR(def_5) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + class GVAR(def_5_top) : GVAR(def_5) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + + /********************* ***************************/ + class GVAR(def_tiny_15) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 15}; + submunitionAmmo = QGVAR(tiny); + }; + class GVAR(def_tiny_15_lo) : GVAR(def_tiny_15) { + submunitionConeAngle = 85; + }; + class GVAR(def_tiny_15_mid) : GVAR(def_tiny_15) { + submunitionConeAngle = 85; + triggerSpeedCoef[] = {-1.5, 1.5}; + }; + class GVAR(def_tiny_15_hi) : GVAR(def_tiny_15) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + class GVAR(def_tiny_15_top) : GVAR(def_tiny_15) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + + /********************* ***************************/ + class GVAR(def_tiny_10) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 10}; + submunitionAmmo = QGVAR(tiny); + }; + class GVAR(def_tiny_10_lo) : GVAR(def_tiny_10) { + submunitionConeAngle = 85; + }; + class GVAR(def_tiny_10_mid) : GVAR(def_tiny_10) { + submunitionConeAngle = 85; + triggerSpeedCoef[] = {-1.5, 1.5}; + }; + class GVAR(def_tiny_10_hi) : GVAR(def_tiny_10) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + class GVAR(def_tiny_10_top) : GVAR(def_tiny_10) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + + /********************* ***************************/ + class GVAR(def_tiny_5) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 5}; + submunitionAmmo = QGVAR(tiny); + }; + class GVAR(def_tiny_5_lo) : GVAR(def_tiny_5) { + submunitionConeAngle = 85; + }; + class GVAR(def_tiny_5_mid) : GVAR(def_tiny_5) { + submunitionConeAngle = 85; + triggerSpeedCoef[] = {-1.5, 1.5}; + }; + class GVAR(def_tiny_5_hi) : GVAR(def_tiny_5) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + class GVAR(def_tiny_5_top) : GVAR(def_tiny_5) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + /********************* ***************************/ + class GVAR(def_small_15) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 15}; + submunitionAmmo = QGVAR(small); + }; + class GVAR(def_small_15_lo) : GVAR(def_small_15) { + submunitionConeAngle = 815; + }; + class GVAR(def_small_15_mid) : GVAR(def_small_15) { + submunitionConeAngle = 815; + triggerSpeedCoef[] = {-1.15, 1.15}; + }; + class GVAR(def_small_15_hi) : GVAR(def_small_15) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.15, -0.715}; + }; + class GVAR(def_small_15_top) : GVAR(def_small_15) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.15, -0.715}; + }; + /********************* ***************************/ + class GVAR(def_small_10) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 10}; + submunitionAmmo = QGVAR(small); + }; + class GVAR(def_small_10_lo) : GVAR(def_small_10) { + submunitionConeAngle = 810; + }; + class GVAR(def_small_10_mid) : GVAR(def_small_10) { + submunitionConeAngle = 810; + triggerSpeedCoef[] = {-1.10, 1.10}; + }; + class GVAR(def_small_10_hi) : GVAR(def_small_10) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.10, -0.710}; + }; + class GVAR(def_small_10_top) : GVAR(def_small_10) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.10, -0.710}; + }; + /********************* ***************************/ + class GVAR(def_small_5) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 5}; + submunitionAmmo = QGVAR(small); + }; + class GVAR(def_small_5_lo) : GVAR(def_small_5) { + submunitionConeAngle = 85; + }; + class GVAR(def_small_5_mid) : GVAR(def_small_5) { + submunitionConeAngle = 85; + triggerSpeedCoef[] = {-1.5, 1.5}; + }; + class GVAR(def_small_5_hi) : GVAR(def_small_5) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + class GVAR(def_small_5_top) : GVAR(def_small_5) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + + /******************* targeted fragments ********************/ + class GVAR(spawnbase_targeted) : GVAR(spawnbase) { + access = 2; + submunitionConeType[] = {"random", 2}; + submunitionConeAngle = 2; + submunitionInitSpeed = 0; + triggerSpeedCoef[] = {0.5, 1}; + }; + + class GVAR(tiny_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(tiny_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(tiny_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(tiny_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(tiny_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(tiny_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; + }; + + class GVAR(tiny_HD_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(tiny_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(tiny_HD_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(tiny_HD_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(tiny_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(tiny_HD_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; + }; + + class GVAR(small_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(small_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(small_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(small_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(small_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(small_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; + }; + + class GVAR(small_HD_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(small_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(small_HD_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(small_HD_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(small_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(small_HD_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; + }; + + class GVAR(medium_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(medium_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(medium_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(medium_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(medium_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(medium_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; + }; + + class GVAR(medium_HD_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(medium_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(medium_HD_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(medium_HD_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(medium_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(medium_HD_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; + }; + + class GVAR(large_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(large_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(large_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(large_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(large_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(large_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; + }; + + class GVAR(large_HD_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(large_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(large_HD_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(large_HD_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(large_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(large_HD_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; + }; + + class GVAR(huge_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(huge_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(huge_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(huge_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(huge_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(huge_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; + }; + + class GVAR(huge_HD_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(huge_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(huge_HD_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(huge_HD_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(huge_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(huge_HD_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; + }; +}; \ No newline at end of file diff --git a/addons/frag/README.md b/addons/frag/README.md index ca62771f00e..e5c9a35a05d 100644 --- a/addons/frag/README.md +++ b/addons/frag/README.md @@ -1,4 +1,4 @@ ace_frag ======== -Shrapnel system for explosives. +Explosive fragmentation, round spalling, and explosive reflection \ No newline at end of file diff --git a/addons/frag/initSettings.inc.sqf b/addons/frag/initSettings.inc.sqf index 421d5d45664..29fbefe6fe4 100644 --- a/addons/frag/initSettings.inc.sqf +++ b/addons/frag/initSettings.inc.sqf @@ -3,7 +3,7 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; [ QGVAR(enabled), "CHECKBOX", [LSTRING(EnableFrag), LSTRING(EnableFrag_Desc)], - _category, + [_category, LSTRING(Frag)], true, 1 ] call CBA_fnc_addSetting; @@ -11,30 +11,44 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; [ QGVAR(spallEnabled), "CHECKBOX", [LSTRING(EnableSpall), LSTRING(EnableSpall_Desc)], - _category, + [_category, LSTRING(Spall)], false, 1 ] call CBA_fnc_addSetting; [ QGVAR(reflectionsEnabled), "CHECKBOX", [LSTRING(EnableReflections), LSTRING(EnableReflections_Desc)], - _category, + [_category, LSTRING(Reflections)], false, 1 ] call CBA_fnc_addSetting; + +/// !*! TODO: add stringtable entries [ - QGVAR(maxTrack), "SLIDER", - [LSTRING(MaxTrack), LSTRING(MaxTrack_Desc)], - _category, - [0, 50, 10, -1], - 1 + QGVAR(enSubMunit), "LIST", + ["Enable submunition fragmentation", "Enables submunition fragmentation when fragmentation is enabled"], + [_category, LSTRING(Frag)], + [[2, 1, 0], ["complex fragementation","simple fragmentation","no fragmentation"], 2] ] call CBA_fnc_addSetting; [ - QGVAR(maxTrackPerFrame), "SLIDER", - [LSTRING(MaxTrackPerFrame), LSTRING(MaxTrackPerFrame_Desc)], - _category, - [0, 50, 10, -1], - 1 + QGVAR(reflectionsEnabled), "CHECKBOX", + "Enable reflections", + [_category, LSTRING(Frag)], + false +] call CBA_fnc_addSetting; + +[ + QGVAR(atLeastOne), "CHECKBOX", + "At least one round hit", + [_category, LSTRING(Frag)], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(BlackList), "EDITBOX", + ["Default BlackList", "Array of ammo classnames strings to blackist fragmentation for."], + [_category, LSTRING(Frag)], + QUOTE(['B_556x45_Ball']) ] call CBA_fnc_addSetting; diff --git a/addons/frag/initSettingsDebug.inc.sqf b/addons/frag/initSettingsDebug.inc.sqf new file mode 100644 index 00000000000..92b4a78b95e --- /dev/null +++ b/addons/frag/initSettingsDebug.inc.sqf @@ -0,0 +1,54 @@ +private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; + +[ + QGVAR(debugOptions), + "CHECKBOX", + "Enable debug mode", + [_category, LSTRING(Debug)], + true // [min, max, default, trailing decimals] +] call CBA_fnc_addSetting; + +// debug options +[ + QGVAR(dbgSphere), + "CHECKBOX", + "Enable debug impact spheres", + [_category, LSTRING(Debug)], + false, + 0, + {}, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(frameHint), + "CHECKBOX", + "Show framerate hint", + [_category, LSTRING(Debug)], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(fadeRounds), + "CHECKBOX", + "Fade round traces over time", + [_category, LSTRING(Debug)], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(dltTrace), + "CHECKBOX", + "Delete fire trace on fade", + [_category, LSTRING(Debug)], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(drawHitBox), + "CHECKBOX", + "Draw unit hitboxes", + [_category, LSTRING(Debug)], + true +] call CBA_fnc_addSetting; + diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index 0215e9f4d74..f57bb7ad126 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -2,7 +2,7 @@ #define COMPONENT_BEAUTIFIED Frag #include "\z\ace\addons\main\script_mod.hpp" -// #define DRAW_FRAG_INFO +// #define LOG_FRAG_INFO // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS diff --git a/addons/frag/stringtable.xml b/addons/frag/stringtable.xml index 7addcd4c388..ac8b64cd7c5 100644 --- a/addons/frag/stringtable.xml +++ b/addons/frag/stringtable.xml @@ -17,6 +17,15 @@ 破片模拟 模擬碎片 + + Fragmentation + + + Spalling + + + Explosion Reflections + Fragmentation Simulation Symulacja fragmentacji From 3c1e91278744f98187092350d4974ec73830fdfc Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 8 Jan 2024 15:22:52 -0600 Subject: [PATCH 002/282] Initial commit: - Added new ammo cfg types - Added new caching functions - Added dev functions - Transfered core system to vanilla projectile EHs - Added stringtable sub categories - Reworked fragmenting and spalling to us submunitions - Frag - Implemented system around chance to hit - Switched from hitbox estimation to hitting specific HPs - Updated chance to miss method based on solid angle hit chance - Split random & targeted frag to their own subfunctions - Spall - Uses a system of estimated momentum changes to generate spall --- addons/frag/CfgAmmo.hpp | 1074 ++++++++--------- addons/frag/XEH_PREP.hpp | 40 +- addons/frag/XEH_postInit.sqf | 51 +- addons/frag/XEH_preInit.sqf | 24 +- addons/frag/functions/fnc_addBlackList.sqf | 10 +- addons/frag/functions/fnc_addPfhRound.sqf | 77 -- addons/frag/functions/fnc_dev_addRound.sqf | 114 ++ addons/frag/functions/fnc_dev_addTrack.sqf | 26 - addons/frag/functions/fnc_dev_clearTraces.sqf | 24 + addons/frag/functions/fnc_dev_drawTrace.sqf | 75 ++ addons/frag/functions/fnc_dev_drawTraces.sqf | 37 - addons/frag/functions/fnc_dev_fadeRound.sqf | 34 + .../frag/functions/fnc_dev_fragCalcDump.sqf | 90 ++ addons/frag/functions/fnc_dev_sphereDraw.sqf | 52 + .../frag/functions/fnc_dev_startTracing.sqf | 23 - addons/frag/functions/fnc_dev_stopTracing.sqf | 23 - .../functions/fnc_dev_switchUnitHandle.sqf | 43 + addons/frag/functions/fnc_dev_trackHitBox.sqf | 71 ++ addons/frag/functions/fnc_dev_trackObj.sqf | 123 ++ addons/frag/functions/fnc_dev_trackTrace.sqf | 27 - addons/frag/functions/fnc_doFrag.sqf | 59 + addons/frag/functions/fnc_doFragRandom.sqf | 71 ++ addons/frag/functions/fnc_doFragTargeted.sqf | 175 +++ addons/frag/functions/fnc_doReflections.sqf | 2 +- addons/frag/functions/fnc_doSpall.sqf | 179 ++- addons/frag/functions/fnc_doSpallMomentum.sqf | 109 ++ addons/frag/functions/fnc_fired.sqf | 74 +- addons/frag/functions/fnc_fragInfo.sqf | 86 ++ addons/frag/functions/fnc_frago.sqf | 194 --- addons/frag/functions/fnc_initBlackList.sqf | 51 + addons/frag/functions/fnc_masterPFH.sqf | 56 - addons/frag/functions/fnc_pfhRound.sqf | 59 - addons/frag/functions/fnc_shouldFrag.sqf | 55 + addons/frag/functions/fnc_shouldSpall.sqf | 31 + addons/frag/functions/fnc_spallHP.sqf | 42 - addons/frag/functions/fnc_spallTrack.sqf | 39 - addons/frag/functions/fnc_submunition.sqf | 40 + addons/frag/functions/script_component.hpp | 1 + addons/frag/initSettings.inc.sqf | 24 +- addons/frag/initSettingsDebug.inc.sqf | 66 +- addons/frag/script_component.hpp | 2 +- 41 files changed, 2074 insertions(+), 1379 deletions(-) delete mode 100644 addons/frag/functions/fnc_addPfhRound.sqf create mode 100644 addons/frag/functions/fnc_dev_addRound.sqf delete mode 100644 addons/frag/functions/fnc_dev_addTrack.sqf create mode 100644 addons/frag/functions/fnc_dev_clearTraces.sqf create mode 100644 addons/frag/functions/fnc_dev_drawTrace.sqf delete mode 100644 addons/frag/functions/fnc_dev_drawTraces.sqf create mode 100644 addons/frag/functions/fnc_dev_fadeRound.sqf create mode 100644 addons/frag/functions/fnc_dev_fragCalcDump.sqf create mode 100644 addons/frag/functions/fnc_dev_sphereDraw.sqf delete mode 100644 addons/frag/functions/fnc_dev_startTracing.sqf delete mode 100644 addons/frag/functions/fnc_dev_stopTracing.sqf create mode 100644 addons/frag/functions/fnc_dev_switchUnitHandle.sqf create mode 100644 addons/frag/functions/fnc_dev_trackHitBox.sqf create mode 100644 addons/frag/functions/fnc_dev_trackObj.sqf delete mode 100644 addons/frag/functions/fnc_dev_trackTrace.sqf create mode 100644 addons/frag/functions/fnc_doFrag.sqf create mode 100644 addons/frag/functions/fnc_doFragRandom.sqf create mode 100644 addons/frag/functions/fnc_doFragTargeted.sqf create mode 100644 addons/frag/functions/fnc_doSpallMomentum.sqf create mode 100644 addons/frag/functions/fnc_fragInfo.sqf delete mode 100644 addons/frag/functions/fnc_frago.sqf create mode 100644 addons/frag/functions/fnc_initBlackList.sqf delete mode 100644 addons/frag/functions/fnc_masterPFH.sqf delete mode 100644 addons/frag/functions/fnc_pfhRound.sqf create mode 100644 addons/frag/functions/fnc_shouldFrag.sqf create mode 100644 addons/frag/functions/fnc_shouldSpall.sqf delete mode 100644 addons/frag/functions/fnc_spallHP.sqf delete mode 100644 addons/frag/functions/fnc_spallTrack.sqf create mode 100644 addons/frag/functions/fnc_submunition.sqf create mode 100644 addons/frag/functions/script_component.hpp diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index eb524e5c184..1cebe063740 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -10,7 +10,7 @@ class CfgAmmo { GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; - GVAR(fragCount) = 17500; + GVAR(fragCount) = 17500; GVAR(metal) = 140000; GVAR(charge) = 87000; GVAR(gurney_c) = 2320; @@ -20,7 +20,7 @@ class CfgAmmo { GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large ), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; - GVAR(fragCount) = 17500; + GVAR(fragCount) = 17500; GVAR(metal) = 140000; GVAR(charge) = 87000; GVAR(gurney_c) = 2320; @@ -31,7 +31,7 @@ class CfgAmmo { GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; - GVAR(fragCount) = 17500; + GVAR(fragCount) = 17500; GVAR(metal) = 140000; GVAR(charge) = 87000; GVAR(gurney_c) = 2320; @@ -51,7 +51,7 @@ class CfgAmmo { individual grenades. */ GVAR(classes)[] = {QGVAR(tiny)}; - GVAR(fragCount) = 1000; + GVAR(fragCount) = 1000; GVAR(metal) = 210; // metal in grams GVAR(charge) = 185; // explosive in grams GVAR(gurney_c) = 2843; // Gurney velocity constant for explosive type. See: http://en.wikipedia.org/wiki/Gurney_equations @@ -69,7 +69,7 @@ class CfgAmmo { GVAR(force) = 1; GVAR(classes)[] = {QGVAR(small)}; - GVAR(fragCount) = 800; // guess based on probability hit of 1% + GVAR(fragCount) = 800; // guess based on probability hit of 1% GVAR(metal) = 200; GVAR(charge) = 32; GVAR(gurney_c) = 2700; @@ -80,7 +80,7 @@ class CfgAmmo { GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(small_HD)}; - GVAR(fragCount) = 270; // seems to have greater framentation ability, but lower range per source + GVAR(fragCount) = 270; // seems to have greater framentation ability, but lower range per source GVAR(metal) = 200; GVAR(charge) = 45; GVAR(gurney_c) = 2830; @@ -94,7 +94,7 @@ class CfgAmmo { GVAR(force) = 0; EGVAR(vehicle_damage,incendiary) = 0; }; - // What is this even? + // What is this even? class ACE_G40mm_HE_VOG25P: G_40mm_HE { GVAR(skip) = 0; GVAR(force) = 1; @@ -106,7 +106,7 @@ class CfgAmmo { class R_PG32V_F; class R_TBG32V_F: R_PG32V_F { // Thermobaric GVAR(enabled) = 1; - GVAR(fragCount) = 200; + GVAR(fragCount) = 200; GVAR(metal) = 400; GVAR(charge) = 210; GVAR(gurney_c) = 2800; @@ -121,7 +121,7 @@ class CfgAmmo { }; class M_Titan_AP: M_Titan_AT { // "anti personnel" GVAR(skip) = 0; - GVAR(fragCount) = 800; // guesstimate / provides ~80 m frag range + GVAR(fragCount) = 800; // guesstimate / provides ~80 m frag range GVAR(enabled) = 1; GVAR(metal) = 400; GVAR(charge) = 210; @@ -135,7 +135,7 @@ class CfgAmmo { class R_MRAAWS_HEAT_F; class R_MRAAWS_HE_F: R_MRAAWS_HEAT_F { GVAR(enabled) = 1; - GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) + GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) GVAR(metal) = 2300; GVAR(charge) = 590; GVAR(gurney_c) = 2800; @@ -151,7 +151,7 @@ class CfgAmmo { GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) + GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) GVAR(metal) = 3850; GVAR(charge) = 1040; GVAR(gurney_c) = 2700; @@ -166,7 +166,7 @@ class CfgAmmo { GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 1600; // guesstimate / provides ~112 m frag range (1% chance to hit) + GVAR(fragCount) = 1600; // guesstimate / provides ~112 m frag range (1% chance to hit) GVAR(metal) = 56250; GVAR(charge) = 39000; GVAR(gurney_c) = 2700; @@ -175,7 +175,7 @@ class CfgAmmo { class Rocket_04_HE_F: MissileBase { // Shrieker (Hydra 70) GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) + GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) GVAR(metal) = 3850; GVAR(charge) = 1040; GVAR(gurney_c) = 2700; @@ -184,7 +184,7 @@ class CfgAmmo { class M_Scalpel_AT: MissileBase { // 9K121 Vikhr GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 800; // guesstimate based on frag jacket, provides ~80 m frag range (1% chance to hit) + GVAR(fragCount) = 800; // guesstimate based on frag jacket, provides ~80 m frag range (1% chance to hit) GVAR(metal) = 10000; GVAR(charge) = 3000; GVAR(gurney_c) = 2700; @@ -195,7 +195,7 @@ class CfgAmmo { GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 350; // guesstimate based on frag jacket, provides ~50 m frag range (1% chance to hit) + GVAR(fragCount) = 350; // guesstimate based on frag jacket, provides ~50 m frag range (1% chance to hit) GVAR(metal) = 8000; GVAR(charge) = 2400; GVAR(gurney_c) = 2700; @@ -216,18 +216,18 @@ class CfgAmmo { GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; - GVAR(fragCount) = 3250; // http://18.195.19.6/bitstream/handle/20.500.12242/1200/15-01916.pdf?sequence=1&isAllowed=y + GVAR(fragCount) = 3250; // http://18.195.19.6/bitstream/handle/20.500.12242/1200/15-01916.pdf?sequence=1&isAllowed=y GVAR(metal) = 36000; GVAR(charge) = 9979; GVAR(gurney_c) = 2440; GVAR(gurney_k) = "1/2"; }; class Sh_82mm_AMOS: Sh_155mm_AMOS { - //http://65.175.100.54/uxofiles/mulvaney/techdatasheets/81mm-HE-M821.pdf + //http://65.175.100.54/uxofiles/mulvaney/techdatasheets/81mm-HE-M821.pdf GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 1600; // based on mass and fragment energy/count + GVAR(fragCount) = 1600; // based on mass and fragment energy/count GVAR(metal) = 2500; GVAR(charge) = 726; GVAR(gurney_c) = 2440; @@ -246,7 +246,7 @@ class CfgAmmo { GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 1600; // based on mass and fragment energy/count + GVAR(fragCount) = 1600; // based on mass and fragment energy/count GVAR(metal) = 11400; GVAR(charge) = 7100; GVAR(gurney_c) = 2800; @@ -256,7 +256,7 @@ class CfgAmmo { GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 2000; + GVAR(fragCount) = 2000; GVAR(metal) = 23000; GVAR(charge) = 3148; GVAR(gurney_c) = 2830; @@ -280,18 +280,18 @@ class CfgAmmo { GVAR(gurney_c) = 2320; GVAR(gurney_k) = "1/2"; }; - // Special - class Default; - class Laserbeam : Default { - GVAR(skip) = 1; - }; + // Special + class Default; + class Laserbeam : Default { + GVAR(skip) = 1; + }; class B_65x39_Caseless; class GVAR(base): B_65x39_Caseless { ACE_damageType = "grenade"; // compatibility with medical_damage, shrapnel should produce grenade wounds timeToLive = 4; typicalSpeed = 800; - maxSpeed = 1500; + maxSpeed = 1500; deflecting = 65; }; @@ -380,522 +380,522 @@ class CfgAmmo { }; - // format fragType_spawn_n_range - /********************* ***************************/ + // format fragType_spawn_n_range + /********************* ***************************/ class GVAR(spawnbase) : B_65x39_Caseless { access = 2; deleteParentWhenTriggered = 1; - submunitionConeType[] = {"random", 25}; - submunitionAmmo[] = {QGVAR(tiny), 3, QGVAR(tiny_HD), 3, QGVAR(small), 4, QGVAR(small_HD), 4, QGVAR(medium_HD), 5}; + submunitionConeType[] = {"random", 25}; + submunitionAmmo[] = {QGVAR(tiny), 3, QGVAR(tiny_HD), 3, QGVAR(small), 4, QGVAR(small_HD), 4, QGVAR(medium_HD), 5}; submunitionDirectionType = "SubmunitionModelDirection"; - submunitionConeAngleHorizontal = 15; - submunitionConeAngle = 87; + submunitionConeAngleHorizontal = 15; + submunitionConeAngle = 87; submunitionInitialOffset[] = {0,0,0}; - submunitionInitSpeed = 1000; - submunitionParentSpeedCoef = 1; - triggerSpeedCoef[] = {0.75, 1.5}; + submunitionInitSpeed = 1000; + submunitionParentSpeedCoef = 1; + triggerSpeedCoef[] = {0.75, 1.5}; triggerTime = 0; - }; - - /********************* ***************************/ - class GVAR(def_10) : GVAR(spawnbase) { - submunitionConeType[] = {"random", 10}; - }; - class GVAR(def_10_lo) : GVAR(def_10) { - submunitionConeAngle = 85; - }; - class GVAR(def_10_mid) : GVAR(def_10) { - submunitionConeAngle = 85; - triggerSpeedCoef[] = {-1.5, 1.5}; - }; - class GVAR(def_10_hi) : GVAR(def_10) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - class GVAR(def_10_top) : GVAR(def_10) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - - /********************* ***************************/ - class GVAR(def_15) : GVAR(spawnbase) { - submunitionConeType[] = {"random", 15}; - }; - class GVAR(def_15_lo) : GVAR(def_15) { - submunitionConeAngle = 85; - }; - class GVAR(def_15_mid) : GVAR(def_15) { - submunitionConeAngle = 85; - triggerSpeedCoef[] = {-1.5, 1.5}; - }; - class GVAR(def_15_hi) : GVAR(def_15) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - class GVAR(def_15_top) : GVAR(def_15) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - - /********************* ***************************/ - class GVAR(def_5) : GVAR(spawnbase) { - submunitionConeType[] = {"random", 5}; - }; - class GVAR(def_5_lo) : GVAR(def_5) { - submunitionConeAngle = 85; - }; - class GVAR(def_5_mid) : GVAR(def_5) { - submunitionConeAngle = 85; - triggerSpeedCoef[] = {-1.5, 1.5}; - }; - class GVAR(def_5_hi) : GVAR(def_5) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - class GVAR(def_5_top) : GVAR(def_5) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - - /********************* ***************************/ - class GVAR(def_tiny_15) : GVAR(spawnbase) { - submunitionConeType[] = {"random", 15}; - submunitionAmmo = QGVAR(tiny); - }; - class GVAR(def_tiny_15_lo) : GVAR(def_tiny_15) { - submunitionConeAngle = 85; - }; - class GVAR(def_tiny_15_mid) : GVAR(def_tiny_15) { - submunitionConeAngle = 85; - triggerSpeedCoef[] = {-1.5, 1.5}; - }; - class GVAR(def_tiny_15_hi) : GVAR(def_tiny_15) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - class GVAR(def_tiny_15_top) : GVAR(def_tiny_15) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - - /********************* ***************************/ - class GVAR(def_tiny_10) : GVAR(spawnbase) { - submunitionConeType[] = {"random", 10}; - submunitionAmmo = QGVAR(tiny); - }; - class GVAR(def_tiny_10_lo) : GVAR(def_tiny_10) { - submunitionConeAngle = 85; - }; - class GVAR(def_tiny_10_mid) : GVAR(def_tiny_10) { - submunitionConeAngle = 85; - triggerSpeedCoef[] = {-1.5, 1.5}; - }; - class GVAR(def_tiny_10_hi) : GVAR(def_tiny_10) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - class GVAR(def_tiny_10_top) : GVAR(def_tiny_10) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - - /********************* ***************************/ - class GVAR(def_tiny_5) : GVAR(spawnbase) { - submunitionConeType[] = {"random", 5}; - submunitionAmmo = QGVAR(tiny); - }; - class GVAR(def_tiny_5_lo) : GVAR(def_tiny_5) { - submunitionConeAngle = 85; - }; - class GVAR(def_tiny_5_mid) : GVAR(def_tiny_5) { - submunitionConeAngle = 85; - triggerSpeedCoef[] = {-1.5, 1.5}; - }; - class GVAR(def_tiny_5_hi) : GVAR(def_tiny_5) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - class GVAR(def_tiny_5_top) : GVAR(def_tiny_5) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - /********************* ***************************/ - class GVAR(def_small_15) : GVAR(spawnbase) { - submunitionConeType[] = {"random", 15}; - submunitionAmmo = QGVAR(small); - }; - class GVAR(def_small_15_lo) : GVAR(def_small_15) { - submunitionConeAngle = 815; - }; - class GVAR(def_small_15_mid) : GVAR(def_small_15) { - submunitionConeAngle = 815; - triggerSpeedCoef[] = {-1.15, 1.15}; - }; - class GVAR(def_small_15_hi) : GVAR(def_small_15) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.15, -0.715}; - }; - class GVAR(def_small_15_top) : GVAR(def_small_15) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.15, -0.715}; - }; - /********************* ***************************/ - class GVAR(def_small_10) : GVAR(spawnbase) { - submunitionConeType[] = {"random", 10}; - submunitionAmmo = QGVAR(small); - }; - class GVAR(def_small_10_lo) : GVAR(def_small_10) { - submunitionConeAngle = 810; - }; - class GVAR(def_small_10_mid) : GVAR(def_small_10) { - submunitionConeAngle = 810; - triggerSpeedCoef[] = {-1.10, 1.10}; - }; - class GVAR(def_small_10_hi) : GVAR(def_small_10) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.10, -0.710}; - }; - class GVAR(def_small_10_top) : GVAR(def_small_10) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.10, -0.710}; - }; - /********************* ***************************/ - class GVAR(def_small_5) : GVAR(spawnbase) { - submunitionConeType[] = {"random", 5}; - submunitionAmmo = QGVAR(small); - }; - class GVAR(def_small_5_lo) : GVAR(def_small_5) { - submunitionConeAngle = 85; - }; - class GVAR(def_small_5_mid) : GVAR(def_small_5) { - submunitionConeAngle = 85; - triggerSpeedCoef[] = {-1.5, 1.5}; - }; - class GVAR(def_small_5_hi) : GVAR(def_small_5) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - class GVAR(def_small_5_top) : GVAR(def_small_5) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - - /******************* targeted fragments ********************/ - class GVAR(spawnbase_targeted) : GVAR(spawnbase) { + }; + + /********************* ***************************/ + class GVAR(def_10) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 10}; + }; + class GVAR(def_10_lo) : GVAR(def_10) { + submunitionConeAngle = 85; + }; + class GVAR(def_10_mid) : GVAR(def_10) { + submunitionConeAngle = 85; + triggerSpeedCoef[] = {-1.5, 1.5}; + }; + class GVAR(def_10_hi) : GVAR(def_10) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + class GVAR(def_10_top) : GVAR(def_10) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + + /********************* ***************************/ + class GVAR(def_15) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 15}; + }; + class GVAR(def_15_lo) : GVAR(def_15) { + submunitionConeAngle = 85; + }; + class GVAR(def_15_mid) : GVAR(def_15) { + submunitionConeAngle = 85; + triggerSpeedCoef[] = {-1.5, 1.5}; + }; + class GVAR(def_15_hi) : GVAR(def_15) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + class GVAR(def_15_top) : GVAR(def_15) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + + /********************* ***************************/ + class GVAR(def_5) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 5}; + }; + class GVAR(def_5_lo) : GVAR(def_5) { + submunitionConeAngle = 85; + }; + class GVAR(def_5_mid) : GVAR(def_5) { + submunitionConeAngle = 85; + triggerSpeedCoef[] = {-1.5, 1.5}; + }; + class GVAR(def_5_hi) : GVAR(def_5) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + class GVAR(def_5_top) : GVAR(def_5) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + + /********************* ***************************/ + class GVAR(def_tiny_15) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 15}; + submunitionAmmo = QGVAR(tiny); + }; + class GVAR(def_tiny_15_lo) : GVAR(def_tiny_15) { + submunitionConeAngle = 85; + }; + class GVAR(def_tiny_15_mid) : GVAR(def_tiny_15) { + submunitionConeAngle = 85; + triggerSpeedCoef[] = {-1.5, 1.5}; + }; + class GVAR(def_tiny_15_hi) : GVAR(def_tiny_15) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + class GVAR(def_tiny_15_top) : GVAR(def_tiny_15) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + + /********************* ***************************/ + class GVAR(def_tiny_10) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 10}; + submunitionAmmo = QGVAR(tiny); + }; + class GVAR(def_tiny_10_lo) : GVAR(def_tiny_10) { + submunitionConeAngle = 85; + }; + class GVAR(def_tiny_10_mid) : GVAR(def_tiny_10) { + submunitionConeAngle = 85; + triggerSpeedCoef[] = {-1.5, 1.5}; + }; + class GVAR(def_tiny_10_hi) : GVAR(def_tiny_10) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + class GVAR(def_tiny_10_top) : GVAR(def_tiny_10) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + + /********************* ***************************/ + class GVAR(def_tiny_5) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 5}; + submunitionAmmo = QGVAR(tiny); + }; + class GVAR(def_tiny_5_lo) : GVAR(def_tiny_5) { + submunitionConeAngle = 85; + }; + class GVAR(def_tiny_5_mid) : GVAR(def_tiny_5) { + submunitionConeAngle = 85; + triggerSpeedCoef[] = {-1.5, 1.5}; + }; + class GVAR(def_tiny_5_hi) : GVAR(def_tiny_5) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + class GVAR(def_tiny_5_top) : GVAR(def_tiny_5) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + /********************* ***************************/ + class GVAR(def_small_15) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 15}; + submunitionAmmo = QGVAR(small); + }; + class GVAR(def_small_15_lo) : GVAR(def_small_15) { + submunitionConeAngle = 815; + }; + class GVAR(def_small_15_mid) : GVAR(def_small_15) { + submunitionConeAngle = 815; + triggerSpeedCoef[] = {-1.15, 1.15}; + }; + class GVAR(def_small_15_hi) : GVAR(def_small_15) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.15, -0.715}; + }; + class GVAR(def_small_15_top) : GVAR(def_small_15) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.15, -0.715}; + }; + /********************* ***************************/ + class GVAR(def_small_10) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 10}; + submunitionAmmo = QGVAR(small); + }; + class GVAR(def_small_10_lo) : GVAR(def_small_10) { + submunitionConeAngle = 810; + }; + class GVAR(def_small_10_mid) : GVAR(def_small_10) { + submunitionConeAngle = 810; + triggerSpeedCoef[] = {-1.10, 1.10}; + }; + class GVAR(def_small_10_hi) : GVAR(def_small_10) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.10, -0.710}; + }; + class GVAR(def_small_10_top) : GVAR(def_small_10) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.10, -0.710}; + }; + /********************* ***************************/ + class GVAR(def_small_5) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 5}; + submunitionAmmo = QGVAR(small); + }; + class GVAR(def_small_5_lo) : GVAR(def_small_5) { + submunitionConeAngle = 85; + }; + class GVAR(def_small_5_mid) : GVAR(def_small_5) { + submunitionConeAngle = 85; + triggerSpeedCoef[] = {-1.5, 1.5}; + }; + class GVAR(def_small_5_hi) : GVAR(def_small_5) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + class GVAR(def_small_5_top) : GVAR(def_small_5) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.5, -0.75}; + }; + + /******************* targeted fragments ********************/ + class GVAR(spawnbase_targeted) : GVAR(spawnbase) { access = 2; - submunitionConeType[] = {"random", 2}; - submunitionConeAngle = 2; - submunitionInitSpeed = 0; - triggerSpeedCoef[] = {0.5, 1}; - }; - - class GVAR(tiny_spawner_2_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(tiny_spawner_2_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(tiny_spawner_2_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(tiny_spawner_3_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(tiny_spawner_3_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(tiny_spawner_3_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; - }; - - class GVAR(tiny_HD_spawner_2_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(tiny_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(tiny_HD_spawner_2_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(tiny_HD_spawner_3_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(tiny_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(tiny_HD_spawner_3_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; - }; - - class GVAR(small_spawner_2_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(small_spawner_2_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(small_spawner_2_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(small_spawner_3_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(small_spawner_3_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(small_spawner_3_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; - }; - - class GVAR(small_HD_spawner_2_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(small_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(small_HD_spawner_2_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(small_HD_spawner_3_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(small_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(small_HD_spawner_3_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; - }; - - class GVAR(medium_spawner_2_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(medium_spawner_2_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(medium_spawner_2_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(medium_spawner_3_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(medium_spawner_3_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(medium_spawner_3_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; - }; - - class GVAR(medium_HD_spawner_2_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(medium_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(medium_HD_spawner_2_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(medium_HD_spawner_3_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(medium_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(medium_HD_spawner_3_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; - }; - - class GVAR(large_spawner_2_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(large_spawner_2_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(large_spawner_2_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(large_spawner_3_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(large_spawner_3_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(large_spawner_3_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; - }; - - class GVAR(large_HD_spawner_2_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(large_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(large_HD_spawner_2_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(large_HD_spawner_3_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(large_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(large_HD_spawner_3_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; - }; - - class GVAR(huge_spawner_2_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(huge_spawner_2_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(huge_spawner_2_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(huge_spawner_3_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(huge_spawner_3_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(huge_spawner_3_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; - }; - - class GVAR(huge_HD_spawner_2_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(huge_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(huge_HD_spawner_2_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(huge_HD_spawner_3_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(huge_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(huge_HD_spawner_3_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; - }; + submunitionConeType[] = {"random", 2}; + submunitionConeAngle = 2; + submunitionInitSpeed = 0; + triggerSpeedCoef[] = {0.5, 1}; + }; + + class GVAR(tiny_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(tiny_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(tiny_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(tiny_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(tiny_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(tiny_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; + }; + + class GVAR(tiny_HD_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(tiny_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(tiny_HD_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(tiny_HD_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(tiny_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(tiny_HD_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; + }; + + class GVAR(small_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(small_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(small_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(small_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(small_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(small_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; + }; + + class GVAR(small_HD_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(small_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(small_HD_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(small_HD_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(small_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(small_HD_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; + }; + + class GVAR(medium_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(medium_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(medium_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(medium_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(medium_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(medium_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; + }; + + class GVAR(medium_HD_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(medium_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(medium_HD_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(medium_HD_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(medium_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(medium_HD_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; + }; + + class GVAR(large_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(large_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(large_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(large_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(large_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(large_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; + }; + + class GVAR(large_HD_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(large_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(large_HD_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(large_HD_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(large_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(large_HD_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; + }; + + class GVAR(huge_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(huge_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(huge_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(huge_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(huge_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(huge_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; + }; + + class GVAR(huge_HD_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(huge_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(huge_HD_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; + }; + class GVAR(huge_HD_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(huge_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; + }; + class GVAR(huge_HD_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; + }; }; \ No newline at end of file diff --git a/addons/frag/XEH_PREP.hpp b/addons/frag/XEH_PREP.hpp index a7fb8ff8c34..d46ebd25aba 100644 --- a/addons/frag/XEH_PREP.hpp +++ b/addons/frag/XEH_PREP.hpp @@ -1,23 +1,33 @@ +// dev +PREP(dev_fragCalcDump); PREP(dev_debugAmmo); +PREP(dev_trackHitBox); +PREP(dev_fadeRound); +PREP(dev_sphereDraw); +PREP(dev_addRound); +PREP(dev_trackObj); +PREP(dev_drawTrace); +PREP(dev_clearTraces); +PREP(dev_switchUnitHandle); -PREP(doSpall); +// Frag +PREP(addBlackList); +PREP(initBlackList); PREP(fired); -PREP(frago); -PREP(spallTrack); +PREP(submunition); +PREP(shouldFrag); +PREP(fragInfo); +PREP(doFrag); +PREP(doFragTargeted); +PREP(doFragRandom); -// * Other */ -PREP(addBlackList); -PREP(dev_addTrack); -PREP(dev_drawTraces); -PREP(spallHP); -PREP(dev_startTracing); -PREP(dev_stopTracing); -PREP(dev_trackTrace); +// Spall +PREP(shouldSpall); +PREP(doSpall); +PREP(doSpallMomentum); -// New tracking mechanisms -PREP(masterPFH); -PREP(pfhRound); -PREP(addPfhRound); +// * Other */ +//PREP(spallHP); Look at me !*! // Explosive Reflection PREP(findReflections); diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index ecebd793ce1..94b2247e94d 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -1,32 +1,39 @@ #include "script_component.hpp" -if (isServer) then { - GVAR(lastFragTime) = -1; - [QGVAR(frag_eh), {_this call FUNC(frago);}] call CBA_fnc_addEventHandler; -}; - ["CBA_settingsInitialized", { - if (!GVAR(enabled)) exitWith {}; - - // Register fire event handler - ["ace_firedPlayer", LINKFUNC(fired)] call CBA_fnc_addEventHandler; - ["ace_firedNonPlayer", LINKFUNC(fired)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler; - ["ace_firedNonPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler; - - addMissionEventHandler ["EachFrame", {call FUNC(masterPFH)}]; + if (isServer) then { + [QGVAR(frag_eh), LINKFUNC(doFrag)] call CBA_fnc_addEventHandler; + [QGVAR(spall_eh), LINKFUNC(doFragMomentum)] call CBA_fnc_addEventHandler; + [] call FUNC(initBlackList); + }; + + if (hasInterface) then { + ["ace_firedPlayer", LINKFUNC(fired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler; + }; + + ["ace_firedNonPlayer", LINKFUNC(fired)] call CBA_fnc_addEventHandler; + ["ace_firedNonPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler; + + // Debug info +#ifdef DEBUG_MODE_FULL + if (hasInterface && GVAR(debugOptions)) then + { + private _h = [LINKFUNC(dev_drawTrace), 0] call CBA_fnc_addPerFrameHandler; + missionNamespace setVariable [QGVAR(dev_drawPFEH), _h]; + ["unit", LINKFUNC(dev_switchUnitHandle), true] call CBA_fnc_addPlayerEventHandler; + [objNull, ace_player] call FUNC(dev_switchUnitHandle); + ["ace_firedPlayer", LINKFUNC(fired)] call CBA_fnc_addEventHandler; + ["ace_firedNonPlayer", LINKFUNC(fired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler; + ["ace_firedNonPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler; + }; +#endif }] call CBA_fnc_addEventHandler; -// Cache for ammo type configs -GVAR(cacheRoundsTypesToTrack) = [false] call CBA_fnc_createNamespace; - // Debug stuff: -#ifdef DRAW_FRAG_INFO -[] call FUNC(dev_startTracing); -#endif - -#ifdef DEBUG_MODE_FULL +#ifdef LOG_FRAG_INFO [true, true, 30] call FUNC(dev_debugAmmo); #endif diff --git a/addons/frag/XEH_preInit.sqf b/addons/frag/XEH_preInit.sqf index dc616917b88..d857a1930b5 100644 --- a/addons/frag/XEH_preInit.sqf +++ b/addons/frag/XEH_preInit.sqf @@ -6,20 +6,24 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -GVAR(blackList) = []; -GVAR(traceFrags) = false; -GVAR(spallHPData) = []; -GVAR(spallIsTrackingCount) = 0; +GVAR(materialSpallCache) = createHashMap; +GVAR(spallRoundCache) = createHashMap; -GVAR(traceID) = -1; -GVAR(traces) = []; -GVAR(tracesStarted) = false; +GVAR(shouldFragCache) = createHashMap; +GVAR(fragInfoCache) = createHashMap; +GVAR(lastFragTime) = -2; -GVAR(lastIterationIndex) = 0; -GVAR(objects) = []; -GVAR(arguments) = []; #include "initSettings.inc.sqf" +#ifdef DEBUG_MODE_FULL +GVAR(dev_trackLines) = createHashMap; +GVAR(dev_hitBoxes) = createHashMap; +GVAR(dev_failedToDelete) = 0; +GVAR(dev_eventSpheres) = []; +#include "initSettingsDebug.inc.sqf" +#endif + + ADDON = true; diff --git a/addons/frag/functions/fnc_addBlackList.sqf b/addons/frag/functions/fnc_addBlackList.sqf index d0cc127d059..d9c3d8054d7 100644 --- a/addons/frag/functions/fnc_addBlackList.sqf +++ b/addons/frag/functions/fnc_addBlackList.sqf @@ -1,6 +1,6 @@ -#include "..\script_component.hpp" +#include "script_component.hpp" /* - * Author: Jaynus, NouberNou + * Author: Jaynus, NouberNou, Lambda.Tiger * Adds a round to the blacklist (will be ignored). * * Arguments: @@ -10,12 +10,12 @@ * None * * Example: - * [bullet] call ace_frag_fnc_addBlackList + * [projectile] call ace_frag_fnc_addBlackList * * Public: No */ -params ["_round"]; +params ["_proj"]; TRACE_1("addBlackList",_round); -GVAR(blackList) pushBack _round; +GVAR(shouldFragCache) set [typeOf _ammo, [false, false]]; diff --git a/addons/frag/functions/fnc_addPfhRound.sqf b/addons/frag/functions/fnc_addPfhRound.sqf deleted file mode 100644 index 7c2b5d16810..00000000000 --- a/addons/frag/functions/fnc_addPfhRound.sqf +++ /dev/null @@ -1,77 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: Jaynus, NouberNou - * Starts tracking a round that will frag. - * Should only be called once per round. - * - * Arguments: - * 0: Shooter - * 1: Ammo classname - * 2: Projectile - * - * Return Value: - * None - * - * Example: - * [player, "handGrenade", bullet] call ace_frag_fnc_addPfhRound - * - * Public: No - */ - -params ["_gun", "_type", "_round"]; -TRACE_3("addPfhRound",_gun,_type,_round); - -if (!GVAR(enabled)) exitWith {TRACE_1("setting disabled",_this);}; - -if (!alive _round) exitWith {TRACE_1("round dead?",_this);}; - -if (_round in GVAR(blackList)) exitWith { - TRACE_1("round in blackList",_this); - REM(GVAR(blackList),_round); -}; - -// Exit on max track -if ((count GVAR(objects)) >= GVAR(maxTrack)) exitWith {TRACE_1("maxTrack limit",count GVAR(objects));}; - -private _doSpall = false; -if (GVAR(SpallEnabled)) then { - if (GVAR(spallIsTrackingCount) <= 0) then { - GVAR(spallHPData) = []; - }; - if (GVAR(spallIsTrackingCount) > 5) then { - TRACE_1("At Spall Limit",GVAR(spallIsTrackingCount)); - } else { - _doSpall = true; - INC(GVAR(spallIsTrackingCount)); - }; - TRACE_2("",_doSpall,GVAR(spallIsTrackingCount)); -}; - -#ifdef DRAW_FRAG_INFO -[ACE_player, _round, [0, 1, 0, 1]] call FUNC(dev_addTrack); -#endif - -// We only do the single track object check here. -// We should do an {!(_round in GVAR(objects))} -// But we leave that out here for optimization. So this cannot be a framework function -// Otherwise, it should only be added once and from the FiredEH -if (alive _round) then { - private _spallTrack = []; - private _spallTrackID = []; - - private _args = [ - _round, getPosASL _round, velocity _round, _type, diag_frameno, getPosASL _round, _doSpall, _spallTrack, _spallTrackID, - getNumber (configFile >> "CfgAmmo" >> _type >> QGVAR(skip)), - getNumber (configFile >> "CfgAmmo" >> _type >> "explosive"), - getNumber (configFile >> "CfgAmmo" >> _type >> "indirectHitRange"), - getNumber (configFile >> "CfgAmmo" >> _type >> QGVAR(force)), - getNumber (configFile >> "CfgAmmo" >> _type >> "indirecthit") * (sqrt (getNumber (configFile >> "CfgAmmo" >> _type >> "indirectHitRange"))) - ]; - TRACE_1("Initializing track", _round); - GVAR(objects) pushBack _round; - GVAR(arguments) pushBack _args; - - if (_doSpall) then { - [_round, 1, _spallTrack, _spallTrackID] call FUNC(spallTrack); - }; -}; diff --git a/addons/frag/functions/fnc_dev_addRound.sqf b/addons/frag/functions/fnc_dev_addRound.sqf new file mode 100644 index 00000000000..72cb344fc8d --- /dev/null +++ b/addons/frag/functions/fnc_dev_addRound.sqf @@ -0,0 +1,114 @@ +#include "script_component.hpp" +/* + * Author: Lambda.Tiger + * This function adds a round to be traced + * + * Arguments: + * 0: Projectile + * 1: Add projectile event handlers + * 2: Is the round blue + * + * Return Value: + * None + * + * Example: + * [_proj, false, false] call ace_frag_dev_addRound; + * + * Public: No + */ +params [ + "_proj", + ["_addEHs", true, [false]], + ["_sidePlayer", true, [false]] +]; + +/// track round on each frame +// Create entry in position array from hashmap +private _pID = getObjectID _proj; +if (GVAR(fadeRounds)) then +{ + if (_sidePlayer) then + { + GVAR(dev_trackLines) set [_pID, [__FADE_INIT, [getposATL _proj], [0, 0, 1, __FADE_INIT]]]; + } else + { + GVAR(dev_trackLines) set [_pID, [__FADE_INIT, [getposATL _proj], [1, 0.5, 0, __FADE_INIT]]]; + }; + + // add fading factor + [LINKFUNC(dev_fadeRound), __FADE_INTERVAL, [_pID]] call CBA_fnc_addPerFrameHandler; +} else +{ + if (_sidePlayer) then + { + GVAR(dev_trackLines) set [_pID, [1, [getposATL _proj], [0, 0, 1, 1]]]; + } else + { + GVAR(dev_trackLines) set [_pID, [1, [getposATL _proj], [1, 0, 0, 1]]]; + }; +}; +// eventhandler to track round and cleanup when round is "dead" +[ + { + if (isGamePaused) exitWith {}; + params ["_par", "_h"]; + _par params ["_proj"]; + if (!alive _proj) exitWith + { + [_h] call CBA_fnc_removePerFrameHandler; + }; + private _arr = GVAR(dev_trackLines) getOrDefault [(getObjectID _proj), -1]; + if (typeName _arr == "SCALAR") exitWith {}; + (_arr#1) pushBack getPosATL _proj; + if (_arr#0 <= 0) exitWith + { + [_h] call CBA_fnc_removePerFrameHandler; + }; + }, + 0, + [_proj] +] call CBA_fnc_addPerFrameHandler; + +if (!_addEHs) exitWith {}; + +// Add hitpart eventHandler +_proj addEventHandler [ + "HitPart", + { + params ["_proj", "", "", "_posASL"]; + private _arr = (GVAR(dev_trackLines) get (getObjectID _proj))#1; + _arr pushBack ASLtoATL _posASL; + if (GVAR(dbgSphere)) then + { + [_posASL, "green"] call FUNC(dev_sphereDraw); + }; + } +]; + +// Add explode eventHandler +_proj addEventHandler [ + "Explode", + { + params ["_proj", "_posASL"]; + private _arr = (GVAR(dev_trackLines) get (getObjectID _proj))#1; + _arr pushBack ASLtoATL _posASL; + if (GVAR(dbgSphere)) then + { + [_posASL, "red"] call FUNC(dev_sphereDraw); + }; + } +]; + +// Add deflected eventHandler +_proj addEventHandler [ + "Deflected", + { + params ["_proj", "_posASL"]; + private _arr = (GVAR(dev_trackLines) get (getObjectID _proj))#1; + _arr pushBack ASLtoATL _posASL; + if (GVAR(dbgSphere)) then + { + [_posASL, "blue"] call FUNC(dev_sphereDraw); + }; + } +]; \ No newline at end of file diff --git a/addons/frag/functions/fnc_dev_addTrack.sqf b/addons/frag/functions/fnc_dev_addTrack.sqf deleted file mode 100644 index 0e75a9fb994..00000000000 --- a/addons/frag/functions/fnc_dev_addTrack.sqf +++ /dev/null @@ -1,26 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: ACE-Team - * - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_frag_fnc_dev_addTrack - * - * Public: No - */ - -params ["_origin", "_obj", ["_color", [1, 0, 0, 1]]]; - -private _positions = []; -private _objSpd = vectorMagnitude (velocity _obj); -_positions pushBack [getPos _obj, _objSpd]; -private _data = [_origin, typeOf _origin, typeOf _obj, _objSpd, _positions, _color]; - -private _index = GVAR(traces) pushBack _data; -[DFUNC(dev_trackTrace), 0, [_obj, _index, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/frag/functions/fnc_dev_clearTraces.sqf b/addons/frag/functions/fnc_dev_clearTraces.sqf new file mode 100644 index 00000000000..eabdeaeb314 --- /dev/null +++ b/addons/frag/functions/fnc_dev_clearTraces.sqf @@ -0,0 +1,24 @@ +#include "script_component.hpp" +/* + * Author: Lambda.Tiger + * Cleares all dev spheres and traces + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ace_frag_fnc_dev_clearTraces; + * + * Public: No + */ +GVAR(dev_trackLines) = createHashMap; +for "_i" from 0 to count GVAR(dev_eventSpheres) - 1 do +{ + deleteVehicle (GVAR(dev_eventSpheres)#_i); +}; +GVAR(dev_eventSpheres) = +[]; + +GVAR(dev_hitBoxes) = createHashMap; \ No newline at end of file diff --git a/addons/frag/functions/fnc_dev_drawTrace.sqf b/addons/frag/functions/fnc_dev_drawTrace.sqf new file mode 100644 index 00000000000..c7ff03b13f2 --- /dev/null +++ b/addons/frag/functions/fnc_dev_drawTrace.sqf @@ -0,0 +1,75 @@ +#include "script_component.hpp" +/* + * Author: Lambda.Tiger + * Per frame function to draw all dev traces + * + * Arguments: + * none + * + * Return Value: + * None + * + * Example: + * + * Public: No + */ + +private _deleteArr = []; +{ + private _alpha = _y#0; + // leave if trace is not to be drawn + if (GVAR(dltTrace) && _alpha <= 0) then + { + _deleteArr pushBack _x; + continue; + }; + + if (count (_y#1) > 1) then + { + private _color = _y#2; + for "_j" from 1 to count (_y#1) - 1 do + { + drawLine3D [_y#1#(_j-1), _y#1#_j, _color]; + }; + }; +} forEach GVAR(dev_trackLines); + +if (GVAR(dltTrace)) then +{ + for "_i" from 0 to count _deleteArr - 1 do + { + GVAR(dev_trackLines) deleteAt (_deleteArr#_i); + }; +}; + +if (GVAR(drawHitBox)) then { + + #define HB_DRAW_ARRS [[3,2,1,5,6,7,3,0,4,5],[0,1],[2,6],[7,4]] + _deleteArr = []; + { + _y params ["_obj", "_pts", "_color"]; + if (!alive _obj) then + { + _deleteArr pushBack _x; + continue; + }; + + { + for "_i" from 1 to count _x -1 do + { + drawLine3D [_obj modelToWorld (_pts#(_x#_i)), _obj modelToWorld (_pts#(_x#(_i-1))), _color]; + }; + } forEach HB_DRAW_ARRS; + + } forEach GVAR(dev_hitBoxes); + + for "_i" from 0 to count _deleteArr - 1 do + { + GVAR(dev_hitBoxes) deleteAt (_deleteArr#_i); + }; +}; + +if (GVAR(frameHint)) then +{ + hintsilent str (1/diag_deltaTime); +}; \ No newline at end of file diff --git a/addons/frag/functions/fnc_dev_drawTraces.sqf b/addons/frag/functions/fnc_dev_drawTraces.sqf deleted file mode 100644 index 7fcca3c48fe..00000000000 --- a/addons/frag/functions/fnc_dev_drawTraces.sqf +++ /dev/null @@ -1,37 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: ACE-Team - * - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_frag_fnc_dev_drawTraces - * - * Public: No - */ - -{ - _x params ["", "", "", "", "_positions", "_color"]; - private _index = 0; - private _max = count _positions; - // private _lastSpd = []; - private _lastPos = []; - while {_index < _max} do { - _data1 = _positions select _index; - _data2 = _positions select ([_index + ACE_TRACE_DRAW_INC, _max - 1] select (_index + ACE_TRACE_DRAW_INC >= _max)); - - _pos1 = _data1 select 0; - _pos2 = _data2 select 0; - ADD(_index,ACE_TRACE_DRAW_INC); - - drawLine3D [_pos1, _pos2, _color]; - _lastPos = _pos2; - // _lastSpd = _data1 select 1; - }; - // drawIcon3D ["", [1,0,0,1], _lastPos, 0, 0, 0, format ["%1m/s", _lastSpd], 1, 0.05, "RobotoCondensed"]; -} forEach GVAR(traces); diff --git a/addons/frag/functions/fnc_dev_fadeRound.sqf b/addons/frag/functions/fnc_dev_fadeRound.sqf new file mode 100644 index 00000000000..49d1f566c45 --- /dev/null +++ b/addons/frag/functions/fnc_dev_fadeRound.sqf @@ -0,0 +1,34 @@ +#include "script_component.hpp" +/* + * Author: Lambda.Tiger + * Fades a trace over time based on given parameters + * + * Arguments: + * 0: PFEH arguments + * 1: PHEH handle + * + * Return Value: + * None + * + * Example: + * + * Public: No + */ +params ["_args", "_h"]; + +private _arr = GVAR(dev_trackLines) getOrDefault [(_args#0), []]; +if (count _arr < 3) exitWith +{ + [_h] call CBA_fnc_removePerFrameHandler; +}; + +private _alpha = _arr#0; +private _color = _arr#2; +_alpha = (_alpha - __FADE_RATE) min 1; +_arr set [0, _alpha]; +_color set [3, _alpha]; +_color set [1, (0.5 - _alpha/2) max 0]; +if (_alpha <= 0 ) then +{ + [_h] call CBA_fnc_removePerFrameHandler; +}; \ No newline at end of file diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf new file mode 100644 index 00000000000..162c88d9654 --- /dev/null +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -0,0 +1,90 @@ +#include "script_component.hpp" +/* + * Author: Lambda.Tiger, based on fnc_dev_debugAmmo by "ACE-Team" + * Dumps all ammo types to see if there's any reason to spawn fragments + * given power, distance, and lifetime of each fragement + * + * Arguments: + * 0: _dispAll - Display rounds that will never frag (power < 5). + * Default value false + * 1: _minFrgPowRng - minimum range for sqrt power calculation + * + * Return Value: + * None + * + * Example: + * [false, 10] call ace_frag_fnc_fragoCalcDump + * + * Public: No + */ + +params [["_dispAll", false, [false]], ["_minFrgPowRng", 35, [123]]]; + +#define DT 0.01 + +private _allMagsConfigs = configProperties [configFile >> "cfgAmmo", "isClass _x && !('ace' in configName _x)", true]; +private _processedCfgAmmos = []; + + + +private _nPrinted = 0; + +diag_log text "//****************** fragCalcDump Beg ******************//"; +// Processing ammo types +{ + private _ammo = toLower configName _x; + + if (_ammo == "" || {_ammo in _processedCfgAmmos} ) then {continue}; + + + // calculating hit range + + private _skip = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(skip)); + private _force = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(force)); + private _explosive = getNumber (configFile >> "cfgAmmo" >> _ammo >> "explosive"); + private _indirectHit = getNumber(configFile >> "cfgAmmo" >> _ammo >> "indirectHit"); + private _indirectRange = getNumber(configFile >> "cfgAmmo" >> _ammo >> "indirectHitRange"); + + _shouldFrag = if (_skip == 1 || (_force == 0 && {_explosive < 0.5 || {_indirectHit < 3 + || {_indirectRange < 5 && _indirectHit < _indirectRange}}})) then { + false; + } else { + true; + }; + + // Gunery equation from frago + private _c = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(CHARGE)); + if (_c == 0) then {_c = 1;}; + private _m = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(METAL)); + if (_m == 0) then {_m = 2;}; + private _k = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(GURNEY_K)); + if (_k == 0) then {_k = 0.8;}; + private _gC = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(GURNEY_C)); + if (_gC == 0) then {_gC = 2440;}; + private _fragCount = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(fragCount)); + if (_fragCount == 0) then {_fragCount = 200; _warn = true}; + profilerLog (str (sqrt (_fragCount / (4 * pi * 0.005)))); + private _velocity = 0.8 * _gC * sqrt (_c /(_m + _c * _k)); + // number of shrapnel to send a direction + private _count = ceil (random (sqrt (_m / 1000))); + private _fragPowerSpeedRange = [0.5, 1] vectorMultiply _fragPower; + + if (_nSkip || _dispALl) then + { + diag_log text format ["Ammo type: %1", _ammo]; + diag_log text format [" Indirect hit range: %1", _indirectHitRange]; + diag_log text format [" Frag sqrtPower: %1", _fragPowerSqrt]; + diag_log text format [" Frag range: %1", _fragRange]; + diag_log text format [" Frag speed range: %1", _fragPowerSpeedRange]; + diag_log text format [" Number frags: %1", _count]; + diag_log text " ~~~ Fragments ~~~"; + + + INC(_nPrinted); + }; + + _processedCfgAmmos pushBack _ammo; +} forEach _allMagsConfigs; + +diag_log text "//****************** fragCalcDump End ******************//"; +diag_log text format ["//********************** printed %1 *********************//", _nPrinted]; \ No newline at end of file diff --git a/addons/frag/functions/fnc_dev_sphereDraw.sqf b/addons/frag/functions/fnc_dev_sphereDraw.sqf new file mode 100644 index 00000000000..b578138e1d0 --- /dev/null +++ b/addons/frag/functions/fnc_dev_sphereDraw.sqf @@ -0,0 +1,52 @@ +#include "script_component.hpp" +/* + * Author: Lambda.Tiger + * Add a colored sphere at a specified point + * + * Arguments: + * 0: ASL position to add sphere + * 1: Color of sphere + * + * Return Value: + * None + * + * Example: + * [unit0, player] call ace_frag_fnc_dev_switchUnitHandle; + * + * Public: No + */ +params [ + ["_posASL", [0,0,0], [[]], [2,3]], + ["_color", "(1,0,0,0.5)", [""]] +]; + +if (count _posASL < 3) then +{ + _posASL pushBack 0; + _posASL = ASLtoATL _posASL; + _posASL set [2, 0]; + _posASL = ATLtoASL _posASL; +}; + +if (_color select [0,1] != "(") then +{ + switch (toLower _color) do + { + case "blue": { _color = "(0,0,0.8,0.5)"; }; + case "black": { _color = "(1,1,1,0.5)"; }; + case "white": { _color = "(0,0,0,0.5)"; }; + case "red": { _color = "(0.8,0,0,0.5)"; }; + case "green": { _color = "(0,0.8,0,0.5)"; }; + case "yellow": { _color = "(0.8,0.8,0,0.5)"; }; + case "orange": { _color = "(0.8,0.518,0,0.5)"; }; + default { _color = "(0.8,0.8,0,0.5)";}; + }; +}; +private _clrStr = "#(argb,8,8,3)color" + _color; + +private _sphere = "Sign_Sphere25cm_F" createVehicle [1,2,34]; +_sphere setObjectTexture [0, _clrStr]; +_sphere setPosASL _posASL; +GVAR(dev_eventSpheres) pushBack _sphere; + +_sphere; \ No newline at end of file diff --git a/addons/frag/functions/fnc_dev_startTracing.sqf b/addons/frag/functions/fnc_dev_startTracing.sqf deleted file mode 100644 index 897dde3011e..00000000000 --- a/addons/frag/functions/fnc_dev_startTracing.sqf +++ /dev/null @@ -1,23 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: ACE-Team - * - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_frag_fnc_dev_startTracing - * - * Public: No - */ - -if (GVAR(tracesStarted)) exitWith {}; - -INFO("Starting Trace Drawing"); - -GVAR(tracesStarted) = true; -GVAR(traceID) = [LINKFUNC(dev_drawTraces), 0, []] call CBA_fnc_addPerFrameHandler; diff --git a/addons/frag/functions/fnc_dev_stopTracing.sqf b/addons/frag/functions/fnc_dev_stopTracing.sqf deleted file mode 100644 index 949d3cd55d6..00000000000 --- a/addons/frag/functions/fnc_dev_stopTracing.sqf +++ /dev/null @@ -1,23 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: ACE-Team - * Dev things - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * None - * - * Public: No - */ - -if (!GVAR(tracesStarted)) exitWith {}; - -INFO("Ending Trace Drawing"); - -GVAR(tracesStarted) = false; -[GVAR(traceID)] call CBA_fnc_removePerFrameHandler; diff --git a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf new file mode 100644 index 00000000000..0ed7a597988 --- /dev/null +++ b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf @@ -0,0 +1,43 @@ +#include "script_component.hpp" +/* + * Author: Lambda.Tiger + * Handle for debug actions when switching units + * + * Arguments: + * 0: Last unit + * 1: Current unit + * + * Return Value: + * None + * + * Example: + * [unit0, player] call ace_frag_fnc_dev_switchUnitHandle; + * + * Public: No + */ +params ["_lVic", "_cVic"]; + + +if (_cVic isEqualTo objNull || {!local _cVic || _lVic isEqualTo _cVic}) exitWith {}; + + +private _aID = missionNamespace getVariable [QGVAR(dev_clearTraceAction), -1]; +if (_aID > -1 && {_lVic isNotEqualTo objNull}) then +{ + _lVic removeAction _aID; +}; + +_aID = _cVic addAction +[ + "Reset Lines", + FUNC(dev_clearTraces), + nil, // arguments + 1.5, // priority + true, // showWindow + false, // hideOnUse + "", // shortcut + "true", // condition + 8 +]; + +missionNamespace getVariable [QGVAR(dev_clearTraceAction), _aID]; \ No newline at end of file diff --git a/addons/frag/functions/fnc_dev_trackHitBox.sqf b/addons/frag/functions/fnc_dev_trackHitBox.sqf new file mode 100644 index 00000000000..54705f3935a --- /dev/null +++ b/addons/frag/functions/fnc_dev_trackHitBox.sqf @@ -0,0 +1,71 @@ +#include "script_component.hpp" +/* + * Author: Lambda.Tiger + * Add a hitbox outline to an object + * + * Arguments: + * 0: Object to draw hitbox + * 1: Add center sphere + * + * Return Value: + * None + * + * Example: + * [player] call ace_frag_fnc_dev_trackHitBox; + * + * Public: No + */ +params [ + ["_obj", objNull, [objNull]], + ["_addSphere", true, [false]] +]; + +if (isNull _obj) exitWith {}; + +private _box = []; +if (_obj isKindOf "CAManBase") then { + if (vehicle _obj == _obj) then { + _box = 0 boundingBox _obj; + } else { + _box = boundingBoxReal [_obj, "Geometry"]; + }; +} else { + _box = boundingBoxReal [_obj, "FireGeometry"]; +}; +_box params ["_lowP","_upP"]; + +private _stance = stance _obj; +switch (true) do { + case (_stance isEqualTo "STAND"): {_upP set [2, 1.9];}; + case (_stance isEqualTo "CROUCH"): {_upP set [2, 1.3];}; + case (_stance isEqualTo "PRONE"): {_upP set [2, 0.8];}; +}; +private _centerPoint = ASLToAGL getPosASL _obj; + +if (_addSphere && vehicle _obj isEqualTo _obj) then { + private _centerSphere = [getPosASL _obj, "yellow"] call FUNC(dev_sphereDraw); + _centerSphere disableCollisionWith vehicle _obj; + _centerSphere attachTo [_obj, _obj worldToModel _centerPoint]; +}; +private _p1 = _upP; +private _p7 = _lowP; + +private _points =[ + _upP, + [_p1#0,_p7#1,_p1#2], + [_p7#0,_p7#1,_p1#2], + [_p7#0,_p1#1,_p1#2], + [_p1#0,_p1#1,_p7#2], + [_p1#0,_p7#1,_p7#2], + _lowP, + [_p7#0,_p1#1,_p7#2] +]; + +_color = switch (side _obj) do { + case east: {[1, 0, 0, 1]}; + case resistance: {[0, 1, 0, 1]}; + default {[0, 0, 1, 1]}; +}; +//TRACE_3("box params", _obj, _points, _color); + +GVAR(dev_hitBoxes) set [getObjectID _obj, [_obj, _points, _color]]; \ No newline at end of file diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf new file mode 100644 index 00000000000..4da8e860310 --- /dev/null +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -0,0 +1,123 @@ +#include "script_component.hpp" +/* + * Author: Lambda.Tiger + * This function adds an object to have it's course tracked (every frame). + * + * Arguments: + * 0: Object to draw hitbox + * 1: Color of trace + * 2: Whether the object is a projectile + * + * Return Value: + * None + * + * Example: + * [player] call ace_frag_fnc_dev_trackObj; + * + * Public: No + */ +params ["_obj", ["_color", "blue", [""]], ["_isProj", false, [false]]]; + +/// track round on each frame +// Create entry in position array from hashmap +private _pID = getObjectID _obj; +if (GVAR(fadeRounds)) then +{ + private _colorArray = switch (toLower _color) do { + case "purple": {[0.8, 0, 0.8, __FADE_INIT]}; + case "blue": {[0, 0, 0.8, __FADE_INIT]}; + case "green": {[0, 0.8, 0, __FADE_INIT]}; + case "orange": {[0.8, 0.518, 0, __FADE_INIT]}; + case "yellow": {[0.8, 0.8, 0, __FADE_INIT] }; + case "red": {[0.8, 0, 0, __FADE_INIT]}; + case "black": {[1, 1, 1, __FADE_INIT]}; + case "white": {[0, 0, 0, __FADE_INIT]}; + default {[0, 0.8, 0.8, __FADE_INIT]}; + }; + + GVAR(dev_trackLines) set [_pID, [__FADE_INIT, [getposATL _obj], _colorArray]]; + // add fading factor + [LINKFUNC(dev_fadeRound), __FADE_INTERVAL, [_pID]] call CBA_fnc_addPerFrameHandler; +} else +{ + private _colorArray = switch (toLower _color) do { + case "purple": {[0.8, 0, 0.8, 1]}; + case "blue": {[0, 0, 0.8, 1]}; + case "green": {[0, 0.8, 0, 1]}; + case "orange": {[0.8, 0.518, 0, 1]}; + case "yellow": {[0.8, 0.8, 0, 1] }; + case "red": {[0.8, 0, 0, 1]}; + case "black": {[1, 1, 1, 1]}; + case "white": {[0, 0, 0, 1]}; + default {[0, 0.8, 0.8, 1]}; + }; + GVAR(dev_trackLines) set [_pID, [1, [getposATL _obj], _colorArray]]; +}; +// eventhandler to track round and cleanup when round is "dead" +[ + { + if (isGamePaused) exitWith {}; + params ["_par", "_h"]; + _par params ["_obj"]; + if (!alive _obj) exitWith { + [_h] call CBA_fnc_removePerFrameHandler; + }; + private _arr = GVAR(dev_trackLines) getOrDefault [(getObjectID _obj), -1]; + + if (typeName _arr isEqualTo "SCALAR") exitWith { + [_h] call CBA_fnc_removePerFrameHandler; + }; + + (_arr#1) pushBack getPosATL _obj; + if (_arr#0 <= 0) exitWith { + [_h] call CBA_fnc_removePerFrameHandler; + }; + }, + 0, + [_obj] +] call CBA_fnc_addPerFrameHandler; + +if (!_isProj) exitWith {}; + + +// Add hitpart eventHandler +_obj addEventHandler [ + "HitPart", + { + params ["_proj", "", "", "_posASL"]; + private _arr = (GVAR(dev_trackLines) get (getObjectID _proj))#1; + _arr pushBack ASLtoATL _posASL; + if (GVAR(dbgSphere)) then + { + [_posASL, "green"] call FUNC(dev_sphereDraw); + }; + } +]; + +// Add explode eventHandler +_obj addEventHandler [ + "Explode", + { + params ["_proj", "_posASL"]; + private _arr = (GVAR(dev_trackLines) get (getObjectID _proj))#1; + _arr pushBack ASLtoATL _posASL; + if (GVAR(dbgSphere)) then + { + [_posASL, "red"] call FUNC(dev_sphereDraw); + }; + } +]; + +// Add deflected eventHandler +_proj addEventHandler [ + "Deflected", + { + params ["_proj", "_posASL"]; + private _arr = (GVAR(dev_trackLines) get (getObjectID _proj))#1; + _arr pushBack ASLtoATL _posASL; + if (GVAR(dbgSphere)) then + { + [_posASL, "blue"] call FUNC(dev_sphereDraw); + }; + } +]; \ No newline at end of file diff --git a/addons/frag/functions/fnc_dev_trackTrace.sqf b/addons/frag/functions/fnc_dev_trackTrace.sqf deleted file mode 100644 index 6c010bdb631..00000000000 --- a/addons/frag/functions/fnc_dev_trackTrace.sqf +++ /dev/null @@ -1,27 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: ACE-Team - * Dev things - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_frag_fnc_dev_trackTrace - * - * Public: No - */ - -params ["_args", "_pfhID"]; -_args params ["_tracerObj", "_index"]; - -if (alive _tracerObj && {GVAR(traces) isNotEqualTo []}) then { - private _data = GVAR(traces) select _index; - private _positions = _data select 4; - _positions pushBack [getPos _tracerObj, vectorMagnitude (velocity _tracerObj)]; -} else { - [_pfhID] call CBA_fnc_removePerFrameHandler; -}; diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf new file mode 100644 index 00000000000..574723ce7f4 --- /dev/null +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -0,0 +1,59 @@ +#include "script_component.hpp" +/* + * Author: Lambda.Tiger + * This function handles creating both random and targeted fragments as well + * as handling some of the performance optimizations. + * + * Arguments: + * 0: Array of argumentse + * 0.0: projectile that's fragmenting + * 0.1: ASL position of projectile + * 0.2: velocity of projectile + * 1: Whether the projectile is a submunition + * + * Return Value: + * None + * + * Example: + * [[_proj, getPosASL _proj, velocity _proj]] call ace_frag_fnc_doFrag; + * + * Public: No + */ + +params ["_args", ["_isSubMunit", false, [false]]]; +_args params [ + ["_proj", objNull, [objNull]], + ["_posASL", [0,0,0], [[]], [3]], + ["_vel", [0,0,0] , [[]], [3]] +]; + +private _timeSince = CBA_missionTime - GVAR(lastFragTime); +if (isNull _proj || {_posASL isEqualTo [0,0,0] || _timeSince < 0.2}) exitWith {}; +GVAR(lastFragTime) = CBA_missionTime; +private _maxFrags = round (linearConversion [0.1, 1.5, _timeSince, MAX_FRAG_COUNT_MIN, MAX_FRAG_COUNT_MAX, true]); + +private _ammo = typeOf _proj; +private _ammoArr = [_ammo] call FUNC(fragInfo); +_ammoArr params ["_fragRange", "_fragVel", "_fragTypes", "_modFragCount"]; + +private _shotParents = getShotParents _proj; + +private _heightAGL = (ASLToAGL _posASL)#2; +if (_heightAGL < 0.25) then { + _posASL = _posASL vectorAdd [0, 0, 0.25]; +}; + +// make timesince a gvar? +TRACE_4("fnc_doFragTargeted IF", _fragRange, _timeSince, _isSubMunit, GVAR(enSubMunit)); +if (_fragRange > 3 && _timeSince > 0.3 && {!_isSubMunit || {GVAR(enSubMunit) == 2}}) then { + _maxFrags = _maxFrags - ([_posASL, _fragVel, _fragRange, _maxFrags, _fragTypes, _modFragCount, _shotParents] call FUNC(doFragTargeted)); +}; + +// make a gvar? +if (_timeSince > 0.2 && {GVAR(enSubMunit) != 0}) then { + [_posASL, _vel, _heightAGL, _fragTypes, _maxFrags, _shotParents] call FUNC(doFragRandom); +}; + +if (GVAR(reflectionsEnabled)) then { + [_posASL, _shellType] call FUNC(doReflections); +}; \ No newline at end of file diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf new file mode 100644 index 00000000000..cd799d89cab --- /dev/null +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -0,0 +1,71 @@ +#include "script_component.hpp" +/* + * Author: Lambda.Tiger + * This function creates fragments randomly spreading out from an explosion to + * a maximum of 15 + * + * Arguments: + * 0: Position of fragmenting projectile ASL + * 1: Velocity of the fragmenting projectile + * 2: Height (AGL) of the fragmenting projectile + * 3: Type of fragments to generate + * 4: Remaining fragment budget + * 5: Shot parent + * + * Return Value: + * None + * + * Example: + * [getPosASL _proj, velocity _proj, 50, 50, [], 1, [player, player]] call ace_frag_fnc_doFragRandom; + * + * Public: No + */ + +params [ + "_posASL", + ["_projVel", [0,0,0]], + ["_heightAGL", 2, [123]], + ["_fragType", [], [[]]], + ["_fragCnt", 10, [123]], + ["_shotPrnt", [objNull, objNull], [[]], [2]] +]; +TRACE_5("fnc_doFragRandom", _posASL, _projVel, _heightAGL, _fragType, _fragCnt); + +// See CfgAmmo for different frag types +private _hMode = switch (true) do { + case (_heightAGL > 10): {"_top"}; + case (_heightAGL > 5): {"_hi"}; + case (_heightAGL > 1.5): {"_mid"}; + default {"_mid"}; +}; + +// Select the cfgAmmo type +private _type = if (count _fragType > 0 && + {"ace_frag_tiny" isEqualTo (_fragType#0)}) then { + QGVAR(def_tiny_) +} else { + QGVAR(def_small_) +}; + +_fragCnt = switch (true) do { + case (_fragCnt <= 5): {"5"}; + case (_fragCnt <= 10): {"10"}; + default {"15"}; +}; + +// Spawn the fragment spawner +private _fragSpawner = createVehicle [_type + _fragCnt + _hMode, ASLToATL _posASL, [], 0, "CAN_COLLIDE"]; +_fragSpawner setVelocity _projVel; +_fragSpawner setShotParents _shotParents; + +#ifdef DEBUG_MODE_FULL + systemChat ("fragging, id: " + getObjectID _proj); + _fragSpawner addEventHandler [ + "SubmunitionCreated", + { + params ["","_proj","_posASL"]; + [_posASL] call FUNC(dev_sphereDraw); + [_proj, "green", true] call FUNC(dev_trackObj); + } + ]; +#endif \ No newline at end of file diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf new file mode 100644 index 00000000000..f810eb9fb66 --- /dev/null +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -0,0 +1,175 @@ +#include "script_component.hpp" +/* + * Author: Lambda.Tiger + * This function creates fragments targeted at specific entities, up to + * a configured maximum + * + * Arguments: + * 0: Position of fragmenting projectile ASL + * 1: Velocity of the fragmenting projectile + * 2: Maximum range of fragments to calculate + * 3: Maximum number of fragments to produce + * 4: Types of fragments + * 5: A modified parameter used to calulate whether a framgent hits + * 6: Shot parent + * + * Return Value: + * None + * + * Example: + * [getPosASL _proj, velocity _proj, 50, 50, [], 1, [player, player]] call ace_frag_fnc_doFragTargeted; + * + * Public: No + */ + +params [ + "_posASL", + ["_fragVel", 800, [123]], + ["_fragRange", 50, [123]], + ["_maxFrags", 20, [123]], + ["_fragTypes", [], [[]]], + ["_modFragCount", 1, [123]], + ["_shotPrnt", [objNull, objNull], [[]], [2]] +]; +TRACE_5("fnc_doFragTargeted", _posASL, _fragRange, _maxFrags, _fragTypes, _modFragCount); + +if (_fragTypes isEqualTo []) then { + _fragTypes = [ + QGVAR(tiny), QGVAR(tiny), QGVAR(tiny), + QGVAR(tiny_HD), QGVAR(tiny_HD), QGVAR(tiny_HD), + QGVAR(small), QGVAR(small), QGVAR(small), QGVAR(small), + QGVAR(small_HD), QGVAR(small_HD), QGVAR(small_HD), QGVAR(small_HD), + QGVAR(medium_HD), QGVAR(medium_HD), QGVAR(medium_HD), QGVAR(medium_HD), QGVAR(medium_HD) + ]; +}; + +private _objects = (ASLToATL _posASL) nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], _fragRange]; +if (_objects isEqualTo []) exitWith { + TRACE_2("No nearby targets", _posASL, _fragRange); + 0; +}; + + +// grab crews and add them in so that targets stay approx. sorted by distance +{ + private _crew = (crew _x); + if (count _crew > 1) then { + private _arr = [_x]; + { + _arr pushBackUnique _x; + } forEach _crew; + + _objects set [_forEachIndex, _arr]; + }; +} forEach _objects; +_objects = flatten _objects; // flatten out sub arrays +TRACE_3("Targets found", _posASL, _fragRange, count _objects); + +// limit number of fragments per direction (2D) to 10 using _fragArcs +private _fragArcs = createHashMap; +private _fragCount = 0; // limit of # of fragments to _maxFrags +{ + if (!alive _x) then {continue}; + private _target = _x; + + #ifdef DEBUG_MODE_DRAWFRAG + [_target, false] call FUNC(dev_trackHitBox); + #endif + + // Calculate volume and height of target + private _vol = 1.5; + private _height = 0; + private _crossSectionArea = 1; + private _isPerson = _target isKindOf "CAManBase"; + if (_isPerson) then { + private _stance = stance _target; + switch (true) do { + case (_stance isEqualTo "STAND"): {_height = 1.9; _crossSectionArea = 1.5;}; + case (_stance isEqualTo "CROUCH"): {_height = 1.2; _crossSectionArea = 1;}; + default {_height = 0.5; _crossSectionArea = 0.75;}; + }; + } else { + private _boxParams = boundingBoxReal [_target, "FireGeometry"]; + _boxParams params ["_pointA", "_pointB"]; + private _dims = _pointB vectorDiff _pointA; + _vol = (_dims#0) * (_dims#1) * (_dims#2); + _crossSectionArea = (_dims#1)*(_dims#2); + _height = _dims#2; + }; + + if (_vol <= 0.5) then {continue}; // too small => exit + + + private _distance = _target distance _posASL; + + // calculate chance to be hit by a fragment + private _fragChance = _crossSectionArea*_modFragCount/(_distance^2); + private _count = if (_fragChance > 1) then { + 3 min (floor _fragChance); + } else { + [0, 1] select (GVAR(atLeastOne) || {random 1 < _fragChance}); + }; + if (_count == 0) then {TRACE_2("fragments",_fragChance,_count); continue}; + + // Approximate offset to hit including speed & gravity + private _locFragVel = _fragVel * (1 - random 0.5); + private _tof = _distance / _locFragVel; + private _targetPos = (velocity _target vectorMultiply _tof) vectorAdd [0, 0, 9.81 / 2 * _tof ^ 2]; + + // handle limiting fragments per dewgree arc + private _dir = floor (_posASL getDir _target); + private _fragPerArc = _fragArcs getOrDefault [_dir, 0]; + if (_fragPerArc > 10) then { + continue; + } else { + _fragArcs set [_dir, _fragPerArc + _count]; + }; + + // actual target pos for fragment to hit + if _isPerson then { + private _hitPoint = selectRandom _FRAG_HITPOINTS; + private _hitPointPos = _target selectionPosition [_hitPoint, "HitPoints", "AveragePoint"]; + _targetPos = _target modelToWorldWorld _hitPointPos; + } else { + _targetPos = getPosASL _target vectorAdd [ + -0.5 + random 1, + -0.5 + random 1, + (0.1 + random 0.4) * _height + ]; + }; + + // select a fragment / submunition frag spawner + private _fragSpawner = selectRandom _fragTypes; + if (_count > 1) then { + _fragSpawner = _fragSpawner + "_spawner_" + str _count + (switch (true) do { + case (_distance < 10): {"_short"}; + case (_distance < 20): {"_mid"}; + default {"_far"}; + }); + }; + + TRACE_4("fragments",_fragSpawner,_fragChance,_distance,_locFragVel); + + // Create fragment + private _vecDir = _posASL vectorFromTo _targetPos; + private _fragObj = createVehicle [_fragSpawner, ASLtoATL _posASL, [], 0, "CAN_COLLIDE"]; + _fragObj setVectorDir _vecDir; + _fragObj setVelocity (_vecDir vectorMultiply _locFragVel); + _fragObj setShotParents _shotPrnt; + #ifdef DEBUG_MODE_DRAWFRAG + [_fragObj, "purple", true] call FUNC(dev_trackObj); + [_targetPos, "orange"] call FUNC(dev_sphereDraw); + #endif + + _fragCount = _fragCount + _count; + if (_fragCount >= _maxFrags) then { + TRACE_2("maxFrags", _fragCount, _maxFrags); + break + }; +} forEach _objects; +#ifdef DEBUG_MODE_FULL +systemChat ("fragCount cnt: " + str _fragCount); +TRACE_1("fragCount",_fragCount); +#endif + +_fragCount \ No newline at end of file diff --git a/addons/frag/functions/fnc_doReflections.sqf b/addons/frag/functions/fnc_doReflections.sqf index 023a283e81b..7b16385d756 100644 --- a/addons/frag/functions/fnc_doReflections.sqf +++ b/addons/frag/functions/fnc_doReflections.sqf @@ -1,4 +1,4 @@ -#include "..\script_component.hpp" +#include "script_component.hpp" /* * Author: ACE-Team * Dev things diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index 8b5a06d812d..c5f99b892f6 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -1,4 +1,4 @@ -#include "..\script_component.hpp" +#include "script_component.hpp" /* * Author: ACE-Team * Dev things @@ -14,126 +14,97 @@ * * Public: No */ +params ["_projectile", "_hitObj", "", "_lPosASL", "_lVel", "", "", "" ,"_surfaceType"]; -#define WEIGHTED_SIZE [QGVAR(spall_small), 4, QGVAR(spall_medium), 3, QGVAR(spall_large), 2, QGVAR(spall_huge), 1] +if (!isNil "_hitObj" && {_hitObj isKindOf "man"}) exitWith {}; -params ["_hitData", "_hitPartDataIndex"]; -private _initialData = GVAR(spallHPData) select (_hitData select 0); -_initialData params ["_hpId", "_object", "_roundType", "_round", "_curPos", "_velocity"]; +if ((isNil "_lPosASL") || {!(_lPosASL isEqualTypeArray [0,0,0])}) exitWith {WARNING_1("Problem with hitPart data - bad pos [%1]",_lPosASL);}; -private _hpData = (_hitData select 1) select _hitPartDataIndex; -private _objectHit = _hpData param [0, objNull]; -TRACE_1("",_objectHit); -if ((isNil "_objectHit") || {isNull _objectHit}) exitWith {WARNING_1("Problem with hitPart data - bad object [%1]",_objectHit);}; -_objectHit removeEventHandler ["hitPart", _hpId]; -private _caliber = getNumber (configFile >> "CfgAmmo" >> _roundType >> "caliber"); -private _explosive = getNumber (configFile >> "CfgAmmo" >> _roundType >> "explosive"); -private _idh = getNumber (configFile >> "CfgAmmo" >> _roundType >> "indirectHitRange"); - -if !(_caliber >= 2.5 || {(_explosive > 0 && {_idh >= 1})}) exitWith {}; -// ACE_player sideChat format ["BBBB"]; -private _exit = false; -private _vm = 1; - -private _oldVelocity = vectorMagnitude _velocity; -private _curVelocity = vectorMagnitude (velocity _round); - -if (alive _round) then { - private _diff = _velocity vectorDiff (velocity _round); - private _polar = _diff call CBA_fnc_vect2polar; - // ACE_player sideChat format ["polar: %1", _polar]; - if (abs (_polar select 1) > 45 || {abs (_polar select 2) > 45}) then { - if (_caliber < 2.5) then { - // ACE_player sideChat format ["exit!"]; - _exit = true; - } else { - SUB(_vm,_curVelocity / _oldVelocity); - }; +private _posASL = _lPosASL; +private _vel = [0, 0, 0]; +private _lVelUnit = vectorNormalized _lVel; +private _velMod = 1; +if (alive _projectile) then { + _vel = velocity _projectile; + _posASL = getPosASL _projectile; + // Dot product math + private _diffAngle = acos (_lVelUnit vectorDotProduct vectorNormalized _vel); + + if (abs _diffAngle > 45) then { + SUB(_velMod, (vectorMagnitude _vel) / (vectorMagnitude _lVel)); }; + _projectile setVariable [QGVAR(lastSpallTime), diag_tickTime ]; }; -if (_exit) exitWith {}; -private _unitDir = vectorNormalized _velocity; -private _pos = _hpData select 3; -private _spallPos = []; -if ((isNil "_pos") || {!(_pos isEqualTypeArray [0,0,0])}) exitWith {WARNING_1("Problem with hitPart data - bad pos [%1]",_pos);}; -for "_i" from 0 to 100 do { - private _pos1 = _pos vectorAdd (_unitDir vectorMultiply (0.01 * _i)); - private _pos2 = _pos vectorAdd (_unitDir vectorMultiply (0.01 * (_i + 1))); - // _data = [nil, nil, nil, 1, [[ASLtoATL _pos1, 1], [ASLtoATL _pos2, 1]]]; - // NOU_TRACES pushBack _data; - if (!lineIntersects [_pos1, _pos2]) exitWith { - // ACE_player sideChat format ["FOUND!"]; - _spallPos = _pos2; - }; +//** start calculating where the spalling should come **// +private _unitStep = _lVelUnit vectorMultiply 0.05; +private _spallPos = +_lPosASL; +// exit if we hit the ground +if (terrainIntersectASL [_lPosASL vectorAdd _unitStep, _lPosASL]) exitWith {}; +// step through +for "_i" from 1 to 20 do +{ + private _nPos = _spallPos vectorAdd _unitStep; + if (!lineIntersects [_spallPos, _nPos]) then {break}; + _spallPos = +_nPos; }; -if (_spallPos isEqualTo []) exitWith {}; -private _spallPolar = _velocity call CBA_fnc_vect2polar; +#ifdef DEBUG_MODE_FULL +[_spallPos, "orange"] call FUNC(dev_sphereDraw); +[_lPosASL, "orange"] call FUNC(dev_sphereDraw); +#endif +// find last intersect with the object + +private _ammo = typeOf _projectile; +private _explosive = getNumber (configFile >> "CfgAmmo" >> _ammo >> "explosive"); + +#ifdef DEBUG_MODE_FULL +private _dv = vectorMagnitude _lVel - vectorMagnitude _vel; +private _caliber = getNumber (configFile >> "cfgAmmo" >> _ammo >> "caliber"); +systemChat ("dV: " + str _dv + ", caliber: " + str _caliber + ", product: " + str (_caliber*_dv)); +#endif if (_explosive > 0) then { // ACE_player sideChat format ["EXPLOSIVE!"]; - private _warn = false; - private _c = getNumber (configFile >> "CfgAmmo" >> _roundType >> QGVAR(CHARGE)); - if (_c == 0) then {_c = 1; _warn = true;}; - private _m = getNumber (configFile >> "CfgAmmo" >> _roundType >> QGVAR(METAL)); - if (_m == 0) then {_m = 2; _warn = true;}; - private _k = getNumber (configFile >> "CfgAmmo" >> _roundType >> QGVAR(GURNEY_K)); - if (_k == 0) then {_k = 1 / 2; _warn = true;}; - private _gC = getNumber (configFile >> "CfgAmmo" >> _roundType >> QGVAR(GURNEY_C)); - if (_gC == 0) then {_gC = 2440; _warn = true;}; + //private _warn = false; + private _c = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ace_frag_CHARGE"); + if (_c == 0) then {_c = 1}; //; _warn = true;}; + private _m = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ace_frag_METAL"); + if (_m == 0) then {_m = 2;};// _warn = true;}; + private _k = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ace_frag_GURNEY_K"); + if (_k == 0) then {_k = 1 / 2;};// _warn = true;}; + private _gC = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ace_frag_GURNEY_C"); + if (_gC == 0) then {_gC = 2440};// _warn = true;}; // if (_warn) then { // WARNING_1("Ammo class %1 lacks proper explosive properties definitions for frag!",_roundType); //TODO: turn this off when we get closer to release // }; - private _fragPower = (((_m / _c) + _k) ^ - (1 / 2)) * _gC; - _spallPolar set [0, _fragPower * 0.66]; + _velMod = (((_m / _c) + _k) ^ - (1 / 2)) * _gC * 0.66 * _velMod; }; // diag_log text format ["SPALL POWER: %1", _spallPolar select 0]; -private _spread = 15 + (random 25); -private _spallCount = 5 + (random 10); -TRACE_1("",_spallCount); -for "_i" from 1 to _spallCount do { - private _elev = ((_spallPolar select 2) - _spread) + (random (_spread * 2)); - private _dir = ((_spallPolar select 1) - _spread) + (random (_spread * 2)); - if (abs _elev > 90) then { - ADD(_dir,180); - }; - _dir = _dir % 360; - private _vel = (_spallPolar select 0) * 0.33 * _vm; - _vel = (_vel - (_vel * 0.25)) + (random (_vel * 0.5)); - - private _spallFragVect = [_vel, _dir, _elev] call CBA_fnc_polar2vect; - private _fragment = (selectRandomWeighted WEIGHTED_SIZE) createVehicleLocal [0,0,10000]; - _fragment setPosASL _spallPos; - _fragment setVelocity _spallFragVect; - - #ifdef DRAW_FRAG_INFO - [ACE_player, _fragment, [1, 0.5, 0, 1]] call FUNC(dev_addTrack); - #endif -}; - -_spread = 5 + (random 5); -_spallCount = 3 + (random 5); -for "_i" from 1 to _spallCount do { - private _elev = ((_spallPolar select 2) - _spread) + (random (_spread * 2)); - private _dir = ((_spallPolar select 1) - _spread) + (random (_spread * 2)); - if (abs _elev > 90) then { - ADD(_dir,180); - }; - _dir = _dir % 360; - private _vel = (_spallPolar select 0) * 0.55 * _vm; - _vel = (_vel - (_vel * 0.25)) + (random (_vel * 0.5)); - - private _spallFragVect = [_vel, _dir, _elev] call CBA_fnc_polar2vect; - private _fragment = (selectRandomWeighted WEIGHTED_SIZE) createVehicleLocal [0, 0, 10000]; - _fragment setPosASL _spallPos; - _fragment setVelocity _spallFragVect; - - #ifdef DRAW_FRAG_INFO - [ACE_player, _fragment, [1, 0, 0, 1]] call FUNC(dev_addTrack); - #endif -}; +// range of spread 15-40 +// N rounds 5-15 +// speed from 0.75-1.5 +// range of spread 5-10 +// N rounds 3-8 +// speed from 0.75-1.5 +private _velScalar = 0.33 * _velMod; + +private _fragSpawner = QGVAR(base) createVehicleLocal [0,0,12345]; +_fragSpawner setPosASL _spallPos; +_fragSpawner setVectorDirandUp [vectorDir _projectile, vectorUp _projectile]; +_fragSpawner setVelocity (_lVelUnit vectorMultiply _velScalar); + + +#ifdef DEBUG_MODE_FULL +_fragSpawner addEventHandler [ + "SubmunitionCreated", + { + params ["", "_subProj"]; + [_subProj] call FUNC(dev_addRound); + } +]; +#endif \ No newline at end of file diff --git a/addons/frag/functions/fnc_doSpallMomentum.sqf b/addons/frag/functions/fnc_doSpallMomentum.sqf new file mode 100644 index 00000000000..6881033dd6c --- /dev/null +++ b/addons/frag/functions/fnc_doSpallMomentum.sqf @@ -0,0 +1,109 @@ +#include "script_component.hpp" +/* + * Author: Lambda.Tiger + * This function creates spalling if the hit slowed the speed down enough. + * + * Arguments: + * Arguments are the same as BI's "HitPart" EH: + * https://community.bistudio.com/wiki/Arma_3:_Event_Handlers#HitPart + * + * Return Value: + * None + * + * Example: + * [BIS_HITPART_EH_ARGS] call ace_frag_fnc_doSpallMomentum; + * + * Public: No + */ +params ["_projectile", "_hitObj", "", "_lPosASL", "_lVel", "", "", "" ,"_surfaceType"]; + +if (CBA_missionTime - GVAR(lastHitTick) < ACE_FRAG_SPALL_HOLDOFF) exitWith {}; + +if (_hitObj isNotEqualTo objNull && {_hitObj isKindOf "man"}) exitWith {}; +if ((isNil "_lPosASL") || {!(_lPosASL isEqualTypeArray [0,0,0])}) exitWith { + TRACE_1("Problem with hitPart data - bad pos",_lPosASL); +}; + +private _vel = if (alive _projectile) then { + _velocity _projectile; +} else { + [0, 0, 0] +}; +private _lVelUnit = vectorNormalized _lVel; + + +// Find spall speed / fragment +private _ammo = typeOf _projectile; +private _dV = vectorMagnitude _lVel - vectorMagnitude _vel; +private _caliber = getNumber (configFile >> "cfgAmmo" >> _ammo >> "caliber"); // !*! optimize this later? +private _deltaMomentum = 0.4 * _caliber * sqrt( _dV * 0.032 ); + +TRACE_3("found speed",_dV,_caliber,_deltaMomentum); + +if (_deltaMomentum < 1) exitWith { + TRACE_1("lowImpulse",_ammo); +}; + +//** start calculating where the spalling should come !*! could be better **// +private _unitStep = _lVelUnit vectorMultiply 0.05; +private _spallPos = +_lPosASL; +// exit if we hit the ground +if (terrainIntersectASL [_lPosASL vectorAdd _unitStep, _lPosASL]) exitWith { + TRACE_3("terrainIntersect",_lPosASL,_unitStep,_lPosASL); +}; +// step through +for "_i" from 1 to 20 do +{ + private _nPos = _spallPos vectorAdd _unitStep; + if (!lineIntersects [_spallPos, _nPos]) then { _spallPos = _nPos; break}; + _spallPos = +_nPos; +}; + +#ifdef DEBUG_MODE_FULL +[_spallPos, "green"] call FUNC(dev_sphereDraw); +[_lPosASL vectorAdd _lVelUnit, "orange"] call FUNC(dev_sphereDraw); +[_lPosASL, "orange"] call FUNC(dev_sphereDraw); +private _str = GVAR(hitLog) getOrDefault [str _surfaceType, "["]; +_str =_str + str [_dV, _caliber, abs vectorMagnitude (_lPosASL vectorDiff _spallPos)] + ";"; +GVAR(hitLog) set [str _surfaceType, _str]; +if (_deltaMomentum < 2) exitWith {}; +#endif + +//***** Passed all other exit withs, performance o'clock */ +GVAR(lastHitTick) = CBA_missionTime; + +//***** Select spalled fragments **// +// diag_log text format ["SPALL POWER: %1", _spallPolar select 0]; +// range of spread 15-40 +// N rounds 5-15 +// speed from 0.75-1.5 +// range of spread 5-10 +// N rounds 3-8 +// speed from 0.75-1.5 + +private _fragSpawnType = switch (true) do +{ + case (_deltaMomentum < 3): { QGVAR(spall_tiny) }; + case (_deltaMomentum < 5): { QGVAR(spall_small) }; + case (_deltaMomentum < 8): { QGVAR(spall_medium) }; + case (_deltaMomentum < 11): { QGVAR(spall_large) }; + default { QGVAR(spall_huge) }; +}; + + +//***** Spawn spalled fragments +private _fragSpawner = createVehicleLocal [_fragSpawnType, ASLToATL _spallPos, [], 0, "CAN_COLLIDE"]; +_fragSpawner setVectorDirandUp [vectorDir _projectile, vectorUp _projectile]; +_fragSpawner setVelocity _lVelUnit; + + +#ifdef DEBUG_MODE_FULL +systemChat ("bSpd: " + str speed _fragSpawner + ", frag: " + _fragSpawnType + ", dm: " + str _deltaMomentum); +_fragSpawner addEventHandler [ + "SubmunitionCreated", + { + params ["", "_subProj"]; + [_subProj] call FUNC(dev_addRound); + } +]; +#endif \ No newline at end of file diff --git a/addons/frag/functions/fnc_fired.sqf b/addons/frag/functions/fnc_fired.sqf index 355da901c61..5ed9206a42c 100644 --- a/addons/frag/functions/fnc_fired.sqf +++ b/addons/frag/functions/fnc_fired.sqf @@ -1,6 +1,6 @@ -#include "..\script_component.hpp" +#include "script_component.hpp" /* - * Author: nou, jaynus, PabstMirror + * Author: nou, jaynus, PabstMirror, Lambda.Tiger * Called from the unified fired EH for all. * If spall is not enabled (default), then cache and only track those that will actually trigger fragmentation. * @@ -17,42 +17,44 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); -private _shouldAdd = GVAR(cacheRoundsTypesToTrack) getVariable _ammo; -if (isNil "_shouldAdd") then { - TRACE_1("no cache for round",_ammo); - - //Read configs and test if it would actually cause a frag, using same logic as FUNC(pfhRound) - private _skip = getNumber (configFile >> "CfgAmmo" >> _ammo >> QGVAR(skip)); - private _explosive = getNumber (configFile >> "CfgAmmo" >> _ammo >> "explosive"); - private _indirectRange = getNumber (configFile >> "CfgAmmo" >> _ammo >> "indirectHitRange"); - private _force = getNumber (configFile >> "CfgAmmo" >> _ammo >> QGVAR(force)); - private _fragPower = getNumber (configFile >> "CfgAmmo" >> _ammo >> "indirecthit") * (sqrt (getNumber (configFile >> "CfgAmmo" >> _ammo >> "indirectHitRange"))); - - _shouldAdd = (_skip == 0) && {(_force == 1) || {_explosive > 0.5 && {_indirectRange >= 4.5} && {_fragPower >= 35}}}; - - if (GVAR(spallEnabled) && {!_shouldAdd}) then { - private _caliber = getNumber (configFile >> "CfgAmmo" >> _ammo >> "caliber"); - if !(_caliber >= 2.5 || {(_explosive > 0 && {_indirectRange >= 1})}) exitWith {}; // from check in doSpall: line 34 - TRACE_1("Won't frag, but will spall",_caliber); - _shouldAdd = true; - }; - - TRACE_6("Setting Cache",_skip,_explosive,_indirectRange,_force,_fragPower,_shouldAdd); - GVAR(cacheRoundsTypesToTrack) setVariable [_ammo, _shouldAdd]; +if (isNil "_ammo" || + {_ammo isEqualTo "" || + {isNil "_projectile" || + {isNull _projectile}}}) exitWith { + WARNING("bad ammo or projectile"); }; -if (_shouldAdd) then { - // firedMan will have nil "_gunner", so just check _unit; for firedVehicle we want to check _gunner - private _localShooter = if (isNil "_gunner") then {local _unit} else {local _gunner}; - TRACE_4("",_localShooter,_unit,_ammo,_projectile); - if (!_localShooter) exitWith {}; - if (_weapon == "Put") exitWith {}; // Ignore explosives placed without ace_explosives - - // Skip if less than 0.5 second from last shot - if ((CBA_missionTime - (_unit getVariable [QGVAR(lastTrack), -1])) < 0.5) exitWith {}; - _unit setVariable [QGVAR(lastTrack), CBA_missionTime]; +/******* _shouldFrag format *****/ +// 0: doFragmnent - will the piece fragment +// 1: hasSubmuntion - will the round create submunitions +private _shouldFrag = _ammo call FUNC(shouldFrag); +_shouldFrag params ["_doFrag", "_doSubmunit"]; + +if (_doFrag) then { + // wait for frag damage to kill units before spawning fragments + _projectile addEventHandler ["Explode", { + if (isServer) then { + [FUNC(doFrag), [_this]] call CBA_fnc_execNextFrame; + } else { + [QGVAR(frag_eh), [_this]] call CBA_fnc_serverEvent; + }; + } + ]; +}; - [_unit, _ammo, _projectile] call FUNC(addPfhRound); +if (_doSubmunit && {GVAR(enSubMunit)> 0}) then { + _projectile addEventHandler ["SubmunitionCreated", {_this call FUNC(submunition)}]; }; + +private _shouldSpall = _ammo call FUNC(shouldSpall); + +if (GVAR(spallEnabled) && {_shouldSpall}) then +{_projectile addEventHandler [ + "HitPart", + { + [LINKFUNC(doSpallMomentum), _this] call CBA_fnc_execNextFrame; + [QGVAR(spall_eh), [_this]] call CBA_fnc_serverEvent; + } + ]; +}; \ No newline at end of file diff --git a/addons/frag/functions/fnc_fragInfo.sqf b/addons/frag/functions/fnc_fragInfo.sqf new file mode 100644 index 00000000000..9211b79bd2b --- /dev/null +++ b/addons/frag/functions/fnc_fragInfo.sqf @@ -0,0 +1,86 @@ +#include "script_component.hpp" +/* + * Author: Lambda.Tiger + * This function returns fragmentation parameters for a specific + * ammo type. + * + * Arguments: + * 0: _ammo - cfgAmmo type of ammo to check + * + * Return Value: + * _ammoInfo + * 0: _fragRange - search range for fragments + * 1: _fragVel - gurney equation calculated velocity + * 2: _fragTypes - array of fragment types + * 3: _fragCount - modified frag count used under assumptions + * of spherical fragmentation + * + * Example: + * ["B_556x45_Ball"] call ace_frag_fnc_fragInfo; + * + * Public: No + */ + +params ["_ammo"]; + +private _ammoInfo = GVAR(fragInfoCache) get _ammo; + +if !(isNil "_ammoInfo") exitWith {_ammoInfo}; + +private _fragTypes = []; +private _warn = false; +if (isArray (configFile >> "cfgAmmo" >> _ammo >> QGVAR(CLASSES))) then { + _fragTypes = getArray (configFile >> "cfgAmmo" >> _ammo >> QGVAR(CLASSES)); +} else { + _warn = true; +}; + +/************ Gurney equation notes *****************/ +// see https://en.wikipedia.org/wiki/Gurney_equations +// +// GURNEY_K is the constant added to _m/_c +// GURNEY_C = sqrt(2E) +// +// _c = 185; // grams of comp-b +// _m = 210; // grams of fragmentating metal +// _k = 3/5; // spherical K factor +// _gC = 2843; // Gurney constant of comp-b in /ms + +// _c = 429; // grams of tritonal +// _m = 496; // grams of fragmentating metal +// _k = 1/2; // cylindrical K factor +// _gC = 2320; // Gurney constant of tritonal in m/s +// Equation - 0.8 for empirical 80% speed +// 0.8 * (((_m / _c) + _k) ^ - (1 / 2)) * _gC; +// or 0.8 * _gC * sqrt (_c /(_m + _c * _k)); (slightly faster to compute) + +private _c = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(CHARGE)); +if (_c == 0) then {_c = 1; _warn = true;}; +private _m = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(METAL)); +if (_m == 0) then {_m = 2; _warn = true;}; +private _k = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(GURNEY_K)); +if (_k == 0) then {_k = 0.8; _warn = true;}; +private _gC = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(GURNEY_C)); +if (_gC == 0) then {_gC = 2440; _warn = true;}; +private _fragCount = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(fragCount)); +if (_fragCount == 0) then {_fragCount = 200; _warn = true;}; + +if (_warn) then { + INFO_1("Ammo class %1 lacks proper explosive properties definitions for frag!",_ammo); +}; + +/********************** _ammoInfo format *************************/ +// 0: _fragRange - search range for fragments +// 1: _fragVel - gurney equation calculated velocity +// 2: _fragTypes - array of fragment types +// 3: _fragCount - modified frag count used under assumptions +// of spherical fragmentation +_ammoInfo = [ + sqrt (_fragCount / (4 * pi * 0.005)), + 0.8 * _gC * sqrt (_c / (_m + _c * _k)), + _fragTypes, + _fragCount / 4 / pi +]; + +GVAR(fragInfoCache) set [_ammo, _ammoInfo]; +_ammoInfo \ No newline at end of file diff --git a/addons/frag/functions/fnc_frago.sqf b/addons/frag/functions/fnc_frago.sqf deleted file mode 100644 index f2700654c31..00000000000 --- a/addons/frag/functions/fnc_frago.sqf +++ /dev/null @@ -1,194 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: Jaynus, NouberNou - * Server func to create the fragmentation for a round. - * - * Arguments: - * 0: Last Position (ASL) - * 1: Velocity - * 2: Ammo Classname - * - * Return Value: - * None - * - * Example: - * [[], [], "handGrenade"] call ace_frag_fnc_frago - * - * Public: No - */ - -#define FRAG_VEC_VAR 0.004 -#define MAX_FRAG_COUNT 50 - -BEGIN_COUNTER(frago); - -params ["_lastPos", "_lastVel", "_shellType"]; -TRACE_3("frago",_lastPos,_lastVel,_shellType); - -// Limit max frag count if there was a recent frag -private _maxFrags = round (MAX_FRAG_COUNT * linearConversion [0.1, 1.5, (CBA_missionTime - GVAR(lastFragTime)), 0.1, 1, true]); -TRACE_2("",_maxFrags,CBA_missionTime - GVAR(lastFragTime)); -GVAR(lastFragTime) = CBA_missionTime; - -private _fragTypes = [ - QGVAR(tiny), QGVAR(tiny), QGVAR(tiny), - QGVAR(tiny_HD), QGVAR(tiny_HD), QGVAR(tiny_HD), - QGVAR(small), QGVAR(small), QGVAR(small), QGVAR(small), - QGVAR(small_HD), QGVAR(small_HD), QGVAR(small_HD), QGVAR(small_HD), - QGVAR(medium_HD), QGVAR(medium_HD), QGVAR(medium_HD), QGVAR(medium_HD), QGVAR(medium_HD) -]; - -private _warn = false; -if (isArray (configFile >> "CfgAmmo" >> _shellType >> QGVAR(CLASSES))) then { - _fragTypes = getArray (configFile >> "CfgAmmo" >> _shellType >> QGVAR(CLASSES)); -} else { - _warn = true; -}; - -private _indirectHitRange = getNumber(configFile >> "CfgAmmo" >> _shellType >> "indirecthitrange"); -private _fragRange = 20 * _indirectHitRange * 4; -// _c = 185; // grams of comp-b -// _m = 210; // grams of fragmentating metal -// _k = 3/5; // spherical K factor -// _gC = 2843; // Gurney constant of comp-b in /ms - -// _c = 429; // grams of tritonal -// _m = 496; // grams of fragmentating metal -// _k = 1/2; // spherical K factor -// _gC = 2320; // Gurney constant of tritonal in /ms - -private _c = getNumber (configFile >> "CfgAmmo" >> _shellType >> QGVAR(CHARGE)); -if (_c == 0) then {_c = 1; _warn = true;}; -private _m = getNumber (configFile >> "CfgAmmo" >> _shellType >> QGVAR(METAL)); -if (_m == 0) then {_m = 2; _warn = true;}; -private _k = getNumber (configFile >> "CfgAmmo" >> _shellType >> QGVAR(GURNEY_K)); -if (_k == 0) then {_k = 0.5; _warn = true;}; -private _gC = getNumber (configFile >> "CfgAmmo" >> _shellType >> QGVAR(GURNEY_C)); -if (_gC == 0) then {_gC = 2440; _warn = true;}; - -if (_warn) then { - INFO_1("Ammo class %1 lacks proper explosive properties definitions for frag!",_shellType); -}; - -// Gunery equation is for a non-fragmenting metal, imperical value of 80% represents fragmentation -private _fragPower = 0.8 * (((_m / _c) + _k) ^ - (1 / 2)) * _gC; - -private _atlPos = ASLtoATL _lastPos; - -private _fragPowerRandom = _fragPower * 0.5; -if ((_atlPos select 2) < 0.5) then { - _lastPos vectorAdd [0, 0, 0.5]; -}; - -private _objects = _atlPos nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], _fragRange]; -// Add unique crews in faster way -{ - { - _objects pushBackUnique _x; - } forEach (crew _x); -} forEach _objects; -TRACE_2("",_fragRange,count _objects); - -private _fragCount = 0; - -private _fragArcs = []; -_fragArcs set [360, 0]; - -private _doRandom = true; -if (_objects isNotEqualTo []) then { - if (GVAR(reflectionsEnabled)) then { - [_lastPos, _shellType] call FUNC(doReflections); - }; - { - private _target = _x; - if (alive _target) then { - (boundingBox _target) params ["_boundingBoxA", "_boundingBoxB"]; - - private _cubic = ((abs (_boundingBoxA select 0)) + (_boundingBoxB select 0)) * ((abs (_boundingBoxA select 1)) + (_boundingBoxB select 1)) * ((abs (_boundingBoxA select 2)) + (_boundingBoxB select 2)); - - if (_cubic <= 1) exitWith {}; - // _doRandom = true; - - private _targetVel = velocity _target; - private _targetPos = getPosASL _target; - private _distance = _targetPos vectorDistance _lastPos; - private _add = ((_boundingBoxB select 2) / 2) + ((((_distance - (_fragpower / 8)) max 0) / _fragPower) * 10); - - _targetPos = _targetPos vectorAdd [ - (_targetVel select 0) * (_distance / _fragPower), - (_targetVel select 1) * (_distance / _fragPower), - _add - ]; - - private _baseVec = _lastPos vectorFromTo _targetPos; - - private _dir = floor (_baseVec call CBA_fnc_vectDir); - private _currentCount = RETDEF(_fragArcs select _dir,0); - if (_currentCount < 10) then { - private _count = ceil (random (sqrt (_m / 1000))); - private _vecVar = FRAG_VEC_VAR; - if (!(_target isKindOf "Man")) then { - ADD(_vecVar,(sqrt _cubic) / 2000); - if ((crew _target) isEqualTo [] && {_count > 0}) then { - _count = 0 max (_count / 2); - }; - }; - for "_i" from 1 to _count do { - private _vec = _baseVec vectorDiff [ - (_vecVar / 2) + (random _vecVar), - (_vecVar / 2) + (random _vecVar), - (_vecVar / 2) + (random _vecVar) - ]; - - private _fp = _fragPower - (random (_fragPowerRandom)); - private _vel = _vec vectorMultiply _fp; - - private _fragObj = (selectRandom _fragTypes) createVehicleLocal [0,0,10000]; - // TRACE_4("targeted",_fp, typeOf _fragObj,_lastPos vectorDistance _targetPos,typeOf _x); - _fragObj setPosASL _lastPos; - _fragObj setVectorDir _vec; - _fragObj setVelocity _vel; - #ifdef DRAW_FRAG_INFO - [ACE_player, _fragObj, [1,0,0,1]] call FUNC(dev_addTrack); - #endif - INC(_fragCount); - INC(_currentCount); - }; - _fragArcs set [_dir, _currentCount]; - }; - }; - if (_fragCount > _maxFrags) exitWith {}; - } forEach _objects; - TRACE_1("targeted",_fragCount); - if (_fragCount > _maxFrags) exitWith {}; - private _randomCount = ceil ((_maxFrags - _fragCount) * 0.35); - TRACE_1("",_randomCount); - private _sectorSize = 360 / (_randomCount max 1); - - if (_doRandom) then { - for "_i" from 1 to _randomCount do { - // Distribute evenly - private _sectorOffset = 360 * (_i - 1) / (_randomCount max 1); - private _randomDir = random (_sectorSize); - _vec = [cos (_sectorOffset + _randomDir), sin (_sectorOffset + _randomDir), sin (30 - (random 45))]; - - _fp = (_fragPower - (random (_fragPowerRandom))); - - _vel = _vec vectorMultiply _fp; - - _fragObj = (selectRandom _fragTypes) createVehicleLocal [0, 0, 10000]; - _fragObj setPosASL _lastPos; - _fragObj setVectorDir _vec; - _fragObj setVelocity _vel; - - #ifdef DRAW_FRAG_INFO - [ACE_player, _fragObj, [1,0.5,0,1]] call FUNC(dev_addTrack); - #endif - INC(_fragCount); - }; - }; -}; - -TRACE_1("total created",_fragCount); - -END_COUNTER(frago); diff --git a/addons/frag/functions/fnc_initBlackList.sqf b/addons/frag/functions/fnc_initBlackList.sqf new file mode 100644 index 00000000000..b67c0a31d93 --- /dev/null +++ b/addons/frag/functions/fnc_initBlackList.sqf @@ -0,0 +1,51 @@ +#include "script_component.hpp" +/* + * Author: Lambda.Tiger + * Adds setting defined blacklisted rounds to blacklist + * + * Arguments: + * Mne + * + * Return Value: + * None + * + * Example: + * [] call ace_frag_fnc_addBlackList + * + * Public: No + */ + +TRACE_1("Beginning blacklist init", GVAR(BlackList)); + +if (!ADDON) then { + [FUNC(initBlackList), [], 1] call CBA_fnc_waitAndExecute; +}; + +// could improve text parsing +private _convArray = parseSimpleArray GVAR(BlackList); + +if (count _convArray == 0 ) exitWith { + TRACE_1("Empty blacklist", _convArray); +}; + +private _errors = 0; +private _items = count _convArray; +for "_i" from 0 to _items - 1 do { + private _ammo = _convArray#_i; + if (typeName _ammo isNotEqualTo "STRING") then { + INFO_1("Improper ammo string at index %1", _i); + INC(_errors); + continue; + }; + + if (!isClass (configFile >> "cfgAmmo" >> _ammo)) then { + INFO_1("Ammo class: %1 does not exist", str _ammo); + INC(_errors); + continue; + }; + + GVAR(shouldFragCache) set [_convArray#_i, [false, false]]; +}; + + +INFO_2("Initialized blacklist. Total items found: %1, number of items failed: %2", _items, _errors); \ No newline at end of file diff --git a/addons/frag/functions/fnc_masterPFH.sqf b/addons/frag/functions/fnc_masterPFH.sqf deleted file mode 100644 index 6e75e809511..00000000000 --- a/addons/frag/functions/fnc_masterPFH.sqf +++ /dev/null @@ -1,56 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: jaynus - * Master single PFH abstraction for all rounds being tracked by frag/spall. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_frag_fnc_masterPFH - * - * Public: No - */ - -BEGIN_COUNTER(PFH); - -// Fast exit if nothing to do -if (GVAR(objects) isEqualTo []) exitWith {END_COUNTER(PFH);}; - -private _gcIndex = []; - -private _iter = 0; -private _objectCount = count GVAR(objects); -while {_objectCount > 0 && {_iter < (GVAR(maxTrackPerFrame) min _objectCount)}} do { - - if (GVAR(lastIterationIndex) >= _objectCount) then { - GVAR(lastIterationIndex) = 0; - }; - private _object = GVAR(objects) select GVAR(lastIterationIndex); - - if (!isNil "_object") then { - private _args = GVAR(arguments) select GVAR(lastIterationIndex); - - if (!(_args call FUNC(pfhRound))) then { - _gcIndex pushBack GVAR(lastIterationIndex); // Add it to the GC if it returns false - }; - }; - INC(_iter); - INC(GVAR(lastIterationIndex)); -}; - -// Clean up dead object references -private _deletionCount = 0; -{ - TRACE_1("GC Projectile", _x); - private _deleteIndex = _x - _deletionCount; - GVAR(objects) deleteAt _deleteIndex; - GVAR(arguments) deleteAt _deleteIndex; - - INC(_deletionCount); -} forEach _gcIndex; - -END_COUNTER(PFH); diff --git a/addons/frag/functions/fnc_pfhRound.sqf b/addons/frag/functions/fnc_pfhRound.sqf deleted file mode 100644 index bd5a229f0ea..00000000000 --- a/addons/frag/functions/fnc_pfhRound.sqf +++ /dev/null @@ -1,59 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: ACE-Team - * - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_frag_fnc_pfhRound - * - * Public: No - */ - -params ["_round", "_lastPos", "_lastVel", "_shellType", "_firedFrame", "_firedPos", "_doSpall", "_spallTrack", "_foundObjectHPIds", "_skip", "_explosive", "_indirectRange", "_force", "_fragPower"]; - -if (_round in GVAR(blackList)) exitWith { - false -}; - -if (!alive _round) exitWith { - if ((diag_frameno - _firedFrame) > 1) then { //skip if deleted within a single frame - if (_skip == 0) then { - if ((_explosive > 0.5 && {_indirectRange >= 4.5} && {_fragPower >= 35}) || {_force == 1}) then { - // shotbullet, shotShell don't seem to explode when touching water, so don't create frags - if ((surfaceIsWater _lastPos) && {(toLower getText (configFile >> "CfgAmmo" >> _shellType >> "simulation")) in ["shotbullet", "shotshell"]}) exitWith {}; - private _fuseDist = getNumber(configFile >> "CfgAmmo" >> _shellType >> "fuseDistance"); - private _isArmed = _firedPos vectorDistance _lastPos >= _fuseDist; // rounds explode at exactly fuseDistance, so check inclusive - TRACE_2("",_fuseDist,_isArmed); - if (!_isArmed) exitWith {TRACE_1("round not armed",_this);}; - TRACE_3("Sending frag event to server",_lastPos,_lastVel,_shellType); - [QGVAR(frag_eh), [_lastPos,_lastVel,_shellType]] call CBA_fnc_serverEvent; - }; - }; - }; - if (_doSpall) then { - DEC(GVAR(spallIsTrackingCount)); - TRACE_1("doSpall",_foundObjectHPIds); - { - if (!isNil "_x") then { - _x removeEventHandler ["hitPart", _foundObjectHPIds select _forEachIndex]; - }; - } forEach _spallTrack; - }; - false -}; - -_this set [1, getPosASL _round]; -_this set [2, velocity _round]; - -if (_doSpall) then { - private _scale = ((count GVAR(objects)) / GVAR(maxTrackPerFrame)) max 0.1; - [_round, _scale, _spallTrack, _foundObjectHPIds] call FUNC(spallTrack); -}; - -true diff --git a/addons/frag/functions/fnc_shouldFrag.sqf b/addons/frag/functions/fnc_shouldFrag.sqf new file mode 100644 index 00000000000..16d69b31179 --- /dev/null +++ b/addons/frag/functions/fnc_shouldFrag.sqf @@ -0,0 +1,55 @@ +#include "script_component.hpp" +/* + * Author: Lambda.Tiger + * This function checks whether an ammunition type should cause fragmentation + * and whether any submunitions exist + * + * Arguments: + * 0: _ammo - cfgAmmo type of ammo to check + * + * Return Value: + * _shouldFrag + * 0 - Should the specific round fragment + * 1 - Does the munition have a child submunition + * + * Example: + * ["B_556x45_Ball"] call ace_frag_fnc_shouldFrag; + * + * Public: No + */ + +params ["_ammo"]; + +private _shouldFrag = GVAR(shouldFragCache) get _ammo; + +if !(isNil "_shouldFrag") exitWith {_shouldFrag}; +// two arguments, 1st for munition should frag, 2nd for +_shouldFrag = [true, false]; + +private _skip = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(skip)); +private _force = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(force)); +private _explosive = getNumber (configFile >> "cfgAmmo" >> _ammo >> "explosive"); +private _indirectHit = getNumber(configFile >> "cfgAmmo" >> _ammo >> "indirectHit"); +private _indirectRange = getNumber(configFile >> "cfgAmmo" >> _ammo >> "indirectHitRange"); + +if (_skip == 1 || (_force == 0 && {_explosive < 0.5 || {_indirectHit < 3 + || {_indirectRange < 5 && _indirectHit < _indirectRange}}})) then { + TRACE_4("No frag" ,_skip, _explosive, _indirectRange, _indirectHit); + _shouldFrag set [0, false]; +}; + +if (GVAR(enSubMunit) > 0) then { + private _hasSubmunit = if (isText (configFile >> "cfgAmmo" >> _ammo >> "submunitionAmmo")) then { + "" isNotEqualTo getText (configFile >> "cfgAmmo" >> _ammo >> "submunitionAmmo"); + } else + { + [] isNotEqualTo getArray (configFile >> "cfgAmmo" >> _ammo >> "submunitionAmmo"); + }; + + _shouldFrag set [1, _hasSubmunit]; + TRACE_2("Submunition" ,_ammo, _hasSubmunit); +}; + +GVAR(shouldFragCache) set [_ammo, _shouldFrag]; + +_shouldFrag \ No newline at end of file diff --git a/addons/frag/functions/fnc_shouldSpall.sqf b/addons/frag/functions/fnc_shouldSpall.sqf new file mode 100644 index 00000000000..af7d28268e0 --- /dev/null +++ b/addons/frag/functions/fnc_shouldSpall.sqf @@ -0,0 +1,31 @@ +#include "script_component.hpp" +/* + * Author: Lambda.Tiger + * This function checks whether an ammunition type should cause spalling + * + * + * Arguments: + * 0: _ammo - cfgAmmo type of ammo to check + * + * Return Value: + * Whether the round type would spall when hitting an object + * + * Example: + * ["B_556x45_Ball"] call ace_frag_fnc_shouldSpall; + * + * Public: No + */ + +params ["_ammo"]; + +private _shouldSpall = GVAR(spallCahche) get _ammo; + +if !(isNil "_shouldSpall") exitWith {_shouldSpall}; + +private _caliber = getNumber (configFile >> "CfgAmmo" >> _ammo >> "caliber"); +private _explosive = getNumber (configFile >> "CfgAmmo" >> _ammo >> "explosive"); +private _idH = getNumber (configFile >> "CfgAmmo" >> _ammo >> "indirectHitRange"); + +_shouldSpall = (_caliber >= 2.5 || _explosive > 0 && _idh >= 1); + +_shouldSpall \ No newline at end of file diff --git a/addons/frag/functions/fnc_spallHP.sqf b/addons/frag/functions/fnc_spallHP.sqf deleted file mode 100644 index 367bea76449..00000000000 --- a/addons/frag/functions/fnc_spallHP.sqf +++ /dev/null @@ -1,42 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: ACE-Team - * Handles the HitPart event - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_frag_fnc_spallHP - * - * Public: No - */ - -//player sideChat format ["f: %1 c: %2", (_this select 0), (count GVAR(spallHPData))]; - -params ["_index", "_hitPartData"]; - -private _initialData = GVAR(spallHPData) param [_index, []]; -if (_initialData isEqualTo []) exitWith {}; - -private _hpRound = (_hitPartData select 0) select 2; -private _round = _initialData select 3; -private _hpDirect = (_hitPartData select 0) select 10; - -if (_hpDirect && {_round == _hpRound}) then { - { - // diag_log text format ["HPDUMP-------------------------------------"]; - // { - // _hp = _x; - // diag_log text format ["%1 --", _forEachIndex]; - // { - // diag_log text format ["%1: %2", _forEachIndex, _x]; - // } forEach _hp; - // } forEach (_this select 1); - [DFUNC(doSpall), [_this, _forEachIndex]] call CBA_fnc_execNextFrame; - // player sideChat "WEEE"; - } forEach _hitPartData; -}; diff --git a/addons/frag/functions/fnc_spallTrack.sqf b/addons/frag/functions/fnc_spallTrack.sqf deleted file mode 100644 index 43dae8afcb0..00000000000 --- a/addons/frag/functions/fnc_spallTrack.sqf +++ /dev/null @@ -1,39 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: ACE-Team - * Add HitPart EventHandler to objects in the projectile's path - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_frag_fnc_spallTrack - * - * Public: No - */ - -params ["_round", "_multiplier", "_foundObjects", "_foundObjectHPIds"]; - -private _delta = (1 / diag_fps) * _multiplier; -private _curPos = getPosASL _round; -private _velocity = velocity _round; - -private _velocityStep = _velocity vectorMultiply _delta; -private _forwardPos = _curPos vectorAdd _velocityStep; - - -private _intersectsWith = lineIntersectsWith [_curPos, _forwardPos]; - -if (_intersectsWith isEqualTo []) exitWith {}; -{ - // diag_log text format ["Adding HP: %1", _x]; - private _index = count GVAR(spallHPData); - private _hpId = _x addEventHandler ["hitPart", compile format ["[%1, _this] call " + QFUNC(spallHP), _index]]; - _foundObjects pushBack _x; - _foundObjectHPIds pushBack _hpId; - private _data = [_hpId, _x, typeOf _round, _round, _curPos, _velocity, 0, _foundObjects, _foundObjectHPIds]; - GVAR(spallHPData) pushBack _data; -} forEach (_intersectsWith select {!(_x in _foundObjects)}); diff --git a/addons/frag/functions/fnc_submunition.sqf b/addons/frag/functions/fnc_submunition.sqf new file mode 100644 index 00000000000..90c31ef6d23 --- /dev/null +++ b/addons/frag/functions/fnc_submunition.sqf @@ -0,0 +1,40 @@ +#include "script_component.hpp" +/* + * Author: Lambda.Tiger + * This function adds event handlers for submunition fragmentation. + * It begins by confirming fragmentation and submunition fragmentation is + * enabled, requests cached (or live calculated) ammo information array. + * and uses that information to add event handlers as needed to the given + * submunition. + * + * Arguments: + * Inherits from BI SubmunitionCraeted EH + * + * Return Value: + * none + * + * Example: + * ["", _submunitionProjectile] call ace_frag_submunition + * + * Public: No + */ + +if (!GVAR(enabled) || {GVAR(enSubMunit) == 0}) exitWith {}; +// params ["_projectile", "_submunitionProjectile", "_pos", "_velocity"]; +params ["", "_submunitionProjectile"]; + +private _shouldFrag = GVAR(shouldFragCache) getOrDefaultCall [typeOf _submunitionProjectile, FUNC(shouldFrag), true]; +_shouldFrag params ["_doFrag", "_doSubmunit"]; + + +if (_doFrag) then { + _submunitionProjectile addEventHandler ["Explode", {[_this, true] call FUNC(doFrag)}]; +}; + +if (_doSubmunit) then { + _submunitionProjectile addEventHandler ["SubmunitionCreated", {_this call FUNC(submunition)}]; +}; + +#ifdef DEBUG_MODE_FULL + [_submunitionProjectile] call UNC(dev_addRound); +#endif \ No newline at end of file diff --git a/addons/frag/functions/script_component.hpp b/addons/frag/functions/script_component.hpp new file mode 100644 index 00000000000..83123137512 --- /dev/null +++ b/addons/frag/functions/script_component.hpp @@ -0,0 +1 @@ +#include "\z\ace\addons\frag\script_component.hpp" \ No newline at end of file diff --git a/addons/frag/initSettings.inc.sqf b/addons/frag/initSettings.inc.sqf index 29fbefe6fe4..b0ba7d89e57 100644 --- a/addons/frag/initSettings.inc.sqf +++ b/addons/frag/initSettings.inc.sqf @@ -26,29 +26,29 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; /// !*! TODO: add stringtable entries [ - QGVAR(enSubMunit), "LIST", - ["Enable submunition fragmentation", "Enables submunition fragmentation when fragmentation is enabled"], + QGVAR(enSubMunit), "LIST", + ["Enable submunition fragmentation", "Enables submunition fragmentation when fragmentation is enabled"], [_category, LSTRING(Frag)], - [[2, 1, 0], ["complex fragementation","simple fragmentation","no fragmentation"], 2] + [[2, 1, 0], ["complex fragementation","simple fragmentation","no fragmentation"], 2] ] call CBA_fnc_addSetting; [ - QGVAR(reflectionsEnabled), "CHECKBOX", - "Enable reflections", + QGVAR(reflectionsEnabled), "CHECKBOX", + "Enable reflections", [_category, LSTRING(Frag)], - false + false ] call CBA_fnc_addSetting; [ - QGVAR(atLeastOne), "CHECKBOX", - "At least one round hit", + QGVAR(atLeastOne), "CHECKBOX", + "At least one round hit", [_category, LSTRING(Frag)], - true + true ] call CBA_fnc_addSetting; [ - QGVAR(BlackList), "EDITBOX", - ["Default BlackList", "Array of ammo classnames strings to blackist fragmentation for."], + QGVAR(BlackList), "EDITBOX", + ["Default BlackList", "Array of ammo classnames strings to blackist fragmentation for."], [_category, LSTRING(Frag)], - QUOTE(['B_556x45_Ball']) + QUOTE(['B_556x45_Ball']) ] call CBA_fnc_addSetting; diff --git a/addons/frag/initSettingsDebug.inc.sqf b/addons/frag/initSettingsDebug.inc.sqf index 92b4a78b95e..c6b9ce495d9 100644 --- a/addons/frag/initSettingsDebug.inc.sqf +++ b/addons/frag/initSettingsDebug.inc.sqf @@ -1,54 +1,54 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; [ - QGVAR(debugOptions), - "CHECKBOX", - "Enable debug mode", - [_category, LSTRING(Debug)], - true // [min, max, default, trailing decimals] + QGVAR(debugOptions), + "CHECKBOX", + "Enable debug mode", + [_category, LSTRING(Debug)], + true // [min, max, default, trailing decimals] ] call CBA_fnc_addSetting; // debug options [ - QGVAR(dbgSphere), - "CHECKBOX", - "Enable debug impact spheres", - [_category, LSTRING(Debug)], - false, - 0, - {}, - true + QGVAR(dbgSphere), + "CHECKBOX", + "Enable debug impact spheres", + [_category, LSTRING(Debug)], + false, + 0, + {}, + true ] call CBA_fnc_addSetting; [ - QGVAR(frameHint), - "CHECKBOX", - "Show framerate hint", - [_category, LSTRING(Debug)], - true + QGVAR(frameHint), + "CHECKBOX", + "Show framerate hint", + [_category, LSTRING(Debug)], + true ] call CBA_fnc_addSetting; [ - QGVAR(fadeRounds), - "CHECKBOX", - "Fade round traces over time", - [_category, LSTRING(Debug)], - true + QGVAR(fadeRounds), + "CHECKBOX", + "Fade round traces over time", + [_category, LSTRING(Debug)], + true ] call CBA_fnc_addSetting; [ - QGVAR(dltTrace), - "CHECKBOX", - "Delete fire trace on fade", - [_category, LSTRING(Debug)], - true + QGVAR(dltTrace), + "CHECKBOX", + "Delete fire trace on fade", + [_category, LSTRING(Debug)], + true ] call CBA_fnc_addSetting; [ - QGVAR(drawHitBox), - "CHECKBOX", - "Draw unit hitboxes", - [_category, LSTRING(Debug)], - true + QGVAR(drawHitBox), + "CHECKBOX", + "Draw unit hitboxes", + [_category, LSTRING(Debug)], + true ] call CBA_fnc_addSetting; diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index f57bb7ad126..a070ea952e3 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -17,4 +17,4 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define ACE_TRACE_DRAW_INC 1 +#define ACE_FRAG_SPALL_HOLDOFF 0.1 From 4e0e18a9c4a1e1ca4044d49612f327f9eec10a83 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 8 Jan 2024 15:29:41 -0600 Subject: [PATCH 003/282] Added temporary todo list to ace frag README.md --- addons/frag/README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/addons/frag/README.md b/addons/frag/README.md index e5c9a35a05d..8c1ed22103f 100644 --- a/addons/frag/README.md +++ b/addons/frag/README.md @@ -1,4 +1,13 @@ ace_frag ======== -Explosive fragmentation, round spalling, and explosive reflection \ No newline at end of file +Explosive fragmentation, round spalling, and explosive reflection + +TODO: +- More extensive MP testing +- move from FIRED to init EH's +- rework spalling position finding +- Look at spalling per material type +- performance optimization +- Finish stringtable expansion with additional normal & debug settings +- cDLC, RHS, CUP compats \ No newline at end of file From 51196804f9dc085cb1241420604b3b83d7b53371 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 8 Jan 2024 15:33:36 -0600 Subject: [PATCH 004/282] Fixed accidental tab addition --- addons/frag/CfgAmmo.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index 1cebe063740..bb80aad48a9 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -19,7 +19,7 @@ class CfgAmmo { class Bomb_04_F: ammo_Bomb_LaserGuidedBase { GVAR(enabled) = 1; - GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large ), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; + GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; GVAR(fragCount) = 17500; GVAR(metal) = 140000; GVAR(charge) = 87000; From 742304ec252f37267264654fc43733989494885d Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 8 Jan 2024 15:33:45 -0600 Subject: [PATCH 005/282] expanded TODOs --- addons/frag/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/frag/README.md b/addons/frag/README.md index 8c1ed22103f..a658e5a9d29 100644 --- a/addons/frag/README.md +++ b/addons/frag/README.md @@ -10,4 +10,5 @@ TODO: - Look at spalling per material type - performance optimization - Finish stringtable expansion with additional normal & debug settings -- cDLC, RHS, CUP compats \ No newline at end of file +- cDLC, RHS, CUP compats +- look at / try to understand explosion reflections \ No newline at end of file From 370f1ce67f99b7018551f341a0a4bf9ee489fae4 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 8 Jan 2024 15:38:19 -0600 Subject: [PATCH 006/282] Added shot parents to spalling --- addons/frag/functions/fnc_doSpallMomentum.sqf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_doSpallMomentum.sqf b/addons/frag/functions/fnc_doSpallMomentum.sqf index 6881033dd6c..978dd73447f 100644 --- a/addons/frag/functions/fnc_doSpallMomentum.sqf +++ b/addons/frag/functions/fnc_doSpallMomentum.sqf @@ -90,12 +90,14 @@ private _fragSpawnType = switch (true) do default { QGVAR(spall_huge) }; }; +// Shot parent +private _shotParent = getShotParents _projectile; //***** Spawn spalled fragments private _fragSpawner = createVehicleLocal [_fragSpawnType, ASLToATL _spallPos, [], 0, "CAN_COLLIDE"]; _fragSpawner setVectorDirandUp [vectorDir _projectile, vectorUp _projectile]; _fragSpawner setVelocity _lVelUnit; - +_fragSpawner setShotParents _shotParent; #ifdef DEBUG_MODE_FULL systemChat ("bSpd: " + str speed _fragSpawner + ", frag: " + _fragSpawnType + ", dm: " + str _deltaMomentum); From 42832aa95c2b1a86b4db43a519397ff6644f8abf Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 8 Jan 2024 15:38:26 -0600 Subject: [PATCH 007/282] Clarified variable names --- addons/frag/functions/fnc_doSpallMomentum.sqf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/addons/frag/functions/fnc_doSpallMomentum.sqf b/addons/frag/functions/fnc_doSpallMomentum.sqf index 978dd73447f..3f0f74a8aa3 100644 --- a/addons/frag/functions/fnc_doSpallMomentum.sqf +++ b/addons/frag/functions/fnc_doSpallMomentum.sqf @@ -94,14 +94,14 @@ private _fragSpawnType = switch (true) do private _shotParent = getShotParents _projectile; //***** Spawn spalled fragments -private _fragSpawner = createVehicleLocal [_fragSpawnType, ASLToATL _spallPos, [], 0, "CAN_COLLIDE"]; -_fragSpawner setVectorDirandUp [vectorDir _projectile, vectorUp _projectile]; -_fragSpawner setVelocity _lVelUnit; -_fragSpawner setShotParents _shotParent; +private _spallSpawner = createVehicleLocal [_fragSpawnType, ASLToATL _spallPos, [], 0, "CAN_COLLIDE"]; +_spallSpawner setVectorDirandUp [vectorDir _projectile, vectorUp _projectile]; +_spallSpawner setVelocity _lVelUnit; +_spallSpawner setShotParents _shotParent; #ifdef DEBUG_MODE_FULL -systemChat ("bSpd: " + str speed _fragSpawner + ", frag: " + _fragSpawnType + ", dm: " + str _deltaMomentum); -_fragSpawner addEventHandler [ +systemChat ("bSpd: " + str speed _spallSpawner + ", frag: " + _fragSpawnType + ", dm: " + str _deltaMomentum); +_spallSpawner addEventHandler [ "SubmunitionCreated", { params ["", "_subProj"]; From c95a8ca21b48f2348b460f09258a18cb8a87a6d1 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 8 Jan 2024 16:05:46 -0600 Subject: [PATCH 008/282] Fixed configname conflict after merging spall & frag cfgAmmos --- addons/frag/CfgAmmo.hpp | 52 ++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index bb80aad48a9..0cdd3c26021 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -362,21 +362,57 @@ class CfgAmmo { airFriction = QUOTE(BASE_DRAG_HD*0.5); caliber = 2.8; }; + + ////////////////// + + class GVAR(spallBase) : B_65x39_Caseless + { + access = 3; + submunitionAmmo[] = {"ace_frag_small_c",4,"ace_frag_medium_c",3,"ace_frag_large_c",2,"ace_frag_huge_c",1}; + submunitionConeType[] = {"random", 20}; + submunitionConeAngle = 40; + submunitionDirectionType = "SubmunitionModelDirection"; + triggerTime = 0; + submunitionInitialOffset[] = {0,0,0}; + submunitionInitSpeed = 0; + triggerSpeedCoef[] = {0.75,1.25}; + deleteParentWhenTriggered = 1; + submunitionParentSpeedCoef = 1; + }; + + class GVAR(spall_tiny) : GVAR(spallBase) + { + submunitionAmmo[] = {"ace_frag_small_c", 4, "ace_frag_medium_c", 1}; + submunitionConeType[] = {"poissondisccenter", 5}; + submunitionConeAngle = 40; + }; - class GVAR(spall_small): GVAR(small) { - timeToLive = 0.2; + class GVAR(spall_small) : GVAR(spallBase) + { + submunitionAmmo[] = {"ace_frag_small_c", 4,"ace_frag_medium_c", 1}; + submunitionConeType[] = {"poissondisccenter", 10}; + submunitionConeAngle = 40; }; - class GVAR(spall_medium): GVAR(medium) { - timeToLive = 0.2; + class GVAR(spall_medium) : GVAR(spallBase) + { + submunitionAmmo[] = {"ace_frag_small_c", 2, "ace_frag_small_HD_c", 1,"ace_frag_medium_c", 3, "ace_frag_medium_HD_c", 1, "ace_frag_large_c", 2}; + submunitionConeType[] = {"poissondisccenter", 15}; + submunitionConeAngle = 40; }; - class GVAR(spall_large): GVAR(large) { - timeToLive = 0.25; + class GVAR(spall_large) : GVAR(spallBase) + { + submunitionAmmo[] = {"ace_frag_tiny_c", 3, "ace_frag_tiny_HD_c", 3, "ace_frag_small_c", 4, "ace_frag_small_HD_c", 4, "ace_frag_medium_HD_c", 5, "ace_frag_large_c", 2, "ace_frag_large_HD_c", 2, "ace_frag_huge_c",1}; + submunitionConeType[] = {"poissondisccenter", 15}; + submunitionConeAngle = 40; }; - class GVAR(spall_huge): GVAR(huge) { - timeToLive = 0.3; + class GVAR(spall_huge) : GVAR(spallBase) + { + submunitionAmmo[] = {"ace_frag_tiny_c", 3, "ace_frag_tiny_HD_c", 3, "ace_frag_small_c", 4, "ace_frag_small_HD_c", 4, "ace_frag_medium_HD_c", 5, "ace_frag_large_c", 2, "ace_frag_large_HD_c", 2, "ace_frag_huge_c",1}; + submunitionConeType[] = {"poissondisccenter", 20}; + submunitionConeAngle = 40; }; From c6ba93a26dab30a3cb2d9e2cc7715a10dc9bf305 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 8 Jan 2024 18:06:30 -0600 Subject: [PATCH 009/282] Split configs and added init EH --- addons/frag/CfgAmmo.hpp | 859 +--------------------------- addons/frag/cfgAmmoBaseEH.hpp | 84 +++ addons/frag/cfgAmmoFragAddition.hpp | 282 +++++++++ addons/frag/cfgAmmoFragSpawner.hpp | 518 +++++++++++++++++ addons/frag/cfgAmmoSpall.hpp | 49 ++ 5 files changed, 938 insertions(+), 854 deletions(-) create mode 100644 addons/frag/cfgAmmoBaseEH.hpp create mode 100644 addons/frag/cfgAmmoFragAddition.hpp create mode 100644 addons/frag/cfgAmmoFragSpawner.hpp create mode 100644 addons/frag/cfgAmmoSpall.hpp diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index 0cdd3c26021..35f2c7e8999 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -3,290 +3,13 @@ #define BASE_DRAG_HD (BASE_DRAG * HD_MULT) class CfgAmmo { + class B_65x39_Caseless; - // ~~~~ Bombs: - class ammo_Bomb_LaserGuidedBase; - class Bo_GBU12_LGB: ammo_Bomb_LaserGuidedBase { - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; - GVAR(fragCount) = 17500; - GVAR(metal) = 140000; - GVAR(charge) = 87000; - GVAR(gurney_c) = 2320; - GVAR(gurney_k) = "1/2"; - }; - class Bomb_04_F: ammo_Bomb_LaserGuidedBase { - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; - GVAR(fragCount) = 17500; - GVAR(metal) = 140000; - GVAR(charge) = 87000; - GVAR(gurney_c) = 2320; - GVAR(gurney_k) = "1/2"; - }; - class BombCore; - class Bo_Mk82: BombCore { - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; - GVAR(fragCount) = 17500; - GVAR(metal) = 140000; - GVAR(charge) = 87000; - GVAR(gurney_c) = 2320; - GVAR(gurney_k) = "1/2"; - }; - - // ~~~~ Grenades: - class GrenadeBase; - class Grenade; - class GrenadeHand: Grenade { - GVAR(enabled) = 1; - - GVAR(skip) = 0; - GVAR(force) = 1; - /* - These values are based on the M67 Grenade, should be tweaked for - individual grenades. - */ - GVAR(classes)[] = {QGVAR(tiny)}; - GVAR(fragCount) = 1000; - GVAR(metal) = 210; // metal in grams - GVAR(charge) = 185; // explosive in grams - GVAR(gurney_c) = 2843; // Gurney velocity constant for explosive type. See: http://en.wikipedia.org/wiki/Gurney_equations - GVAR(gurney_k) = "3/5"; // Gurney shape factor, in this case a sphere. See: http://en.wikipedia.org/wiki/Gurney_equations - }; - class GrenadeHand_stone: GrenadeHand { - GVAR(skip) = 1; - }; - class SmokeShell: GrenadeHand { - GVAR(skip) = 1; - }; - class G_40mm_HE: GrenadeBase { - // Source: http://www.inetres.com/gp/military/infantry/grenade/40mm_ammo.html#M441 - GVAR(enabled) = 1; - GVAR(force) = 1; - - GVAR(classes)[] = {QGVAR(small)}; - GVAR(fragCount) = 800; // guess based on probability hit of 1% - GVAR(metal) = 200; - GVAR(charge) = 32; - GVAR(gurney_c) = 2700; - GVAR(gurney_k) = "3/5"; // interior fragmenter/charge is a sphere - }; - class G_40mm_HEDP: G_40mm_HE { - // Source: http://www.inetres.com/gp/military/infantry/grenade/40mm_ammo.html#M433 - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(small_HD)}; - GVAR(fragCount) = 270; // seems to have greater framentation ability, but lower range per source - GVAR(metal) = 200; - GVAR(charge) = 45; - GVAR(gurney_c) = 2830; - GVAR(gurney_k) = "1/2"; - }; - - class ACE_G_40mm_HEDP: G_40mm_HEDP {}; - class ACE_G_40mm_HE: G_40mm_HE {}; - class ACE_G_40mm_Practice: ACE_G_40mm_HE { - GVAR(skip) = 1; - GVAR(force) = 0; - EGVAR(vehicle_damage,incendiary) = 0; - }; - // What is this even? - class ACE_G40mm_HE_VOG25P: G_40mm_HE { - GVAR(skip) = 0; - GVAR(force) = 1; - }; - - - // ~~~~ RPGs: - class MissileBase; - class R_PG32V_F; - class R_TBG32V_F: R_PG32V_F { // Thermobaric - GVAR(enabled) = 1; - GVAR(fragCount) = 200; - GVAR(metal) = 400; - GVAR(charge) = 210; - GVAR(gurney_c) = 2800; - GVAR(gurney_k) = "3/5"; - GVAR(classes)[] = {QGVAR(medium_HD)}; - }; - class M_Titan_AA: MissileBase { - GVAR(skip) = 1; - }; - class M_Titan_AT: MissileBase { - GVAR(skip) = 1; - }; - class M_Titan_AP: M_Titan_AT { // "anti personnel" - GVAR(skip) = 0; - GVAR(fragCount) = 800; // guesstimate / provides ~80 m frag range - GVAR(enabled) = 1; - GVAR(metal) = 400; - GVAR(charge) = 210; - GVAR(gurney_c) = 2800; - GVAR(gurney_k) = "3/5"; - GVAR(classes)[] = {QGVAR(medium_HD)}; - }; - - // https://ofb.gov.in/product/products/product-details/84-mm-he-round-ffv-441-b - // https://armypubs.army.mil/epubs/DR_pubs/DR_a/pdf/web/ARN18072_TC%203-22x84%20FINAL%20WEB.pdf (page 99, Table A-6. HE 441D RS, 84-mm projectile) - class R_MRAAWS_HEAT_F; - class R_MRAAWS_HE_F: R_MRAAWS_HEAT_F { - GVAR(enabled) = 1; - GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) - GVAR(metal) = 2300; - GVAR(charge) = 590; - GVAR(gurney_c) = 2800; - GVAR(gurney_k) = "1/2"; - GVAR(classes)[] = {QGVAR(small)}; - }; - - - // ~~~~ Missiles: - class M_PG_AT; - class M_AT: M_PG_AT { // DAR (Hydra 70) - // Source: http://fas.org/man/dod-101/sys/missile/hydra-70.htm - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) - GVAR(metal) = 3850; - GVAR(charge) = 1040; - GVAR(gurney_c) = 2700; - GVAR(gurney_k) = "1/2"; - }; - class RocketBase; - class R_80mm_HE: RocketBase { - GVAR(skip) = 1; - }; - class Missile_AGM_02_F: MissileBase { - // Source: http://fas.org/man/dod-101/sys/smart/agm-65.htm - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 1600; // guesstimate / provides ~112 m frag range (1% chance to hit) - GVAR(metal) = 56250; - GVAR(charge) = 39000; - GVAR(gurney_c) = 2700; - GVAR(gurney_k) = "1/2"; - }; - class Rocket_04_HE_F: MissileBase { // Shrieker (Hydra 70) - GVAR(enabled) = 1; - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) - GVAR(metal) = 3850; - GVAR(charge) = 1040; - GVAR(gurney_c) = 2700; - GVAR(gurney_k) = "1/2"; - }; - class M_Scalpel_AT: MissileBase { // 9K121 Vikhr - GVAR(enabled) = 1; - GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 800; // guesstimate based on frag jacket, provides ~80 m frag range (1% chance to hit) - GVAR(metal) = 10000; - GVAR(charge) = 3000; - GVAR(gurney_c) = 2700; - GVAR(gurney_k) = "1/2"; - }; - class ACE_Hellfire_AGM114K: M_Scalpel_AT { - // Source: http://www.designation-systems.net/dusrm/m-114.html - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 350; // guesstimate based on frag jacket, provides ~50 m frag range (1% chance to hit) - GVAR(metal) = 8000; - GVAR(charge) = 2400; - GVAR(gurney_c) = 2700; - GVAR(gurney_k) = "1/2"; - }; - class M_Air_AA: MissileBase { - GVAR(skip) = 1; - }; - class Missile_AA_04_F: MissileBase { - GVAR(skip) = 1; - }; - - // curator ammo entries - class ShellBase; - class Sh_125mm_HEAT; - class Sh_155mm_AMOS: ShellBase { - // Source: http://www.globalsecurity.org/military/systems/munitions/m795.htm - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; - GVAR(fragCount) = 3250; // http://18.195.19.6/bitstream/handle/20.500.12242/1200/15-01916.pdf?sequence=1&isAllowed=y - GVAR(metal) = 36000; - GVAR(charge) = 9979; - GVAR(gurney_c) = 2440; - GVAR(gurney_k) = "1/2"; - }; - class Sh_82mm_AMOS: Sh_155mm_AMOS { - //http://65.175.100.54/uxofiles/mulvaney/techdatasheets/81mm-HE-M821.pdf - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 1600; // based on mass and fragment energy/count - GVAR(metal) = 2500; - GVAR(charge) = 726; - GVAR(gurney_c) = 2440; - GVAR(gurney_k) = "1/2"; - }; - class ModuleOrdnanceMortar_F_Ammo: Sh_82mm_AMOS { - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(metal) = 800; - GVAR(charge) = 4200; - GVAR(gurney_c) = 2320; - GVAR(gurney_k) = "1/2"; - }; - class Sh_105mm_HEAT_MP: Sh_125mm_HEAT { - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 1600; // based on mass and fragment energy/count - GVAR(metal) = 11400; - GVAR(charge) = 7100; - GVAR(gurney_c) = 2800; - GVAR(gurney_k) = "1/2"; - }; - class Sh_120mm_HE: ShellBase { - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 2000; - GVAR(metal) = 23000; - GVAR(charge) = 3148; - GVAR(gurney_c) = 2830; - GVAR(gurney_k) = "1/2"; - }; - class Sh_125mm_HE: Sh_120mm_HE { - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(metal) = 16000; - GVAR(charge) = 3200; - GVAR(gurney_c) = 2440; - GVAR(gurney_k) = "1/2"; - }; - class ModuleOrdnanceHowitzer_F_ammo: Sh_155mm_AMOS { - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; - GVAR(metal) = 1950; - GVAR(charge) = 15800; - GVAR(gurney_c) = 2320; - GVAR(gurney_k) = "1/2"; - }; - // Special - class Default; - class Laserbeam : Default { - GVAR(skip) = 1; - }; + #include "cfgAmmoBaseEH.hpp" + #include "cfgAmmoSpall.hpp" + #include "cfgAmmoFragAddition.hpp" + #include "cfgAmmoFragSpawner.hpp" - class B_65x39_Caseless; class GVAR(base): B_65x39_Caseless { ACE_damageType = "grenade"; // compatibility with medical_damage, shrapnel should produce grenade wounds timeToLive = 4; @@ -362,576 +85,4 @@ class CfgAmmo { airFriction = QUOTE(BASE_DRAG_HD*0.5); caliber = 2.8; }; - - ////////////////// - - class GVAR(spallBase) : B_65x39_Caseless - { - access = 3; - submunitionAmmo[] = {"ace_frag_small_c",4,"ace_frag_medium_c",3,"ace_frag_large_c",2,"ace_frag_huge_c",1}; - submunitionConeType[] = {"random", 20}; - submunitionConeAngle = 40; - submunitionDirectionType = "SubmunitionModelDirection"; - triggerTime = 0; - submunitionInitialOffset[] = {0,0,0}; - submunitionInitSpeed = 0; - triggerSpeedCoef[] = {0.75,1.25}; - deleteParentWhenTriggered = 1; - submunitionParentSpeedCoef = 1; - }; - - class GVAR(spall_tiny) : GVAR(spallBase) - { - submunitionAmmo[] = {"ace_frag_small_c", 4, "ace_frag_medium_c", 1}; - submunitionConeType[] = {"poissondisccenter", 5}; - submunitionConeAngle = 40; - }; - - class GVAR(spall_small) : GVAR(spallBase) - { - submunitionAmmo[] = {"ace_frag_small_c", 4,"ace_frag_medium_c", 1}; - submunitionConeType[] = {"poissondisccenter", 10}; - submunitionConeAngle = 40; - }; - - class GVAR(spall_medium) : GVAR(spallBase) - { - submunitionAmmo[] = {"ace_frag_small_c", 2, "ace_frag_small_HD_c", 1,"ace_frag_medium_c", 3, "ace_frag_medium_HD_c", 1, "ace_frag_large_c", 2}; - submunitionConeType[] = {"poissondisccenter", 15}; - submunitionConeAngle = 40; - }; - - class GVAR(spall_large) : GVAR(spallBase) - { - submunitionAmmo[] = {"ace_frag_tiny_c", 3, "ace_frag_tiny_HD_c", 3, "ace_frag_small_c", 4, "ace_frag_small_HD_c", 4, "ace_frag_medium_HD_c", 5, "ace_frag_large_c", 2, "ace_frag_large_HD_c", 2, "ace_frag_huge_c",1}; - submunitionConeType[] = {"poissondisccenter", 15}; - submunitionConeAngle = 40; - }; - - class GVAR(spall_huge) : GVAR(spallBase) - { - submunitionAmmo[] = {"ace_frag_tiny_c", 3, "ace_frag_tiny_HD_c", 3, "ace_frag_small_c", 4, "ace_frag_small_HD_c", 4, "ace_frag_medium_HD_c", 5, "ace_frag_large_c", 2, "ace_frag_large_HD_c", 2, "ace_frag_huge_c",1}; - submunitionConeType[] = {"poissondisccenter", 20}; - submunitionConeAngle = 40; - }; - - - // format fragType_spawn_n_range - /********************* ***************************/ - class GVAR(spawnbase) : B_65x39_Caseless { - access = 2; - deleteParentWhenTriggered = 1; - submunitionConeType[] = {"random", 25}; - submunitionAmmo[] = {QGVAR(tiny), 3, QGVAR(tiny_HD), 3, QGVAR(small), 4, QGVAR(small_HD), 4, QGVAR(medium_HD), 5}; - submunitionDirectionType = "SubmunitionModelDirection"; - submunitionConeAngleHorizontal = 15; - submunitionConeAngle = 87; - submunitionInitialOffset[] = {0,0,0}; - submunitionInitSpeed = 1000; - submunitionParentSpeedCoef = 1; - triggerSpeedCoef[] = {0.75, 1.5}; - triggerTime = 0; - }; - - /********************* ***************************/ - class GVAR(def_10) : GVAR(spawnbase) { - submunitionConeType[] = {"random", 10}; - }; - class GVAR(def_10_lo) : GVAR(def_10) { - submunitionConeAngle = 85; - }; - class GVAR(def_10_mid) : GVAR(def_10) { - submunitionConeAngle = 85; - triggerSpeedCoef[] = {-1.5, 1.5}; - }; - class GVAR(def_10_hi) : GVAR(def_10) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - class GVAR(def_10_top) : GVAR(def_10) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - - /********************* ***************************/ - class GVAR(def_15) : GVAR(spawnbase) { - submunitionConeType[] = {"random", 15}; - }; - class GVAR(def_15_lo) : GVAR(def_15) { - submunitionConeAngle = 85; - }; - class GVAR(def_15_mid) : GVAR(def_15) { - submunitionConeAngle = 85; - triggerSpeedCoef[] = {-1.5, 1.5}; - }; - class GVAR(def_15_hi) : GVAR(def_15) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - class GVAR(def_15_top) : GVAR(def_15) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - - /********************* ***************************/ - class GVAR(def_5) : GVAR(spawnbase) { - submunitionConeType[] = {"random", 5}; - }; - class GVAR(def_5_lo) : GVAR(def_5) { - submunitionConeAngle = 85; - }; - class GVAR(def_5_mid) : GVAR(def_5) { - submunitionConeAngle = 85; - triggerSpeedCoef[] = {-1.5, 1.5}; - }; - class GVAR(def_5_hi) : GVAR(def_5) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - class GVAR(def_5_top) : GVAR(def_5) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - - /********************* ***************************/ - class GVAR(def_tiny_15) : GVAR(spawnbase) { - submunitionConeType[] = {"random", 15}; - submunitionAmmo = QGVAR(tiny); - }; - class GVAR(def_tiny_15_lo) : GVAR(def_tiny_15) { - submunitionConeAngle = 85; - }; - class GVAR(def_tiny_15_mid) : GVAR(def_tiny_15) { - submunitionConeAngle = 85; - triggerSpeedCoef[] = {-1.5, 1.5}; - }; - class GVAR(def_tiny_15_hi) : GVAR(def_tiny_15) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - class GVAR(def_tiny_15_top) : GVAR(def_tiny_15) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - - /********************* ***************************/ - class GVAR(def_tiny_10) : GVAR(spawnbase) { - submunitionConeType[] = {"random", 10}; - submunitionAmmo = QGVAR(tiny); - }; - class GVAR(def_tiny_10_lo) : GVAR(def_tiny_10) { - submunitionConeAngle = 85; - }; - class GVAR(def_tiny_10_mid) : GVAR(def_tiny_10) { - submunitionConeAngle = 85; - triggerSpeedCoef[] = {-1.5, 1.5}; - }; - class GVAR(def_tiny_10_hi) : GVAR(def_tiny_10) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - class GVAR(def_tiny_10_top) : GVAR(def_tiny_10) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - - /********************* ***************************/ - class GVAR(def_tiny_5) : GVAR(spawnbase) { - submunitionConeType[] = {"random", 5}; - submunitionAmmo = QGVAR(tiny); - }; - class GVAR(def_tiny_5_lo) : GVAR(def_tiny_5) { - submunitionConeAngle = 85; - }; - class GVAR(def_tiny_5_mid) : GVAR(def_tiny_5) { - submunitionConeAngle = 85; - triggerSpeedCoef[] = {-1.5, 1.5}; - }; - class GVAR(def_tiny_5_hi) : GVAR(def_tiny_5) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - class GVAR(def_tiny_5_top) : GVAR(def_tiny_5) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - /********************* ***************************/ - class GVAR(def_small_15) : GVAR(spawnbase) { - submunitionConeType[] = {"random", 15}; - submunitionAmmo = QGVAR(small); - }; - class GVAR(def_small_15_lo) : GVAR(def_small_15) { - submunitionConeAngle = 815; - }; - class GVAR(def_small_15_mid) : GVAR(def_small_15) { - submunitionConeAngle = 815; - triggerSpeedCoef[] = {-1.15, 1.15}; - }; - class GVAR(def_small_15_hi) : GVAR(def_small_15) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.15, -0.715}; - }; - class GVAR(def_small_15_top) : GVAR(def_small_15) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.15, -0.715}; - }; - /********************* ***************************/ - class GVAR(def_small_10) : GVAR(spawnbase) { - submunitionConeType[] = {"random", 10}; - submunitionAmmo = QGVAR(small); - }; - class GVAR(def_small_10_lo) : GVAR(def_small_10) { - submunitionConeAngle = 810; - }; - class GVAR(def_small_10_mid) : GVAR(def_small_10) { - submunitionConeAngle = 810; - triggerSpeedCoef[] = {-1.10, 1.10}; - }; - class GVAR(def_small_10_hi) : GVAR(def_small_10) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.10, -0.710}; - }; - class GVAR(def_small_10_top) : GVAR(def_small_10) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.10, -0.710}; - }; - /********************* ***************************/ - class GVAR(def_small_5) : GVAR(spawnbase) { - submunitionConeType[] = {"random", 5}; - submunitionAmmo = QGVAR(small); - }; - class GVAR(def_small_5_lo) : GVAR(def_small_5) { - submunitionConeAngle = 85; - }; - class GVAR(def_small_5_mid) : GVAR(def_small_5) { - submunitionConeAngle = 85; - triggerSpeedCoef[] = {-1.5, 1.5}; - }; - class GVAR(def_small_5_hi) : GVAR(def_small_5) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - class GVAR(def_small_5_top) : GVAR(def_small_5) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.5, -0.75}; - }; - - /******************* targeted fragments ********************/ - class GVAR(spawnbase_targeted) : GVAR(spawnbase) { - access = 2; - submunitionConeType[] = {"random", 2}; - submunitionConeAngle = 2; - submunitionInitSpeed = 0; - triggerSpeedCoef[] = {0.5, 1}; - }; - - class GVAR(tiny_spawner_2_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(tiny_spawner_2_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(tiny_spawner_2_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(tiny_spawner_3_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(tiny_spawner_3_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(tiny_spawner_3_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; - }; - - class GVAR(tiny_HD_spawner_2_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(tiny_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(tiny_HD_spawner_2_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(tiny_HD_spawner_3_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(tiny_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(tiny_HD_spawner_3_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; - }; - - class GVAR(small_spawner_2_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(small_spawner_2_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(small_spawner_2_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(small_spawner_3_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(small_spawner_3_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(small_spawner_3_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; - }; - - class GVAR(small_HD_spawner_2_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(small_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(small_HD_spawner_2_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(small_HD_spawner_3_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(small_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(small_HD_spawner_3_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; - }; - - class GVAR(medium_spawner_2_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(medium_spawner_2_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(medium_spawner_2_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(medium_spawner_3_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(medium_spawner_3_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(medium_spawner_3_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; - }; - - class GVAR(medium_HD_spawner_2_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(medium_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(medium_HD_spawner_2_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(medium_HD_spawner_3_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(medium_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(medium_HD_spawner_3_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; - }; - - class GVAR(large_spawner_2_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(large_spawner_2_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(large_spawner_2_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(large_spawner_3_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(large_spawner_3_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(large_spawner_3_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; - }; - - class GVAR(large_HD_spawner_2_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(large_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(large_HD_spawner_2_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(large_HD_spawner_3_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(large_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(large_HD_spawner_3_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; - }; - - class GVAR(huge_spawner_2_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(huge_spawner_2_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(huge_spawner_2_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(huge_spawner_3_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(huge_spawner_3_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(huge_spawner_3_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; - }; - - class GVAR(huge_HD_spawner_2_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(huge_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(huge_HD_spawner_2_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; - }; - class GVAR(huge_HD_spawner_3_short) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(huge_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; - }; - class GVAR(huge_HD_spawner_3_far) : GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; - }; }; \ No newline at end of file diff --git a/addons/frag/cfgAmmoBaseEH.hpp b/addons/frag/cfgAmmoBaseEH.hpp new file mode 100644 index 00000000000..f76d01b8079 --- /dev/null +++ b/addons/frag/cfgAmmoBaseEH.hpp @@ -0,0 +1,84 @@ +#define ACE_FRAG_ADD_EH class EventHandlers {\ + class ADDON {\ + init = QUOTE(_this call FUNC(initRound));\ + };\ +} + +class BombCore; +class Bo_Mk82: BombCore { + ACE_FRAG_ADD_EH; +}; + +class BulletCore; +class BulletBase: BulletCore { + ACE_FRAG_ADD_EH; +}; + +class Grenade; +class GrenadeHand: Grenade { + ACE_FRAG_ADD_EH; +}; + +class GrenadeCore; +class GrenadeBase: GrenadeCore { + ACE_FRAG_ADD_EH; +}; + +class LaserBombCore; +class ammo_Bomb_LaserGuidedBase: LaserBombCore { + ACE_FRAG_ADD_EH; +}; + +class MissileCore; +class MissileBase: MissileCore { + ACE_FRAG_ADD_EH; +}; + +class RocketCore; +class RocketBase: RocketCore { + ACE_FRAG_ADD_EH; +}; + +class ArtilleryRocketCore: RocketCore { + ACE_FRAG_ADD_EH; +}; + +class ShellCore; +class ShellBase: ShellCore { + ACE_FRAG_ADD_EH; +}; + +class ShotDeployCore; +class ShotDeployBase: ShotDeployCore { + ACE_FRAG_ADD_EH; +}; + +class ShotgunCore; +class ShotgunBase: ShotgunCore { + ACE_FRAG_ADD_EH; +}; + +class SubmunitionCore; +class SubmunitionBase: SubmunitionCore { + ACE_FRAG_ADD_EH; +}; + +class BoundingMineCore; +class BoundingMineBase: BoundingMineCore { + ACE_FRAG_ADD_EH; +}; + +class PipeBombCore; +class PipeBombBase: PipeBombCore { + ACE_FRAG_ADD_EH; +}; + +class DirectionalBombCore; +class DirectionalBombBase: DirectionalBombCore { + ACE_FRAG_ADD_EH; +}; + +class MineCore; +class MineBase: MineCore { + ACE_FRAG_ADD_EH; +}; \ No newline at end of file diff --git a/addons/frag/cfgAmmoFragAddition.hpp b/addons/frag/cfgAmmoFragAddition.hpp new file mode 100644 index 00000000000..87f93d174b2 --- /dev/null +++ b/addons/frag/cfgAmmoFragAddition.hpp @@ -0,0 +1,282 @@ + +// ~~~~ Bombs: +class ammo_Bomb_LaserGuidedBase; +class Bo_GBU12_LGB: ammo_Bomb_LaserGuidedBase { + GVAR(enabled) = 1; + + GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; + GVAR(fragCount) = 17500; + GVAR(metal) = 140000; + GVAR(charge) = 87000; + GVAR(gurney_c) = 2320; + GVAR(gurney_k) = "1/2"; +}; +class Bomb_04_F: ammo_Bomb_LaserGuidedBase { + GVAR(enabled) = 1; + + GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; + GVAR(fragCount) = 17500; + GVAR(metal) = 140000; + GVAR(charge) = 87000; + GVAR(gurney_c) = 2320; + GVAR(gurney_k) = "1/2"; +}; +class BombCore; +class Bo_Mk82: BombCore { + GVAR(enabled) = 1; + + GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; + GVAR(fragCount) = 17500; + GVAR(metal) = 140000; + GVAR(charge) = 87000; + GVAR(gurney_c) = 2320; + GVAR(gurney_k) = "1/2"; +}; + +// ~~~~ Grenades: +class GrenadeBase; +class Grenade; +class GrenadeHand: Grenade { + GVAR(enabled) = 1; + + GVAR(skip) = 0; + GVAR(force) = 1; + /* + These values are based on the M67 Grenade, should be tweaked for + individual grenades. + */ + GVAR(classes)[] = {QGVAR(tiny)}; + GVAR(fragCount) = 1000; + GVAR(metal) = 210; // metal in grams + GVAR(charge) = 185; // explosive in grams + GVAR(gurney_c) = 2843; // Gurney velocity constant for explosive type. See: http://en.wikipedia.org/wiki/Gurney_equations + GVAR(gurney_k) = "3/5"; // Gurney shape factor, in this case a sphere. See: http://en.wikipedia.org/wiki/Gurney_equations +}; +class GrenadeHand_stone: GrenadeHand { + GVAR(skip) = 1; +}; +class SmokeShell: GrenadeHand { + GVAR(skip) = 1; +}; +class G_40mm_HE: GrenadeBase { + // Source: http://www.inetres.com/gp/military/infantry/grenade/40mm_ammo.html#M441 + GVAR(enabled) = 1; + GVAR(force) = 1; + + GVAR(classes)[] = {QGVAR(small)}; + GVAR(fragCount) = 800; // guess based on probability hit of 1% + GVAR(metal) = 200; + GVAR(charge) = 32; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "3/5"; // interior fragmenter/charge is a sphere +}; +class G_40mm_HEDP: G_40mm_HE { + // Source: http://www.inetres.com/gp/military/infantry/grenade/40mm_ammo.html#M433 + GVAR(enabled) = 1; + + GVAR(classes)[] = {QGVAR(small_HD)}; + GVAR(fragCount) = 270; // seems to have greater framentation ability, but lower range per source + GVAR(metal) = 200; + GVAR(charge) = 45; + GVAR(gurney_c) = 2830; + GVAR(gurney_k) = "1/2"; +}; + +class ACE_G_40mm_HEDP: G_40mm_HEDP {}; +class ACE_G_40mm_HE: G_40mm_HE {}; +class ACE_G_40mm_Practice: ACE_G_40mm_HE { + GVAR(skip) = 1; + GVAR(force) = 0; + EGVAR(vehicle_damage,incendiary) = 0; +}; +// What is this even? +class ACE_G40mm_HE_VOG25P: G_40mm_HE { + GVAR(skip) = 0; + GVAR(force) = 1; +}; + + +// ~~~~ RPGs: +class MissileBase; +class R_PG32V_F; +class R_TBG32V_F: R_PG32V_F { // Thermobaric + GVAR(enabled) = 1; + GVAR(fragCount) = 200; + GVAR(metal) = 400; + GVAR(charge) = 210; + GVAR(gurney_c) = 2800; + GVAR(gurney_k) = "3/5"; + GVAR(classes)[] = {QGVAR(medium_HD)}; +}; +class M_Titan_AA: MissileBase { + GVAR(skip) = 1; +}; +class M_Titan_AT: MissileBase { + GVAR(skip) = 1; +}; +class M_Titan_AP: M_Titan_AT { // "anti personnel" + GVAR(skip) = 0; + GVAR(fragCount) = 800; // guesstimate / provides ~80 m frag range + GVAR(enabled) = 1; + GVAR(metal) = 400; + GVAR(charge) = 210; + GVAR(gurney_c) = 2800; + GVAR(gurney_k) = "3/5"; + GVAR(classes)[] = {QGVAR(medium_HD)}; +}; + +// https://ofb.gov.in/product/products/product-details/84-mm-he-round-ffv-441-b +// https://armypubs.army.mil/epubs/DR_pubs/DR_a/pdf/web/ARN18072_TC%203-22x84%20FINAL%20WEB.pdf (page 99, Table A-6. HE 441D RS, 84-mm projectile) +class R_MRAAWS_HEAT_F; +class R_MRAAWS_HE_F: R_MRAAWS_HEAT_F { + GVAR(enabled) = 1; + GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) + GVAR(metal) = 2300; + GVAR(charge) = 590; + GVAR(gurney_c) = 2800; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(small)}; +}; + + +// ~~~~ Missiles: +class M_PG_AT; +class M_AT: M_PG_AT { // DAR (Hydra 70) + // Source: http://fas.org/man/dod-101/sys/missile/hydra-70.htm + GVAR(enabled) = 1; + + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) + GVAR(metal) = 3850; + GVAR(charge) = 1040; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/2"; +}; +class RocketBase; +class R_80mm_HE: RocketBase { + GVAR(skip) = 1; +}; +class Missile_AGM_02_F: MissileBase { + // Source: http://fas.org/man/dod-101/sys/smart/agm-65.htm + GVAR(enabled) = 1; + + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(fragCount) = 1600; // guesstimate / provides ~112 m frag range (1% chance to hit) + GVAR(metal) = 56250; + GVAR(charge) = 39000; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/2"; +}; +class Rocket_04_HE_F: MissileBase { // Shrieker (Hydra 70) + GVAR(enabled) = 1; + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) + GVAR(metal) = 3850; + GVAR(charge) = 1040; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/2"; +}; +class M_Scalpel_AT: MissileBase { // 9K121 Vikhr + GVAR(enabled) = 1; + GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium_HD)}; + GVAR(fragCount) = 800; // guesstimate based on frag jacket, provides ~80 m frag range (1% chance to hit) + GVAR(metal) = 10000; + GVAR(charge) = 3000; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/2"; +}; +class ACE_Hellfire_AGM114K: M_Scalpel_AT { + // Source: http://www.designation-systems.net/dusrm/m-114.html + GVAR(enabled) = 1; + + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(fragCount) = 350; // guesstimate based on frag jacket, provides ~50 m frag range (1% chance to hit) + GVAR(metal) = 8000; + GVAR(charge) = 2400; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/2"; +}; +class M_Air_AA: MissileBase { + GVAR(skip) = 1; +}; +class Missile_AA_04_F: MissileBase { + GVAR(skip) = 1; +}; + +// curator ammo entries +class ShellBase; +class Sh_125mm_HEAT; +class Sh_155mm_AMOS: ShellBase { + // Source: http://www.globalsecurity.org/military/systems/munitions/m795.htm + GVAR(enabled) = 1; + + GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; + GVAR(fragCount) = 3250; // http://18.195.19.6/bitstream/handle/20.500.12242/1200/15-01916.pdf?sequence=1&isAllowed=y + GVAR(metal) = 36000; + GVAR(charge) = 9979; + GVAR(gurney_c) = 2440; + GVAR(gurney_k) = "1/2"; +}; +class Sh_82mm_AMOS: Sh_155mm_AMOS { + //http://65.175.100.54/uxofiles/mulvaney/techdatasheets/81mm-HE-M821.pdf + GVAR(enabled) = 1; + + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(fragCount) = 1600; // based on mass and fragment energy/count + GVAR(metal) = 2500; + GVAR(charge) = 726; + GVAR(gurney_c) = 2440; + GVAR(gurney_k) = "1/2"; +}; +class ModuleOrdnanceMortar_F_Ammo: Sh_82mm_AMOS { + GVAR(enabled) = 1; + + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(metal) = 800; + GVAR(charge) = 4200; + GVAR(gurney_c) = 2320; + GVAR(gurney_k) = "1/2"; +}; +class Sh_105mm_HEAT_MP: Sh_125mm_HEAT { + GVAR(enabled) = 1; + + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(fragCount) = 1600; // based on mass and fragment energy/count + GVAR(metal) = 11400; + GVAR(charge) = 7100; + GVAR(gurney_c) = 2800; + GVAR(gurney_k) = "1/2"; +}; +class Sh_120mm_HE: ShellBase { + GVAR(enabled) = 1; + + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(fragCount) = 2000; + GVAR(metal) = 23000; + GVAR(charge) = 3148; + GVAR(gurney_c) = 2830; + GVAR(gurney_k) = "1/2"; +}; +class Sh_125mm_HE: Sh_120mm_HE { + GVAR(enabled) = 1; + + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(metal) = 16000; + GVAR(charge) = 3200; + GVAR(gurney_c) = 2440; + GVAR(gurney_k) = "1/2"; +}; +class ModuleOrdnanceHowitzer_F_ammo: Sh_155mm_AMOS { + GVAR(enabled) = 1; + + GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; + GVAR(metal) = 1950; + GVAR(charge) = 15800; + GVAR(gurney_c) = 2320; + GVAR(gurney_k) = "1/2"; +}; +// Special +class Default; +class Laserbeam : Default { + GVAR(skip) = 1; +}; diff --git a/addons/frag/cfgAmmoFragSpawner.hpp b/addons/frag/cfgAmmoFragSpawner.hpp new file mode 100644 index 00000000000..265372066fc --- /dev/null +++ b/addons/frag/cfgAmmoFragSpawner.hpp @@ -0,0 +1,518 @@ +// format fragType_spawn_n_range +/********************* ***************************/ +class GVAR(spawnbase) : B_65x39_Caseless { + access = 2; + deleteParentWhenTriggered = 1; + submunitionConeType[] = {"random", 25}; + submunitionAmmo[] = {QGVAR(tiny), 3, QGVAR(tiny_HD), 3, QGVAR(small), 4, QGVAR(small_HD), 4, QGVAR(medium_HD), 5}; + submunitionDirectionType = "SubmunitionModelDirection"; + submunitionConeAngleHorizontal = 15; + submunitionConeAngle = 87; + submunitionInitialOffset[] = {0,0,0}; + submunitionInitSpeed = 1000; + submunitionParentSpeedCoef = 1; + triggerSpeedCoef[] = {0.75, 1.5}; + triggerTime = 0; +}; + +/********************* ***************************/ +class GVAR(def_10) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 10}; +}; +class GVAR(def_10_lo) : GVAR(def_10) { + submunitionConeAngle = 85; +}; +class GVAR(def_10_mid) : GVAR(def_10) { + submunitionConeAngle = 85; + triggerSpeedCoef[] = {-1.5, 1.5}; +}; +class GVAR(def_10_hi) : GVAR(def_10) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.5, -0.75}; +}; +class GVAR(def_10_top) : GVAR(def_10) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.5, -0.75}; +}; + +/********************* ***************************/ +class GVAR(def_15) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 15}; +}; +class GVAR(def_15_lo) : GVAR(def_15) { + submunitionConeAngle = 85; +}; +class GVAR(def_15_mid) : GVAR(def_15) { + submunitionConeAngle = 85; + triggerSpeedCoef[] = {-1.5, 1.5}; +}; +class GVAR(def_15_hi) : GVAR(def_15) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.5, -0.75}; +}; +class GVAR(def_15_top) : GVAR(def_15) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.5, -0.75}; +}; + +/********************* ***************************/ +class GVAR(def_5) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 5}; +}; +class GVAR(def_5_lo) : GVAR(def_5) { + submunitionConeAngle = 85; +}; +class GVAR(def_5_mid) : GVAR(def_5) { + submunitionConeAngle = 85; + triggerSpeedCoef[] = {-1.5, 1.5}; +}; +class GVAR(def_5_hi) : GVAR(def_5) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.5, -0.75}; +}; +class GVAR(def_5_top) : GVAR(def_5) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.5, -0.75}; +}; + +/********************* ***************************/ +class GVAR(def_tiny_15) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 15}; + submunitionAmmo = QGVAR(tiny); +}; +class GVAR(def_tiny_15_lo) : GVAR(def_tiny_15) { + submunitionConeAngle = 85; +}; +class GVAR(def_tiny_15_mid) : GVAR(def_tiny_15) { + submunitionConeAngle = 85; + triggerSpeedCoef[] = {-1.5, 1.5}; +}; +class GVAR(def_tiny_15_hi) : GVAR(def_tiny_15) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.5, -0.75}; +}; +class GVAR(def_tiny_15_top) : GVAR(def_tiny_15) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.5, -0.75}; +}; + +/********************* ***************************/ +class GVAR(def_tiny_10) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 10}; + submunitionAmmo = QGVAR(tiny); +}; +class GVAR(def_tiny_10_lo) : GVAR(def_tiny_10) { + submunitionConeAngle = 85; +}; +class GVAR(def_tiny_10_mid) : GVAR(def_tiny_10) { + submunitionConeAngle = 85; + triggerSpeedCoef[] = {-1.5, 1.5}; +}; +class GVAR(def_tiny_10_hi) : GVAR(def_tiny_10) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.5, -0.75}; +}; +class GVAR(def_tiny_10_top) : GVAR(def_tiny_10) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.5, -0.75}; +}; + +/********************* ***************************/ +class GVAR(def_tiny_5) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 5}; + submunitionAmmo = QGVAR(tiny); +}; +class GVAR(def_tiny_5_lo) : GVAR(def_tiny_5) { + submunitionConeAngle = 85; +}; +class GVAR(def_tiny_5_mid) : GVAR(def_tiny_5) { + submunitionConeAngle = 85; + triggerSpeedCoef[] = {-1.5, 1.5}; +}; +class GVAR(def_tiny_5_hi) : GVAR(def_tiny_5) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.5, -0.75}; +}; +class GVAR(def_tiny_5_top) : GVAR(def_tiny_5) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.5, -0.75}; +}; +/********************* ***************************/ +class GVAR(def_small_15) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 15}; + submunitionAmmo = QGVAR(small); +}; +class GVAR(def_small_15_lo) : GVAR(def_small_15) { + submunitionConeAngle = 815; +}; +class GVAR(def_small_15_mid) : GVAR(def_small_15) { + submunitionConeAngle = 815; + triggerSpeedCoef[] = {-1.15, 1.15}; +}; +class GVAR(def_small_15_hi) : GVAR(def_small_15) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.15, -0.715}; +}; +class GVAR(def_small_15_top) : GVAR(def_small_15) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.15, -0.715}; +}; +/********************* ***************************/ +class GVAR(def_small_10) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 10}; + submunitionAmmo = QGVAR(small); +}; +class GVAR(def_small_10_lo) : GVAR(def_small_10) { + submunitionConeAngle = 810; +}; +class GVAR(def_small_10_mid) : GVAR(def_small_10) { + submunitionConeAngle = 810; + triggerSpeedCoef[] = {-1.10, 1.10}; +}; +class GVAR(def_small_10_hi) : GVAR(def_small_10) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.10, -0.710}; +}; +class GVAR(def_small_10_top) : GVAR(def_small_10) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.10, -0.710}; +}; +/********************* ***************************/ +class GVAR(def_small_5) : GVAR(spawnbase) { + submunitionConeType[] = {"random", 5}; + submunitionAmmo = QGVAR(small); +}; +class GVAR(def_small_5_lo) : GVAR(def_small_5) { + submunitionConeAngle = 85; +}; +class GVAR(def_small_5_mid) : GVAR(def_small_5) { + submunitionConeAngle = 85; + triggerSpeedCoef[] = {-1.5, 1.5}; +}; +class GVAR(def_small_5_hi) : GVAR(def_small_5) { + submunitionConeAngle = 80; + triggerSpeedCoef[] = {-1.5, -0.75}; +}; +class GVAR(def_small_5_top) : GVAR(def_small_5) { + submunitionConeAngle = 60; + triggerSpeedCoef[] = {-1.5, -0.75}; +}; + +/******************* targeted fragments ********************/ +class GVAR(spawnbase_targeted) : GVAR(spawnbase) { + access = 2; + submunitionConeType[] = {"random", 2}; + submunitionConeAngle = 2; + submunitionInitSpeed = 0; + triggerSpeedCoef[] = {0.5, 1}; +}; + +class GVAR(tiny_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(tiny_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(tiny_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(tiny_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; +}; +class GVAR(tiny_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; +}; +class GVAR(tiny_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; +}; + +class GVAR(tiny_HD_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(tiny_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(tiny_HD_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(tiny_HD_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; +}; +class GVAR(tiny_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; +}; +class GVAR(tiny_HD_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(tiny_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; +}; + +class GVAR(small_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(small_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(small_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(small_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; +}; +class GVAR(small_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; +}; +class GVAR(small_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; +}; + +class GVAR(small_HD_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(small_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(small_HD_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(small_HD_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; +}; +class GVAR(small_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; +}; +class GVAR(small_HD_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(small_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; +}; + +class GVAR(medium_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(medium_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(medium_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(medium_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; +}; +class GVAR(medium_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; +}; +class GVAR(medium_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; +}; + +class GVAR(medium_HD_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(medium_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(medium_HD_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(medium_HD_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; +}; +class GVAR(medium_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; +}; +class GVAR(medium_HD_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(medium_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; +}; + +class GVAR(large_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(large_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(large_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(large_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; +}; +class GVAR(large_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; +}; +class GVAR(large_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; +}; + +class GVAR(large_HD_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(large_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(large_HD_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(large_HD_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; +}; +class GVAR(large_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; +}; +class GVAR(large_HD_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(large_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; +}; + +class GVAR(huge_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(huge_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(huge_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(huge_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; +}; +class GVAR(huge_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; +}; +class GVAR(huge_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; +}; + +class GVAR(huge_HD_spawner_2_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(huge_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(huge_HD_spawner_2_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 2}; +}; +class GVAR(huge_HD_spawner_3_short) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge_HD); + submunitionConeAngle = 4.5; + submunitionConeType[] = {"random", 3}; +}; +class GVAR(huge_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge_HD); + submunitionConeAngle = 2; + submunitionConeType[] = {"random", 3}; +}; +class GVAR(huge_HD_spawner_3_far) : GVAR(spawnbase_targeted) { + submunitionAmmo = QGVAR(huge_HD); + submunitionConeAngle = 0.9; + submunitionConeType[] = {"random", 3}; +}; \ No newline at end of file diff --git a/addons/frag/cfgAmmoSpall.hpp b/addons/frag/cfgAmmoSpall.hpp new file mode 100644 index 00000000000..9eb2e7a322e --- /dev/null +++ b/addons/frag/cfgAmmoSpall.hpp @@ -0,0 +1,49 @@ +class GVAR(spallBase) : B_65x39_Caseless +{ + access = 3; + submunitionAmmo[] = {"ace_frag_small_c",4,"ace_frag_medium_c",3,"ace_frag_large_c",2,"ace_frag_huge_c",1}; + submunitionConeType[] = {"random", 20}; + submunitionConeAngle = 40; + submunitionDirectionType = "SubmunitionModelDirection"; + triggerTime = 0; + submunitionInitialOffset[] = {0,0,0}; + submunitionInitSpeed = 0; + triggerSpeedCoef[] = {0.75,1.25}; + deleteParentWhenTriggered = 1; + submunitionParentSpeedCoef = 1; +}; + +class GVAR(spall_tiny) : GVAR(spallBase) +{ + submunitionAmmo[] = {"ace_frag_small_c", 4, "ace_frag_medium_c", 1}; + submunitionConeType[] = {"poissondisccenter", 5}; + submunitionConeAngle = 40; +}; + +class GVAR(spall_small) : GVAR(spallBase) +{ + submunitionAmmo[] = {"ace_frag_small_c", 4,"ace_frag_medium_c", 1}; + submunitionConeType[] = {"poissondisccenter", 10}; + submunitionConeAngle = 40; +}; + +class GVAR(spall_medium) : GVAR(spallBase) +{ + submunitionAmmo[] = {"ace_frag_small_c", 2, "ace_frag_small_HD_c", 1,"ace_frag_medium_c", 3, "ace_frag_medium_HD_c", 1, "ace_frag_large_c", 2}; + submunitionConeType[] = {"poissondisccenter", 15}; + submunitionConeAngle = 40; +}; + +class GVAR(spall_large) : GVAR(spallBase) +{ + submunitionAmmo[] = {"ace_frag_tiny_c", 3, "ace_frag_tiny_HD_c", 3, "ace_frag_small_c", 4, "ace_frag_small_HD_c", 4, "ace_frag_medium_HD_c", 5, "ace_frag_large_c", 2, "ace_frag_large_HD_c", 2, "ace_frag_huge_c",1}; + submunitionConeType[] = {"poissondisccenter", 15}; + submunitionConeAngle = 40; +}; + +class GVAR(spall_huge) : GVAR(spallBase) +{ + submunitionAmmo[] = {"ace_frag_tiny_c", 3, "ace_frag_tiny_HD_c", 3, "ace_frag_small_c", 4, "ace_frag_small_HD_c", 4, "ace_frag_medium_HD_c", 5, "ace_frag_large_c", 2, "ace_frag_large_HD_c", 2, "ace_frag_huge_c",1}; + submunitionConeType[] = {"poissondisccenter", 20}; + submunitionConeAngle = 40; +}; \ No newline at end of file From bfb3fa851c692fd6e1886586de4175bad9640d5f Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 8 Jan 2024 18:06:57 -0600 Subject: [PATCH 010/282] added fnc_initRound --- addons/frag/XEH_PREP.hpp | 7 +-- addons/frag/XEH_postInit.sqf | 4 +- addons/frag/functions/fnc_initRound.sqf | 62 +++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 addons/frag/functions/fnc_initRound.sqf diff --git a/addons/frag/XEH_PREP.hpp b/addons/frag/XEH_PREP.hpp index d46ebd25aba..855cfdd8d96 100644 --- a/addons/frag/XEH_PREP.hpp +++ b/addons/frag/XEH_PREP.hpp @@ -10,10 +10,13 @@ PREP(dev_drawTrace); PREP(dev_clearTraces); PREP(dev_switchUnitHandle); +// Base +PREP(fired); +PREP(initRound); + // Frag PREP(addBlackList); PREP(initBlackList); -PREP(fired); PREP(submunition); PREP(shouldFrag); PREP(fragInfo); @@ -25,8 +28,6 @@ PREP(doFragRandom); PREP(shouldSpall); PREP(doSpall); PREP(doSpallMomentum); - -// * Other */ //PREP(spallHP); Look at me !*! // Explosive Reflection diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index 94b2247e94d..6bd79cc1016 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -7,13 +7,13 @@ [] call FUNC(initBlackList); }; - if (hasInterface) then { + /*if (hasInterface) then { ["ace_firedPlayer", LINKFUNC(fired)] call CBA_fnc_addEventHandler; ["ace_firedPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler; }; ["ace_firedNonPlayer", LINKFUNC(fired)] call CBA_fnc_addEventHandler; - ["ace_firedNonPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler; + ["ace_firedNonPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler;*/ // Debug info #ifdef DEBUG_MODE_FULL diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf new file mode 100644 index 00000000000..4571dde8a53 --- /dev/null +++ b/addons/frag/functions/fnc_initRound.sqf @@ -0,0 +1,62 @@ +#include "script_component.hpp" +/* + * Author: Lambda.Tiger + * This function checks whether an ammunition type should cause fragmentation + * and whether any submunitions exist + * + * Arguments: + * 0: _ammo - cfgAmmo type of ammo to check + * + * Return Value: + * _shouldFrag + * 0 - Should the specific round fragment + * 1 - Does the munition have a child submunition + * + * Example: + * ["B_556x45_Ball"] call ace_frag_fnc_shouldFrag; + * + * Public: No + */ + params ["_projectile"]; +private _ammo = typeOf _proj; +systemChat (str _ammo + " " + str _projectile); + if (isNil "_ammo" || + {_ammo isEqualTo "" || + {isNil "_projectile" || + {isNull _projectile}}}) exitWith { + WARNING("bad ammo or projectile"); +}; + +/******* _shouldFrag format *****/ +// 0: doFragmnent - will the piece fragment +// 1: hasSubmuntion - will the round create submunitions +private _shouldFrag = _ammo call FUNC(shouldFrag); +_shouldFrag params ["_doFrag", "_doSubmunit"]; + +if (_doFrag) then { + // wait for frag damage to kill units before spawning fragments + _projectile addEventHandler ["Explode", { + if (isServer) then { + [FUNC(doFrag), [_this]] call CBA_fnc_execNextFrame; + } else { + [QGVAR(frag_eh), [_this]] call CBA_fnc_serverEvent; + }; + } + ]; +}; + +if (_doSubmunit && {GVAR(enSubMunit)> 0}) then { + _projectile addEventHandler ["SubmunitionCreated", {_this call FUNC(submunition)}]; +}; + +private _shouldSpall = _ammo call FUNC(shouldSpall); + +if (GVAR(spallEnabled) && {_shouldSpall}) then +{_projectile addEventHandler [ + "HitPart", + { + [LINKFUNC(doSpallMomentum), _this] call CBA_fnc_execNextFrame; + [QGVAR(spall_eh), [_this]] call CBA_fnc_serverEvent; + } + ]; +}; \ No newline at end of file From 14e7ef7cba4e17b781b0985234c3cecf975b73b9 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 8 Jan 2024 18:07:15 -0600 Subject: [PATCH 011/282] removed leftover script profiler calls --- addons/frag/functions/fnc_dev_fragCalcDump.sqf | 2 +- addons/frag/functions/fnc_doSpallMomentum.sqf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf index 162c88d9654..40ce58acccb 100644 --- a/addons/frag/functions/fnc_dev_fragCalcDump.sqf +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -63,7 +63,7 @@ diag_log text "//****************** fragCalcDump Beg ******************//"; if (_gC == 0) then {_gC = 2440;}; private _fragCount = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(fragCount)); if (_fragCount == 0) then {_fragCount = 200; _warn = true}; - profilerLog (str (sqrt (_fragCount / (4 * pi * 0.005)))); + private _velocity = 0.8 * _gC * sqrt (_c /(_m + _c * _k)); // number of shrapnel to send a direction private _count = ceil (random (sqrt (_m / 1000))); diff --git a/addons/frag/functions/fnc_doSpallMomentum.sqf b/addons/frag/functions/fnc_doSpallMomentum.sqf index 3f0f74a8aa3..2ac297e993b 100644 --- a/addons/frag/functions/fnc_doSpallMomentum.sqf +++ b/addons/frag/functions/fnc_doSpallMomentum.sqf @@ -25,7 +25,7 @@ if ((isNil "_lPosASL") || {!(_lPosASL isEqualTypeArray [0,0,0])}) exitWith { }; private _vel = if (alive _projectile) then { - _velocity _projectile; + velocity _projectile; } else { [0, 0, 0] }; From 596240a57d68096ef3e8bbbf449e25cd2d80ead3 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 8 Jan 2024 21:38:15 -0600 Subject: [PATCH 012/282] Added init event handlers instead of fired --- addons/frag/XEH_postInit.sqf | 15 +++------ addons/frag/cfgAmmoBaseEH.hpp | 5 +-- addons/frag/functions/fnc_initRound.sqf | 42 +++++++++++-------------- 3 files changed, 27 insertions(+), 35 deletions(-) diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index 6bd79cc1016..f50279ce8a9 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -17,16 +17,11 @@ // Debug info #ifdef DEBUG_MODE_FULL - if (hasInterface && GVAR(debugOptions)) then - { - private _h = [LINKFUNC(dev_drawTrace), 0] call CBA_fnc_addPerFrameHandler; - missionNamespace setVariable [QGVAR(dev_drawPFEH), _h]; - ["unit", LINKFUNC(dev_switchUnitHandle), true] call CBA_fnc_addPlayerEventHandler; - [objNull, ace_player] call FUNC(dev_switchUnitHandle); - ["ace_firedPlayer", LINKFUNC(fired)] call CBA_fnc_addEventHandler; - ["ace_firedNonPlayer", LINKFUNC(fired)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler; - ["ace_firedNonPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler; + if (hasInterface && GVAR(debugOptions)) then { + private _h = [LINKFUNC(dev_drawTrace), 0] call CBA_fnc_addPerFrameHandler; + missionNamespace setVariable [QGVAR(dev_drawPFEH), _h]; + ["unit", LINKFUNC(dev_switchUnitHandle), true] call CBA_fnc_addPlayerEventHandler; + [objNull, ace_player] call FUNC(dev_switchUnitHandle); }; #endif }] call CBA_fnc_addEventHandler; diff --git a/addons/frag/cfgAmmoBaseEH.hpp b/addons/frag/cfgAmmoBaseEH.hpp index f76d01b8079..050a7d769d5 100644 --- a/addons/frag/cfgAmmoBaseEH.hpp +++ b/addons/frag/cfgAmmoBaseEH.hpp @@ -1,6 +1,6 @@ #define ACE_FRAG_ADD_EH class EventHandlers {\ class ADDON {\ - init = QUOTE(_this call FUNC(initRound));\ + init = QUOTE(_this call FUNC(initRound););\ };\ } @@ -9,7 +9,8 @@ class Bo_Mk82: BombCore { ACE_FRAG_ADD_EH; }; -class BulletCore; +// We need this since autocannons generally inherit from BulletBase +class BulletCore; class BulletBase: BulletCore { ACE_FRAG_ADD_EH; }; diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index 4571dde8a53..fc13bba93f9 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -1,37 +1,32 @@ #include "script_component.hpp" /* * Author: Lambda.Tiger - * This function checks whether an ammunition type should cause fragmentation - * and whether any submunitions exist - * + * This function adds rounds using their config init EH + * Arguments: - * 0: _ammo - cfgAmmo type of ammo to check + * 0: _projectile - The object created * * Return Value: - * _shouldFrag - * 0 - Should the specific round fragment - * 1 - Does the munition have a child submunition + * None * * Example: - * ["B_556x45_Ball"] call ace_frag_fnc_shouldFrag; + * [_proj] call ace_frag_fnc_initRound; * * Public: No */ - params ["_projectile"]; -private _ammo = typeOf _proj; -systemChat (str _ammo + " " + str _projectile); - if (isNil "_ammo" || +params ["_projectile"]; + +private _ammo = typeOf _projectile; +if (isNil "_ammo" || {_ammo isEqualTo "" || {isNil "_projectile" || {isNull _projectile}}}) exitWith { - WARNING("bad ammo or projectile"); + TRACE_2("bad ammo or projectile",_ammo,_projectile); }; -/******* _shouldFrag format *****/ -// 0: doFragmnent - will the piece fragment -// 1: hasSubmuntion - will the round create submunitions + private _shouldFrag = _ammo call FUNC(shouldFrag); -_shouldFrag params ["_doFrag", "_doSubmunit"]; +_shouldFrag params ["_doFrag"]; if (_doFrag) then { // wait for frag damage to kill units before spawning fragments @@ -45,18 +40,19 @@ if (_doFrag) then { ]; }; -if (_doSubmunit && {GVAR(enSubMunit)> 0}) then { - _projectile addEventHandler ["SubmunitionCreated", {_this call FUNC(submunition)}]; -}; private _shouldSpall = _ammo call FUNC(shouldSpall); if (GVAR(spallEnabled) && {_shouldSpall}) then -{_projectile addEventHandler [ +{ + _projectile addEventHandler [ "HitPart", { - [LINKFUNC(doSpallMomentum), _this] call CBA_fnc_execNextFrame; - [QGVAR(spall_eh), [_this]] call CBA_fnc_serverEvent; + if (isServer) then { + [LINKFUNC(doSpallMomentum), _this] call CBA_fnc_execNextFrame; + } else { + [QGVAR(spall_eh), [_this]] call CBA_fnc_serverEvent; + }; } ]; }; \ No newline at end of file From 990667b24b5c9753694c179d2da29dc51d9ce8b7 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 8 Jan 2024 21:38:55 -0600 Subject: [PATCH 013/282] changed some WARNINGs to TRACEs --- addons/frag/functions/fnc_fired.sqf | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/addons/frag/functions/fnc_fired.sqf b/addons/frag/functions/fnc_fired.sqf index 5ed9206a42c..32f72b60997 100644 --- a/addons/frag/functions/fnc_fired.sqf +++ b/addons/frag/functions/fnc_fired.sqf @@ -22,7 +22,7 @@ if (isNil "_ammo" || {_ammo isEqualTo "" || {isNil "_projectile" || {isNull _projectile}}}) exitWith { - WARNING("bad ammo or projectile"); + TRACE_2("bad ammo or projectile",_projectile,_ammo); }; /******* _shouldFrag format *****/ @@ -53,8 +53,11 @@ if (GVAR(spallEnabled) && {_shouldSpall}) then {_projectile addEventHandler [ "HitPart", { - [LINKFUNC(doSpallMomentum), _this] call CBA_fnc_execNextFrame; - [QGVAR(spall_eh), [_this]] call CBA_fnc_serverEvent; + if (isServer) then { + [LINKFUNC(doSpallMomentum), _this] call CBA_fnc_execNextFrame; + } else { + [QGVAR(spall_eh), [_this]] call CBA_fnc_serverEvent; + }; } ]; }; \ No newline at end of file From 53976e39a344fbe1a922afba1f6c264e64b3766f Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 8 Jan 2024 21:40:12 -0600 Subject: [PATCH 014/282] fixed spelling errors --- addons/frag/README.md | 2 +- addons/frag/XEH_PREP.hpp | 1 + addons/frag/functions/fnc_doFragTargeted.sqf | 4 ++-- addons/frag/functions/fnc_submunition.sqf | 2 +- addons/frag/script_component.hpp | 17 +++++++++++++++-- 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/addons/frag/README.md b/addons/frag/README.md index a658e5a9d29..1b2378aed90 100644 --- a/addons/frag/README.md +++ b/addons/frag/README.md @@ -8,7 +8,7 @@ TODO: - move from FIRED to init EH's - rework spalling position finding - Look at spalling per material type -- performance optimization - Finish stringtable expansion with additional normal & debug settings +- performance optimization - cDLC, RHS, CUP compats - look at / try to understand explosion reflections \ No newline at end of file diff --git a/addons/frag/XEH_PREP.hpp b/addons/frag/XEH_PREP.hpp index 855cfdd8d96..e7d3597d02e 100644 --- a/addons/frag/XEH_PREP.hpp +++ b/addons/frag/XEH_PREP.hpp @@ -1,4 +1,5 @@ // dev +PREP(dev_fired); PREP(dev_fragCalcDump); PREP(dev_debugAmmo); PREP(dev_trackHitBox); diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index f810eb9fb66..8d8de1c48d3 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -127,7 +127,7 @@ private _fragCount = 0; // limit of # of fragments to _maxFrags // actual target pos for fragment to hit if _isPerson then { - private _hitPoint = selectRandom _FRAG_HITPOINTS; + private _hitPoint = selectRandom ACE_FRAG_HITPOINTS; private _hitPointPos = _target selectionPosition [_hitPoint, "HitPoints", "AveragePoint"]; _targetPos = _target modelToWorldWorld _hitPointPos; } else { @@ -156,7 +156,7 @@ private _fragCount = 0; // limit of # of fragments to _maxFrags _fragObj setVectorDir _vecDir; _fragObj setVelocity (_vecDir vectorMultiply _locFragVel); _fragObj setShotParents _shotPrnt; - #ifdef DEBUG_MODE_DRAWFRAG + #ifdef DEBUG_MODE_FULL [_fragObj, "purple", true] call FUNC(dev_trackObj); [_targetPos, "orange"] call FUNC(dev_sphereDraw); #endif diff --git a/addons/frag/functions/fnc_submunition.sqf b/addons/frag/functions/fnc_submunition.sqf index 90c31ef6d23..70fc19655c2 100644 --- a/addons/frag/functions/fnc_submunition.sqf +++ b/addons/frag/functions/fnc_submunition.sqf @@ -36,5 +36,5 @@ if (_doSubmunit) then { }; #ifdef DEBUG_MODE_FULL - [_submunitionProjectile] call UNC(dev_addRound); + [_submunitionProjectile] call FUNC(dev_addRound); #endif \ No newline at end of file diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index a070ea952e3..95d69d37fbd 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -3,8 +3,8 @@ #include "\z\ace\addons\main\script_mod.hpp" // #define LOG_FRAG_INFO -// #define DEBUG_MODE_FULL -// #define DISABLE_COMPILE_CACHE +#define DEBUG_MODE_FULL +#define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_FRAG @@ -17,4 +17,17 @@ #include "\z\ace\addons\main\script_macros.hpp" +#define ACE_FRAG_HOLDOFF 1 #define ACE_FRAG_SPALL_HOLDOFF 0.1 +#define ACE_FRAG_COUNT_MIN 5 +#define ACE_FRAG_COUNT_MAX 50 +#define ACE_FRAG_HITPOINTS ["spine1","spine2","spine3","head","leftarm","leftarmroll","leftforearm","rightarm","rightarmroll","rightforearm","pelvis","leftupleg","leftuplegroll","leftlegroll","leftfoot","rightupleg","rightuplegroll","rightleg","rightlegroll","rightfoot"] +#define ACE_FRAG_HITPOINTS_WEIGHTS + +#ifdef DEBUG_MODE_FULL +#define __FADE_TIME 1 +#define __FADE_START 0.5 +#define __FADE_INTERVAL 0.1 +#define __FADE_RATE __FADE_INTERVAL/__FADE_TIME/2 +#define __FADE_INIT (__FADE_TIME+__FADE_START)/__FADE_TIME/2 +#endif \ No newline at end of file From fbb3c8ad9395d5864dcf9632933b19d022b3ecae Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 8 Jan 2024 21:40:37 -0600 Subject: [PATCH 015/282] removed some init eventhandlers to make debugging easier --- addons/frag/CfgAmmo.hpp | 4 ++++ addons/frag/cfgAmmoFragSpawner.hpp | 1 + addons/frag/cfgAmmoSpall.hpp | 13 +++++++------ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index 35f2c7e8999..d7d148e65c7 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -1,6 +1,9 @@ #define BASE_DRAG -0.01 #define HD_MULT 5 #define BASE_DRAG_HD (BASE_DRAG * HD_MULT) +#define ACE_FRAG_RM_EH class EventHandlers {\ + delete ADDON;\ +} class CfgAmmo { class B_65x39_Caseless; @@ -16,6 +19,7 @@ class CfgAmmo { typicalSpeed = 800; maxSpeed = 1500; deflecting = 65; + ACE_FRAG_RM_EH; }; class GVAR(tiny): GVAR(base) { diff --git a/addons/frag/cfgAmmoFragSpawner.hpp b/addons/frag/cfgAmmoFragSpawner.hpp index 265372066fc..be85d81be13 100644 --- a/addons/frag/cfgAmmoFragSpawner.hpp +++ b/addons/frag/cfgAmmoFragSpawner.hpp @@ -13,6 +13,7 @@ class GVAR(spawnbase) : B_65x39_Caseless { submunitionParentSpeedCoef = 1; triggerSpeedCoef[] = {0.75, 1.5}; triggerTime = 0; + ACE_FRAG_RM_EH; }; /********************* ***************************/ diff --git a/addons/frag/cfgAmmoSpall.hpp b/addons/frag/cfgAmmoSpall.hpp index 9eb2e7a322e..b3bcb4f9d82 100644 --- a/addons/frag/cfgAmmoSpall.hpp +++ b/addons/frag/cfgAmmoSpall.hpp @@ -1,7 +1,7 @@ class GVAR(spallBase) : B_65x39_Caseless { access = 3; - submunitionAmmo[] = {"ace_frag_small_c",4,"ace_frag_medium_c",3,"ace_frag_large_c",2,"ace_frag_huge_c",1}; + submunitionAmmo[] = {QGVAR(small),4,QGVAR(medium),3,QGVAR(large),2,QGVAR(huge),1}; submunitionConeType[] = {"random", 20}; submunitionConeAngle = 40; submunitionDirectionType = "SubmunitionModelDirection"; @@ -11,39 +11,40 @@ class GVAR(spallBase) : B_65x39_Caseless triggerSpeedCoef[] = {0.75,1.25}; deleteParentWhenTriggered = 1; submunitionParentSpeedCoef = 1; + ACE_FRAG_RM_EH; }; class GVAR(spall_tiny) : GVAR(spallBase) { - submunitionAmmo[] = {"ace_frag_small_c", 4, "ace_frag_medium_c", 1}; + submunitionAmmo[] = {QGVAR(small), 4, QGVAR(medium), 1}; submunitionConeType[] = {"poissondisccenter", 5}; submunitionConeAngle = 40; }; class GVAR(spall_small) : GVAR(spallBase) { - submunitionAmmo[] = {"ace_frag_small_c", 4,"ace_frag_medium_c", 1}; + submunitionAmmo[] = {QGVAR(small), 4,QGVAR(medium), 1}; submunitionConeType[] = {"poissondisccenter", 10}; submunitionConeAngle = 40; }; class GVAR(spall_medium) : GVAR(spallBase) { - submunitionAmmo[] = {"ace_frag_small_c", 2, "ace_frag_small_HD_c", 1,"ace_frag_medium_c", 3, "ace_frag_medium_HD_c", 1, "ace_frag_large_c", 2}; + submunitionAmmo[] = {QGVAR(small), 2, QGVAR(small_HD), 1,QGVAR(medium), 3, QGVAR(medium_HD), 1, QGVAR(large), 2}; submunitionConeType[] = {"poissondisccenter", 15}; submunitionConeAngle = 40; }; class GVAR(spall_large) : GVAR(spallBase) { - submunitionAmmo[] = {"ace_frag_tiny_c", 3, "ace_frag_tiny_HD_c", 3, "ace_frag_small_c", 4, "ace_frag_small_HD_c", 4, "ace_frag_medium_HD_c", 5, "ace_frag_large_c", 2, "ace_frag_large_HD_c", 2, "ace_frag_huge_c",1}; + submunitionAmmo[] = {QGVAR(tiny), 3, QGVAR(tiny_HD), 3, QGVAR(small), 4, QGVAR(small_HD), 4, QGVAR(medium_HD), 5, QGVAR(large), 2, QGVAR(large_HD), 2, QGVAR(huge),1}; submunitionConeType[] = {"poissondisccenter", 15}; submunitionConeAngle = 40; }; class GVAR(spall_huge) : GVAR(spallBase) { - submunitionAmmo[] = {"ace_frag_tiny_c", 3, "ace_frag_tiny_HD_c", 3, "ace_frag_small_c", 4, "ace_frag_small_HD_c", 4, "ace_frag_medium_HD_c", 5, "ace_frag_large_c", 2, "ace_frag_large_HD_c", 2, "ace_frag_huge_c",1}; + submunitionAmmo[] = {QGVAR(tiny), 3, QGVAR(tiny_HD), 3, QGVAR(small), 4, QGVAR(small_HD), 4, QGVAR(medium_HD), 5, QGVAR(large), 2, QGVAR(large_HD), 2, QGVAR(huge),1}; submunitionConeType[] = {"poissondisccenter", 20}; submunitionConeAngle = 40; }; \ No newline at end of file From 1933ea4cfe4e7ff2f312bbecf71a466aea90f31b Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 8 Jan 2024 21:41:05 -0600 Subject: [PATCH 016/282] reworked formatting and debug functions to increase readability --- addons/frag/functions/fnc_dev_addRound.sqf | 4 ++-- addons/frag/functions/fnc_dev_fired.sqf | 18 ++++++++++++++++++ addons/frag/functions/fnc_dev_trackObj.sqf | 8 ++++++-- addons/frag/functions/fnc_shouldFrag.sqf | 2 +- 4 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 addons/frag/functions/fnc_dev_fired.sqf diff --git a/addons/frag/functions/fnc_dev_addRound.sqf b/addons/frag/functions/fnc_dev_addRound.sqf index 72cb344fc8d..49d4d24bc4f 100644 --- a/addons/frag/functions/fnc_dev_addRound.sqf +++ b/addons/frag/functions/fnc_dev_addRound.sqf @@ -18,8 +18,8 @@ */ params [ "_proj", - ["_addEHs", true, [false]], - ["_sidePlayer", true, [false]] + ["_addEHs", true, [true]], + ["_sidePlayer", true, [true]] ]; /// track round on each frame diff --git a/addons/frag/functions/fnc_dev_fired.sqf b/addons/frag/functions/fnc_dev_fired.sqf new file mode 100644 index 00000000000..3570035bb2c --- /dev/null +++ b/addons/frag/functions/fnc_dev_fired.sqf @@ -0,0 +1,18 @@ +#include "script_component.hpp" +/* + * Author: Lambda.Tiger + * Add fired rounds to dev track. + * + * Arguments: + * None. Parameters inherited from EFUNC(common,firedEH) + * + * Return Value: + * None + * + * Example: + * [clientFiredBIS-XEH] call ace_frag_fnc_fired + * + * Public: No + */ + +[_projectile, true, ((side _unit) getFriend (side ACE_player)) >= 0.6] call FUNC(dev_addRound); \ No newline at end of file diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index 4da8e860310..9b43ec9c5c3 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -16,8 +16,12 @@ * * Public: No */ -params ["_obj", ["_color", "blue", [""]], ["_isProj", false, [false]]]; - +params [ + "_obj", + ["_color", "blue", ["blue"]], + ["_isProj", false, [false]] +]; +TRACE_4("devDraw",_this,_obj,_color,_isProj); /// track round on each frame // Create entry in position array from hashmap private _pID = getObjectID _obj; diff --git a/addons/frag/functions/fnc_shouldFrag.sqf b/addons/frag/functions/fnc_shouldFrag.sqf index 16d69b31179..587b21d4bdd 100644 --- a/addons/frag/functions/fnc_shouldFrag.sqf +++ b/addons/frag/functions/fnc_shouldFrag.sqf @@ -34,7 +34,7 @@ private _indirectRange = getNumber(configFile >> "cfgAmmo" >> _ammo >> "indirect if (_skip == 1 || (_force == 0 && {_explosive < 0.5 || {_indirectHit < 3 || {_indirectRange < 5 && _indirectHit < _indirectRange}}})) then { - TRACE_4("No frag" ,_skip, _explosive, _indirectRange, _indirectHit); + TRACE_5("No frag",_ammo,_skip, _explosive, _indirectRange, _indirectHit); _shouldFrag set [0, false]; }; From f852a3ab2d00f9c4d161cd0097c521c7374c6a90 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 8 Jan 2024 21:41:31 -0600 Subject: [PATCH 017/282] Added a config defined holdoff per vehicle fragmenting for performance --- addons/frag/functions/fnc_doFrag.sqf | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 574723ce7f4..ad84f8aefc8 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -19,25 +19,34 @@ * * Public: No */ - params ["_args", ["_isSubMunit", false, [false]]]; _args params [ ["_proj", objNull, [objNull]], ["_posASL", [0,0,0], [[]], [3]], ["_vel", [0,0,0] , [[]], [3]] ]; +TRACE_3("",_proj,_posASL,_vel); + +private _shotParents = getShotParents _proj; +private _shotParentVic = _shotParents#0; +if (_shotParentVic getVariable [QGVAR(nextFragTime), -1] < CBA_missionTime) exitWith { + TRACE_1("vehicleTimeExit",_shotParentVic); +}; +_shotParentVic setVariable [QGVAR(nextFragTime), CBA_missionTime + ACE_FRAG_HOLDOFF]; private _timeSince = CBA_missionTime - GVAR(lastFragTime); -if (isNull _proj || {_posASL isEqualTo [0,0,0] || _timeSince < 0.2}) exitWith {}; +if (isNull _proj || {_posASL isEqualTo [0,0,0] || _timeSince < 0.2}) exitWith { + TRACE_3("timeExit",_timeSince,CBA_missionTime,GVAR(lastFragTime)); +}; GVAR(lastFragTime) = CBA_missionTime; -private _maxFrags = round (linearConversion [0.1, 1.5, _timeSince, MAX_FRAG_COUNT_MIN, MAX_FRAG_COUNT_MAX, true]); +private _maxFrags = round (linearConversion [0.1, 1.5, _timeSince, ACE_FRAG_COUNT_MIN, ACE_FRAG_COUNT_MAX, true]); +TRACE_3("",_timeSince,CBA_missionTime,_maxFrags); + private _ammo = typeOf _proj; private _ammoArr = [_ammo] call FUNC(fragInfo); _ammoArr params ["_fragRange", "_fragVel", "_fragTypes", "_modFragCount"]; -private _shotParents = getShotParents _proj; - private _heightAGL = (ASLToAGL _posASL)#2; if (_heightAGL < 0.25) then { _posASL = _posASL vectorAdd [0, 0, 0.25]; From c3f04596c04782605b46b1a9aee957a0080835e5 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 8 Jan 2024 21:41:52 -0600 Subject: [PATCH 018/282] removed some redundant switch cases --- addons/frag/functions/fnc_doFragRandom.sqf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index cd799d89cab..f06a8b64323 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -35,13 +35,12 @@ TRACE_5("fnc_doFragRandom", _posASL, _projVel, _heightAGL, _fragType, _fragCnt); private _hMode = switch (true) do { case (_heightAGL > 10): {"_top"}; case (_heightAGL > 5): {"_hi"}; - case (_heightAGL > 1.5): {"_mid"}; default {"_mid"}; }; // Select the cfgAmmo type private _type = if (count _fragType > 0 && - {"ace_frag_tiny" isEqualTo (_fragType#0)}) then { + {"ace_frag_tiny" isEqualTo (_fragType#0)}) then { QGVAR(def_tiny_) } else { QGVAR(def_small_) @@ -55,6 +54,7 @@ _fragCnt = switch (true) do { // Spawn the fragment spawner private _fragSpawner = createVehicle [_type + _fragCnt + _hMode, ASLToATL _posASL, [], 0, "CAN_COLLIDE"]; +_fragSpawner setVectorDirandUp [[0,0,1], [1,0,0]]; _fragSpawner setVelocity _projVel; _fragSpawner setShotParents _shotParents; @@ -63,9 +63,9 @@ _fragSpawner setShotParents _shotParents; _fragSpawner addEventHandler [ "SubmunitionCreated", { - params ["","_proj","_posASL"]; - [_posASL] call FUNC(dev_sphereDraw); - [_proj, "green", true] call FUNC(dev_trackObj); + params ["","_subProj"]; + [_subProj, "green", true] call FUNC(dev_trackObj); } ]; + [_posASL] call FUNC(dev_sphereDraw); #endif \ No newline at end of file From 02dd35f63f8c3f0b23b49bce1f87689642c7d05c Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 8 Jan 2024 21:55:02 -0600 Subject: [PATCH 019/282] Reformatted for readability and optimized first if statement --- addons/frag/functions/fnc_initRound.sqf | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index fc13bba93f9..9a1677d2b6d 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -14,23 +14,23 @@ * * Public: No */ -params ["_projectile"]; +params [ + ["_projectile", objNull, [objNull]] +]; private _ammo = typeOf _projectile; -if (isNil "_ammo" || - {_ammo isEqualTo "" || - {isNil "_projectile" || - {isNull _projectile}}}) exitWith { +if (_ammo isEqualTo "" || {isNull _projectile}) exitWith { TRACE_2("bad ammo or projectile",_ammo,_projectile); }; - private _shouldFrag = _ammo call FUNC(shouldFrag); _shouldFrag params ["_doFrag"]; if (_doFrag) then { // wait for frag damage to kill units before spawning fragments - _projectile addEventHandler ["Explode", { + _projectile addEventHandler [ + "Explode", + { if (isServer) then { [FUNC(doFrag), [_this]] call CBA_fnc_execNextFrame; } else { From afad27181cd120b413396a491e7befc7c1d71fe8 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 8 Jan 2024 22:22:43 -0600 Subject: [PATCH 020/282] Added wiki docs --- docs/wiki/framework/frag-framework.md | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/docs/wiki/framework/frag-framework.md b/docs/wiki/framework/frag-framework.md index 07c59764f58..b8916549eae 100644 --- a/docs/wiki/framework/frag-framework.md +++ b/docs/wiki/framework/frag-framework.md @@ -8,7 +8,7 @@ order: 7 mod: ace version: major: 3 - minor: 0 + minor: 16 patch: 0 --- @@ -26,7 +26,8 @@ The system for the end-developer is easy to use, and only requires minimal resea ```cpp class CfgAmmo { class MyGrenade { - ace_frag_enabled = 1; // Enable fragmentation (0-disabled, 1-enabled) + ace_frag_enabled = 1; // Deprecated + ace_frag_fragCount = 1200; // Approximate number of fragments the explosive makes - information below ace_frag_metal = 210; // Amount of metal being fragmented (grams) - information below ace_frag_charge = 185; // Amount of explosive filler (grams) - information below ace_frag_gurney_c = 2843; // Gurney velocity constant for explosive type - information below @@ -40,13 +41,21 @@ class CfgAmmo { ### 1.1 Metal amount +`ace_frag_fragCount` + +Number of fragments that would be fragmented. This number may be found online or inferred from similar munitions. This affects the to be hit by a fragment and maximum range a fragment may hit a unit. + +Dimensionless value, count of number of fragments. + +### 1.2 Metal amount + `ace_frag_metal` -Amount of metal being fragmented (generally taken as the entire weight of the warhead, though in some cases you might want to only include the fragmentation jacket or body. +Amount of metal being fragmented. Generally taken as the entire weight of the warhead, though in some cases you might want to only include the fragmentation jacket or body. Dimensionless value, as long as same unit as `ace_frag_charge` (for example `kg/kg` or `g/g` or `lbs/lbs`). -### 1.2 Explosives filler amount +### 1.3 Explosives filler amount `ace_frag_charge` @@ -54,7 +63,7 @@ Amount of explosive filler in the warhead. `ace_frag_metal` and `ace_frag_charge Dimensionless value, as long as same unit as `ace_frag_metal` (for example `kg/kg` or `g/g` or `lbs/lbs`). -### 1.3 Gurney velocity constant +### 1.4 Gurney velocity constant `ace_frag_gurney_c` @@ -77,7 +86,7 @@ Tetryl | 2500 m/s TNT | 2440 m/s Tritonal | 2320 m/s -### 1.4 Gurney shape factor +### 1.5 Gurney shape factor `ace_frag_gurney_k` @@ -91,7 +100,7 @@ Plate | 3/5 There are other configurations but these are the most common. If you are interested in others check out the wikipedia link given above. Most of these will not correctly function in ACE3 though due to additional variables for the equation. -### 1.5 Fragments type +### 1.6 Fragments type `ace_frag_classes[]` @@ -112,13 +121,13 @@ There are different types of fragmentation fragments to choose from, and they ca The tinier the piece of fragmentation the shorter the distance of travel. The `_HD` variants are all even higher drag versions. Grenades generally should use the `_HD` variants. Experimentation here is important. -### 1.6 Ignore fragmentation +### 1.7 Ignore fragmentation `ace_frag_skip` Setting this to `1` will skip fragmentation for ammo of this type. This is useful for things that might cause high network load, such as FFAR rockets, or possibly even 40mm grenades from AGLs. Experimentation under network conditions is required. -### 1.7 Force fragmentation +### 1.8 Force fragmentation `ace_frag_force` From 55c7a233d18eb3e8236db437e0cd94f3ef961953 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 8 Jan 2024 23:58:11 -0600 Subject: [PATCH 021/282] removed duplicate setting --- addons/frag/initSettings.inc.sqf | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/addons/frag/initSettings.inc.sqf b/addons/frag/initSettings.inc.sqf index b0ba7d89e57..bb04c9df691 100644 --- a/addons/frag/initSettings.inc.sqf +++ b/addons/frag/initSettings.inc.sqf @@ -15,6 +15,8 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; false, 1 ] call CBA_fnc_addSetting; + + [ QGVAR(reflectionsEnabled), "CHECKBOX", [LSTRING(EnableReflections), LSTRING(EnableReflections_Desc)], @@ -32,13 +34,6 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; [[2, 1, 0], ["complex fragementation","simple fragmentation","no fragmentation"], 2] ] call CBA_fnc_addSetting; -[ - QGVAR(reflectionsEnabled), "CHECKBOX", - "Enable reflections", - [_category, LSTRING(Frag)], - false -] call CBA_fnc_addSetting; - [ QGVAR(atLeastOne), "CHECKBOX", "At least one round hit", From 76c2c324935c2e4f594007faa14257bd4c5b4f5c Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 8 Jan 2024 23:59:06 -0600 Subject: [PATCH 022/282] Updated to use cached info --- addons/frag/functions/fnc_doSpall.sqf | 32 ++++++++------------------- 1 file changed, 9 insertions(+), 23 deletions(-) diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index c5f99b892f6..00cbe9addef 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -26,15 +26,15 @@ private _vel = [0, 0, 0]; private _lVelUnit = vectorNormalized _lVel; private _velMod = 1; if (alive _projectile) then { - _vel = velocity _projectile; - _posASL = getPosASL _projectile; - // Dot product math + _vel = velocity _projectile; + _posASL = getPosASL _projectile; + // Dot product math private _diffAngle = acos (_lVelUnit vectorDotProduct vectorNormalized _vel); if (abs _diffAngle > 45) then { SUB(_velMod, (vectorMagnitude _vel) / (vectorMagnitude _lVel)); }; - _projectile setVariable [QGVAR(lastSpallTime), diag_tickTime ]; + _projectile setVariable [QGVAR(lastSpallTime), diag_tickTime ]; }; @@ -46,9 +46,9 @@ if (terrainIntersectASL [_lPosASL vectorAdd _unitStep, _lPosASL]) exitWith {}; // step through for "_i" from 1 to 20 do { - private _nPos = _spallPos vectorAdd _unitStep; - if (!lineIntersects [_spallPos, _nPos]) then {break}; - _spallPos = +_nPos; + private _nPos = _spallPos vectorAdd _unitStep; + if (!lineIntersects [_spallPos, _nPos]) then {break}; + _spallPos = +_nPos; }; #ifdef DEBUG_MODE_FULL [_spallPos, "orange"] call FUNC(dev_sphereDraw); @@ -66,22 +66,8 @@ systemChat ("dV: " + str _dv + ", caliber: " + str _caliber + ", product: " + st #endif if (_explosive > 0) then { - // ACE_player sideChat format ["EXPLOSIVE!"]; - //private _warn = false; - private _c = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ace_frag_CHARGE"); - if (_c == 0) then {_c = 1}; //; _warn = true;}; - private _m = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ace_frag_METAL"); - if (_m == 0) then {_m = 2;};// _warn = true;}; - private _k = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ace_frag_GURNEY_K"); - if (_k == 0) then {_k = 1 / 2;};// _warn = true;}; - private _gC = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ace_frag_GURNEY_C"); - if (_gC == 0) then {_gC = 2440};// _warn = true;}; - - // if (_warn) then { - // WARNING_1("Ammo class %1 lacks proper explosive properties definitions for frag!",_roundType); //TODO: turn this off when we get closer to release - // }; - - _velMod = (((_m / _c) + _k) ^ - (1 / 2)) * _gC * 0.66 * _velMod; + private _fragMod = (_ammo call FUNC(fragInfo))#1; + _velMod = _fragMod * _velMod; }; // diag_log text format ["SPALL POWER: %1", _spallPolar select 0]; From af40eb1d5e880332a72bb7f731e29e819b0af8b6 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 9 Jan 2024 00:24:48 -0600 Subject: [PATCH 023/282] Made larger spalls less lethal --- addons/frag/cfgAmmoSpall.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/frag/cfgAmmoSpall.hpp b/addons/frag/cfgAmmoSpall.hpp index b3bcb4f9d82..7c822676a2a 100644 --- a/addons/frag/cfgAmmoSpall.hpp +++ b/addons/frag/cfgAmmoSpall.hpp @@ -37,14 +37,14 @@ class GVAR(spall_medium) : GVAR(spallBase) class GVAR(spall_large) : GVAR(spallBase) { - submunitionAmmo[] = {QGVAR(tiny), 3, QGVAR(tiny_HD), 3, QGVAR(small), 4, QGVAR(small_HD), 4, QGVAR(medium_HD), 5, QGVAR(large), 2, QGVAR(large_HD), 2, QGVAR(huge),1}; + submunitionAmmo[] = {QGVAR(tiny), 3, QGVAR(tiny_HD), 3, QGVAR(small), 4, QGVAR(small_HD), 4, QGVAR(medium_HD), 5, QGVAR(large), 1, QGVAR(large_HD), 2}; submunitionConeType[] = {"poissondisccenter", 15}; submunitionConeAngle = 40; }; class GVAR(spall_huge) : GVAR(spallBase) { - submunitionAmmo[] = {QGVAR(tiny), 3, QGVAR(tiny_HD), 3, QGVAR(small), 4, QGVAR(small_HD), 4, QGVAR(medium_HD), 5, QGVAR(large), 2, QGVAR(large_HD), 2, QGVAR(huge),1}; + submunitionAmmo[] = {QGVAR(tiny), 3, QGVAR(tiny_HD), 3, QGVAR(small), 4, QGVAR(small_HD), 4, QGVAR(medium), 5, QGVAR(large), 1, QGVAR(large_HD), 2}; submunitionConeType[] = {"poissondisccenter", 20}; submunitionConeAngle = 40; }; \ No newline at end of file From fe310760fc4ebd0e8bc3a547e34b49d2e191e5d0 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 9 Jan 2024 00:25:58 -0600 Subject: [PATCH 024/282] Fixed variable names and mislabeled inequalities --- addons/frag/XEH_preInit.sqf | 1 + addons/frag/functions/fnc_doFrag.sqf | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/frag/XEH_preInit.sqf b/addons/frag/XEH_preInit.sqf index d857a1930b5..566cfc37211 100644 --- a/addons/frag/XEH_preInit.sqf +++ b/addons/frag/XEH_preInit.sqf @@ -9,6 +9,7 @@ PREP_RECOMPILE_END; GVAR(materialSpallCache) = createHashMap; GVAR(spallRoundCache) = createHashMap; +GVAR(lastSpallTime) = -2; GVAR(shouldFragCache) = createHashMap; GVAR(fragInfoCache) = createHashMap; diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index ad84f8aefc8..999ed368b6f 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -29,7 +29,7 @@ TRACE_3("",_proj,_posASL,_vel); private _shotParents = getShotParents _proj; private _shotParentVic = _shotParents#0; -if (_shotParentVic getVariable [QGVAR(nextFragTime), -1] < CBA_missionTime) exitWith { +if (_shotParentVic getVariable [QGVAR(nextFragTime), -1] > CBA_missionTime) exitWith { TRACE_1("vehicleTimeExit",_shotParentVic); }; _shotParentVic setVariable [QGVAR(nextFragTime), CBA_missionTime + ACE_FRAG_HOLDOFF]; From 3a088bb24c582f6d468e771bf937bf15f036e729 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 9 Jan 2024 00:26:43 -0600 Subject: [PATCH 025/282] Returned some missing variable names. --- addons/frag/functions/fnc_doSpallMomentum.sqf | 49 +++++++++++-------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/addons/frag/functions/fnc_doSpallMomentum.sqf b/addons/frag/functions/fnc_doSpallMomentum.sqf index 2ac297e993b..8abac240956 100644 --- a/addons/frag/functions/fnc_doSpallMomentum.sqf +++ b/addons/frag/functions/fnc_doSpallMomentum.sqf @@ -15,12 +15,27 @@ * * Public: No */ -params ["_projectile", "_hitObj", "", "_lPosASL", "_lVel", "", "", "" ,"_surfaceType"]; +params [ + "_projectile", + ["_hitObj", objNull], + "", + ["_lPosASL", [0, 0, 0]], + ["_lVel", [0, 0, 0]], + "", + "", + "", + ["_surfaceType", ""] +]; + +if (CBA_missionTime - GVAR(lastSpallTime) < ACE_FRAG_SPALL_HOLDOFF) exitWith { + TRACE_2("timeExit",CBA_missionTime,GVAR(lastSpallTime)); +}; -if (CBA_missionTime - GVAR(lastHitTick) < ACE_FRAG_SPALL_HOLDOFF) exitWith {}; +if (!(isNull _hitObj) && {_hitObj isKindOf "man"}) exitWith { + TRACE_1("hitPerson",_hitObj); +}; -if (_hitObj isNotEqualTo objNull && {_hitObj isKindOf "man"}) exitWith {}; -if ((isNil "_lPosASL") || {!(_lPosASL isEqualTypeArray [0,0,0])}) exitWith { +if (_lPosASL isEqualTo [0,0,0]) exitWith { TRACE_1("Problem with hitPart data - bad pos",_lPosASL); }; @@ -54,33 +69,25 @@ if (terrainIntersectASL [_lPosASL vectorAdd _unitStep, _lPosASL]) exitWith { // step through for "_i" from 1 to 20 do { - private _nPos = _spallPos vectorAdd _unitStep; - if (!lineIntersects [_spallPos, _nPos]) then { _spallPos = _nPos; break}; - _spallPos = +_nPos; + private _nPos = _spallPos vectorAdd _unitStep; + if (!lineIntersects [_spallPos, _nPos]) then { _spallPos = _nPos vectorAdd _unitStep; break}; + _spallPos = +_nPos; }; #ifdef DEBUG_MODE_FULL [_spallPos, "green"] call FUNC(dev_sphereDraw); [_lPosASL vectorAdd _lVelUnit, "orange"] call FUNC(dev_sphereDraw); [_lPosASL, "orange"] call FUNC(dev_sphereDraw); -private _str = GVAR(hitLog) getOrDefault [str _surfaceType, "["]; +private _str = GVAR(materialSpallCache) getOrDefault [str _surfaceType, "["]; _str =_str + str [_dV, _caliber, abs vectorMagnitude (_lPosASL vectorDiff _spallPos)] + ";"; -GVAR(hitLog) set [str _surfaceType, _str]; +GVAR(materialSpallCache) set [str _surfaceType, _str]; if (_deltaMomentum < 2) exitWith {}; #endif - + //***** Passed all other exit withs, performance o'clock */ -GVAR(lastHitTick) = CBA_missionTime; - -//***** Select spalled fragments **// -// diag_log text format ["SPALL POWER: %1", _spallPolar select 0]; -// range of spread 15-40 -// N rounds 5-15 -// speed from 0.75-1.5 -// range of spread 5-10 -// N rounds 3-8 -// speed from 0.75-1.5 +GVAR(lastSpallTime) = CBA_missionTime; +//***** Select spalled fragment spawner **// private _fragSpawnType = switch (true) do { case (_deltaMomentum < 3): { QGVAR(spall_tiny) }; @@ -96,7 +103,7 @@ private _shotParent = getShotParents _projectile; //***** Spawn spalled fragments private _spallSpawner = createVehicleLocal [_fragSpawnType, ASLToATL _spallPos, [], 0, "CAN_COLLIDE"]; _spallSpawner setVectorDirandUp [vectorDir _projectile, vectorUp _projectile]; -_spallSpawner setVelocity _lVelUnit; +_spallSpawner setVelocity (_lVelUnit vectorMultiply (_dV/2)); _spallSpawner setShotParents _shotParent; #ifdef DEBUG_MODE_FULL From fc398ff042718a617e8675336856482149499b53 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 9 Jan 2024 00:27:13 -0600 Subject: [PATCH 026/282] Updated some stringtable entries --- addons/frag/script_component.hpp | 4 ++-- addons/frag/stringtable.xml | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index 95d69d37fbd..71417a8c60c 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -4,7 +4,7 @@ // #define LOG_FRAG_INFO #define DEBUG_MODE_FULL -#define DISABLE_COMPILE_CACHE +// #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_FRAG @@ -18,7 +18,7 @@ #include "\z\ace\addons\main\script_macros.hpp" #define ACE_FRAG_HOLDOFF 1 -#define ACE_FRAG_SPALL_HOLDOFF 0.1 +#define ACE_FRAG_SPALL_HOLDOFF 0.2 #define ACE_FRAG_COUNT_MIN 5 #define ACE_FRAG_COUNT_MAX 50 #define ACE_FRAG_HITPOINTS ["spine1","spine2","spine3","head","leftarm","leftarmroll","leftforearm","rightarm","rightarmroll","rightforearm","pelvis","leftupleg","leftuplegroll","leftlegroll","leftfoot","rightupleg","rightuplegroll","rightleg","rightlegroll","rightfoot"] diff --git a/addons/frag/stringtable.xml b/addons/frag/stringtable.xml index ac8b64cd7c5..79e46856118 100644 --- a/addons/frag/stringtable.xml +++ b/addons/frag/stringtable.xml @@ -26,6 +26,9 @@ Explosion Reflections + + Debug + Fragmentation Simulation Symulacja fragmentacji From 601083bce3537855fe38d35d4bf5ef79009b536f Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 9 Jan 2024 00:54:11 -0600 Subject: [PATCH 027/282] Increased readability to doSpallMomentum --- addons/frag/functions/fnc_doSpallMomentum.sqf | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/addons/frag/functions/fnc_doSpallMomentum.sqf b/addons/frag/functions/fnc_doSpallMomentum.sqf index 8abac240956..b35baa4d046 100644 --- a/addons/frag/functions/fnc_doSpallMomentum.sqf +++ b/addons/frag/functions/fnc_doSpallMomentum.sqf @@ -70,8 +70,11 @@ if (terrainIntersectASL [_lPosASL vectorAdd _unitStep, _lPosASL]) exitWith { for "_i" from 1 to 20 do { private _nPos = _spallPos vectorAdd _unitStep; - if (!lineIntersects [_spallPos, _nPos]) then { _spallPos = _nPos vectorAdd _unitStep; break}; - _spallPos = +_nPos; + if (!lineIntersects [_spallPos, _nPos]) then { + _spallPos = _nPos vectorAdd _unitStep; + break + }; + _spallPos = _nPos; }; #ifdef DEBUG_MODE_FULL From 132dc6d4c86be8fe46f3a627de7ff829a65ae48b Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 9 Jan 2024 11:54:52 -0600 Subject: [PATCH 028/282] Fixed author lists --- addons/frag/functions/fnc_addBlackList.sqf | 2 +- addons/frag/functions/fnc_doFrag.sqf | 6 +++--- addons/frag/functions/fnc_doFragRandom.sqf | 2 +- addons/frag/functions/fnc_doFragTargeted.sqf | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/addons/frag/functions/fnc_addBlackList.sqf b/addons/frag/functions/fnc_addBlackList.sqf index d9c3d8054d7..3308351064e 100644 --- a/addons/frag/functions/fnc_addBlackList.sqf +++ b/addons/frag/functions/fnc_addBlackList.sqf @@ -18,4 +18,4 @@ params ["_proj"]; TRACE_1("addBlackList",_round); -GVAR(shouldFragCache) set [typeOf _ammo, [false, false]]; +GVAR(shouldFragCache) set [typeOf _ammo, [false, false]]; \ No newline at end of file diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 999ed368b6f..1b47fe053ab 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" /* - * Author: Lambda.Tiger + * Author: Jaynus, NouberNou, Lambda.Tiger * This function handles creating both random and targeted fragments as well * as handling some of the performance optimizations. * @@ -28,6 +28,7 @@ _args params [ TRACE_3("",_proj,_posASL,_vel); private _shotParents = getShotParents _proj; +private _ammo = typeOf _proj; private _shotParentVic = _shotParents#0; if (_shotParentVic getVariable [QGVAR(nextFragTime), -1] > CBA_missionTime) exitWith { TRACE_1("vehicleTimeExit",_shotParentVic); @@ -35,7 +36,7 @@ if (_shotParentVic getVariable [QGVAR(nextFragTime), -1] > CBA_missionTime) exit _shotParentVic setVariable [QGVAR(nextFragTime), CBA_missionTime + ACE_FRAG_HOLDOFF]; private _timeSince = CBA_missionTime - GVAR(lastFragTime); -if (isNull _proj || {_posASL isEqualTo [0,0,0] || _timeSince < 0.2}) exitWith { +if (_ammo isEqualTo "" || {_posASL isEqualTo [0,0,0] || _timeSince < 0.2}) exitWith { TRACE_3("timeExit",_timeSince,CBA_missionTime,GVAR(lastFragTime)); }; GVAR(lastFragTime) = CBA_missionTime; @@ -43,7 +44,6 @@ private _maxFrags = round (linearConversion [0.1, 1.5, _timeSince, ACE_FRAG_COUN TRACE_3("",_timeSince,CBA_missionTime,_maxFrags); -private _ammo = typeOf _proj; private _ammoArr = [_ammo] call FUNC(fragInfo); _ammoArr params ["_fragRange", "_fragVel", "_fragTypes", "_modFragCount"]; diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index f06a8b64323..39d78370cba 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" /* - * Author: Lambda.Tiger + * Author: Jaynus, NouberNou, Lambda.Tiger * This function creates fragments randomly spreading out from an explosion to * a maximum of 15 * diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index 8d8de1c48d3..22eaf0624dd 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" /* - * Author: Lambda.Tiger + * Author: Jaynus, NouberNou, Lambda.Tiger * This function creates fragments targeted at specific entities, up to * a configured maximum * From 48d37a96e0e44a682d59e4a6f4568714a288094d Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 9 Jan 2024 14:00:43 -0600 Subject: [PATCH 029/282] update caching access function names to align with each other and added some preliminary material consideration for spalling --- ...Addition.hpp => cfgAmmoFragParameters.hpp} | 0 addons/frag/functions/fnc_doFrag.sqf | 2 +- addons/frag/functions/fnc_doFragRandom.sqf | 3 +- addons/frag/functions/fnc_doSpall.sqf | 2 +- addons/frag/functions/fnc_doSpallMomentum.sqf | 14 ++++---- .../{fnc_fragInfo.sqf => fnc_getFragInfo.sqf} | 2 +- addons/frag/functions/fnc_getMaterialInfo.sqf | 35 +++++++++++++++++++ 7 files changed, 46 insertions(+), 12 deletions(-) rename addons/frag/{cfgAmmoFragAddition.hpp => cfgAmmoFragParameters.hpp} (100%) rename addons/frag/functions/{fnc_fragInfo.sqf => fnc_getFragInfo.sqf} (98%) create mode 100644 addons/frag/functions/fnc_getMaterialInfo.sqf diff --git a/addons/frag/cfgAmmoFragAddition.hpp b/addons/frag/cfgAmmoFragParameters.hpp similarity index 100% rename from addons/frag/cfgAmmoFragAddition.hpp rename to addons/frag/cfgAmmoFragParameters.hpp diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 1b47fe053ab..074b0cd2e1d 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -44,7 +44,7 @@ private _maxFrags = round (linearConversion [0.1, 1.5, _timeSince, ACE_FRAG_COUN TRACE_3("",_timeSince,CBA_missionTime,_maxFrags); -private _ammoArr = [_ammo] call FUNC(fragInfo); +private _ammoArr = [_ammo] call FUNC(getFragInfo); _ammoArr params ["_fragRange", "_fragVel", "_fragTypes", "_modFragCount"]; private _heightAGL = (ASLToAGL _posASL)#2; diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index 39d78370cba..919a3ee049d 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -31,14 +31,13 @@ params [ ]; TRACE_5("fnc_doFragRandom", _posASL, _projVel, _heightAGL, _fragType, _fragCnt); -// See CfgAmmo for different frag types +// See cfgAmmoFragSpawner for different frag types private _hMode = switch (true) do { case (_heightAGL > 10): {"_top"}; case (_heightAGL > 5): {"_hi"}; default {"_mid"}; }; -// Select the cfgAmmo type private _type = if (count _fragType > 0 && {"ace_frag_tiny" isEqualTo (_fragType#0)}) then { QGVAR(def_tiny_) diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index 00cbe9addef..8777be45ead 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -66,7 +66,7 @@ systemChat ("dV: " + str _dv + ", caliber: " + str _caliber + ", product: " + st #endif if (_explosive > 0) then { - private _fragMod = (_ammo call FUNC(fragInfo))#1; + private _fragMod = (_ammo call FUNC(getFragInfo))#1; _velMod = _fragMod * _velMod; }; diff --git a/addons/frag/functions/fnc_doSpallMomentum.sqf b/addons/frag/functions/fnc_doSpallMomentum.sqf index b35baa4d046..dc843899442 100644 --- a/addons/frag/functions/fnc_doSpallMomentum.sqf +++ b/addons/frag/functions/fnc_doSpallMomentum.sqf @@ -51,18 +51,19 @@ private _lVelUnit = vectorNormalized _lVel; private _ammo = typeOf _projectile; private _dV = vectorMagnitude _lVel - vectorMagnitude _vel; private _caliber = getNumber (configFile >> "cfgAmmo" >> _ammo >> "caliber"); // !*! optimize this later? -private _deltaMomentum = 0.4 * _caliber * sqrt( _dV * 0.032 ); +// scaled momentum change made on caliber-mass assumption ~sqrt(2)/20 * caliber ~= mass +private _deltaMomentum = 0.07071 * _caliber * sqrt( _dV ); TRACE_3("found speed",_dV,_caliber,_deltaMomentum); -if (_deltaMomentum < 1) exitWith { +if (_deltaMomentum < 2) exitWith { TRACE_1("lowImpulse",_ammo); }; //** start calculating where the spalling should come !*! could be better **// private _unitStep = _lVelUnit vectorMultiply 0.05; private _spallPos = +_lPosASL; -// exit if we hit the ground + if (terrainIntersectASL [_lPosASL vectorAdd _unitStep, _lPosASL]) exitWith { TRACE_3("terrainIntersect",_lPosASL,_unitStep,_lPosASL); }; @@ -81,16 +82,15 @@ for "_i" from 1 to 20 do [_spallPos, "green"] call FUNC(dev_sphereDraw); [_lPosASL vectorAdd _lVelUnit, "orange"] call FUNC(dev_sphereDraw); [_lPosASL, "orange"] call FUNC(dev_sphereDraw); -private _str = GVAR(materialSpallCache) getOrDefault [str _surfaceType, "["]; -_str =_str + str [_dV, _caliber, abs vectorMagnitude (_lPosASL vectorDiff _spallPos)] + ";"; -GVAR(materialSpallCache) set [str _surfaceType, _str]; -if (_deltaMomentum < 2) exitWith {}; #endif //***** Passed all other exit withs, performance o'clock */ GVAR(lastSpallTime) = CBA_missionTime; //***** Select spalled fragment spawner **// + +private _material = [_surfaceType] call FUNC(getMaterialInfo); + private _fragSpawnType = switch (true) do { case (_deltaMomentum < 3): { QGVAR(spall_tiny) }; diff --git a/addons/frag/functions/fnc_fragInfo.sqf b/addons/frag/functions/fnc_getFragInfo.sqf similarity index 98% rename from addons/frag/functions/fnc_fragInfo.sqf rename to addons/frag/functions/fnc_getFragInfo.sqf index 9211b79bd2b..0044896f771 100644 --- a/addons/frag/functions/fnc_fragInfo.sqf +++ b/addons/frag/functions/fnc_getFragInfo.sqf @@ -16,7 +16,7 @@ * of spherical fragmentation * * Example: - * ["B_556x45_Ball"] call ace_frag_fnc_fragInfo; + * ["B_556x45_Ball"] call ace_frag_fnc_getFragInfo; * * Public: No */ diff --git a/addons/frag/functions/fnc_getMaterialInfo.sqf b/addons/frag/functions/fnc_getMaterialInfo.sqf new file mode 100644 index 00000000000..a4423a05cf8 --- /dev/null +++ b/addons/frag/functions/fnc_getMaterialInfo.sqf @@ -0,0 +1,35 @@ +#include "script_component.hpp" +/* + * Author: Lambda.Tiger + * This function returns fragmentation parameters for a specific + * ammo type. + * + * Arguments: + * 0: _ammo - cfgAmmo type of ammo to check + * + * Return Value: + * _ammoInfo + * 0: _fragRange - search range for fragments + * 1: _fragVel - gurney equation calculated velocity + * 2: _fragTypes - array of fragment types + * 3: _fragCount - modified frag count used under assumptions + * of spherical fragmentation + * + * Example: + * ["B_556x45_Ball"] call ace_frag_fnc_getFragInfo; + * + * Public: No + */ + +params ["_surfType"]; + +private _material = GVAR(materialSpallCache) get _surfType; + +if !(isNil "_material") exitWith {_material}; + +private _str = GVAR(materialSpallCache) getOrDefault [str _surfaceType, "["]; +_str =_str + str [_dV, _caliber, abs vectorMagnitude (_lPosASL vectorDiff _spallPos)] + ";"; + +GVAR(materialSpallCache) set [_surfaceType, _material]; + +_material \ No newline at end of file From ed116f1b2b98bd689362e58ac541fb6e23089bac Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 9 Jan 2024 14:01:12 -0600 Subject: [PATCH 030/282] additional changes for spalling material consideration --- addons/frag/XEH_PREP.hpp | 2 +- addons/frag/XEH_preInit.sqf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/frag/XEH_PREP.hpp b/addons/frag/XEH_PREP.hpp index e7d3597d02e..7ef64f52a68 100644 --- a/addons/frag/XEH_PREP.hpp +++ b/addons/frag/XEH_PREP.hpp @@ -20,7 +20,7 @@ PREP(addBlackList); PREP(initBlackList); PREP(submunition); PREP(shouldFrag); -PREP(fragInfo); +PREP(getFragInfo); PREP(doFrag); PREP(doFragTargeted); PREP(doFragRandom); diff --git a/addons/frag/XEH_preInit.sqf b/addons/frag/XEH_preInit.sqf index 566cfc37211..463702efb84 100644 --- a/addons/frag/XEH_preInit.sqf +++ b/addons/frag/XEH_preInit.sqf @@ -8,7 +8,7 @@ PREP_RECOMPILE_END; GVAR(materialSpallCache) = createHashMap; -GVAR(spallRoundCache) = createHashMap; +GVAR(spallRoundCache) = createHashMapFromArray [["", "metal"]]; GVAR(lastSpallTime) = -2; GVAR(shouldFragCache) = createHashMap; From 026e12b2f9947a309237ea3ddfb9438e77541255 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 9 Jan 2024 17:25:09 -0600 Subject: [PATCH 031/282] Added methods to retrieve impact surface type --- addons/frag/CfgAmmo.hpp | 12 +++--- addons/frag/XEH_PREP.hpp | 1 + addons/frag/XEH_preInit.sqf | 4 +- addons/frag/functions/fnc_doSpallMomentum.sqf | 38 ++++++++++--------- addons/frag/functions/fnc_getMaterialInfo.sqf | 37 ++++++++++++++++-- addons/frag/functions/fnc_initRound.sqf | 38 +++++++++++++++---- addons/frag/script_component.hpp | 3 +- 7 files changed, 95 insertions(+), 38 deletions(-) diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index d7d148e65c7..1088f39a081 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -8,12 +8,7 @@ class CfgAmmo { class B_65x39_Caseless; - #include "cfgAmmoBaseEH.hpp" - #include "cfgAmmoSpall.hpp" - #include "cfgAmmoFragAddition.hpp" - #include "cfgAmmoFragSpawner.hpp" - - class GVAR(base): B_65x39_Caseless { + class GVAR(base): B_65x39_Caseless { ACE_damageType = "grenade"; // compatibility with medical_damage, shrapnel should produce grenade wounds timeToLive = 4; typicalSpeed = 800; @@ -89,4 +84,9 @@ class CfgAmmo { airFriction = QUOTE(BASE_DRAG_HD*0.5); caliber = 2.8; }; + + #include "cfgAmmoBaseEH.hpp" + #include "cfgAmmoSpall.hpp" + #include "cfgAmmoFragParameters.hpp" + #include "cfgAmmoFragSpawner.hpp" }; \ No newline at end of file diff --git a/addons/frag/XEH_PREP.hpp b/addons/frag/XEH_PREP.hpp index 7ef64f52a68..16dde5e8c7f 100644 --- a/addons/frag/XEH_PREP.hpp +++ b/addons/frag/XEH_PREP.hpp @@ -29,6 +29,7 @@ PREP(doFragRandom); PREP(shouldSpall); PREP(doSpall); PREP(doSpallMomentum); +PREP(getMaterialInfo); //PREP(spallHP); Look at me !*! // Explosive Reflection diff --git a/addons/frag/XEH_preInit.sqf b/addons/frag/XEH_preInit.sqf index 463702efb84..e38296c5c47 100644 --- a/addons/frag/XEH_preInit.sqf +++ b/addons/frag/XEH_preInit.sqf @@ -7,8 +7,8 @@ PREP_RECOMPILE_START; PREP_RECOMPILE_END; -GVAR(materialSpallCache) = createHashMap; -GVAR(spallRoundCache) = createHashMapFromArray [["", "metal"]]; +GVAR(materialSpallCache) = createHashMapFromArray [["", "metal"]]; +GVAR(spallRoundCache) = createHashMap; GVAR(lastSpallTime) = -2; GVAR(shouldFragCache) = createHashMap; diff --git a/addons/frag/functions/fnc_doSpallMomentum.sqf b/addons/frag/functions/fnc_doSpallMomentum.sqf index dc843899442..bfc22a2b996 100644 --- a/addons/frag/functions/fnc_doSpallMomentum.sqf +++ b/addons/frag/functions/fnc_doSpallMomentum.sqf @@ -15,24 +15,28 @@ * * Public: No */ +TRACE_1("",_this); params [ "_projectile", ["_hitObj", objNull], - "", +// "", ["_lPosASL", [0, 0, 0]], ["_lVel", [0, 0, 0]], - "", - "", - "", - ["_surfaceType", ""] +// "", +// "", +// "", + ["_surfaceType", ""], + ["_ammo", "", [""]], + ["_shotParents", [objNull, objNull], [[]]], + ["_vUp", [0,0,1]] ]; if (CBA_missionTime - GVAR(lastSpallTime) < ACE_FRAG_SPALL_HOLDOFF) exitWith { TRACE_2("timeExit",CBA_missionTime,GVAR(lastSpallTime)); }; -if (!(isNull _hitObj) && {_hitObj isKindOf "man"}) exitWith { - TRACE_1("hitPerson",_hitObj); +if (isNull _hitObj || {_hitObj isKindOf "man"}) exitWith { + TRACE_1("invalidHit",_hitObj); }; if (_lPosASL isEqualTo [0,0,0]) exitWith { @@ -48,7 +52,6 @@ private _lVelUnit = vectorNormalized _lVel; // Find spall speed / fragment -private _ammo = typeOf _projectile; private _dV = vectorMagnitude _lVel - vectorMagnitude _vel; private _caliber = getNumber (configFile >> "cfgAmmo" >> _ammo >> "caliber"); // !*! optimize this later? // scaled momentum change made on caliber-mass assumption ~sqrt(2)/20 * caliber ~= mass @@ -60,6 +63,9 @@ if (_deltaMomentum < 2) exitWith { TRACE_1("lowImpulse",_ammo); }; +private _material = [_surfaceType] call FUNC(getMaterialInfo); +TRACE_1("materialCacheRetrieved",_material); + //** start calculating where the spalling should come !*! could be better **// private _unitStep = _lVelUnit vectorMultiply 0.05; private _spallPos = +_lPosASL; @@ -79,9 +85,11 @@ for "_i" from 1 to 20 do }; #ifdef DEBUG_MODE_FULL -[_spallPos, "green"] call FUNC(dev_sphereDraw); -[_lPosASL vectorAdd _lVelUnit, "orange"] call FUNC(dev_sphereDraw); -[_lPosASL, "orange"] call FUNC(dev_sphereDraw); +if GVAR(dbgSphere) then { + [_spallPos, "green"] call FUNC(dev_sphereDraw); + [_lPosASL vectorAdd _lVelUnit, "orange"] call FUNC(dev_sphereDraw); + [_lPosASL, "orange"] call FUNC(dev_sphereDraw); +}; #endif //***** Passed all other exit withs, performance o'clock */ @@ -89,7 +97,6 @@ GVAR(lastSpallTime) = CBA_missionTime; //***** Select spalled fragment spawner **// -private _material = [_surfaceType] call FUNC(getMaterialInfo); private _fragSpawnType = switch (true) do { @@ -100,14 +107,11 @@ private _fragSpawnType = switch (true) do default { QGVAR(spall_huge) }; }; -// Shot parent -private _shotParent = getShotParents _projectile; - //***** Spawn spalled fragments private _spallSpawner = createVehicleLocal [_fragSpawnType, ASLToATL _spallPos, [], 0, "CAN_COLLIDE"]; -_spallSpawner setVectorDirandUp [vectorDir _projectile, vectorUp _projectile]; +_spallSpawner setVectorDirandUp [_lVelUnit, _vUp]; _spallSpawner setVelocity (_lVelUnit vectorMultiply (_dV/2)); -_spallSpawner setShotParents _shotParent; +_spallSpawner setShotParents _shotParents; #ifdef DEBUG_MODE_FULL systemChat ("bSpd: " + str speed _spallSpawner + ", frag: " + _fragSpawnType + ", dm: " + str _deltaMomentum); diff --git a/addons/frag/functions/fnc_getMaterialInfo.sqf b/addons/frag/functions/fnc_getMaterialInfo.sqf index a4423a05cf8..abab212b28e 100644 --- a/addons/frag/functions/fnc_getMaterialInfo.sqf +++ b/addons/frag/functions/fnc_getMaterialInfo.sqf @@ -25,11 +25,40 @@ params ["_surfType"]; private _material = GVAR(materialSpallCache) get _surfType; -if !(isNil "_material") exitWith {_material}; +TRACE_2("materialCache",_surfType,_material); +if !(isNil "_material") exitWith { + _material +}; -private _str = GVAR(materialSpallCache) getOrDefault [str _surfaceType, "["]; -_str =_str + str [_dV, _caliber, abs vectorMagnitude (_lPosASL vectorDiff _spallPos)] + ";"; +if (isClass (configFile >> "CfgSurfaces" >> _surfType)) then { + _material = getText (configFile >> "CfgSurfaces" >> _surfType >> "soundEnviron"); +} else { // Messy way when a surface isn't added to cfgSurfaces + private _surfFileText = loadFile _surfType; + _surfFileText = (tolower _surfFileText) splitString " ;="+ endl; + private _idx = _surfFileText find "soundenviron"; + _material = _surfFileText#(_idx+1); + if (_material isEqualTo "empty") then { + _idx = _surfFileText find "soundhit"; + _material = _surfFileText#(_idx+1); + }; +}; +TRACE_1("soundFound",_material); -GVAR(materialSpallCache) set [_surfaceType, _material]; + +_material = switch (true) do { + case ("dirt" in _material); + case ("grass" in _material): { "ground" }; + case ("gravel" in _material); + case ("rock" in _material): { "rock" }; + case ("wood" in _material): { "wood" }; + case ("lino" in _material); + case ("building" isEqualTo _material); + case ("concrete" in _material): { "concrete" }; + case ("metal" in _material): { "metal" }; + default { "ground" }; +}; + +GVAR(materialSpallCache) set [_surfType, _material]; +TRACE_2("materialCacheSet",_surfType,_material); _material \ No newline at end of file diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index 9a1677d2b6d..21715417169 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -15,7 +15,7 @@ * Public: No */ params [ - ["_projectile", objNull, [objNull]] + ["_projectile", objNull, [objNull]] ]; private _ammo = typeOf _projectile; @@ -29,12 +29,21 @@ _shouldFrag params ["_doFrag"]; if (_doFrag) then { // wait for frag damage to kill units before spawning fragments _projectile addEventHandler [ - "Explode", - { + "Explode", + { + params ["_proj"]; + private _shotParents = getShotParents _proj; + private _ammo = typeOf _proj; if (isServer) then { - [FUNC(doFrag), [_this]] call CBA_fnc_execNextFrame; + [ + FUNC(doFrag), + _this + [_ammo, _shotParents] + ] call CBA_fnc_execNextFrame; } else { - [QGVAR(frag_eh), [_this]] call CBA_fnc_serverEvent; + [ + QGVAR(frag_eh), + [_this + [_ammo, _shotParents]] + ] call CBA_fnc_serverEvent; }; } ]; @@ -45,13 +54,26 @@ private _shouldSpall = _ammo call FUNC(shouldSpall); if (GVAR(spallEnabled) && {_shouldSpall}) then { - _projectile addEventHandler [ + _projectile addEventHandler [ "HitPart", { + params ["_proj", "_hitObj", "", + "_posASL", "_vel", "", "", + "", "surfType" + ]; + private _shotPrnt = getShotParents _proj; + private _ammo = typeOf _proj; + private _vUp = vectorUp _proj; if (isServer) then { - [LINKFUNC(doSpallMomentum), _this] call CBA_fnc_execNextFrame; + [ + LINKFUNC(doSpallMomentum), + [_proj, _hitObj, _posASL, _vel, surfType, _shotPrnt, _ammo, _vUp] + ] call CBA_fnc_execNextFrame; } else { - [QGVAR(spall_eh), [_this]] call CBA_fnc_serverEvent; + [ + QGVAR(spall_eh), + [_proj, _hitObj, _posASL, _vel, surfType, _shotPrnt, _ammo, _vUp] + ] call CBA_fnc_serverEvent; }; } ]; diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index 71417a8c60c..333ace4f89d 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -17,7 +17,8 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define ACE_FRAG_HOLDOFF 1 +#define ACE_FRAG_HOLDOFF 0.2 +#define ACE_FRAG_HOLDOFF_VEHICLE 1 #define ACE_FRAG_SPALL_HOLDOFF 0.2 #define ACE_FRAG_COUNT_MIN 5 #define ACE_FRAG_COUNT_MAX 50 From a9a5a4a9bab8bb8d73e66164d940b56e83cb5ae7 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 9 Jan 2024 17:25:38 -0600 Subject: [PATCH 032/282] dealt with cases were projectile is deleted before fragmentation --- addons/frag/functions/fnc_doFrag.sqf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 074b0cd2e1d..412678377e1 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -23,20 +23,20 @@ params ["_args", ["_isSubMunit", false, [false]]]; _args params [ ["_proj", objNull, [objNull]], ["_posASL", [0,0,0], [[]], [3]], - ["_vel", [0,0,0] , [[]], [3]] + ["_vel", [0,0,0] , [[]], [3]], + ["_ammo", "", [""]], + ["_shotParents", [objNull, objNull], [[]]] ]; TRACE_3("",_proj,_posASL,_vel); -private _shotParents = getShotParents _proj; -private _ammo = typeOf _proj; private _shotParentVic = _shotParents#0; if (_shotParentVic getVariable [QGVAR(nextFragTime), -1] > CBA_missionTime) exitWith { TRACE_1("vehicleTimeExit",_shotParentVic); }; -_shotParentVic setVariable [QGVAR(nextFragTime), CBA_missionTime + ACE_FRAG_HOLDOFF]; +_shotParentVic setVariable [QGVAR(nextFragTime), CBA_missionTime + ACE_FRAG_HOLDOFF_VEHICLE]; private _timeSince = CBA_missionTime - GVAR(lastFragTime); -if (_ammo isEqualTo "" || {_posASL isEqualTo [0,0,0] || _timeSince < 0.2}) exitWith { +if (_ammo isEqualTo "" || {_posASL isEqualTo [0,0,0] || _timeSince < ACE_FRAG_HOLDOFF}) exitWith { TRACE_3("timeExit",_timeSince,CBA_missionTime,GVAR(lastFragTime)); }; GVAR(lastFragTime) = CBA_missionTime; From 210a876c0cdd4f53bfa2bcfe6333ff2a2ec754d9 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 9 Jan 2024 17:36:36 -0600 Subject: [PATCH 033/282] missed underscore --- addons/frag/functions/fnc_initRound.sqf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index 21715417169..51e0d81f153 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -59,7 +59,7 @@ if (GVAR(spallEnabled) && {_shouldSpall}) then { params ["_proj", "_hitObj", "", "_posASL", "_vel", "", "", - "", "surfType" + "", "_surfType" ]; private _shotPrnt = getShotParents _proj; private _ammo = typeOf _proj; @@ -67,12 +67,12 @@ if (GVAR(spallEnabled) && {_shouldSpall}) then if (isServer) then { [ LINKFUNC(doSpallMomentum), - [_proj, _hitObj, _posASL, _vel, surfType, _shotPrnt, _ammo, _vUp] + [_proj, _hitObj, _posASL, _vel, _surfType, _shotPrnt, _ammo, _vUp] ] call CBA_fnc_execNextFrame; } else { [ QGVAR(spall_eh), - [_proj, _hitObj, _posASL, _vel, surfType, _shotPrnt, _ammo, _vUp] + [_proj, _hitObj, _posASL, _vel, _surfType, _shotPrnt, _ammo, _vUp] ] call CBA_fnc_serverEvent; }; } From acb72490398a7acd67d8e81941cccf96ac7257f2 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 9 Jan 2024 19:03:12 -0600 Subject: [PATCH 034/282] added impact angle calculation handle to minimize spawning spall inside walls --- addons/frag/functions/fnc_doSpallMomentum.sqf | 49 ++++++++++--------- addons/frag/functions/fnc_initRound.sqf | 6 +-- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/addons/frag/functions/fnc_doSpallMomentum.sqf b/addons/frag/functions/fnc_doSpallMomentum.sqf index bfc22a2b996..f70ebef9a09 100644 --- a/addons/frag/functions/fnc_doSpallMomentum.sqf +++ b/addons/frag/functions/fnc_doSpallMomentum.sqf @@ -17,26 +17,26 @@ */ TRACE_1("",_this); params [ - "_projectile", - ["_hitObj", objNull], + "_projectile", + ["_hitObj", objNull], // "", - ["_lPosASL", [0, 0, 0]], - ["_lVel", [0, 0, 0]], + ["_lPosASL", [0, 0, 0]], + ["_lVel", [0, 0, 0]], + ["_sNorm", [0, 0, 0]], // "", // "", -// "", - ["_surfaceType", ""], - ["_ammo", "", [""]], - ["_shotParents", [objNull, objNull], [[]]], - ["_vUp", [0,0,1]] + ["_surfaceType", ""], + ["_ammo", "", [""]], + ["_shotParents", [objNull, objNull], [[]]], + ["_vUp", [0,0,1]] ]; if (CBA_missionTime - GVAR(lastSpallTime) < ACE_FRAG_SPALL_HOLDOFF) exitWith { - TRACE_2("timeExit",CBA_missionTime,GVAR(lastSpallTime)); + TRACE_2("timeExit",CBA_missionTime,GVAR(lastSpallTime)); }; if (isNull _hitObj || {_hitObj isKindOf "man"}) exitWith { - TRACE_1("invalidHit",_hitObj); + TRACE_1("invalidHit",_hitObj); }; if (_lPosASL isEqualTo [0,0,0]) exitWith { @@ -48,7 +48,6 @@ private _vel = if (alive _projectile) then { } else { [0, 0, 0] }; -private _lVelUnit = vectorNormalized _lVel; // Find spall speed / fragment @@ -67,32 +66,38 @@ private _material = [_surfaceType] call FUNC(getMaterialInfo); TRACE_1("materialCacheRetrieved",_material); //** start calculating where the spalling should come !*! could be better **// +private _lVelUnit = vectorNormalized _lVel; private _unitStep = _lVelUnit vectorMultiply 0.05; private _spallPos = +_lPosASL; + +if (120 > acos ((vectorNormalized _lVelUnit) vectorDotProduct _sNorm)) then { + _spallPos = _spallPos vectorAdd (_unitStep vectorMultiply 5); +}; + if (terrainIntersectASL [_lPosASL vectorAdd _unitStep, _lPosASL]) exitWith { TRACE_3("terrainIntersect",_lPosASL,_unitStep,_lPosASL); }; // step through for "_i" from 1 to 20 do { - private _nPos = _spallPos vectorAdd _unitStep; - if (!lineIntersects [_spallPos, _nPos]) then { - _spallPos = _nPos vectorAdd _unitStep; - break - }; - _spallPos = _nPos; + private _nPos = _spallPos vectorAdd _unitStep; + if (!lineIntersects [_spallPos, _nPos]) then { + _spallPos = _nPos vectorAdd _unitStep; + break + }; + _spallPos = _nPos; }; #ifdef DEBUG_MODE_FULL if GVAR(dbgSphere) then { - [_spallPos, "green"] call FUNC(dev_sphereDraw); - [_lPosASL vectorAdd _lVelUnit, "orange"] call FUNC(dev_sphereDraw); - [_lPosASL, "orange"] call FUNC(dev_sphereDraw); + [_spallPos, "green"] call FUNC(dev_sphereDraw); + [_lPosASL vectorAdd _lVelUnit, "orange"] call FUNC(dev_sphereDraw); + [_lPosASL, "orange"] call FUNC(dev_sphereDraw); }; #endif -//***** Passed all other exit withs, performance o'clock */ +//***** Passed all exit withs *****// GVAR(lastSpallTime) = CBA_missionTime; //***** Select spalled fragment spawner **// diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index 51e0d81f153..7d50661e675 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -58,7 +58,7 @@ if (GVAR(spallEnabled) && {_shouldSpall}) then "HitPart", { params ["_proj", "_hitObj", "", - "_posASL", "_vel", "", "", + "_posASL", "_vel", "_sNorm", "", "", "_surfType" ]; private _shotPrnt = getShotParents _proj; @@ -67,12 +67,12 @@ if (GVAR(spallEnabled) && {_shouldSpall}) then if (isServer) then { [ LINKFUNC(doSpallMomentum), - [_proj, _hitObj, _posASL, _vel, _surfType, _shotPrnt, _ammo, _vUp] + [_proj, _hitObj, _posASL, _vel, _sNorm, _surfType, _ammo, _shotPrnt, _vUp] ] call CBA_fnc_execNextFrame; } else { [ QGVAR(spall_eh), - [_proj, _hitObj, _posASL, _vel, _surfType, _shotPrnt, _ammo, _vUp] + [_proj, _hitObj, _posASL, _vel, _sNorm, _surfType, _ammo, _shotPrnt, _vUp] ] call CBA_fnc_serverEvent; }; } From 71f26f5df64a89aa9d068554c2b9bc7ae0ba170d Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 9 Jan 2024 21:07:01 -0600 Subject: [PATCH 035/282] Updated spall to use material --- addons/frag/cfgAmmoSpall.hpp | 139 +++++++++++++++--- addons/frag/functions/fnc_doSpallMomentum.sqf | 28 ++-- 2 files changed, 136 insertions(+), 31 deletions(-) diff --git a/addons/frag/cfgAmmoSpall.hpp b/addons/frag/cfgAmmoSpall.hpp index 7c822676a2a..59e478ad7fb 100644 --- a/addons/frag/cfgAmmoSpall.hpp +++ b/addons/frag/cfgAmmoSpall.hpp @@ -1,5 +1,4 @@ -class GVAR(spallBase) : B_65x39_Caseless -{ +class GVAR(spallBase) : B_65x39_Caseless { access = 3; submunitionAmmo[] = {QGVAR(small),4,QGVAR(medium),3,QGVAR(large),2,QGVAR(huge),1}; submunitionConeType[] = {"random", 20}; @@ -14,37 +13,137 @@ class GVAR(spallBase) : B_65x39_Caseless ACE_FRAG_RM_EH; }; -class GVAR(spall_tiny) : GVAR(spallBase) -{ - submunitionAmmo[] = {QGVAR(small), 4, QGVAR(medium), 1}; - submunitionConeType[] = {"poissondisccenter", 5}; - submunitionConeAngle = 40; + +//**** ground ****// +class GVAR(ground_spall_tiny) : GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 9, QGVAR(small), 1}; + submunitionConeType[] = {"poissondisccenter", 4}; }; -class GVAR(spall_small) : GVAR(spallBase) -{ +class GVAR(ground_spall_small) : GVAR(spallBase) { submunitionAmmo[] = {QGVAR(small), 4,QGVAR(medium), 1}; - submunitionConeType[] = {"poissondisccenter", 10}; - submunitionConeAngle = 40; + submunitionConeType[] = {"poissondisccenter", 6}; }; -class GVAR(spall_medium) : GVAR(spallBase) -{ +class GVAR(ground_spall_medium) : GVAR(spallBase) { submunitionAmmo[] = {QGVAR(small), 2, QGVAR(small_HD), 1,QGVAR(medium), 3, QGVAR(medium_HD), 1, QGVAR(large), 2}; submunitionConeType[] = {"poissondisccenter", 15}; - submunitionConeAngle = 40; }; -class GVAR(spall_large) : GVAR(spallBase) -{ +class GVAR(ground_spall_large) : GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 3, QGVAR(tiny_HD), 3, QGVAR(small), 4, QGVAR(small_HD), 4, QGVAR(medium_HD), 5, QGVAR(large), 1, QGVAR(large_HD), 2}; submunitionConeType[] = {"poissondisccenter", 15}; - submunitionConeAngle = 40; }; -class GVAR(spall_huge) : GVAR(spallBase) -{ +class GVAR(ground_spall_huge) : GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 3, QGVAR(tiny_HD), 3, QGVAR(small), 4, QGVAR(small_HD), 4, QGVAR(medium), 5, QGVAR(large), 1, QGVAR(large_HD), 2}; submunitionConeType[] = {"poissondisccenter", 20}; - submunitionConeAngle = 40; +}; + + +//**** rock ****// +class GVAR(rock_spall_tiny) : GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(small), 4, QGVAR(medium_HD), 1}; + submunitionConeType[] = {"poissondisccenter", 4}; +}; + +class GVAR(rock_spall_small) : GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(small), 4, QGVAR(medium), 1}; + submunitionConeType[] = {"poissondisccenter", 5}; +}; + +class GVAR(rock_spall_medium) : GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(small), 4, QGVAR(medium), 1, QGVAR(medium_HD), 2, QGVAR(large_HD), 1}; + submunitionConeType[] = {"poissondisccenter", 7}; +}; + +class GVAR(rock_spall_large) : GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(small), 5, QGVAR(medium), 2, QGVAR(large), 1}; + submunitionConeType[] = {"poissondisccenter", 10}; +}; + +class GVAR(rock_spall_huge) : GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(small), 5, QGVAR(medium), 2, QGVAR(large), 1, QGVAR(huge_HD), 1}; + submunitionConeType[] = {"poissondisccenter", 13}; +}; + + +//**** wood ****// +class GVAR(wood_spall_tiny) : GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 2, QGVAR(small), 4}; + submunitionConeType[] = {"poissondisccenter", 4}; +}; + +class GVAR(wood_spall_small) : GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 2, QGVAR(small), 4, QGVAR(medium), 1}; + submunitionConeType[] = {"poissondisccenter", 6}; +}; + +class GVAR(wood_spall_medium) : GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 2, QGVAR(small), 2, QGVAR(medium), 2, QGVAR(medium_HD), 1, QGVAR(large_HD), 1}; + submunitionConeType[] = {"poissondisccenter", 8}; +}; + +class GVAR(wood_spall_large) : GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 1, QGVAR(small), 3, QGVAR(medium), 2, QGVAR(large_HD), 2, QGVAR(huge_HD), 1}; + submunitionConeType[] = {"poissondisccenter", 10}; +}; + +class GVAR(wood_spall_huge) : GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 1, QGVAR(small), 3, QGVAR(medium), 2, QGVAR(large_HD), 2, QGVAR(huge_HD), 1}; + submunitionConeType[] = {"poissondisccenter", 12}; +}; + + +//**** concrete ****// +class GVAR(concrete_spall_tiny) : GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 6, QGVAR(tiny_HD), 3, QGVAR(small), 1}; + submunitionConeType[] = {"poissondisccenter", 4}; +}; + +class GVAR(concrete_spall_small) : GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 4, QGVAR(tiny_HD), 2, QGVAR(small), 2, QGVAR(medium), 1}; + submunitionConeType[] = {"poissondisccenter", 6}; +}; + +class GVAR(concrete_spall_medium) : GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 6, QGVAR(tiny_HD), 1, QGVAR(small), 4, QGVAR(medium), 5, QGVAR(large_HD), 1}; + submunitionConeType[] = {"poissondisccenter", 9}; +}; + +class GVAR(concrete_spall_large) : GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 6, QGVAR(small), 4, QGVAR(medium), 3, QGVAR(large), 1, QGVAR(large_HD), 2}; + submunitionConeType[] = {"poissondisccenter", 12}; +}; + +class GVAR(concrete_spall_huge) : GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 8, QGVAR(small), 4, QGVAR(medium), 3, QGVAR(large), 1, QGVAR(large_HD), 1, QGVAR(huge_HD), 1}; + submunitionConeType[] = {"poissondisccenter", 18}; +}; + + +//**** metal ****// +class GVAR(metal_spall_tiny) : GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 9, QGVAR(small), 1}; + submunitionConeType[] = {"poissondisccenter", 4}; +}; + +class GVAR(metal_spall_small) : GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 4, QGVAR(small), 2, QGVAR(medium), 1}; + submunitionConeType[] = {"poissondisccenter", 6}; +}; + +class GVAR(metal_metal_spall_medium) : GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 5, QGVAR(small), 4, QGVAR(medium), 2, QGVAR(large), 1}; + submunitionConeType[] = {"poissondisccenter", 8}; +}; + +class GVAR(metal_spall_large) : GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 4, QGVAR(small), 3, QGVAR(medium), 2, QGVAR(large), 1, QGVAR(huge), 1}; + submunitionConeType[] = {"poissondisccenter", 12}; +}; + +class GVAR(metal_spall_huge) : GVAR(spallBase) { + submunitionAmmo[] = {QGVAR(tiny), 8, QGVAR(small), 3, QGVAR(medium), 2, QGVAR(large), 3, QGVAR(huge), 1}; + submunitionConeType[] = {"poissondisccenter", 18}; }; \ No newline at end of file diff --git a/addons/frag/functions/fnc_doSpallMomentum.sqf b/addons/frag/functions/fnc_doSpallMomentum.sqf index f70ebef9a09..a75c4cf4c48 100644 --- a/addons/frag/functions/fnc_doSpallMomentum.sqf +++ b/addons/frag/functions/fnc_doSpallMomentum.sqf @@ -54,8 +54,7 @@ private _vel = if (alive _projectile) then { private _dV = vectorMagnitude _lVel - vectorMagnitude _vel; private _caliber = getNumber (configFile >> "cfgAmmo" >> _ammo >> "caliber"); // !*! optimize this later? // scaled momentum change made on caliber-mass assumption ~sqrt(2)/20 * caliber ~= mass -private _deltaMomentum = 0.07071 * _caliber * sqrt( _dV ); - +private _deltaMomentum = 0.0707 * _caliber * sqrt( _dV ); TRACE_3("found speed",_dV,_caliber,_deltaMomentum); if (_deltaMomentum < 2) exitWith { @@ -63,7 +62,6 @@ if (_deltaMomentum < 2) exitWith { }; private _material = [_surfaceType] call FUNC(getMaterialInfo); -TRACE_1("materialCacheRetrieved",_material); //** start calculating where the spalling should come !*! could be better **// private _lVelUnit = vectorNormalized _lVel; @@ -102,23 +100,31 @@ GVAR(lastSpallTime) = CBA_missionTime; //***** Select spalled fragment spawner **// - -private _fragSpawnType = switch (true) do +private _spawnSize = switch (true) do { - case (_deltaMomentum < 3): { QGVAR(spall_tiny) }; - case (_deltaMomentum < 5): { QGVAR(spall_small) }; - case (_deltaMomentum < 8): { QGVAR(spall_medium) }; - case (_deltaMomentum < 11): { QGVAR(spall_large) }; - default { QGVAR(spall_huge) }; + case (_deltaMomentum < 3): { "_spall_tiny" }; + case (_deltaMomentum < 5): { "_spall_small" }; + case (_deltaMomentum < 8): { "_spall_medium" }; + case (_deltaMomentum < 12): { "_spall_large" }; + default { "_spall_huge" }; }; //***** Spawn spalled fragments -private _spallSpawner = createVehicleLocal [_fragSpawnType, ASLToATL _spallPos, [], 0, "CAN_COLLIDE"]; +private _spallSpawner = createVehicleLocal [ + QUOTE(ADDON##_) + _material + _spawnSize, + ASLToATL _spallPos, + [], + 0, + "CAN_COLLIDE" +]; _spallSpawner setVectorDirandUp [_lVelUnit, _vUp]; _spallSpawner setVelocity (_lVelUnit vectorMultiply (_dV/2)); _spallSpawner setShotParents _shotParents; #ifdef DEBUG_MODE_FULL +if (_material isEqualTo "ground") then { + systemChat "ground spall"; // really shouldn't happen +}; systemChat ("bSpd: " + str speed _spallSpawner + ", frag: " + _fragSpawnType + ", dm: " + str _deltaMomentum); _spallSpawner addEventHandler [ "SubmunitionCreated", From 86f7ec182523bdc2379e3dc1706f43dc4d793df6 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 9 Jan 2024 21:07:21 -0600 Subject: [PATCH 036/282] updated TODO list --- addons/frag/README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/addons/frag/README.md b/addons/frag/README.md index 1b2378aed90..f431279f1f2 100644 --- a/addons/frag/README.md +++ b/addons/frag/README.md @@ -5,9 +5,7 @@ Explosive fragmentation, round spalling, and explosive reflection TODO: - More extensive MP testing -- move from FIRED to init EH's -- rework spalling position finding -- Look at spalling per material type +- remove submunition EHs in frag - Finish stringtable expansion with additional normal & debug settings - performance optimization - cDLC, RHS, CUP compats From fc7d68e12994d41b6b9406c84eae376e1db3246b Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 9 Jan 2024 23:16:08 -0600 Subject: [PATCH 037/282] Fixed additional quotes causing issues in .bisurf files --- addons/frag/functions/fnc_getMaterialInfo.sqf | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/addons/frag/functions/fnc_getMaterialInfo.sqf b/addons/frag/functions/fnc_getMaterialInfo.sqf index abab212b28e..f225124bbf1 100644 --- a/addons/frag/functions/fnc_getMaterialInfo.sqf +++ b/addons/frag/functions/fnc_getMaterialInfo.sqf @@ -1,22 +1,17 @@ #include "script_component.hpp" /* * Author: Lambda.Tiger - * This function returns fragmentation parameters for a specific - * ammo type. + * This function returns a classification of material type based + * on the surface hit. * * Arguments: - * 0: _ammo - cfgAmmo type of ammo to check + * 0: surfacetype - either a cfgSurfaces path .bisurf filepath * * Return Value: - * _ammoInfo - * 0: _fragRange - search range for fragments - * 1: _fragVel - gurney equation calculated velocity - * 2: _fragTypes - array of fragment types - * 3: _fragCount - modified frag count used under assumptions - * of spherical fragmentation + * _material - Material categories as expanded on in line 43 below * * Example: - * ["B_556x45_Ball"] call ace_frag_fnc_getFragInfo; + * [_surfaceType] call ace_frag_fnc_getFragInfo; * * Public: No */ @@ -34,7 +29,7 @@ if (isClass (configFile >> "CfgSurfaces" >> _surfType)) then { _material = getText (configFile >> "CfgSurfaces" >> _surfType >> "soundEnviron"); } else { // Messy way when a surface isn't added to cfgSurfaces private _surfFileText = loadFile _surfType; - _surfFileText = (tolower _surfFileText) splitString " ;="+ endl; + _surfFileText = (tolower _surfFileText) splitString " "";="+ endl; private _idx = _surfFileText find "soundenviron"; _material = _surfFileText#(_idx+1); if (_material isEqualTo "empty") then { From d25d6a61b3a74632017716bf0717c3ddcbfa4d8b Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 9 Jan 2024 23:17:08 -0600 Subject: [PATCH 038/282] readded seperate debug draw define --- addons/frag/XEH_postInit.sqf | 2 +- addons/frag/functions/fnc_doFrag.sqf | 2 +- addons/frag/functions/fnc_doFragRandom.sqf | 2 ++ addons/frag/functions/fnc_doFragTargeted.sqf | 5 ++--- addons/frag/functions/fnc_doSpall.sqf | 4 ++-- addons/frag/functions/fnc_doSpallMomentum.sqf | 4 +++- addons/frag/functions/fnc_initRound.sqf | 2 +- addons/frag/functions/fnc_submunition.sqf | 2 +- addons/frag/script_component.hpp | 1 + 9 files changed, 14 insertions(+), 10 deletions(-) diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index f50279ce8a9..5aa9fc9d510 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -16,7 +16,7 @@ ["ace_firedNonPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler;*/ // Debug info -#ifdef DEBUG_MODE_FULL +#ifdef DEBUG_MODE_DRAW if (hasInterface && GVAR(debugOptions)) then { private _h = [LINKFUNC(dev_drawTrace), 0] call CBA_fnc_addPerFrameHandler; missionNamespace setVariable [QGVAR(dev_drawPFEH), _h]; diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 412678377e1..a3e77fa2567 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -19,6 +19,7 @@ * * Public: No */ +TRACE_1("",_this); params ["_args", ["_isSubMunit", false, [false]]]; _args params [ ["_proj", objNull, [objNull]], @@ -27,7 +28,6 @@ _args params [ ["_ammo", "", [""]], ["_shotParents", [objNull, objNull], [[]]] ]; -TRACE_3("",_proj,_posASL,_vel); private _shotParentVic = _shotParents#0; if (_shotParentVic getVariable [QGVAR(nextFragTime), -1] > CBA_missionTime) exitWith { diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index 919a3ee049d..145926fd00a 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -59,6 +59,8 @@ _fragSpawner setShotParents _shotParents; #ifdef DEBUG_MODE_FULL systemChat ("fragging, id: " + getObjectID _proj); +#endif +#ifdef DEBUG_MODE_DRAW _fragSpawner addEventHandler [ "SubmunitionCreated", { diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index 22eaf0624dd..fd3865c1a90 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -156,7 +156,7 @@ private _fragCount = 0; // limit of # of fragments to _maxFrags _fragObj setVectorDir _vecDir; _fragObj setVelocity (_vecDir vectorMultiply _locFragVel); _fragObj setShotParents _shotPrnt; - #ifdef DEBUG_MODE_FULL + #ifdef DEBUG_MODE_DRAW [_fragObj, "purple", true] call FUNC(dev_trackObj); [_targetPos, "orange"] call FUNC(dev_sphereDraw); #endif @@ -169,7 +169,6 @@ private _fragCount = 0; // limit of # of fragments to _maxFrags } forEach _objects; #ifdef DEBUG_MODE_FULL systemChat ("fragCount cnt: " + str _fragCount); -TRACE_1("fragCount",_fragCount); #endif - +TRACE_1("fragCount",_fragCount); _fragCount \ No newline at end of file diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index 8777be45ead..a3dbb19d835 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -50,7 +50,7 @@ for "_i" from 1 to 20 do if (!lineIntersects [_spallPos, _nPos]) then {break}; _spallPos = +_nPos; }; -#ifdef DEBUG_MODE_FULL +#ifdef DEBUG_MODE_DRAW [_spallPos, "orange"] call FUNC(dev_sphereDraw); [_lPosASL, "orange"] call FUNC(dev_sphereDraw); #endif @@ -85,7 +85,7 @@ _fragSpawner setVectorDirandUp [vectorDir _projectile, vectorUp _projectile]; _fragSpawner setVelocity (_lVelUnit vectorMultiply _velScalar); -#ifdef DEBUG_MODE_FULL +#ifdef DEBUG_MODE_DRAW _fragSpawner addEventHandler [ "SubmunitionCreated", { diff --git a/addons/frag/functions/fnc_doSpallMomentum.sqf b/addons/frag/functions/fnc_doSpallMomentum.sqf index a75c4cf4c48..fe0321336d3 100644 --- a/addons/frag/functions/fnc_doSpallMomentum.sqf +++ b/addons/frag/functions/fnc_doSpallMomentum.sqf @@ -87,7 +87,7 @@ for "_i" from 1 to 20 do _spallPos = _nPos; }; -#ifdef DEBUG_MODE_FULL +#ifdef DEBUG_MODE_DRAW if GVAR(dbgSphere) then { [_spallPos, "green"] call FUNC(dev_sphereDraw); [_lPosASL vectorAdd _lVelUnit, "orange"] call FUNC(dev_sphereDraw); @@ -126,6 +126,8 @@ if (_material isEqualTo "ground") then { systemChat "ground spall"; // really shouldn't happen }; systemChat ("bSpd: " + str speed _spallSpawner + ", frag: " + _fragSpawnType + ", dm: " + str _deltaMomentum); +#endif +#ifdef DEBUG_MODE_DRAW _spallSpawner addEventHandler [ "SubmunitionCreated", { diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index 7d50661e675..b636637044c 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -37,7 +37,7 @@ if (_doFrag) then { if (isServer) then { [ FUNC(doFrag), - _this + [_ammo, _shotParents] + [_this + [_ammo, _shotParents]] ] call CBA_fnc_execNextFrame; } else { [ diff --git a/addons/frag/functions/fnc_submunition.sqf b/addons/frag/functions/fnc_submunition.sqf index 70fc19655c2..560a706b744 100644 --- a/addons/frag/functions/fnc_submunition.sqf +++ b/addons/frag/functions/fnc_submunition.sqf @@ -35,6 +35,6 @@ if (_doSubmunit) then { _submunitionProjectile addEventHandler ["SubmunitionCreated", {_this call FUNC(submunition)}]; }; -#ifdef DEBUG_MODE_FULL +#ifdef DEBUG_MODE_DRAW [_submunitionProjectile] call FUNC(dev_addRound); #endif \ No newline at end of file diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index 333ace4f89d..f98d27e5956 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -4,6 +4,7 @@ // #define LOG_FRAG_INFO #define DEBUG_MODE_FULL +// #define DEBUG_MODE_DRAW // #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS From 98fd580540104c4c96d498f5bc8b1d242f301d88 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 10 Jan 2024 00:16:46 -0600 Subject: [PATCH 039/282] Fixed authors --- addons/frag/functions/fnc_doSpallMomentum.sqf | 2 +- addons/frag/functions/fnc_getFragInfo.sqf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/frag/functions/fnc_doSpallMomentum.sqf b/addons/frag/functions/fnc_doSpallMomentum.sqf index fe0321336d3..eaec55c1d70 100644 --- a/addons/frag/functions/fnc_doSpallMomentum.sqf +++ b/addons/frag/functions/fnc_doSpallMomentum.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" /* - * Author: Lambda.Tiger + * Author: Jaynus, NouberNou, Lambda.Tiger, * This function creates spalling if the hit slowed the speed down enough. * * Arguments: diff --git a/addons/frag/functions/fnc_getFragInfo.sqf b/addons/frag/functions/fnc_getFragInfo.sqf index 0044896f771..09c82476b66 100644 --- a/addons/frag/functions/fnc_getFragInfo.sqf +++ b/addons/frag/functions/fnc_getFragInfo.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" /* - * Author: Lambda.Tiger + * Author: Jaynus, NouberNou, Lambda.Tiger * This function returns fragmentation parameters for a specific * ammo type. * From 1e9345396399cf61c5170e103dcbc0216f092dc6 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 10 Jan 2024 00:17:56 -0600 Subject: [PATCH 040/282] switch from loadFile to preprocessFile and dusted off the regex brain cell --- addons/frag/functions/fnc_getMaterialInfo.sqf | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/addons/frag/functions/fnc_getMaterialInfo.sqf b/addons/frag/functions/fnc_getMaterialInfo.sqf index f225124bbf1..72851b295bc 100644 --- a/addons/frag/functions/fnc_getMaterialInfo.sqf +++ b/addons/frag/functions/fnc_getMaterialInfo.sqf @@ -28,16 +28,17 @@ if !(isNil "_material") exitWith { if (isClass (configFile >> "CfgSurfaces" >> _surfType)) then { _material = getText (configFile >> "CfgSurfaces" >> _surfType >> "soundEnviron"); } else { // Messy way when a surface isn't added to cfgSurfaces - private _surfFileText = loadFile _surfType; - _surfFileText = (tolower _surfFileText) splitString " "";="+ endl; - private _idx = _surfFileText find "soundenviron"; - _material = _surfFileText#(_idx+1); - if (_material isEqualTo "empty") then { - _idx = _surfFileText find "soundhit"; - _material = _surfFileText#(_idx+1); - }; + private _surfFileText = tolower preprocessFile _surfType; + _surfFileText = _surfFileText regexReplace ["[^A-Za-z0-9]", ""]; + private _idx = 12 + (_surfFileText find "soundenviron"); + if (_surfFileText select [_idx, 5] isEqualTo "empty") then { + _idx = 8 + (_surfFileText find "soundhit"); + _material = _surfFileText select [_idx, 10]; + } else { + _material = _surfFileText select [_idx, 10]; + }; }; -TRACE_1("soundFound",_material); +TRACE_1("materialSubString",_material); _material = switch (true) do { From 8f70fa971aa8923ac48e533a494e2b6b9b7adc5f Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 10 Jan 2024 00:30:46 -0600 Subject: [PATCH 041/282] clarified variable names and removed submunition function call paths --- addons/frag/functions/fnc_doFrag.sqf | 23 +++++++++++------------ addons/frag/functions/fnc_fired.sqf | 2 +- addons/frag/functions/fnc_shouldFrag.sqf | 4 ++-- addons/frag/functions/fnc_submunition.sqf | 2 +- addons/frag/initSettings.inc.sqf | 2 +- 5 files changed, 16 insertions(+), 17 deletions(-) diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index a3e77fa2567..38fc261f88e 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -5,11 +5,11 @@ * as handling some of the performance optimizations. * * Arguments: - * 0: Array of argumentse - * 0.0: projectile that's fragmenting - * 0.1: ASL position of projectile - * 0.2: velocity of projectile - * 1: Whether the projectile is a submunition + * 0: projectile that's fragmenting + * 1: ASL position of projectile + * 2: velocity of projectile + * 3: projectile cfgAmmo classname + * 4: getShotParents of projectile at EH * * Return Value: * None @@ -20,8 +20,8 @@ * Public: No */ TRACE_1("",_this); -params ["_args", ["_isSubMunit", false, [false]]]; -_args params [ +/*params ["_args", ["_isSubMunit", false, [false]]]; +_args*/ params [ ["_proj", objNull, [objNull]], ["_posASL", [0,0,0], [[]], [3]], ["_vel", [0,0,0] , [[]], [3]], @@ -52,14 +52,13 @@ if (_heightAGL < 0.25) then { _posASL = _posASL vectorAdd [0, 0, 0.25]; }; -// make timesince a gvar? -TRACE_4("fnc_doFragTargeted IF", _fragRange, _timeSince, _isSubMunit, GVAR(enSubMunit)); -if (_fragRange > 3 && _timeSince > 0.3 && {!_isSubMunit || {GVAR(enSubMunit) == 2}}) then { +// !*! make timesince a gvar? +TRACE_4("fnc_doFragTargeted IF", _fragRange, _timeSince, GVAR(fragSimComplexity)); +if (_fragRange > 3 && _timeSince > 0.3 && {GVAR(fragSimComplexity) == 2}) then { _maxFrags = _maxFrags - ([_posASL, _fragVel, _fragRange, _maxFrags, _fragTypes, _modFragCount, _shotParents] call FUNC(doFragTargeted)); }; -// make a gvar? -if (_timeSince > 0.2 && {GVAR(enSubMunit) != 0}) then { +if (_timeSince > 0.2 && {GVAR(fragSimComplexity) != 0}) then { [_posASL, _vel, _heightAGL, _fragTypes, _maxFrags, _shotParents] call FUNC(doFragRandom); }; diff --git a/addons/frag/functions/fnc_fired.sqf b/addons/frag/functions/fnc_fired.sqf index 32f72b60997..5a2f0cc5c73 100644 --- a/addons/frag/functions/fnc_fired.sqf +++ b/addons/frag/functions/fnc_fired.sqf @@ -43,7 +43,7 @@ if (_doFrag) then { ]; }; -if (_doSubmunit && {GVAR(enSubMunit)> 0}) then { +if (_doSubmunit && {GVAR(fragSimComplexity)> 0}) then { _projectile addEventHandler ["SubmunitionCreated", {_this call FUNC(submunition)}]; }; diff --git a/addons/frag/functions/fnc_shouldFrag.sqf b/addons/frag/functions/fnc_shouldFrag.sqf index 587b21d4bdd..35a85623f37 100644 --- a/addons/frag/functions/fnc_shouldFrag.sqf +++ b/addons/frag/functions/fnc_shouldFrag.sqf @@ -38,7 +38,7 @@ if (_skip == 1 || (_force == 0 && {_explosive < 0.5 || {_indirectHit < 3 _shouldFrag set [0, false]; }; -if (GVAR(enSubMunit) > 0) then { +/*if (GVAR(fragSimComplexity) > 1) then { private _hasSubmunit = if (isText (configFile >> "cfgAmmo" >> _ammo >> "submunitionAmmo")) then { "" isNotEqualTo getText (configFile >> "cfgAmmo" >> _ammo >> "submunitionAmmo"); } else @@ -48,7 +48,7 @@ if (GVAR(enSubMunit) > 0) then { _shouldFrag set [1, _hasSubmunit]; TRACE_2("Submunition" ,_ammo, _hasSubmunit); -}; +};*/ GVAR(shouldFragCache) set [_ammo, _shouldFrag]; diff --git a/addons/frag/functions/fnc_submunition.sqf b/addons/frag/functions/fnc_submunition.sqf index 560a706b744..613154b26c2 100644 --- a/addons/frag/functions/fnc_submunition.sqf +++ b/addons/frag/functions/fnc_submunition.sqf @@ -19,7 +19,7 @@ * Public: No */ -if (!GVAR(enabled) || {GVAR(enSubMunit) == 0}) exitWith {}; +if (!GVAR(enabled) || {GVAR(fragSimComplexity) == 0}) exitWith {}; // params ["_projectile", "_submunitionProjectile", "_pos", "_velocity"]; params ["", "_submunitionProjectile"]; diff --git a/addons/frag/initSettings.inc.sqf b/addons/frag/initSettings.inc.sqf index bb04c9df691..4e41999f5cf 100644 --- a/addons/frag/initSettings.inc.sqf +++ b/addons/frag/initSettings.inc.sqf @@ -28,7 +28,7 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; /// !*! TODO: add stringtable entries [ - QGVAR(enSubMunit), "LIST", + QGVAR(fragSimComplexity), "LIST", ["Enable submunition fragmentation", "Enables submunition fragmentation when fragmentation is enabled"], [_category, LSTRING(Frag)], [[2, 1, 0], ["complex fragementation","simple fragmentation","no fragmentation"], 2] From 0af6a74a411dd0ca19f6c57da164060237d8dfbf Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 10 Jan 2024 00:55:33 -0600 Subject: [PATCH 042/282] Updated debug settings and staged localization strings --- addons/frag/README.md | 3 +- addons/frag/XEH_postInit.sqf | 1 - addons/frag/functions/fnc_dev_trackHitBox.sqf | 2 +- addons/frag/functions/fnc_doFrag.sqf | 4 +- addons/frag/functions/fnc_doFragRandom.sqf | 20 ++++--- addons/frag/functions/fnc_doFragTargeted.sqf | 4 +- addons/frag/functions/fnc_doSpall.sqf | 6 +- addons/frag/functions/fnc_submunition.sqf | 2 +- addons/frag/initSettings.inc.sqf | 9 ++- addons/frag/initSettingsDebug.inc.sqf | 56 +++++++++---------- 10 files changed, 57 insertions(+), 50 deletions(-) diff --git a/addons/frag/README.md b/addons/frag/README.md index f431279f1f2..69ed9111e4b 100644 --- a/addons/frag/README.md +++ b/addons/frag/README.md @@ -4,9 +4,8 @@ ace_frag Explosive fragmentation, round spalling, and explosive reflection TODO: -- More extensive MP testing -- remove submunition EHs in frag - Finish stringtable expansion with additional normal & debug settings +- More extensive MP testing - performance optimization - cDLC, RHS, CUP compats - look at / try to understand explosion reflections \ No newline at end of file diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index 5aa9fc9d510..094164db10a 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -15,7 +15,6 @@ ["ace_firedNonPlayer", LINKFUNC(fired)] call CBA_fnc_addEventHandler; ["ace_firedNonPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler;*/ - // Debug info #ifdef DEBUG_MODE_DRAW if (hasInterface && GVAR(debugOptions)) then { private _h = [LINKFUNC(dev_drawTrace), 0] call CBA_fnc_addPerFrameHandler; diff --git a/addons/frag/functions/fnc_dev_trackHitBox.sqf b/addons/frag/functions/fnc_dev_trackHitBox.sqf index 54705f3935a..2d42657b57b 100644 --- a/addons/frag/functions/fnc_dev_trackHitBox.sqf +++ b/addons/frag/functions/fnc_dev_trackHitBox.sqf @@ -42,7 +42,7 @@ switch (true) do { }; private _centerPoint = ASLToAGL getPosASL _obj; -if (_addSphere && vehicle _obj isEqualTo _obj) then { +if (GVAR(dbgSphere) && {_addSphere && {vehicle _obj isEqualTo _obj}}) then { private _centerSphere = [getPosASL _obj, "yellow"] call FUNC(dev_sphereDraw); _centerSphere disableCollisionWith vehicle _obj; _centerSphere attachTo [_obj, _obj worldToModel _centerPoint]; diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 38fc261f88e..b8cdc72d2ac 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -54,11 +54,11 @@ if (_heightAGL < 0.25) then { // !*! make timesince a gvar? TRACE_4("fnc_doFragTargeted IF", _fragRange, _timeSince, GVAR(fragSimComplexity)); -if (_fragRange > 3 && _timeSince > 0.3 && {GVAR(fragSimComplexity) == 2}) then { +if (_fragRange > 3 && _timeSince > 0.3 && {GVAR(fragSimComplexity) != 1}) then { _maxFrags = _maxFrags - ([_posASL, _fragVel, _fragRange, _maxFrags, _fragTypes, _modFragCount, _shotParents] call FUNC(doFragTargeted)); }; -if (_timeSince > 0.2 && {GVAR(fragSimComplexity) != 0}) then { +if (_timeSince > 0.2 && {GVAR(fragSimComplexity) > 0}) then { [_posASL, _vel, _heightAGL, _fragTypes, _maxFrags, _shotParents] call FUNC(doFragRandom); }; diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index 145926fd00a..8a31bf67871 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -58,15 +58,17 @@ _fragSpawner setVelocity _projVel; _fragSpawner setShotParents _shotParents; #ifdef DEBUG_MODE_FULL - systemChat ("fragging, id: " + getObjectID _proj); +systemChat ("fragging, id: " + getObjectID _proj); #endif #ifdef DEBUG_MODE_DRAW - _fragSpawner addEventHandler [ - "SubmunitionCreated", - { - params ["","_subProj"]; - [_subProj, "green", true] call FUNC(dev_trackObj); - } - ]; - [_posASL] call FUNC(dev_sphereDraw); +_fragSpawner addEventHandler [ + "SubmunitionCreated", + { + params ["","_subProj"]; + [_subProj, "green", true] call FUNC(dev_trackObj); + } +]; +if (GVAR(dbgSphere)) then { + [_posASL] call FUNC(dev_sphereDraw); +}; #endif \ No newline at end of file diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index fd3865c1a90..d969ee98c65 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -158,7 +158,9 @@ private _fragCount = 0; // limit of # of fragments to _maxFrags _fragObj setShotParents _shotPrnt; #ifdef DEBUG_MODE_DRAW [_fragObj, "purple", true] call FUNC(dev_trackObj); - [_targetPos, "orange"] call FUNC(dev_sphereDraw); + if (GVAR(dbgSphere)) then { + [_targetPos, "orange"] call FUNC(dev_sphereDraw); + }; #endif _fragCount = _fragCount + _count; diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index a3dbb19d835..b1281404f2d 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -51,8 +51,10 @@ for "_i" from 1 to 20 do _spallPos = +_nPos; }; #ifdef DEBUG_MODE_DRAW -[_spallPos, "orange"] call FUNC(dev_sphereDraw); -[_lPosASL, "orange"] call FUNC(dev_sphereDraw); +if (GVAR(dbgSphere)) then { + [_spallPos, "orange"] call FUNC(dev_sphereDraw); + [_lPosASL, "orange"] call FUNC(dev_sphereDraw); +}; #endif // find last intersect with the object diff --git a/addons/frag/functions/fnc_submunition.sqf b/addons/frag/functions/fnc_submunition.sqf index 613154b26c2..ed046151e38 100644 --- a/addons/frag/functions/fnc_submunition.sqf +++ b/addons/frag/functions/fnc_submunition.sqf @@ -19,7 +19,7 @@ * Public: No */ -if (!GVAR(enabled) || {GVAR(fragSimComplexity) == 0}) exitWith {}; +if !GVAR(enabled) exitWith {}; // params ["_projectile", "_submunitionProjectile", "_pos", "_velocity"]; params ["", "_submunitionProjectile"]; diff --git a/addons/frag/initSettings.inc.sqf b/addons/frag/initSettings.inc.sqf index 4e41999f5cf..4c5c51849fd 100644 --- a/addons/frag/initSettings.inc.sqf +++ b/addons/frag/initSettings.inc.sqf @@ -29,20 +29,23 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; /// !*! TODO: add stringtable entries [ QGVAR(fragSimComplexity), "LIST", - ["Enable submunition fragmentation", "Enables submunition fragmentation when fragmentation is enabled"], + // [LSTRING(FragMode), LSTRING(FragMode_Desc)] + ["Fragmentation mode", "Sets how fragments are generated"], [_category, LSTRING(Frag)], - [[2, 1, 0], ["complex fragementation","simple fragmentation","no fragmentation"], 2] + [[2, 1, 0], ["Targeted & random fragmentation ","Random fragmentation","Unit targeted fragmentation"], 2] ] call CBA_fnc_addSetting; [ QGVAR(atLeastOne), "CHECKBOX", - "At least one round hit", + // [LSTRING(MinFrag), LSTRING(MinFrag_Desc)] + ["At least one round hit", "Spawn at least one fragment for units in fragmentation range, up to maximum fragments"], [_category, LSTRING(Frag)], true ] call CBA_fnc_addSetting; [ QGVAR(BlackList), "EDITBOX", + // [LSTRING(DefBlackList), LSTRING(DefBlackList_Desc)] ["Default BlackList", "Array of ammo classnames strings to blackist fragmentation for."], [_category, LSTRING(Frag)], QUOTE(['B_556x45_Ball']) diff --git a/addons/frag/initSettingsDebug.inc.sqf b/addons/frag/initSettingsDebug.inc.sqf index c6b9ce495d9..dfcb14f064b 100644 --- a/addons/frag/initSettingsDebug.inc.sqf +++ b/addons/frag/initSettingsDebug.inc.sqf @@ -1,54 +1,54 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; [ - QGVAR(debugOptions), - "CHECKBOX", - "Enable debug mode", - [_category, LSTRING(Debug)], - true // [min, max, default, trailing decimals] + QGVAR(debugOptions), "CHECKBOX", + // [LSTRING(DebugEnable), LSTRING(DebugEnable_Desc)] + ["Enable debug mode", "Enable debug tracing and spheres"], + [_category, LSTRING(Debug)], + true ] call CBA_fnc_addSetting; // debug options [ - QGVAR(dbgSphere), - "CHECKBOX", - "Enable debug impact spheres", - [_category, LSTRING(Debug)], - false, + QGVAR(dbgSphere), "CHECKBOX", + // [LSTRING(DebugEnable), LSTRING(DebugEnable_Desc)] + "Create color coded spheres at ", + [_category, LSTRING(Debug)], + false, 0, {}, true ] call CBA_fnc_addSetting; [ - QGVAR(frameHint), - "CHECKBOX", - "Show framerate hint", - [_category, LSTRING(Debug)], - true + QGVAR(frameHint), "CHECKBOX", + // [LSTRING(FrameHint), LSTRING(FrameHint_Desc)] + ["Show framerate hint", "Show 1/diag_frameTime as a hint"], + [_category, LSTRING(Debug)], + true ] call CBA_fnc_addSetting; [ - QGVAR(fadeRounds), - "CHECKBOX", - "Fade round traces over time", - [_category, LSTRING(Debug)], - true + QGVAR(fadeRounds), "CHECKBOX", + // [LSTRING(FadeRounds), LSTRING(FadeRounds_Desc)] + ["Fade round traces over time", "Fade round traces for added round over time"], + [_category, LSTRING(Debug)], + true ] call CBA_fnc_addSetting; [ - QGVAR(dltTrace), - "CHECKBOX", - "Delete fire trace on fade", - [_category, LSTRING(Debug)], + QGVAR(dltTrace), "CHECKBOX", + // [LSTRING(FadeRounds), LSTRING(FadeRounds_Desc)] + ["Delete fire trace on fade", "Delete faded traces"], + [_category, LSTRING(Debug)], true ] call CBA_fnc_addSetting; [ - QGVAR(drawHitBox), - "CHECKBOX", - "Draw unit hitboxes", - [_category, LSTRING(Debug)], + QGVAR(drawHitBox),"CHECKBOX", + // [LSTRING(DrawHitBox), LSTRING(DrawHitBox_Desc)] + ["Draw unit hitboxes", "Draw added hitboxes each frame"], + [_category, LSTRING(Debug)], true ] call CBA_fnc_addSetting; From 3578b7a2fb67547aeddc91cdbca6c41296e4ce26 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 10 Jan 2024 15:46:17 -0600 Subject: [PATCH 043/282] Fixed small bugs with material selection --- addons/frag/functions/fnc_getMaterialInfo.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_getMaterialInfo.sqf b/addons/frag/functions/fnc_getMaterialInfo.sqf index 72851b295bc..42f638beaa0 100644 --- a/addons/frag/functions/fnc_getMaterialInfo.sqf +++ b/addons/frag/functions/fnc_getMaterialInfo.sqf @@ -48,7 +48,7 @@ _material = switch (true) do { case ("rock" in _material): { "rock" }; case ("wood" in _material): { "wood" }; case ("lino" in _material); - case ("building" isEqualTo _material); + case ("building" in _material); case ("concrete" in _material): { "concrete" }; case ("metal" in _material): { "metal" }; default { "ground" }; From 0da454d2701258224746b7b3052202d454d391dc Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 10 Jan 2024 15:47:50 -0600 Subject: [PATCH 044/282] removed unused functions --- addons/frag/XEH_PREP.hpp | 4 +- addons/frag/XEH_preInit.sqf | 2 +- addons/frag/functions/fnc_dev_addRound.sqf | 24 +---- addons/frag/functions/fnc_dev_drawTrace.sqf | 25 +---- addons/frag/functions/fnc_dev_fadeRound.sqf | 34 ------- addons/frag/functions/fnc_dev_trackObj.sqf | 44 +++------ addons/frag/functions/fnc_doFrag.sqf | 6 +- addons/frag/functions/fnc_doSpall.sqf | 98 ------------------- addons/frag/functions/fnc_doSpallMomentum.sqf | 4 +- addons/frag/functions/fnc_fired.sqf | 2 +- addons/frag/functions/fnc_initRound.sqf | 2 +- 11 files changed, 27 insertions(+), 218 deletions(-) delete mode 100644 addons/frag/functions/fnc_dev_fadeRound.sqf delete mode 100644 addons/frag/functions/fnc_doSpall.sqf diff --git a/addons/frag/XEH_PREP.hpp b/addons/frag/XEH_PREP.hpp index 16dde5e8c7f..350a178038d 100644 --- a/addons/frag/XEH_PREP.hpp +++ b/addons/frag/XEH_PREP.hpp @@ -3,7 +3,6 @@ PREP(dev_fired); PREP(dev_fragCalcDump); PREP(dev_debugAmmo); PREP(dev_trackHitBox); -PREP(dev_fadeRound); PREP(dev_sphereDraw); PREP(dev_addRound); PREP(dev_trackObj); @@ -28,9 +27,8 @@ PREP(doFragRandom); // Spall PREP(shouldSpall); PREP(doSpall); -PREP(doSpallMomentum); +PREP(doSpall); PREP(getMaterialInfo); -//PREP(spallHP); Look at me !*! // Explosive Reflection PREP(findReflections); diff --git a/addons/frag/XEH_preInit.sqf b/addons/frag/XEH_preInit.sqf index e38296c5c47..646bcb1dbc3 100644 --- a/addons/frag/XEH_preInit.sqf +++ b/addons/frag/XEH_preInit.sqf @@ -18,7 +18,7 @@ GVAR(lastFragTime) = -2; #include "initSettings.inc.sqf" -#ifdef DEBUG_MODE_FULL +#ifdef DEBUG_MODE_DRAW GVAR(dev_trackLines) = createHashMap; GVAR(dev_hitBoxes) = createHashMap; GVAR(dev_failedToDelete) = 0; diff --git a/addons/frag/functions/fnc_dev_addRound.sqf b/addons/frag/functions/fnc_dev_addRound.sqf index 49d4d24bc4f..7ad5b05df39 100644 --- a/addons/frag/functions/fnc_dev_addRound.sqf +++ b/addons/frag/functions/fnc_dev_addRound.sqf @@ -24,28 +24,12 @@ params [ /// track round on each frame // Create entry in position array from hashmap -private _pID = getObjectID _proj; -if (GVAR(fadeRounds)) then +if (_sidePlayer) then { - if (_sidePlayer) then - { - GVAR(dev_trackLines) set [_pID, [__FADE_INIT, [getposATL _proj], [0, 0, 1, __FADE_INIT]]]; - } else - { - GVAR(dev_trackLines) set [_pID, [__FADE_INIT, [getposATL _proj], [1, 0.5, 0, __FADE_INIT]]]; - }; - - // add fading factor - [LINKFUNC(dev_fadeRound), __FADE_INTERVAL, [_pID]] call CBA_fnc_addPerFrameHandler; -} else + GVAR(dev_trackLines) set [getObjectID _proj, [1, [getposATL _proj], [0, 0, 1, 1]]]; +} else { - if (_sidePlayer) then - { - GVAR(dev_trackLines) set [_pID, [1, [getposATL _proj], [0, 0, 1, 1]]]; - } else - { - GVAR(dev_trackLines) set [_pID, [1, [getposATL _proj], [1, 0, 0, 1]]]; - }; + GVAR(dev_trackLines) set [getObjectID _proj, [1, [getposATL _proj], [1, 0, 0, 1]]]; }; // eventhandler to track round and cleanup when round is "dead" [ diff --git a/addons/frag/functions/fnc_dev_drawTrace.sqf b/addons/frag/functions/fnc_dev_drawTrace.sqf index c7ff03b13f2..f561d0b5134 100644 --- a/addons/frag/functions/fnc_dev_drawTrace.sqf +++ b/addons/frag/functions/fnc_dev_drawTrace.sqf @@ -16,32 +16,16 @@ private _deleteArr = []; { - private _alpha = _y#0; // leave if trace is not to be drawn - if (GVAR(dltTrace) && _alpha <= 0) then - { - _deleteArr pushBack _x; - continue; - }; - if (count (_y#1) > 1) then - { - private _color = _y#2; + { for "_j" from 1 to count (_y#1) - 1 do { - drawLine3D [_y#1#(_j-1), _y#1#_j, _color]; + drawLine3D [_y#1#(_j-1), _y#1#_j, _y#2]; }; }; } forEach GVAR(dev_trackLines); -if (GVAR(dltTrace)) then -{ - for "_i" from 0 to count _deleteArr - 1 do - { - GVAR(dev_trackLines) deleteAt (_deleteArr#_i); - }; -}; - if (GVAR(drawHitBox)) then { #define HB_DRAW_ARRS [[3,2,1,5,6,7,3,0,4,5],[0,1],[2,6],[7,4]] @@ -67,9 +51,4 @@ if (GVAR(drawHitBox)) then { { GVAR(dev_hitBoxes) deleteAt (_deleteArr#_i); }; -}; - -if (GVAR(frameHint)) then -{ - hintsilent str (1/diag_deltaTime); }; \ No newline at end of file diff --git a/addons/frag/functions/fnc_dev_fadeRound.sqf b/addons/frag/functions/fnc_dev_fadeRound.sqf deleted file mode 100644 index 49d1f566c45..00000000000 --- a/addons/frag/functions/fnc_dev_fadeRound.sqf +++ /dev/null @@ -1,34 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Lambda.Tiger - * Fades a trace over time based on given parameters - * - * Arguments: - * 0: PFEH arguments - * 1: PHEH handle - * - * Return Value: - * None - * - * Example: - * - * Public: No - */ -params ["_args", "_h"]; - -private _arr = GVAR(dev_trackLines) getOrDefault [(_args#0), []]; -if (count _arr < 3) exitWith -{ - [_h] call CBA_fnc_removePerFrameHandler; -}; - -private _alpha = _arr#0; -private _color = _arr#2; -_alpha = (_alpha - __FADE_RATE) min 1; -_arr set [0, _alpha]; -_color set [3, _alpha]; -_color set [1, (0.5 - _alpha/2) max 0]; -if (_alpha <= 0 ) then -{ - [_h] call CBA_fnc_removePerFrameHandler; -}; \ No newline at end of file diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index 9b43ec9c5c3..c06fa763ae7 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -24,39 +24,19 @@ params [ TRACE_4("devDraw",_this,_obj,_color,_isProj); /// track round on each frame // Create entry in position array from hashmap -private _pID = getObjectID _obj; -if (GVAR(fadeRounds)) then -{ - private _colorArray = switch (toLower _color) do { - case "purple": {[0.8, 0, 0.8, __FADE_INIT]}; - case "blue": {[0, 0, 0.8, __FADE_INIT]}; - case "green": {[0, 0.8, 0, __FADE_INIT]}; - case "orange": {[0.8, 0.518, 0, __FADE_INIT]}; - case "yellow": {[0.8, 0.8, 0, __FADE_INIT] }; - case "red": {[0.8, 0, 0, __FADE_INIT]}; - case "black": {[1, 1, 1, __FADE_INIT]}; - case "white": {[0, 0, 0, __FADE_INIT]}; - default {[0, 0.8, 0.8, __FADE_INIT]}; - }; - - GVAR(dev_trackLines) set [_pID, [__FADE_INIT, [getposATL _obj], _colorArray]]; - // add fading factor - [LINKFUNC(dev_fadeRound), __FADE_INTERVAL, [_pID]] call CBA_fnc_addPerFrameHandler; -} else -{ - private _colorArray = switch (toLower _color) do { - case "purple": {[0.8, 0, 0.8, 1]}; - case "blue": {[0, 0, 0.8, 1]}; - case "green": {[0, 0.8, 0, 1]}; - case "orange": {[0.8, 0.518, 0, 1]}; - case "yellow": {[0.8, 0.8, 0, 1] }; - case "red": {[0.8, 0, 0, 1]}; - case "black": {[1, 1, 1, 1]}; - case "white": {[0, 0, 0, 1]}; - default {[0, 0.8, 0.8, 1]}; - }; - GVAR(dev_trackLines) set [_pID, [1, [getposATL _obj], _colorArray]]; +private _colorArray = switch (toLower _color) do { + case "purple": {[0.8, 0, 0.8, 1]}; + case "blue": {[0, 0, 0.8, 1]}; + case "green": {[0, 0.8, 0, 1]}; + case "orange": {[0.8, 0.518, 0, 1]}; + case "yellow": {[0.8, 0.8, 0, 1] }; + case "red": {[0.8, 0, 0, 1]}; + case "black": {[1, 1, 1, 1]}; + case "white": {[0, 0, 0, 1]}; + default {[0, 0.8, 0.8, 1]}; }; +GVAR(dev_trackLines) set [getObjectID _obj, [1, [getposATL _obj], _colorArray]]; + // eventhandler to track round and cleanup when round is "dead" [ { diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index b8cdc72d2ac..8316ee268e2 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -52,9 +52,9 @@ if (_heightAGL < 0.25) then { _posASL = _posASL vectorAdd [0, 0, 0.25]; }; -// !*! make timesince a gvar? -TRACE_4("fnc_doFragTargeted IF", _fragRange, _timeSince, GVAR(fragSimComplexity)); -if (_fragRange > 3 && _timeSince > 0.3 && {GVAR(fragSimComplexity) != 1}) then { +// !*! make holdoff a gvar? +TRACE_3("fnc_doFragTargeted IF", _fragRange, _timeSince, GVAR(fragSimComplexity)); +if (_fragRange > 3 && _timeSince > ACE_FRAG_HOLDOFF*1.5 && GVAR(fragSimComplexity) != 1) then { _maxFrags = _maxFrags - ([_posASL, _fragVel, _fragRange, _maxFrags, _fragTypes, _modFragCount, _shotParents] call FUNC(doFragTargeted)); }; diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf deleted file mode 100644 index b1281404f2d..00000000000 --- a/addons/frag/functions/fnc_doSpall.sqf +++ /dev/null @@ -1,98 +0,0 @@ -#include "script_component.hpp" -/* - * Author: ACE-Team - * Dev things - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_frag_fnc_doSpall - * - * Public: No - */ -params ["_projectile", "_hitObj", "", "_lPosASL", "_lVel", "", "", "" ,"_surfaceType"]; - -if (!isNil "_hitObj" && {_hitObj isKindOf "man"}) exitWith {}; - -if ((isNil "_lPosASL") || {!(_lPosASL isEqualTypeArray [0,0,0])}) exitWith {WARNING_1("Problem with hitPart data - bad pos [%1]",_lPosASL);}; - - -private _posASL = _lPosASL; -private _vel = [0, 0, 0]; -private _lVelUnit = vectorNormalized _lVel; -private _velMod = 1; -if (alive _projectile) then { - _vel = velocity _projectile; - _posASL = getPosASL _projectile; - // Dot product math - private _diffAngle = acos (_lVelUnit vectorDotProduct vectorNormalized _vel); - - if (abs _diffAngle > 45) then { - SUB(_velMod, (vectorMagnitude _vel) / (vectorMagnitude _lVel)); - }; - _projectile setVariable [QGVAR(lastSpallTime), diag_tickTime ]; -}; - - -//** start calculating where the spalling should come **// -private _unitStep = _lVelUnit vectorMultiply 0.05; -private _spallPos = +_lPosASL; -// exit if we hit the ground -if (terrainIntersectASL [_lPosASL vectorAdd _unitStep, _lPosASL]) exitWith {}; -// step through -for "_i" from 1 to 20 do -{ - private _nPos = _spallPos vectorAdd _unitStep; - if (!lineIntersects [_spallPos, _nPos]) then {break}; - _spallPos = +_nPos; -}; -#ifdef DEBUG_MODE_DRAW -if (GVAR(dbgSphere)) then { - [_spallPos, "orange"] call FUNC(dev_sphereDraw); - [_lPosASL, "orange"] call FUNC(dev_sphereDraw); -}; -#endif -// find last intersect with the object - -private _ammo = typeOf _projectile; -private _explosive = getNumber (configFile >> "CfgAmmo" >> _ammo >> "explosive"); - -#ifdef DEBUG_MODE_FULL -private _dv = vectorMagnitude _lVel - vectorMagnitude _vel; -private _caliber = getNumber (configFile >> "cfgAmmo" >> _ammo >> "caliber"); -systemChat ("dV: " + str _dv + ", caliber: " + str _caliber + ", product: " + str (_caliber*_dv)); -#endif - -if (_explosive > 0) then { - private _fragMod = (_ammo call FUNC(getFragInfo))#1; - _velMod = _fragMod * _velMod; -}; - -// diag_log text format ["SPALL POWER: %1", _spallPolar select 0]; -// range of spread 15-40 -// N rounds 5-15 -// speed from 0.75-1.5 -// range of spread 5-10 -// N rounds 3-8 -// speed from 0.75-1.5 -private _velScalar = 0.33 * _velMod; - -private _fragSpawner = QGVAR(base) createVehicleLocal [0,0,12345]; -_fragSpawner setPosASL _spallPos; -_fragSpawner setVectorDirandUp [vectorDir _projectile, vectorUp _projectile]; -_fragSpawner setVelocity (_lVelUnit vectorMultiply _velScalar); - - -#ifdef DEBUG_MODE_DRAW -_fragSpawner addEventHandler [ - "SubmunitionCreated", - { - params ["", "_subProj"]; - [_subProj] call FUNC(dev_addRound); - } -]; -#endif \ No newline at end of file diff --git a/addons/frag/functions/fnc_doSpallMomentum.sqf b/addons/frag/functions/fnc_doSpallMomentum.sqf index eaec55c1d70..42eb09d52ff 100644 --- a/addons/frag/functions/fnc_doSpallMomentum.sqf +++ b/addons/frag/functions/fnc_doSpallMomentum.sqf @@ -11,7 +11,7 @@ * None * * Example: - * [BIS_HITPART_EH_ARGS] call ace_frag_fnc_doSpallMomentum; + * [BIS_HITPART_EH_ARGS] call ace_frag_fnc_doSpall; * * Public: No */ @@ -54,7 +54,7 @@ private _vel = if (alive _projectile) then { private _dV = vectorMagnitude _lVel - vectorMagnitude _vel; private _caliber = getNumber (configFile >> "cfgAmmo" >> _ammo >> "caliber"); // !*! optimize this later? // scaled momentum change made on caliber-mass assumption ~sqrt(2)/20 * caliber ~= mass -private _deltaMomentum = 0.0707 * _caliber * sqrt( _dV ); +private _deltaMomentum = 0.0707 * _caliber * sqrt( _dV ) * GVAR(SpallIntensity); TRACE_3("found speed",_dV,_caliber,_deltaMomentum); if (_deltaMomentum < 2) exitWith { diff --git a/addons/frag/functions/fnc_fired.sqf b/addons/frag/functions/fnc_fired.sqf index 5a2f0cc5c73..d6918a067a5 100644 --- a/addons/frag/functions/fnc_fired.sqf +++ b/addons/frag/functions/fnc_fired.sqf @@ -54,7 +54,7 @@ if (GVAR(spallEnabled) && {_shouldSpall}) then "HitPart", { if (isServer) then { - [LINKFUNC(doSpallMomentum), _this] call CBA_fnc_execNextFrame; + [LINKFUNC(doSpall), _this] call CBA_fnc_execNextFrame; } else { [QGVAR(spall_eh), [_this]] call CBA_fnc_serverEvent; }; diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index b636637044c..bac3b0c8797 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -66,7 +66,7 @@ if (GVAR(spallEnabled) && {_shouldSpall}) then private _vUp = vectorUp _proj; if (isServer) then { [ - LINKFUNC(doSpallMomentum), + LINKFUNC(doSpall), [_proj, _hitObj, _posASL, _vel, _sNorm, _surfType, _ammo, _shotPrnt, _vUp] ] call CBA_fnc_execNextFrame; } else { From 4cada76c81ae803d6821bb28b73a7aef2d4e966b Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 10 Jan 2024 15:48:06 -0600 Subject: [PATCH 045/282] Fleshed out stringtables --- addons/frag/XEH_PREP.hpp | 1 - addons/frag/initSettings.inc.sqf | 31 +++++++--- addons/frag/initSettingsDebug.inc.sqf | 40 +++--------- addons/frag/stringtable.xml | 87 ++++++++++++++++++++------- 4 files changed, 95 insertions(+), 64 deletions(-) diff --git a/addons/frag/XEH_PREP.hpp b/addons/frag/XEH_PREP.hpp index 350a178038d..7d261c91f4b 100644 --- a/addons/frag/XEH_PREP.hpp +++ b/addons/frag/XEH_PREP.hpp @@ -27,7 +27,6 @@ PREP(doFragRandom); // Spall PREP(shouldSpall); PREP(doSpall); -PREP(doSpall); PREP(getMaterialInfo); // Explosive Reflection diff --git a/addons/frag/initSettings.inc.sqf b/addons/frag/initSettings.inc.sqf index 4c5c51849fd..18f77fbc176 100644 --- a/addons/frag/initSettings.inc.sqf +++ b/addons/frag/initSettings.inc.sqf @@ -25,28 +25,41 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; 1 ] call CBA_fnc_addSetting; - /// !*! TODO: add stringtable entries [ QGVAR(fragSimComplexity), "LIST", - // [LSTRING(FragMode), LSTRING(FragMode_Desc)] - ["Fragmentation mode", "Sets how fragments are generated"], + [LSTRING(FragMode), LSTRING(FragMode_Desc)], +// ["Fragmentation mode", "Sets how fragments are generated"], [_category, LSTRING(Frag)], - [[2, 1, 0], ["Targeted & random fragmentation ","Random fragmentation","Unit targeted fragmentation"], 2] + [[2, 1, 0], [LSTRING(FragMode_Opt2),LSTRING(FragMode_Opt1),LSTRING(FragMode_Opt0)], 2], +// [[2, 1, 0], ["Targeted & random fragmentation","Random fragmentation","Unit targeted fragmentation"], 2], + true ] call CBA_fnc_addSetting; [ QGVAR(atLeastOne), "CHECKBOX", - // [LSTRING(MinFrag), LSTRING(MinFrag_Desc)] - ["At least one round hit", "Spawn at least one fragment for units in fragmentation range, up to maximum fragments"], + [LSTRING(MinFrag), LSTRING(MinFrag_Desc)], +// ["At least one round hit", "Spawn at least one fragment for units in fragmentation range, up to maximum fragments"], [_category, LSTRING(Frag)], true ] call CBA_fnc_addSetting; [ QGVAR(BlackList), "EDITBOX", - // [LSTRING(DefBlackList), LSTRING(DefBlackList_Desc)] - ["Default BlackList", "Array of ammo classnames strings to blackist fragmentation for."], + [LSTRING(DefBlackList), LSTRING(DefBlackList_Desc)], +// ["Fragmentation BlackList", "Array of ammo classnames strings to blackist fragmentation for."], + [_category, LSTRING(Frag)], + QUOTE(['B_556x45_Ball']), + true, + nil, + true +] call CBA_fnc_addSetting; + + +[ + QGVAR(SpallIntensity), "SLIDER", + [LSTRING(SpallIntensity), LSTRING(SpallIntensity_Desc)], [_category, LSTRING(Frag)], - QUOTE(['B_556x45_Ball']) + [0.1, 2, 1, 1], + true ] call CBA_fnc_addSetting; diff --git a/addons/frag/initSettingsDebug.inc.sqf b/addons/frag/initSettingsDebug.inc.sqf index dfcb14f064b..382d3ac4b2f 100644 --- a/addons/frag/initSettingsDebug.inc.sqf +++ b/addons/frag/initSettingsDebug.inc.sqf @@ -2,17 +2,16 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; [ QGVAR(debugOptions), "CHECKBOX", - // [LSTRING(DebugEnable), LSTRING(DebugEnable_Desc)] - ["Enable debug mode", "Enable debug tracing and spheres"], + [LSTRING(EnableDebugTrace), LSTRING(EnableDebugTrace_Desc)], [_category, LSTRING(Debug)], true ] call CBA_fnc_addSetting; -// debug options +//*** debug options ***// [ QGVAR(dbgSphere), "CHECKBOX", - // [LSTRING(DebugEnable), LSTRING(DebugEnable_Desc)] - "Create color coded spheres at ", + [LSTRING(HitSphereEnable), LSTRING(HitSphereEnable_Desc)], +// "Create color coded spheres at ", [_category, LSTRING(Debug)], false, 0, @@ -20,35 +19,10 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; true ] call CBA_fnc_addSetting; -[ - QGVAR(frameHint), "CHECKBOX", - // [LSTRING(FrameHint), LSTRING(FrameHint_Desc)] - ["Show framerate hint", "Show 1/diag_frameTime as a hint"], - [_category, LSTRING(Debug)], - true -] call CBA_fnc_addSetting; - -[ - QGVAR(fadeRounds), "CHECKBOX", - // [LSTRING(FadeRounds), LSTRING(FadeRounds_Desc)] - ["Fade round traces over time", "Fade round traces for added round over time"], - [_category, LSTRING(Debug)], - true -] call CBA_fnc_addSetting; - -[ - QGVAR(dltTrace), "CHECKBOX", - // [LSTRING(FadeRounds), LSTRING(FadeRounds_Desc)] - ["Delete fire trace on fade", "Delete faded traces"], - [_category, LSTRING(Debug)], - true -] call CBA_fnc_addSetting; - [ QGVAR(drawHitBox),"CHECKBOX", - // [LSTRING(DrawHitBox), LSTRING(DrawHitBox_Desc)] - ["Draw unit hitboxes", "Draw added hitboxes each frame"], + [LSTRING(DrawHitBox), LSTRING(DrawHitBox_Desc)], +// ["Draw unit hitboxes", "Draw added hitboxes each frame"], [_category, LSTRING(Debug)], true -] call CBA_fnc_addSetting; - +] call CBA_fnc_addSetting; \ No newline at end of file diff --git a/addons/frag/stringtable.xml b/addons/frag/stringtable.xml index 79e46856118..83ac3bd855e 100644 --- a/addons/frag/stringtable.xml +++ b/addons/frag/stringtable.xml @@ -123,6 +123,39 @@ 啟用ACE模擬爆炸反射 Povolit ACE simulaci odrazu exploze + + Simulation Mode + + + Create a combination of random and/or unit targeted fragments + + + Unit targeted fragmentation + + + Random fragmentation + + + Random and targeted fragmentation + + + Disable Fragment Misses + + + For each unit a fragment could be shot towards, create it. This setting has no effect when "Random fragmentation" is selected. + + + BlackListed Ammo Classnames + + + Comma seperated cfgAmmo classnames to always skip. Loaded at mission start. + + + Spalling Intensity + + + Modifier to increase or decrease the number and intensity of spalling events. Increasing this value may cause performance degredation + Maximum Projectiles Tracked Máximos proyectiles rastreados @@ -188,36 +221,48 @@ 設定在每一幀數內,系統最大可追蹤的碎片/剝落粒子數量。此設定可有效幫助系統減低計算壓力 - (SP Only) Frag/Spall Debug Tracing - (Solo SP) Seguimiento de depuración de Fragmentación/Astillamiento - (Tylko SP) Wizualny debug odł./odpr. - (Pouze SP) Debug sledování Frag/Úlomků - (nur SP) Splitter-/Explosions-Debug-Verfolgung - (Somente SP) Depuração de fragmentação e estilhaços traçantes - (SP uniquement) Fragmentation/éclat debug - (Csak SP) Repesz/Pattogzás debug követés + (Local only) Frag/Spall Debug Tracing + (Solo !*!) Seguimiento de depuración de Fragmentación/Astillamiento + (Tylko !*!) Wizualny debug odł./odpr. + (Pouze !*!) Debug sledování Frag/Úlomků + (nur !*!) Splitter-/Explosions-Debug-Verfolgung + (Somente !*!) Depuração de fragmentação e estilhaços traçantes + (!*! uniquement) Fragmentation/éclat debug + (Csak !*!) Repesz/Pattogzás debug követés (Только для одиночной игры) Отслеживаение/отладка осколков - (Solo SP) Debug Tracciamento Frag/Spall - (SP のみ) 破片/剥離のデバッグ用表示 + (Solo !*!) Debug Tracciamento Frag/Spall + (!*! のみ) 破片/剥離のデバッグ用表示 (싱글플레이 전용) 탄환파편/파편 디버그 추적화 (仅单人)追踪显示破片粒子 (僅在單人模式) 碎片/剝落除錯追蹤 - (SP Only) Requires a mission/editor restart. Enables visual tracing of fragmentation and spalling rounds in SP game mode only. - (Solo SP) Requiere un reinicio misión/editor. Permite el seguimiento visual de la fragmentación y astillamientos de los proyectiles en modo SP. - (Tylko SP) Wymaga restartu misji/edytora. Aktywuje wizualne śledzenie odłamków oraz odprysków w trybie gry Single Player. - (nur SP) Splitter-/Explosions-Debugging - (Pouze SP) Vyžaduje restart mise/editoru. Aktivuje vizuální stopování fragmentace a úlomů pouze v režimu jednoho hráče. - (Somente SP) Requer um reinício de missão / editor. Habilita o rastreamento visual de projéteis de fragmentação e estilhaçamento apenas no modo de jogo SP. - (SP seulement) Requiert un redémarrage de mission ou de l'éditeur. Active les traceurs visuels de fragmentation et d'éclats en mode solo seulement. - (Csak SP) Küldetés/Editor újraindítás szükséges. Engedélyezi a repeszek és pattogzó lövedékek vizuális nyomkövetését, csak egyjátékos módok alatt. + (Local only) Requires a mission/editor restart. Enables visual tracing of fragmentation and spalling rounds in SP game mode only. + (Solo !*!) Requiere un reinicio misión/editor. Permite el seguimiento visual de la fragmentación y astillamientos de los proyectiles en modo SP. + (Tylko !*!) Wymaga restartu misji/edytora. Aktywuje wizualne śledzenie odłamków oraz odprysków w trybie gry Single Player. + (nur !*!) Splitter-/Explosions-Debugging + (Pouze !*!) Vyžaduje restart mise/editoru. Aktivuje vizuální stopování fragmentace a úlomů pouze v režimu jednoho hráče. + (Somente !*!) Requer um reinício de missão / editor. Habilita o rastreamento visual de projéteis de fragmentação e estilhaçamento apenas no modo de jogo SP. + (!*! seulement) Requiert un redémarrage de mission ou de l'éditeur. Active les traceurs visuels de fragmentation et d'éclats en mode solo seulement. + (Csak !*!) Küldetés/Editor újraindítás szükséges. Engedélyezi a repeszek és pattogzó lövedékek vizuális nyomkövetését, csak egyjátékos módok alatt. (Только для одиночной игры) Требует перезапуска миссии/редактора. Включает визуальные следы от осколков и обломков в режиме одиночной игры. - (Solo SP) Richiede un restart editor/missione. Abilita il tracciamento visivo di schegge da frammentazione/spalling in modalità Giocatore Singolo. - (SP のみ) ミッションとエディタの再起動が必要です。有効化すると、シングルプレイでのみ破片と剥離の飛翔体が見えるようになります。 + (Solo !*!) Richiede un restart editor/missione. Abilita il tracciamento visivo di schegge da frammentazione/spalling in modalità Giocatore Singolo. + (!*! のみ) ミッションとエディタの再起動が必要です。有効化すると、シングルプレイでのみ破片と剥離の飛翔体が見えるようになります。 (仅单人)激活后,只有在单人模式下才可观察到破片粒子的移动轨迹。 (僅在單人模式) 讓你在單人模式下可觀察到碎片/剝落粒子的移動軌跡 - (SP 전용) 임무 / 편집자가 다시 시작해야합니다. SP 게임 모드에서만 파편화 및 탄환파편의 시각적 추적을 가능하게 합니다. + (!*! 전용) 임무 / 편집자가 다시 시작해야합니다. SP 게임 모드에서만 파편화 및 탄환파편의 시각적 추적을 가능하게 합니다. + + + Draw Event Spheres + + + Draw color coded spheres at any event for tracked rounds. + + + Draw Hitboxes + + + Draw hitboxes on objects added using ace_frag_fnc_dev_trackHitBox. From 34d1762b62be9afa15d0c3101466c78bb3c2f781 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 10 Jan 2024 15:49:37 -0600 Subject: [PATCH 046/282] Fixed one stringtable issue --- addons/frag/stringtable.xml | 70 +++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 19 deletions(-) diff --git a/addons/frag/stringtable.xml b/addons/frag/stringtable.xml index 83ac3bd855e..2ccec341187 100644 --- a/addons/frag/stringtable.xml +++ b/addons/frag/stringtable.xml @@ -220,37 +220,69 @@ 设定在每一帧数内,系统最大可追踪的破片粒子数量。此设定可有效帮助系统减低计算压力。 設定在每一幀數內,系統最大可追蹤的碎片/剝落粒子數量。此設定可有效幫助系統減低計算壓力 + + (SP only) Frag/Spall Debug Tracing + (Solo SP) Seguimiento de depuración de Fragmentación/Astillamiento + (Tylko SP) Wizualny debug odł./odpr. + (Pouze SP) Debug sledování Frag/Úlomků + (nur SP) Splitter-/Explosions-Debug-Verfolgung + (Somente SP) Depuração de fragmentação e estilhaços traçantes + (SP uniquement) Fragmentation/éclat debug + (Csak SP) Repesz/Pattogzás debug követés + (Только для одиночной игры) Отслеживаение/отладка осколков + (Solo SP) Debug Tracciamento Frag/Spall + (SP のみ) 破片/剥離のデバッグ用表示 + (싱글플레이 전용) 탄환파편/파편 디버그 추적화 + (仅单人)追踪显示破片粒子 + (僅在單人模式) 碎片/剝落除錯追蹤 + + + (SP only) Requires a mission/editor restart. Enables visual tracing of fragmentation and spalling rounds in SP game mode only. + (Solo SP) Requiere un reinicio misión/editor. Permite el seguimiento visual de la fragmentación y astillamientos de los proyectiles en modo SP. + (Tylko SP) Wymaga restartu misji/edytora. Aktywuje wizualne śledzenie odłamków oraz odprysków w trybie gry Single Player. + (nur SP) Splitter-/Explosions-Debugging + (Pouze SP) Vyžaduje restart mise/editoru. Aktivuje vizuální stopování fragmentace a úlomů pouze v režimu jednoho hráče. + (Somente SP) Requer um reinício de missão / editor. Habilita o rastreamento visual de projéteis de fragmentação e estilhaçamento apenas no modo de jogo SP. + (SP seulement) Requiert un redémarrage de mission ou de l'éditeur. Active les traceurs visuels de fragmentation et d'éclats en mode solo seulement. + (Csak SP) Küldetés/Editor újraindítás szükséges. Engedélyezi a repeszek és pattogzó lövedékek vizuális nyomkövetését, csak egyjátékos módok alatt. + (Только для одиночной игры) Требует перезапуска миссии/редактора. Включает визуальные следы от осколков и обломков в режиме одиночной игры. + (Solo SP) Richiede un restart editor/missione. Abilita il tracciamento visivo di schegge da frammentazione/spalling in modalità Giocatore Singolo. + (SP のみ) ミッションとエディタの再起動が必要です。有効化すると、シングルプレイでのみ破片と剥離の飛翔体が見えるようになります。 + (仅单人)激活后,只有在单人模式下才可观察到破片粒子的移动轨迹。 + (僅在單人模式) 讓你在單人模式下可觀察到碎片/剝落粒子的移動軌跡 + (SP 전용) 임무 / 편집자가 다시 시작해야합니다. SP 게임 모드에서만 파편화 및 탄환파편의 시각적 추적을 가능하게 합니다. + (Local only) Frag/Spall Debug Tracing - (Solo !*!) Seguimiento de depuración de Fragmentación/Astillamiento - (Tylko !*!) Wizualny debug odł./odpr. - (Pouze !*!) Debug sledování Frag/Úlomků - (nur !*!) Splitter-/Explosions-Debug-Verfolgung - (Somente !*!) Depuração de fragmentação e estilhaços traçantes - (!*! uniquement) Fragmentation/éclat debug - (Csak !*!) Repesz/Pattogzás debug követés + (Solo SP) Seguimiento de depuración de Fragmentación/Astillamiento + (Tylko SP) Wizualny debug odł./odpr. + (Pouze SP) Debug sledování Frag/Úlomků + (nur SP) Splitter-/Explosions-Debug-Verfolgung + (Somente SP) Depuração de fragmentação e estilhaços traçantes + (SP uniquement) Fragmentation/éclat debug + (Csak SP) Repesz/Pattogzás debug követés (Только для одиночной игры) Отслеживаение/отладка осколков - (Solo !*!) Debug Tracciamento Frag/Spall - (!*! のみ) 破片/剥離のデバッグ用表示 + (Solo SP) Debug Tracciamento Frag/Spall + (SP のみ) 破片/剥離のデバッグ用表示 (싱글플레이 전용) 탄환파편/파편 디버그 추적화 (仅单人)追踪显示破片粒子 (僅在單人模式) 碎片/剝落除錯追蹤 (Local only) Requires a mission/editor restart. Enables visual tracing of fragmentation and spalling rounds in SP game mode only. - (Solo !*!) Requiere un reinicio misión/editor. Permite el seguimiento visual de la fragmentación y astillamientos de los proyectiles en modo SP. - (Tylko !*!) Wymaga restartu misji/edytora. Aktywuje wizualne śledzenie odłamków oraz odprysków w trybie gry Single Player. - (nur !*!) Splitter-/Explosions-Debugging - (Pouze !*!) Vyžaduje restart mise/editoru. Aktivuje vizuální stopování fragmentace a úlomů pouze v režimu jednoho hráče. - (Somente !*!) Requer um reinício de missão / editor. Habilita o rastreamento visual de projéteis de fragmentação e estilhaçamento apenas no modo de jogo SP. - (!*! seulement) Requiert un redémarrage de mission ou de l'éditeur. Active les traceurs visuels de fragmentation et d'éclats en mode solo seulement. - (Csak !*!) Küldetés/Editor újraindítás szükséges. Engedélyezi a repeszek és pattogzó lövedékek vizuális nyomkövetését, csak egyjátékos módok alatt. + (Solo SP) Requiere un reinicio misión/editor. Permite el seguimiento visual de la fragmentación y astillamientos de los proyectiles en modo SP. + (Tylko SP) Wymaga restartu misji/edytora. Aktywuje wizualne śledzenie odłamków oraz odprysków w trybie gry Single Player. + (nur SP) Splitter-/Explosions-Debugging + (Pouze SP) Vyžaduje restart mise/editoru. Aktivuje vizuální stopování fragmentace a úlomů pouze v režimu jednoho hráče. + (Somente SP) Requer um reinício de missão / editor. Habilita o rastreamento visual de projéteis de fragmentação e estilhaçamento apenas no modo de jogo SP. + (SP seulement) Requiert un redémarrage de mission ou de l'éditeur. Active les traceurs visuels de fragmentation et d'éclats en mode solo seulement. + (Csak SP) Küldetés/Editor újraindítás szükséges. Engedélyezi a repeszek és pattogzó lövedékek vizuális nyomkövetését, csak egyjátékos módok alatt. (Только для одиночной игры) Требует перезапуска миссии/редактора. Включает визуальные следы от осколков и обломков в режиме одиночной игры. - (Solo !*!) Richiede un restart editor/missione. Abilita il tracciamento visivo di schegge da frammentazione/spalling in modalità Giocatore Singolo. - (!*! のみ) ミッションとエディタの再起動が必要です。有効化すると、シングルプレイでのみ破片と剥離の飛翔体が見えるようになります。 + (Solo SP) Richiede un restart editor/missione. Abilita il tracciamento visivo di schegge da frammentazione/spalling in modalità Giocatore Singolo. + (SP のみ) ミッションとエディタの再起動が必要です。有効化すると、シングルプレイでのみ破片と剥離の飛翔体が見えるようになります。 (仅单人)激活后,只有在单人模式下才可观察到破片粒子的移动轨迹。 (僅在單人模式) 讓你在單人模式下可觀察到碎片/剝落粒子的移動軌跡 - (!*! 전용) 임무 / 편집자가 다시 시작해야합니다. SP 게임 모드에서만 파편화 및 탄환파편의 시각적 추적을 가능하게 합니다. + (SP 전용) 임무 / 편집자가 다시 시작해야합니다. SP 게임 모드에서만 파편화 및 탄환파편의 시각적 추적을 가능하게 합니다. Draw Event Spheres From 7c399b8c9ec2f51277bd2d5a80dfb726807dc90b Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 10 Jan 2024 17:39:46 -0600 Subject: [PATCH 047/282] Forgot to actually cache the spall material --- addons/frag/functions/fnc_shouldSpall.sqf | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/addons/frag/functions/fnc_shouldSpall.sqf b/addons/frag/functions/fnc_shouldSpall.sqf index af7d28268e0..8eae8a81a55 100644 --- a/addons/frag/functions/fnc_shouldSpall.sqf +++ b/addons/frag/functions/fnc_shouldSpall.sqf @@ -18,7 +18,7 @@ params ["_ammo"]; -private _shouldSpall = GVAR(spallCahche) get _ammo; +private _shouldSpall = GVAR(spallRoundCache) get _ammo; if !(isNil "_shouldSpall") exitWith {_shouldSpall}; @@ -26,6 +26,8 @@ private _caliber = getNumber (configFile >> "CfgAmmo" >> _ammo >> "caliber"); private _explosive = getNumber (configFile >> "CfgAmmo" >> _ammo >> "explosive"); private _idH = getNumber (configFile >> "CfgAmmo" >> _ammo >> "indirectHitRange"); -_shouldSpall = (_caliber >= 2.5 || _explosive > 0 && _idh >= 1); +_shouldSpall = _caliber >= 2.5 || (_explosive > 0 && _idh >= 1); + +GVAR(spallRoundCache) set [_ammo, _shouldSpall]; _shouldSpall \ No newline at end of file From ebf1a707c149b041e1aeb984a523f4efef347a9a Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 10 Jan 2024 17:40:36 -0600 Subject: [PATCH 048/282] Added initialization of material cache for performance --- addons/frag/XEH_PREP.hpp | 1 + addons/frag/XEH_postInit.sqf | 1 + addons/frag/XEH_preInit.sqf | 2 +- .../frag/functions/fnc_initMaterialCache.sqf | 96 +++++++++++++++++++ 4 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 addons/frag/functions/fnc_initMaterialCache.sqf diff --git a/addons/frag/XEH_PREP.hpp b/addons/frag/XEH_PREP.hpp index 7d261c91f4b..339cbff61c9 100644 --- a/addons/frag/XEH_PREP.hpp +++ b/addons/frag/XEH_PREP.hpp @@ -28,6 +28,7 @@ PREP(doFragRandom); PREP(shouldSpall); PREP(doSpall); PREP(getMaterialInfo); +PREP(initMaterialCache); // Explosive Reflection PREP(findReflections); diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index 094164db10a..137db6c0d2c 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -5,6 +5,7 @@ [QGVAR(frag_eh), LINKFUNC(doFrag)] call CBA_fnc_addEventHandler; [QGVAR(spall_eh), LINKFUNC(doFragMomentum)] call CBA_fnc_addEventHandler; [] call FUNC(initBlackList); + [] call FUNC(initMaterialCache); }; /*if (hasInterface) then { diff --git a/addons/frag/XEH_preInit.sqf b/addons/frag/XEH_preInit.sqf index 646bcb1dbc3..0356a4e7395 100644 --- a/addons/frag/XEH_preInit.sqf +++ b/addons/frag/XEH_preInit.sqf @@ -7,7 +7,7 @@ PREP_RECOMPILE_START; PREP_RECOMPILE_END; -GVAR(materialSpallCache) = createHashMapFromArray [["", "metal"]]; +GVAR(materialSpallCache) = createHashMap; GVAR(spallRoundCache) = createHashMap; GVAR(lastSpallTime) = -2; diff --git a/addons/frag/functions/fnc_initMaterialCache.sqf b/addons/frag/functions/fnc_initMaterialCache.sqf new file mode 100644 index 00000000000..d0cdc0e8332 --- /dev/null +++ b/addons/frag/functions/fnc_initMaterialCache.sqf @@ -0,0 +1,96 @@ +#include "script_component.hpp" +/* + * Author: Lambda.Tiger + * For performance, we load a bunch of vanilla materials preemptively + * + * Arguments: + * none + * + * Return Value: + * none + * + * Example: + * [] call initMaterialCache; + * + * Public: No + */ + +GVAR(materialSpallCache) = createHashMapFromArray [ + ["a3\data_f\penetration\armour.bisurf","metal"], + ["a3\data_f\penetration\armour_plate.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_100mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_12mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_16mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_1mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_20mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_23mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_250mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_30mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_3mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_40mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_5mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_60mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_7mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_80mm.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_heavy.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_medium.bisurf","metal"], + ["a3\data_f\penetration\armour_plate_thin.bisurf","metal"], + ["a3\data_f\penetration\bell.bisurf","ground"], + ["a3\data_f\penetration\body.bisurf","ground"], + ["a3\data_f\penetration\building.bisurf","concrete"], + ["a3\data_f\penetration\building_dust_particle.bisurf","concrete"], + ["a3\data_f\penetration\building_dust_soft.bisurf","concrete"], + ["a3\data_f\penetration\building_plate.bisurf","concrete"], + ["a3\data_f\penetration\building_wood_particle.bisurf","wood"], + ["a3\data_f\penetration\cactus.bisurf","ground"], + ["a3\data_f\penetration\cloth.bisurf","ground"], + ["a3\data_f\penetration\cloth_plate.bisurf","ground"], + ["a3\data_f\penetration\concrete.bisurf","concrete"], + ["a3\data_f\penetration\concrete_plate.bisurf","concrete"], + ["a3\data_f\penetration\default.bisurf","ground"], + ["a3\data_f\penetration\engine.bisurf","metal"], + ["a3\data_f\penetration\foliage.bisurf","ground"], + ["a3\data_f\penetration\foliage_dead.bisurf","ground"], + ["a3\data_f\penetration\foliage_dead_plate.bisurf","ground"], + ["a3\data_f\penetration\foliage_green.bisurf","ground"], + ["a3\data_f\penetration\foliage_green_big.bisurf","ground"], + ["a3\data_f\penetration\foliage_green_big_plate.bisurf","ground"], + ["a3\data_f\penetration\foliage_green_plate.bisurf","ground"], + ["a3\data_f\penetration\foliage_palm.bisurf","ground"], + ["a3\data_f\penetration\foliage_palm_plate.bisurf","ground"], + ["a3\data_f\penetration\foliage_pine.bisurf","ground"], + ["a3\data_f\penetration\foliage_pine_plate.bisurf","ground"], + ["a3\data_f\penetration\foliage_plate.bisurf","ground"], + ["a3\data_f\penetration\fueltank.bisurf","metal"], + ["a3\data_f\penetration\glass.bisurf","ground"], + ["a3\data_f\penetration\glass_armored.bisurf","ground"], + ["a3\data_f\penetration\glass_armored_plate.bisurf","ground"], + ["a3\data_f\penetration\glass_plate.bisurf","ground"], + ["a3\data_f\penetration\granite.bisurf","ground"], + ["a3\data_f\penetration\granite_plate.bisurf","ground"], + ["a3\data_f\penetration\hard_ground.bisurf","ground"], + ["a3\data_f\penetration\hay.bisurf","ground"], + ["a3\data_f\penetration\iron_cast.bisurf","metal"], + ["a3\data_f\penetration\iron_cast_plate.bisurf","metal"], + ["a3\data_f\penetration\leather.bisurf","ground"], + ["a3\data_f\penetration\meat.bisurf","ground"], + ["a3\data_f\penetration\meatbones.bisurf","ground"], + ["a3\data_f\penetration\medium_ground.bisurf","ground"], + ["a3\data_f\penetration\metal.bisurf","metal"], + ["a3\data_f\penetration\metal_plate.bisurf","metal"], + ["a3\data_f\penetration\metal_plate_thin.bisurf","metal"], + ["a3\data_f\penetration\plastic.bisurf","ground"], + ["a3\data_f\penetration\plastic_plate.bisurf","ground"], + ["a3\data_f\penetration\plexiglass.bisurf","ground"], + ["a3\data_f\penetration\plexiglass_plate.bisurf","ground"], + ["a3\data_f\penetration\rubber.bisurf","ground"], + ["a3\data_f\penetration\soft_ground.bisurf","ground"], + ["a3\data_f\penetration\tyre.bisurf","ground"], + ["a3\data_f\penetration\tyre_armored.bisurf","ground"], + ["a3\data_f\penetration\vehicle_interior.bisurf","metal"], + ["a3\data_f\penetration\void.bisurf","ground"], + ["a3\data_f\penetration\water.bisurf","ground"], + ["a3\data_f\penetration\weapon_plate.bisurf","metal"], + ["a3\data_f\penetration\wood.bisurf","wood"], + ["a3\data_f\penetration\wood_plate.bisurf","wood"] +]; \ No newline at end of file From 2a1f609e3c1626b45e04ff507cde73de05c9ee23 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 10 Jan 2024 17:41:13 -0600 Subject: [PATCH 049/282] changed files names and small optimizations --- ...nc_doSpallMomentum.sqf => fnc_doSpall.sqf} | 24 ++++++++----------- addons/frag/functions/fnc_getMaterialInfo.sqf | 6 ++--- addons/frag/functions/fnc_initRound.sqf | 14 +++++------ addons/frag/script_component.hpp | 2 +- 4 files changed, 20 insertions(+), 26 deletions(-) rename addons/frag/functions/{fnc_doSpallMomentum.sqf => fnc_doSpall.sqf} (92%) diff --git a/addons/frag/functions/fnc_doSpallMomentum.sqf b/addons/frag/functions/fnc_doSpall.sqf similarity index 92% rename from addons/frag/functions/fnc_doSpallMomentum.sqf rename to addons/frag/functions/fnc_doSpall.sqf index 42eb09d52ff..bcdc3b885da 100644 --- a/addons/frag/functions/fnc_doSpallMomentum.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -31,16 +31,17 @@ params [ ["_vUp", [0,0,1]] ]; -if (CBA_missionTime - GVAR(lastSpallTime) < ACE_FRAG_SPALL_HOLDOFF) exitWith { - TRACE_2("timeExit",CBA_missionTime,GVAR(lastSpallTime)); +if (CBA_missionTime - GVAR(lastSpallTime) < ACE_FRAG_SPALL_HOLDOFF || + _lPosASL isEqualTo [0,0,0] || + {isNull _hitObj || {_hitObj isKindOf "man"}}) exitWith { + TRACE_4("time/invldHit",CBA_missionTime,GVAR(lastSpallTime),_hitObj,_lPosASL); }; -if (isNull _hitObj || {_hitObj isKindOf "man"}) exitWith { - TRACE_1("invalidHit",_hitObj); -}; - -if (_lPosASL isEqualTo [0,0,0]) exitWith { - TRACE_1("Problem with hitPart data - bad pos",_lPosASL); +private _material = [_surfaceType] call FUNC(getMaterialInfo); +if (_material isEqualTo "ground") then { +#ifdef DEBUG_MODE_FULL + systemChat "ground spall"; // really shouldn't happen +#endif }; private _vel = if (alive _projectile) then { @@ -49,7 +50,6 @@ private _vel = if (alive _projectile) then { [0, 0, 0] }; - // Find spall speed / fragment private _dV = vectorMagnitude _lVel - vectorMagnitude _vel; private _caliber = getNumber (configFile >> "cfgAmmo" >> _ammo >> "caliber"); // !*! optimize this later? @@ -61,7 +61,6 @@ if (_deltaMomentum < 2) exitWith { TRACE_1("lowImpulse",_ammo); }; -private _material = [_surfaceType] call FUNC(getMaterialInfo); //** start calculating where the spalling should come !*! could be better **// private _lVelUnit = vectorNormalized _lVel; @@ -120,11 +119,8 @@ private _spallSpawner = createVehicleLocal [ _spallSpawner setVectorDirandUp [_lVelUnit, _vUp]; _spallSpawner setVelocity (_lVelUnit vectorMultiply (_dV/2)); _spallSpawner setShotParents _shotParents; - +profilerLog "spalled"; #ifdef DEBUG_MODE_FULL -if (_material isEqualTo "ground") then { - systemChat "ground spall"; // really shouldn't happen -}; systemChat ("bSpd: " + str speed _spallSpawner + ", frag: " + _fragSpawnType + ", dm: " + str _deltaMomentum); #endif #ifdef DEBUG_MODE_DRAW diff --git a/addons/frag/functions/fnc_getMaterialInfo.sqf b/addons/frag/functions/fnc_getMaterialInfo.sqf index 42f638beaa0..b471a5c5730 100644 --- a/addons/frag/functions/fnc_getMaterialInfo.sqf +++ b/addons/frag/functions/fnc_getMaterialInfo.sqf @@ -29,14 +29,12 @@ if (isClass (configFile >> "CfgSurfaces" >> _surfType)) then { _material = getText (configFile >> "CfgSurfaces" >> _surfType >> "soundEnviron"); } else { // Messy way when a surface isn't added to cfgSurfaces private _surfFileText = tolower preprocessFile _surfType; - _surfFileText = _surfFileText regexReplace ["[^A-Za-z0-9]", ""]; + _surfFileText = _surfFileText regexReplace ["[^a-z0-9]", ""]; private _idx = 12 + (_surfFileText find "soundenviron"); if (_surfFileText select [_idx, 5] isEqualTo "empty") then { _idx = 8 + (_surfFileText find "soundhit"); - _material = _surfFileText select [_idx, 10]; - } else { - _material = _surfFileText select [_idx, 10]; }; + _material = _surfFileText select [_idx, 10]; }; TRACE_1("materialSubString",_material); diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index bac3b0c8797..37be4c00242 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -37,12 +37,12 @@ if (_doFrag) then { if (isServer) then { [ FUNC(doFrag), - [_this + [_ammo, _shotParents]] + _this + [_ammo, _shotParents] ] call CBA_fnc_execNextFrame; } else { [ QGVAR(frag_eh), - [_this + [_ammo, _shotParents]] + _this + [_ammo, _shotParents] ] call CBA_fnc_serverEvent; }; } @@ -57,13 +57,13 @@ if (GVAR(spallEnabled) && {_shouldSpall}) then _projectile addEventHandler [ "HitPart", { - params ["_proj", "_hitObj", "", - "_posASL", "_vel", "_sNorm", "", - "", "_surfType" - ]; + params ["_proj", "_hitObj", "", + "_posASL", "_vel", "_sNorm", "", + "", "_surfType" + ]; private _shotPrnt = getShotParents _proj; private _ammo = typeOf _proj; - private _vUp = vectorUp _proj; + private _vUp = vectorUp _proj; if (isServer) then { [ LINKFUNC(doSpall), diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index f98d27e5956..d4c7cc1ee21 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -3,7 +3,7 @@ #include "\z\ace\addons\main\script_mod.hpp" // #define LOG_FRAG_INFO -#define DEBUG_MODE_FULL +// #define DEBUG_MODE_FULL // #define DEBUG_MODE_DRAW // #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS From a04e7a83e6df211cade0404b351b937eff4470b1 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 10 Jan 2024 18:34:54 -0600 Subject: [PATCH 050/282] Small bug & config name fixes --- addons/frag/cfgAmmoSpall.hpp | 2 +- addons/frag/functions/fnc_doSpall.sqf | 17 +++++++++-------- addons/frag/initSettings.inc.sqf | 3 +-- addons/frag/script_component.hpp | 8 ++++++-- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/addons/frag/cfgAmmoSpall.hpp b/addons/frag/cfgAmmoSpall.hpp index 59e478ad7fb..d6de86476a8 100644 --- a/addons/frag/cfgAmmoSpall.hpp +++ b/addons/frag/cfgAmmoSpall.hpp @@ -133,7 +133,7 @@ class GVAR(metal_spall_small) : GVAR(spallBase) { submunitionConeType[] = {"poissondisccenter", 6}; }; -class GVAR(metal_metal_spall_medium) : GVAR(spallBase) { +class GVAR(metal_spall_medium) : GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 5, QGVAR(small), 4, QGVAR(medium), 2, QGVAR(large), 1}; submunitionConeType[] = {"poissondisccenter", 8}; }; diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index bcdc3b885da..3c6752ca864 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -33,7 +33,8 @@ params [ if (CBA_missionTime - GVAR(lastSpallTime) < ACE_FRAG_SPALL_HOLDOFF || _lPosASL isEqualTo [0,0,0] || - {isNull _hitObj || {_hitObj isKindOf "man"}}) exitWith { + {isNull _hitObj || {_hitObj isKindOf "man" || + {_ammo isEqualTo ""}}}) exitWith { TRACE_4("time/invldHit",CBA_missionTime,GVAR(lastSpallTime),_hitObj,_lPosASL); }; @@ -75,6 +76,10 @@ if (120 > acos ((vectorNormalized _lVelUnit) vectorDotProduct _sNorm)) then { if (terrainIntersectASL [_lPosASL vectorAdd _unitStep, _lPosASL]) exitWith { TRACE_3("terrainIntersect",_lPosASL,_unitStep,_lPosASL); }; + +//***** Passed all exit withs *****// +GVAR(lastSpallTime) = CBA_missionTime; + // step through for "_i" from 1 to 20 do { @@ -93,10 +98,6 @@ if GVAR(dbgSphere) then { [_lPosASL, "orange"] call FUNC(dev_sphereDraw); }; #endif - -//***** Passed all exit withs *****// -GVAR(lastSpallTime) = CBA_missionTime; - //***** Select spalled fragment spawner **// private _spawnSize = switch (true) do @@ -109,8 +110,8 @@ private _spawnSize = switch (true) do }; //***** Spawn spalled fragments -private _spallSpawner = createVehicleLocal [ - QUOTE(ADDON##_) + _material + _spawnSize, +private _spallSpawner = createVehicle [ + "ace_frag_" + _material + _spawnSize, ASLToATL _spallPos, [], 0, @@ -119,7 +120,7 @@ private _spallSpawner = createVehicleLocal [ _spallSpawner setVectorDirandUp [_lVelUnit, _vUp]; _spallSpawner setVelocity (_lVelUnit vectorMultiply (_dV/2)); _spallSpawner setShotParents _shotParents; -profilerLog "spalled"; + #ifdef DEBUG_MODE_FULL systemChat ("bSpd: " + str speed _spallSpawner + ", frag: " + _fragSpawnType + ", dm: " + str _deltaMomentum); #endif diff --git a/addons/frag/initSettings.inc.sqf b/addons/frag/initSettings.inc.sqf index 18f77fbc176..08b93698022 100644 --- a/addons/frag/initSettings.inc.sqf +++ b/addons/frag/initSettings.inc.sqf @@ -55,11 +55,10 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; true ] call CBA_fnc_addSetting; - [ QGVAR(SpallIntensity), "SLIDER", [LSTRING(SpallIntensity), LSTRING(SpallIntensity_Desc)], - [_category, LSTRING(Frag)], + [_category, LSTRING(Spall)], [0.1, 2, 1, 1], true ] call CBA_fnc_addSetting; diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index d4c7cc1ee21..50e248fac6a 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -18,9 +18,9 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define ACE_FRAG_HOLDOFF 0.2 +#define ACE_FRAG_HOLDOFF 0.25 #define ACE_FRAG_HOLDOFF_VEHICLE 1 -#define ACE_FRAG_SPALL_HOLDOFF 0.2 +#define ACE_FRAG_SPALL_HOLDOFF 0.25 #define ACE_FRAG_COUNT_MIN 5 #define ACE_FRAG_COUNT_MAX 50 #define ACE_FRAG_HITPOINTS ["spine1","spine2","spine3","head","leftarm","leftarmroll","leftforearm","rightarm","rightarmroll","rightforearm","pelvis","leftupleg","leftuplegroll","leftlegroll","leftfoot","rightupleg","rightuplegroll","rightleg","rightlegroll","rightfoot"] @@ -32,4 +32,8 @@ #define __FADE_INTERVAL 0.1 #define __FADE_RATE __FADE_INTERVAL/__FADE_TIME/2 #define __FADE_INIT (__FADE_TIME+__FADE_START)/__FADE_TIME/2 +#endif + +#ifndef GLUE +#define GLUE(g1,g2) g1##g2 #endif \ No newline at end of file From f202b650c6499cdcf66e81e2a69a50edc4ac4497 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 10 Jan 2024 18:40:25 -0600 Subject: [PATCH 051/282] Removed dev info --- .gitignore | 3 +-- addons/frag/README.md | 9 +-------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 44f28e560a0..9e50c11cbd7 100644 --- a/.gitignore +++ b/.gitignore @@ -19,5 +19,4 @@ Thumbs.db CHANGELOG.md sqfvm.exe ArmaScriptCompiler.exe -*.sqfc -addons/frag/dev \ No newline at end of file +*.sqfc \ No newline at end of file diff --git a/addons/frag/README.md b/addons/frag/README.md index 69ed9111e4b..e5c9a35a05d 100644 --- a/addons/frag/README.md +++ b/addons/frag/README.md @@ -1,11 +1,4 @@ ace_frag ======== -Explosive fragmentation, round spalling, and explosive reflection - -TODO: -- Finish stringtable expansion with additional normal & debug settings -- More extensive MP testing -- performance optimization -- cDLC, RHS, CUP compats -- look at / try to understand explosion reflections \ No newline at end of file +Explosive fragmentation, round spalling, and explosive reflection \ No newline at end of file From eef48da6bc5f954af377ca4f7cdd739d8bb2015d Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 10 Jan 2024 18:51:38 -0600 Subject: [PATCH 052/282] Converetd all stray tabs to spaces --- addons/frag/CfgAmmo.hpp | 14 +++---- addons/frag/XEH_postInit.sqf | 12 +++--- addons/frag/cfgAmmoBaseEH.hpp | 38 +++++++++---------- addons/frag/cfgAmmoFragSpawner.hpp | 34 ++++++++--------- addons/frag/cfgAmmoSpall.hpp | 2 +- addons/frag/functions/fnc_dev_addRound.sqf | 2 +- addons/frag/functions/fnc_dev_drawTrace.sqf | 4 +- .../frag/functions/fnc_dev_fragCalcDump.sqf | 6 +-- .../functions/fnc_dev_switchUnitHandle.sqf | 14 +++---- addons/frag/functions/fnc_dev_trackObj.sqf | 10 ++--- addons/frag/functions/fnc_doFrag.sqf | 9 ++--- addons/frag/functions/fnc_doFragRandom.sqf | 4 +- addons/frag/functions/fnc_doFragTargeted.sqf | 8 ++-- addons/frag/functions/fnc_doSpall.sqf | 23 ++++++----- addons/frag/functions/fnc_fired.sqf | 3 +- addons/frag/functions/fnc_getFragInfo.sqf | 12 +++--- addons/frag/functions/fnc_getMaterialInfo.sqf | 12 +++--- addons/frag/functions/fnc_shouldFrag.sqf | 2 +- addons/frag/initSettings.inc.sqf | 11 +++--- 19 files changed, 109 insertions(+), 111 deletions(-) diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index 1088f39a081..911e18cb309 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -2,19 +2,19 @@ #define HD_MULT 5 #define BASE_DRAG_HD (BASE_DRAG * HD_MULT) #define ACE_FRAG_RM_EH class EventHandlers {\ - delete ADDON;\ + delete ADDON;\ } class CfgAmmo { class B_65x39_Caseless; - class GVAR(base): B_65x39_Caseless { + class GVAR(base): B_65x39_Caseless { ACE_damageType = "grenade"; // compatibility with medical_damage, shrapnel should produce grenade wounds timeToLive = 4; typicalSpeed = 800; maxSpeed = 1500; deflecting = 65; - ACE_FRAG_RM_EH; + ACE_FRAG_RM_EH; }; class GVAR(tiny): GVAR(base) { @@ -85,8 +85,8 @@ class CfgAmmo { caliber = 2.8; }; - #include "cfgAmmoBaseEH.hpp" - #include "cfgAmmoSpall.hpp" - #include "cfgAmmoFragParameters.hpp" - #include "cfgAmmoFragSpawner.hpp" + #include "cfgAmmoBaseEH.hpp" + #include "cfgAmmoSpall.hpp" + #include "cfgAmmoFragParameters.hpp" + #include "cfgAmmoFragSpawner.hpp" }; \ No newline at end of file diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index 137db6c0d2c..063060551b8 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -5,7 +5,7 @@ [QGVAR(frag_eh), LINKFUNC(doFrag)] call CBA_fnc_addEventHandler; [QGVAR(spall_eh), LINKFUNC(doFragMomentum)] call CBA_fnc_addEventHandler; [] call FUNC(initBlackList); - [] call FUNC(initMaterialCache); + [] call FUNC(initMaterialCache); }; /*if (hasInterface) then { @@ -17,11 +17,11 @@ ["ace_firedNonPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler;*/ #ifdef DEBUG_MODE_DRAW - if (hasInterface && GVAR(debugOptions)) then { - private _h = [LINKFUNC(dev_drawTrace), 0] call CBA_fnc_addPerFrameHandler; - missionNamespace setVariable [QGVAR(dev_drawPFEH), _h]; - ["unit", LINKFUNC(dev_switchUnitHandle), true] call CBA_fnc_addPlayerEventHandler; - [objNull, ace_player] call FUNC(dev_switchUnitHandle); + if (hasInterface && GVAR(debugOptions)) then { + private _h = [LINKFUNC(dev_drawTrace), 0] call CBA_fnc_addPerFrameHandler; + missionNamespace setVariable [QGVAR(dev_drawPFEH), _h]; + ["unit", LINKFUNC(dev_switchUnitHandle), true] call CBA_fnc_addPlayerEventHandler; + [objNull, ace_player] call FUNC(dev_switchUnitHandle); }; #endif }] call CBA_fnc_addEventHandler; diff --git a/addons/frag/cfgAmmoBaseEH.hpp b/addons/frag/cfgAmmoBaseEH.hpp index 050a7d769d5..b8a1596af64 100644 --- a/addons/frag/cfgAmmoBaseEH.hpp +++ b/addons/frag/cfgAmmoBaseEH.hpp @@ -1,85 +1,85 @@ #define ACE_FRAG_ADD_EH class EventHandlers {\ - class ADDON {\ - init = QUOTE(_this call FUNC(initRound););\ - };\ + class ADDON {\ + init = QUOTE(_this call FUNC(initRound););\ + };\ } class BombCore; class Bo_Mk82: BombCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH; }; // We need this since autocannons generally inherit from BulletBase class BulletCore; class BulletBase: BulletCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH; }; class Grenade; class GrenadeHand: Grenade { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH; }; class GrenadeCore; class GrenadeBase: GrenadeCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH; }; class LaserBombCore; class ammo_Bomb_LaserGuidedBase: LaserBombCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH; }; class MissileCore; class MissileBase: MissileCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH; }; class RocketCore; class RocketBase: RocketCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH; }; class ArtilleryRocketCore: RocketCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH; }; class ShellCore; class ShellBase: ShellCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH; }; class ShotDeployCore; class ShotDeployBase: ShotDeployCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH; }; class ShotgunCore; class ShotgunBase: ShotgunCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH; }; class SubmunitionCore; class SubmunitionBase: SubmunitionCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH; }; class BoundingMineCore; class BoundingMineBase: BoundingMineCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH; }; class PipeBombCore; class PipeBombBase: PipeBombCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH; }; class DirectionalBombCore; class DirectionalBombBase: DirectionalBombCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH; }; class MineCore; class MineBase: MineCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH; }; \ No newline at end of file diff --git a/addons/frag/cfgAmmoFragSpawner.hpp b/addons/frag/cfgAmmoFragSpawner.hpp index be85d81be13..d7dc0be6891 100644 --- a/addons/frag/cfgAmmoFragSpawner.hpp +++ b/addons/frag/cfgAmmoFragSpawner.hpp @@ -13,7 +13,7 @@ class GVAR(spawnbase) : B_65x39_Caseless { submunitionParentSpeedCoef = 1; triggerSpeedCoef[] = {0.75, 1.5}; triggerTime = 0; - ACE_FRAG_RM_EH; + ACE_FRAG_RM_EH; }; /********************* ***************************/ @@ -23,7 +23,7 @@ class GVAR(def_10) : GVAR(spawnbase) { class GVAR(def_10_lo) : GVAR(def_10) { submunitionConeAngle = 85; }; -class GVAR(def_10_mid) : GVAR(def_10) { +class GVAR(def_10_mid) : GVAR(def_10) { submunitionConeAngle = 85; triggerSpeedCoef[] = {-1.5, 1.5}; }; @@ -31,13 +31,13 @@ class GVAR(def_10_hi) : GVAR(def_10) { submunitionConeAngle = 80; triggerSpeedCoef[] = {-1.5, -0.75}; }; -class GVAR(def_10_top) : GVAR(def_10) { +class GVAR(def_10_top) : GVAR(def_10) { submunitionConeAngle = 60; triggerSpeedCoef[] = {-1.5, -0.75}; }; /********************* ***************************/ -class GVAR(def_15) : GVAR(spawnbase) { +class GVAR(def_15) : GVAR(spawnbase) { submunitionConeType[] = {"random", 15}; }; class GVAR(def_15_lo) : GVAR(def_15) { @@ -57,7 +57,7 @@ class GVAR(def_15_top) : GVAR(def_15) { }; /********************* ***************************/ -class GVAR(def_5) : GVAR(spawnbase) { +class GVAR(def_5) : GVAR(spawnbase) { submunitionConeType[] = {"random", 5}; }; class GVAR(def_5_lo) : GVAR(def_5) { @@ -76,8 +76,8 @@ class GVAR(def_5_top) : GVAR(def_5) { triggerSpeedCoef[] = {-1.5, -0.75}; }; -/********************* ***************************/ -class GVAR(def_tiny_15) : GVAR(spawnbase) { +/********************* ***************************/ +class GVAR(def_tiny_15) : GVAR(spawnbase) { submunitionConeType[] = {"random", 15}; submunitionAmmo = QGVAR(tiny); }; @@ -97,8 +97,8 @@ class GVAR(def_tiny_15_top) : GVAR(def_tiny_15) { triggerSpeedCoef[] = {-1.5, -0.75}; }; -/********************* ***************************/ -class GVAR(def_tiny_10) : GVAR(spawnbase) { +/********************* ***************************/ +class GVAR(def_tiny_10) : GVAR(spawnbase) { submunitionConeType[] = {"random", 10}; submunitionAmmo = QGVAR(tiny); }; @@ -118,8 +118,8 @@ class GVAR(def_tiny_10_top) : GVAR(def_tiny_10) { triggerSpeedCoef[] = {-1.5, -0.75}; }; -/********************* ***************************/ -class GVAR(def_tiny_5) : GVAR(spawnbase) { +/********************* ***************************/ +class GVAR(def_tiny_5) : GVAR(spawnbase) { submunitionConeType[] = {"random", 5}; submunitionAmmo = QGVAR(tiny); }; @@ -138,8 +138,8 @@ class GVAR(def_tiny_5_top) : GVAR(def_tiny_5) { submunitionConeAngle = 60; triggerSpeedCoef[] = {-1.5, -0.75}; }; -/********************* ***************************/ -class GVAR(def_small_15) : GVAR(spawnbase) { +/********************* ***************************/ +class GVAR(def_small_15) : GVAR(spawnbase) { submunitionConeType[] = {"random", 15}; submunitionAmmo = QGVAR(small); }; @@ -158,8 +158,8 @@ class GVAR(def_small_15_top) : GVAR(def_small_15) { submunitionConeAngle = 60; triggerSpeedCoef[] = {-1.15, -0.715}; }; -/********************* ***************************/ -class GVAR(def_small_10) : GVAR(spawnbase) { +/********************* ***************************/ +class GVAR(def_small_10) : GVAR(spawnbase) { submunitionConeType[] = {"random", 10}; submunitionAmmo = QGVAR(small); }; @@ -178,8 +178,8 @@ class GVAR(def_small_10_top) : GVAR(def_small_10) { submunitionConeAngle = 60; triggerSpeedCoef[] = {-1.10, -0.710}; }; -/********************* ***************************/ -class GVAR(def_small_5) : GVAR(spawnbase) { +/********************* ***************************/ +class GVAR(def_small_5) : GVAR(spawnbase) { submunitionConeType[] = {"random", 5}; submunitionAmmo = QGVAR(small); }; diff --git a/addons/frag/cfgAmmoSpall.hpp b/addons/frag/cfgAmmoSpall.hpp index d6de86476a8..3e51df4a150 100644 --- a/addons/frag/cfgAmmoSpall.hpp +++ b/addons/frag/cfgAmmoSpall.hpp @@ -10,7 +10,7 @@ class GVAR(spallBase) : B_65x39_Caseless { triggerSpeedCoef[] = {0.75,1.25}; deleteParentWhenTriggered = 1; submunitionParentSpeedCoef = 1; - ACE_FRAG_RM_EH; + ACE_FRAG_RM_EH; }; diff --git a/addons/frag/functions/fnc_dev_addRound.sqf b/addons/frag/functions/fnc_dev_addRound.sqf index 7ad5b05df39..483ac8cfae0 100644 --- a/addons/frag/functions/fnc_dev_addRound.sqf +++ b/addons/frag/functions/fnc_dev_addRound.sqf @@ -27,7 +27,7 @@ params [ if (_sidePlayer) then { GVAR(dev_trackLines) set [getObjectID _proj, [1, [getposATL _proj], [0, 0, 1, 1]]]; -} else +} else { GVAR(dev_trackLines) set [getObjectID _proj, [1, [getposATL _proj], [1, 0, 0, 1]]]; }; diff --git a/addons/frag/functions/fnc_dev_drawTrace.sqf b/addons/frag/functions/fnc_dev_drawTrace.sqf index f561d0b5134..72fd7cd4527 100644 --- a/addons/frag/functions/fnc_dev_drawTrace.sqf +++ b/addons/frag/functions/fnc_dev_drawTrace.sqf @@ -23,7 +23,7 @@ private _deleteArr = []; { drawLine3D [_y#1#(_j-1), _y#1#_j, _y#2]; }; - }; + }; } forEach GVAR(dev_trackLines); if (GVAR(drawHitBox)) then { @@ -41,7 +41,7 @@ if (GVAR(drawHitBox)) then { { for "_i" from 1 to count _x -1 do { - drawLine3D [_obj modelToWorld (_pts#(_x#_i)), _obj modelToWorld (_pts#(_x#(_i-1))), _color]; + drawLine3D [_obj modelToWorld (_pts#(_x#_i)), _obj modelToWorld (_pts#(_x#(_i-1))), _color]; }; } forEach HB_DRAW_ARRS; diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf index 40ce58acccb..d95f622d47d 100644 --- a/addons/frag/functions/fnc_dev_fragCalcDump.sqf +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -6,7 +6,7 @@ * * Arguments: * 0: _dispAll - Display rounds that will never frag (power < 5). - * Default value false + * Default value false * 1: _minFrgPowRng - minimum range for sqrt power calculation * * Return Value: @@ -63,8 +63,8 @@ diag_log text "//****************** fragCalcDump Beg ******************//"; if (_gC == 0) then {_gC = 2440;}; private _fragCount = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(fragCount)); if (_fragCount == 0) then {_fragCount = 200; _warn = true}; - - private _velocity = 0.8 * _gC * sqrt (_c /(_m + _c * _k)); + + private _velocity = 0.8 * _gC * sqrt (_c /(_m + _c * _k)); // number of shrapnel to send a direction private _count = ceil (random (sqrt (_m / 1000))); private _fragPowerSpeedRange = [0.5, 1] vectorMultiply _fragPower; diff --git a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf index 0ed7a597988..6c05a13699c 100644 --- a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf +++ b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf @@ -31,13 +31,13 @@ _aID = _cVic addAction [ "Reset Lines", FUNC(dev_clearTraces), - nil, // arguments - 1.5, // priority - true, // showWindow - false, // hideOnUse - "", // shortcut - "true", // condition - 8 + nil, // arguments + 1.5, // priority + true, // showWindow + false, // hideOnUse + "", // shortcut + "true", // condition + 8 ]; missionNamespace getVariable [QGVAR(dev_clearTraceAction), _aID]; \ No newline at end of file diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index c06fa763ae7..0f45ad370d7 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -17,9 +17,9 @@ * Public: No */ params [ - "_obj", - ["_color", "blue", ["blue"]], - ["_isProj", false, [false]] + "_obj", + ["_color", "blue", ["blue"]], + ["_isProj", false, [false]] ]; TRACE_4("devDraw",_this,_obj,_color,_isProj); /// track round on each frame @@ -33,7 +33,7 @@ private _colorArray = switch (toLower _color) do { case "red": {[0.8, 0, 0, 1]}; case "black": {[1, 1, 1, 1]}; case "white": {[0, 0, 0, 1]}; - default {[0, 0.8, 0.8, 1]}; + default {[0, 0.8, 0.8, 1]}; }; GVAR(dev_trackLines) set [getObjectID _obj, [1, [getposATL _obj], _colorArray]]; @@ -93,7 +93,7 @@ _obj addEventHandler [ ]; // Add deflected eventHandler -_proj addEventHandler [ +_obj addEventHandler [ "Deflected", { params ["_proj", "_posASL"]; diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 8316ee268e2..74bd5a17461 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -25,19 +25,19 @@ _args*/ params [ ["_proj", objNull, [objNull]], ["_posASL", [0,0,0], [[]], [3]], ["_vel", [0,0,0] , [[]], [3]], - ["_ammo", "", [""]], - ["_shotParents", [objNull, objNull], [[]]] + ["_ammo", "", [""]], + ["_shotParents", [objNull, objNull], [[]]] ]; private _shotParentVic = _shotParents#0; if (_shotParentVic getVariable [QGVAR(nextFragTime), -1] > CBA_missionTime) exitWith { - TRACE_1("vehicleTimeExit",_shotParentVic); + TRACE_1("vehicleTimeExit",_shotParentVic); }; _shotParentVic setVariable [QGVAR(nextFragTime), CBA_missionTime + ACE_FRAG_HOLDOFF_VEHICLE]; private _timeSince = CBA_missionTime - GVAR(lastFragTime); if (_ammo isEqualTo "" || {_posASL isEqualTo [0,0,0] || _timeSince < ACE_FRAG_HOLDOFF}) exitWith { - TRACE_3("timeExit",_timeSince,CBA_missionTime,GVAR(lastFragTime)); + TRACE_3("timeExit",_timeSince,CBA_missionTime,GVAR(lastFragTime)); }; GVAR(lastFragTime) = CBA_missionTime; private _maxFrags = round (linearConversion [0.1, 1.5, _timeSince, ACE_FRAG_COUNT_MIN, ACE_FRAG_COUNT_MAX, true]); @@ -52,7 +52,6 @@ if (_heightAGL < 0.25) then { _posASL = _posASL vectorAdd [0, 0, 0.25]; }; -// !*! make holdoff a gvar? TRACE_3("fnc_doFragTargeted IF", _fragRange, _timeSince, GVAR(fragSimComplexity)); if (_fragRange > 3 && _timeSince > ACE_FRAG_HOLDOFF*1.5 && GVAR(fragSimComplexity) != 1) then { _maxFrags = _maxFrags - ([_posASL, _fragVel, _fragRange, _maxFrags, _fragTypes, _modFragCount, _shotParents] call FUNC(doFragTargeted)); diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index 8a31bf67871..f095e3fd438 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -39,7 +39,7 @@ private _hMode = switch (true) do { }; private _type = if (count _fragType > 0 && - {"ace_frag_tiny" isEqualTo (_fragType#0)}) then { + {"ace_frag_tiny" isEqualTo (_fragType#0)}) then { QGVAR(def_tiny_) } else { QGVAR(def_small_) @@ -69,6 +69,6 @@ _fragSpawner addEventHandler [ } ]; if (GVAR(dbgSphere)) then { - [_posASL] call FUNC(dev_sphereDraw); + [_posASL] call FUNC(dev_sphereDraw); }; #endif \ No newline at end of file diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index d969ee98c65..f0fa8019ef8 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -53,7 +53,7 @@ if (_objects isEqualTo []) exitWith { // grab crews and add them in so that targets stay approx. sorted by distance { private _crew = (crew _x); - if (count _crew > 1) then { + if (count _crew > 1) then { private _arr = [_x]; { _arr pushBackUnique _x; @@ -158,9 +158,9 @@ private _fragCount = 0; // limit of # of fragments to _maxFrags _fragObj setShotParents _shotPrnt; #ifdef DEBUG_MODE_DRAW [_fragObj, "purple", true] call FUNC(dev_trackObj); - if (GVAR(dbgSphere)) then { - [_targetPos, "orange"] call FUNC(dev_sphereDraw); - }; + if (GVAR(dbgSphere)) then { + [_targetPos, "orange"] call FUNC(dev_sphereDraw); + }; #endif _fragCount = _fragCount + _count; diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index 3c6752ca864..0a6d3150357 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -19,12 +19,12 @@ TRACE_1("",_this); params [ "_projectile", ["_hitObj", objNull], -// "", +// "", ["_lPosASL", [0, 0, 0]], ["_lVel", [0, 0, 0]], ["_sNorm", [0, 0, 0]], -// "", -// "", +// "", +// "", ["_surfaceType", ""], ["_ammo", "", [""]], ["_shotParents", [objNull, objNull], [[]]], @@ -32,9 +32,9 @@ params [ ]; if (CBA_missionTime - GVAR(lastSpallTime) < ACE_FRAG_SPALL_HOLDOFF || - _lPosASL isEqualTo [0,0,0] || - {isNull _hitObj || {_hitObj isKindOf "man" || - {_ammo isEqualTo ""}}}) exitWith { + _lPosASL isEqualTo [0,0,0] || + {isNull _hitObj || {_hitObj isKindOf "man" || + {_ammo isEqualTo ""}}}) exitWith { TRACE_4("time/invldHit",CBA_missionTime,GVAR(lastSpallTime),_hitObj,_lPosASL); }; @@ -53,7 +53,7 @@ private _vel = if (alive _projectile) then { // Find spall speed / fragment private _dV = vectorMagnitude _lVel - vectorMagnitude _vel; -private _caliber = getNumber (configFile >> "cfgAmmo" >> _ammo >> "caliber"); // !*! optimize this later? +private _caliber = getNumber (configFile >> "cfgAmmo" >> _ammo >> "caliber"); // scaled momentum change made on caliber-mass assumption ~sqrt(2)/20 * caliber ~= mass private _deltaMomentum = 0.0707 * _caliber * sqrt( _dV ) * GVAR(SpallIntensity); TRACE_3("found speed",_dV,_caliber,_deltaMomentum); @@ -63,20 +63,19 @@ if (_deltaMomentum < 2) exitWith { }; -//** start calculating where the spalling should come !*! could be better **// private _lVelUnit = vectorNormalized _lVel; private _unitStep = _lVelUnit vectorMultiply 0.05; private _spallPos = +_lPosASL; +if (terrainIntersectASL [_lPosASL vectorAdd _unitStep, _lPosASL]) exitWith { + TRACE_3("terrainIntersect",_lPosASL,_unitStep,_lPosASL); +}; + if (120 > acos ((vectorNormalized _lVelUnit) vectorDotProduct _sNorm)) then { _spallPos = _spallPos vectorAdd (_unitStep vectorMultiply 5); }; -if (terrainIntersectASL [_lPosASL vectorAdd _unitStep, _lPosASL]) exitWith { - TRACE_3("terrainIntersect",_lPosASL,_unitStep,_lPosASL); -}; - //***** Passed all exit withs *****// GVAR(lastSpallTime) = CBA_missionTime; diff --git a/addons/frag/functions/fnc_fired.sqf b/addons/frag/functions/fnc_fired.sqf index d6918a067a5..182ee70c24d 100644 --- a/addons/frag/functions/fnc_fired.sqf +++ b/addons/frag/functions/fnc_fired.sqf @@ -33,7 +33,8 @@ _shouldFrag params ["_doFrag", "_doSubmunit"]; if (_doFrag) then { // wait for frag damage to kill units before spawning fragments - _projectile addEventHandler ["Explode", { + _projectile addEventHandler ["Explode", + { if (isServer) then { [FUNC(doFrag), [_this]] call CBA_fnc_execNextFrame; } else { diff --git a/addons/frag/functions/fnc_getFragInfo.sqf b/addons/frag/functions/fnc_getFragInfo.sqf index 09c82476b66..40b9c9a4fc7 100644 --- a/addons/frag/functions/fnc_getFragInfo.sqf +++ b/addons/frag/functions/fnc_getFragInfo.sqf @@ -9,11 +9,11 @@ * * Return Value: * _ammoInfo - * 0: _fragRange - search range for fragments - * 1: _fragVel - gurney equation calculated velocity - * 2: _fragTypes - array of fragment types - * 3: _fragCount - modified frag count used under assumptions - * of spherical fragmentation + * 0: _fragRange - search range for fragments + * 1: _fragVel - gurney equation calculated velocity + * 2: _fragTypes - array of fragment types + * 3: _fragCount - modified frag count used under assumptions + * of spherical fragmentation * * Example: * ["B_556x45_Ball"] call ace_frag_fnc_getFragInfo; @@ -74,7 +74,7 @@ if (_warn) then { // 1: _fragVel - gurney equation calculated velocity // 2: _fragTypes - array of fragment types // 3: _fragCount - modified frag count used under assumptions -// of spherical fragmentation +// of spherical fragmentation _ammoInfo = [ sqrt (_fragCount / (4 * pi * 0.005)), 0.8 * _gC * sqrt (_c / (_m + _c * _k)), diff --git a/addons/frag/functions/fnc_getMaterialInfo.sqf b/addons/frag/functions/fnc_getMaterialInfo.sqf index b471a5c5730..34d401a1a26 100644 --- a/addons/frag/functions/fnc_getMaterialInfo.sqf +++ b/addons/frag/functions/fnc_getMaterialInfo.sqf @@ -29,11 +29,11 @@ if (isClass (configFile >> "CfgSurfaces" >> _surfType)) then { _material = getText (configFile >> "CfgSurfaces" >> _surfType >> "soundEnviron"); } else { // Messy way when a surface isn't added to cfgSurfaces private _surfFileText = tolower preprocessFile _surfType; - _surfFileText = _surfFileText regexReplace ["[^a-z0-9]", ""]; - private _idx = 12 + (_surfFileText find "soundenviron"); - if (_surfFileText select [_idx, 5] isEqualTo "empty") then { - _idx = 8 + (_surfFileText find "soundhit"); - }; + _surfFileText = _surfFileText regexReplace ["[^a-z0-9]", ""]; + private _idx = 12 + (_surfFileText find "soundenviron"); + if (_surfFileText select [_idx, 5] isEqualTo "empty") then { + _idx = 8 + (_surfFileText find "soundhit"); + }; _material = _surfFileText select [_idx, 10]; }; TRACE_1("materialSubString",_material); @@ -46,7 +46,7 @@ _material = switch (true) do { case ("rock" in _material): { "rock" }; case ("wood" in _material): { "wood" }; case ("lino" in _material); - case ("building" in _material); + case ("building" in _material); case ("concrete" in _material): { "concrete" }; case ("metal" in _material): { "metal" }; default { "ground" }; diff --git a/addons/frag/functions/fnc_shouldFrag.sqf b/addons/frag/functions/fnc_shouldFrag.sqf index 35a85623f37..fbfb32b9f8c 100644 --- a/addons/frag/functions/fnc_shouldFrag.sqf +++ b/addons/frag/functions/fnc_shouldFrag.sqf @@ -9,7 +9,7 @@ * * Return Value: * _shouldFrag - * 0 - Should the specific round fragment + * 0 - Should the specific round fragment * 1 - Does the munition have a child submunition * * Example: diff --git a/addons/frag/initSettings.inc.sqf b/addons/frag/initSettings.inc.sqf index 08b93698022..6d44d8061a4 100644 --- a/addons/frag/initSettings.inc.sqf +++ b/addons/frag/initSettings.inc.sqf @@ -25,7 +25,6 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; 1 ] call CBA_fnc_addSetting; -/// !*! TODO: add stringtable entries [ QGVAR(fragSimComplexity), "LIST", [LSTRING(FragMode), LSTRING(FragMode_Desc)], @@ -33,7 +32,7 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; [_category, LSTRING(Frag)], [[2, 1, 0], [LSTRING(FragMode_Opt2),LSTRING(FragMode_Opt1),LSTRING(FragMode_Opt0)], 2], // [[2, 1, 0], ["Targeted & random fragmentation","Random fragmentation","Unit targeted fragmentation"], 2], - true + true ] call CBA_fnc_addSetting; [ @@ -50,9 +49,9 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; // ["Fragmentation BlackList", "Array of ammo classnames strings to blackist fragmentation for."], [_category, LSTRING(Frag)], QUOTE(['B_556x45_Ball']), - true, - nil, - true + true, + nil, + true ] call CBA_fnc_addSetting; [ @@ -60,5 +59,5 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; [LSTRING(SpallIntensity), LSTRING(SpallIntensity_Desc)], [_category, LSTRING(Spall)], [0.1, 2, 1, 1], - true + true ] call CBA_fnc_addSetting; From a64fff960aaff00faae1803ed1db3b23c89284d1 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 10 Jan 2024 19:02:07 -0600 Subject: [PATCH 053/282] Fixed more comments --- addons/frag/cfgAmmoFragSpawner.hpp | 45 +++++++++++++------ addons/frag/cfgAmmoSpall.hpp | 20 ++++++--- addons/frag/functions/fnc_dev_addRound.sqf | 2 +- addons/frag/functions/fnc_dev_trackObj.sqf | 2 +- addons/frag/functions/fnc_doSpall.sqf | 7 +-- addons/frag/functions/fnc_getFragInfo.sqf | 51 ++++++++++++---------- addons/frag/initSettingsDebug.inc.sqf | 3 -- 7 files changed, 80 insertions(+), 50 deletions(-) diff --git a/addons/frag/cfgAmmoFragSpawner.hpp b/addons/frag/cfgAmmoFragSpawner.hpp index d7dc0be6891..3b6a507603c 100644 --- a/addons/frag/cfgAmmoFragSpawner.hpp +++ b/addons/frag/cfgAmmoFragSpawner.hpp @@ -1,5 +1,3 @@ -// format fragType_spawn_n_range -/********************* ***************************/ class GVAR(spawnbase) : B_65x39_Caseless { access = 2; deleteParentWhenTriggered = 1; @@ -16,7 +14,9 @@ class GVAR(spawnbase) : B_65x39_Caseless { ACE_FRAG_RM_EH; }; -/********************* ***************************/ +/* + * Default frag, spawning 10 fragments + */ class GVAR(def_10) : GVAR(spawnbase) { submunitionConeType[] = {"random", 10}; }; @@ -35,8 +35,9 @@ class GVAR(def_10_top) : GVAR(def_10) { submunitionConeAngle = 60; triggerSpeedCoef[] = {-1.5, -0.75}; }; - -/********************* ***************************/ +/* + * Default frag, spawning 15 fragments + */ class GVAR(def_15) : GVAR(spawnbase) { submunitionConeType[] = {"random", 15}; }; @@ -56,7 +57,9 @@ class GVAR(def_15_top) : GVAR(def_15) { triggerSpeedCoef[] = {-1.5, -0.75}; }; -/********************* ***************************/ +/* + * Default frag, spawning 5 fragments + */ class GVAR(def_5) : GVAR(spawnbase) { submunitionConeType[] = {"random", 5}; }; @@ -76,7 +79,9 @@ class GVAR(def_5_top) : GVAR(def_5) { triggerSpeedCoef[] = {-1.5, -0.75}; }; -/********************* ***************************/ +/* + * Default frag, spawning tiny fragments only + */ class GVAR(def_tiny_15) : GVAR(spawnbase) { submunitionConeType[] = {"random", 15}; submunitionAmmo = QGVAR(tiny); @@ -97,7 +102,9 @@ class GVAR(def_tiny_15_top) : GVAR(def_tiny_15) { triggerSpeedCoef[] = {-1.5, -0.75}; }; -/********************* ***************************/ +/* + * Default frag, spawning 10 tiny fragments only + */ class GVAR(def_tiny_10) : GVAR(spawnbase) { submunitionConeType[] = {"random", 10}; submunitionAmmo = QGVAR(tiny); @@ -118,7 +125,9 @@ class GVAR(def_tiny_10_top) : GVAR(def_tiny_10) { triggerSpeedCoef[] = {-1.5, -0.75}; }; -/********************* ***************************/ +/* + * Default frag, spawning 15 tiny fragments only + */ class GVAR(def_tiny_5) : GVAR(spawnbase) { submunitionConeType[] = {"random", 5}; submunitionAmmo = QGVAR(tiny); @@ -138,7 +147,10 @@ class GVAR(def_tiny_5_top) : GVAR(def_tiny_5) { submunitionConeAngle = 60; triggerSpeedCoef[] = {-1.5, -0.75}; }; -/********************* ***************************/ + +/* + * Default frag, spawning 15 tiny fragments only + */ class GVAR(def_small_15) : GVAR(spawnbase) { submunitionConeType[] = {"random", 15}; submunitionAmmo = QGVAR(small); @@ -158,7 +170,10 @@ class GVAR(def_small_15_top) : GVAR(def_small_15) { submunitionConeAngle = 60; triggerSpeedCoef[] = {-1.15, -0.715}; }; -/********************* ***************************/ + +/* + * Default frag, spawning 10 small fragments only + */ class GVAR(def_small_10) : GVAR(spawnbase) { submunitionConeType[] = {"random", 10}; submunitionAmmo = QGVAR(small); @@ -178,7 +193,9 @@ class GVAR(def_small_10_top) : GVAR(def_small_10) { submunitionConeAngle = 60; triggerSpeedCoef[] = {-1.10, -0.710}; }; -/********************* ***************************/ +/* + * Default frag, spawning small fragments only + */ class GVAR(def_small_5) : GVAR(spawnbase) { submunitionConeType[] = {"random", 5}; submunitionAmmo = QGVAR(small); @@ -199,7 +216,9 @@ class GVAR(def_small_5_top) : GVAR(def_small_5) { triggerSpeedCoef[] = {-1.5, -0.75}; }; -/******************* targeted fragments ********************/ +/* + * Targeted fragment spawner, for when multiple fragments are spawned (1-3) + */ class GVAR(spawnbase_targeted) : GVAR(spawnbase) { access = 2; submunitionConeType[] = {"random", 2}; diff --git a/addons/frag/cfgAmmoSpall.hpp b/addons/frag/cfgAmmoSpall.hpp index 3e51df4a150..21e58347e3d 100644 --- a/addons/frag/cfgAmmoSpall.hpp +++ b/addons/frag/cfgAmmoSpall.hpp @@ -14,7 +14,9 @@ class GVAR(spallBase) : B_65x39_Caseless { }; -//**** ground ****// +/* + * ground + */ class GVAR(ground_spall_tiny) : GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 9, QGVAR(small), 1}; submunitionConeType[] = {"poissondisccenter", 4}; @@ -41,7 +43,9 @@ class GVAR(ground_spall_huge) : GVAR(spallBase) { }; -//**** rock ****// +/* + * rock + */ class GVAR(rock_spall_tiny) : GVAR(spallBase) { submunitionAmmo[] = {QGVAR(small), 4, QGVAR(medium_HD), 1}; submunitionConeType[] = {"poissondisccenter", 4}; @@ -68,7 +72,9 @@ class GVAR(rock_spall_huge) : GVAR(spallBase) { }; -//**** wood ****// +/* + * wood + */ class GVAR(wood_spall_tiny) : GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 2, QGVAR(small), 4}; submunitionConeType[] = {"poissondisccenter", 4}; @@ -95,7 +101,9 @@ class GVAR(wood_spall_huge) : GVAR(spallBase) { }; -//**** concrete ****// +/* + * concrete + */ class GVAR(concrete_spall_tiny) : GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 6, QGVAR(tiny_HD), 3, QGVAR(small), 1}; submunitionConeType[] = {"poissondisccenter", 4}; @@ -122,7 +130,9 @@ class GVAR(concrete_spall_huge) : GVAR(spallBase) { }; -//**** metal ****// +/* + * metal + */ class GVAR(metal_spall_tiny) : GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 9, QGVAR(small), 1}; submunitionConeType[] = {"poissondisccenter", 4}; diff --git a/addons/frag/functions/fnc_dev_addRound.sqf b/addons/frag/functions/fnc_dev_addRound.sqf index 483ac8cfae0..332f2e8dc3f 100644 --- a/addons/frag/functions/fnc_dev_addRound.sqf +++ b/addons/frag/functions/fnc_dev_addRound.sqf @@ -22,7 +22,7 @@ params [ ["_sidePlayer", true, [true]] ]; -/// track round on each frame +// track round on each frame // Create entry in position array from hashmap if (_sidePlayer) then { diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index 0f45ad370d7..34f927dd983 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -22,7 +22,7 @@ params [ ["_isProj", false, [false]] ]; TRACE_4("devDraw",_this,_obj,_color,_isProj); -/// track round on each frame +// track round on each frame // Create entry in position array from hashmap private _colorArray = switch (toLower _color) do { case "purple": {[0.8, 0, 0.8, 1]}; diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index 0a6d3150357..da9624da770 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -76,7 +76,7 @@ if (120 > acos ((vectorNormalized _lVelUnit) vectorDotProduct _sNorm)) then { _spallPos = _spallPos vectorAdd (_unitStep vectorMultiply 5); }; -//***** Passed all exit withs *****// +// Passed all exit withs GVAR(lastSpallTime) = CBA_missionTime; // step through @@ -97,7 +97,8 @@ if GVAR(dbgSphere) then { [_lPosASL, "orange"] call FUNC(dev_sphereDraw); }; #endif -//***** Select spalled fragment spawner **// + +// Select spalled fragment spawner private _spawnSize = switch (true) do { @@ -108,7 +109,7 @@ private _spawnSize = switch (true) do default { "_spall_huge" }; }; -//***** Spawn spalled fragments +// Spawn spalled fragments private _spallSpawner = createVehicle [ "ace_frag_" + _material + _spawnSize, ASLToATL _spallPos, diff --git a/addons/frag/functions/fnc_getFragInfo.sqf b/addons/frag/functions/fnc_getFragInfo.sqf index 40b9c9a4fc7..d34da541551 100644 --- a/addons/frag/functions/fnc_getFragInfo.sqf +++ b/addons/frag/functions/fnc_getFragInfo.sqf @@ -35,24 +35,25 @@ if (isArray (configFile >> "cfgAmmo" >> _ammo >> QGVAR(CLASSES))) then { _warn = true; }; -/************ Gurney equation notes *****************/ -// see https://en.wikipedia.org/wiki/Gurney_equations -// -// GURNEY_K is the constant added to _m/_c -// GURNEY_C = sqrt(2E) -// -// _c = 185; // grams of comp-b -// _m = 210; // grams of fragmentating metal -// _k = 3/5; // spherical K factor -// _gC = 2843; // Gurney constant of comp-b in /ms - -// _c = 429; // grams of tritonal -// _m = 496; // grams of fragmentating metal -// _k = 1/2; // cylindrical K factor -// _gC = 2320; // Gurney constant of tritonal in m/s -// Equation - 0.8 for empirical 80% speed -// 0.8 * (((_m / _c) + _k) ^ - (1 / 2)) * _gC; -// or 0.8 * _gC * sqrt (_c /(_m + _c * _k)); (slightly faster to compute) +/************ Gurney equation notes *****************//* + * see https://en.wikipedia.org/wiki/Gurney_equations + * + * GURNEY_K is the constant added to _m/_c + * GURNEY_C = sqrt(2E) + * + * _c = 185; - grams of comp-b + * _m = 210; - grams of fragmentating metal + * _k = 3/5; - spherical K factor + * _gC = 2843; - Gurney constant of comp-b in /ms + * + * _c = 429; - grams of tritonal + * _m = 496; - grams of fragmentating metal + * _k = 1/2; - cylindrical K factor + * _gC = 2320; - Gurney constant of tritonal in m/s + * Equation - 0.8 for empirical 80% speed + * 0.8 * (((_m / _c) + _k) ^ - (1 / 2)) * _gC; + * or 0.8 * _gC * sqrt (_c /(_m + _c * _k)); (slightly faster to compute) + */ private _c = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(CHARGE)); if (_c == 0) then {_c = 1; _warn = true;}; @@ -69,12 +70,14 @@ if (_warn) then { INFO_1("Ammo class %1 lacks proper explosive properties definitions for frag!",_ammo); }; -/********************** _ammoInfo format *************************/ -// 0: _fragRange - search range for fragments -// 1: _fragVel - gurney equation calculated velocity -// 2: _fragTypes - array of fragment types -// 3: _fragCount - modified frag count used under assumptions -// of spherical fragmentation +/********************** _ammoInfo format *************************//* + * 0: _fragRange - search range for fragments, calculated with + * a 0.5% chance to hit as the minimum + * 1: _fragVel - gurney equation calculated velocity + * 2: _fragTypes - array of fragment types + * 3: _fragCount - modified frag count used under assumptions + * of spherical fragmentation + */ _ammoInfo = [ sqrt (_fragCount / (4 * pi * 0.005)), 0.8 * _gC * sqrt (_c / (_m + _c * _k)), diff --git a/addons/frag/initSettingsDebug.inc.sqf b/addons/frag/initSettingsDebug.inc.sqf index 382d3ac4b2f..09072683af4 100644 --- a/addons/frag/initSettingsDebug.inc.sqf +++ b/addons/frag/initSettingsDebug.inc.sqf @@ -7,11 +7,9 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; true ] call CBA_fnc_addSetting; -//*** debug options ***// [ QGVAR(dbgSphere), "CHECKBOX", [LSTRING(HitSphereEnable), LSTRING(HitSphereEnable_Desc)], -// "Create color coded spheres at ", [_category, LSTRING(Debug)], false, 0, @@ -22,7 +20,6 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; [ QGVAR(drawHitBox),"CHECKBOX", [LSTRING(DrawHitBox), LSTRING(DrawHitBox_Desc)], -// ["Draw unit hitboxes", "Draw added hitboxes each frame"], [_category, LSTRING(Debug)], true ] call CBA_fnc_addSetting; \ No newline at end of file From a079f61ded00ee3a309b98ed589690db3a85d8d2 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 10 Jan 2024 19:25:17 -0600 Subject: [PATCH 054/282] reveretd gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9e50c11cbd7..8a7e6945a63 100644 --- a/.gitignore +++ b/.gitignore @@ -19,4 +19,4 @@ Thumbs.db CHANGELOG.md sqfvm.exe ArmaScriptCompiler.exe -*.sqfc \ No newline at end of file +*.sqfc From 3e3ed12503ed1f8e6110164642248c4db5f76c87 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 10 Jan 2024 19:47:05 -0600 Subject: [PATCH 055/282] Final submunition code cull --- addons/frag/XEH_PREP.hpp | 2 - addons/frag/functions/fnc_doFrag.sqf | 3 +- addons/frag/functions/fnc_doSpall.sqf | 14 ++--- addons/frag/functions/fnc_fired.sqf | 64 ----------------------- addons/frag/functions/fnc_initRound.sqf | 5 +- addons/frag/functions/fnc_shouldFrag.sqf | 22 ++------ addons/frag/functions/fnc_submunition.sqf | 40 -------------- addons/frag/initSettings.inc.sqf | 4 -- 8 files changed, 9 insertions(+), 145 deletions(-) delete mode 100644 addons/frag/functions/fnc_fired.sqf delete mode 100644 addons/frag/functions/fnc_submunition.sqf diff --git a/addons/frag/XEH_PREP.hpp b/addons/frag/XEH_PREP.hpp index 339cbff61c9..326ccc82a52 100644 --- a/addons/frag/XEH_PREP.hpp +++ b/addons/frag/XEH_PREP.hpp @@ -11,13 +11,11 @@ PREP(dev_clearTraces); PREP(dev_switchUnitHandle); // Base -PREP(fired); PREP(initRound); // Frag PREP(addBlackList); PREP(initBlackList); -PREP(submunition); PREP(shouldFrag); PREP(getFragInfo); PREP(doFrag); diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 74bd5a17461..5b6d5b5d4de 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -20,8 +20,7 @@ * Public: No */ TRACE_1("",_this); -/*params ["_args", ["_isSubMunit", false, [false]]]; -_args*/ params [ +params [ ["_proj", objNull, [objNull]], ["_posASL", [0,0,0], [[]], [3]], ["_vel", [0,0,0] , [[]], [3]], diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index da9624da770..5a30c0bb742 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -19,12 +19,9 @@ TRACE_1("",_this); params [ "_projectile", ["_hitObj", objNull], -// "", ["_lPosASL", [0, 0, 0]], ["_lVel", [0, 0, 0]], ["_sNorm", [0, 0, 0]], -// "", -// "", ["_surfaceType", ""], ["_ammo", "", [""]], ["_shotParents", [objNull, objNull], [[]]], @@ -70,16 +67,14 @@ private _spallPos = +_lPosASL; if (terrainIntersectASL [_lPosASL vectorAdd _unitStep, _lPosASL]) exitWith { TRACE_3("terrainIntersect",_lPosASL,_unitStep,_lPosASL); }; - +// Passed all exitWiths +GVAR(lastSpallTime) = CBA_missionTime; +// check for less than 30 between norm and projectile (120 of 90 deg offset) if (120 > acos ((vectorNormalized _lVelUnit) vectorDotProduct _sNorm)) then { _spallPos = _spallPos vectorAdd (_unitStep vectorMultiply 5); }; -// Passed all exit withs -GVAR(lastSpallTime) = CBA_missionTime; - -// step through for "_i" from 1 to 20 do { private _nPos = _spallPos vectorAdd _unitStep; @@ -98,8 +93,6 @@ if GVAR(dbgSphere) then { }; #endif -// Select spalled fragment spawner - private _spawnSize = switch (true) do { case (_deltaMomentum < 3): { "_spall_tiny" }; @@ -109,7 +102,6 @@ private _spawnSize = switch (true) do default { "_spall_huge" }; }; -// Spawn spalled fragments private _spallSpawner = createVehicle [ "ace_frag_" + _material + _spawnSize, ASLToATL _spallPos, diff --git a/addons/frag/functions/fnc_fired.sqf b/addons/frag/functions/fnc_fired.sqf deleted file mode 100644 index 182ee70c24d..00000000000 --- a/addons/frag/functions/fnc_fired.sqf +++ /dev/null @@ -1,64 +0,0 @@ -#include "script_component.hpp" -/* - * Author: nou, jaynus, PabstMirror, Lambda.Tiger - * Called from the unified fired EH for all. - * If spall is not enabled (default), then cache and only track those that will actually trigger fragmentation. - * - * Arguments: - * None. Parameters inherited from EFUNC(common,firedEH) - * - * Return Value: - * None - * - * Example: - * [clientFiredBIS-XEH] call ace_frag_fnc_fired - * - * Public: No - */ - -//IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; - -if (isNil "_ammo" || - {_ammo isEqualTo "" || - {isNil "_projectile" || - {isNull _projectile}}}) exitWith { - TRACE_2("bad ammo or projectile",_projectile,_ammo); -}; - -/******* _shouldFrag format *****/ -// 0: doFragmnent - will the piece fragment -// 1: hasSubmuntion - will the round create submunitions -private _shouldFrag = _ammo call FUNC(shouldFrag); -_shouldFrag params ["_doFrag", "_doSubmunit"]; - -if (_doFrag) then { - // wait for frag damage to kill units before spawning fragments - _projectile addEventHandler ["Explode", - { - if (isServer) then { - [FUNC(doFrag), [_this]] call CBA_fnc_execNextFrame; - } else { - [QGVAR(frag_eh), [_this]] call CBA_fnc_serverEvent; - }; - } - ]; -}; - -if (_doSubmunit && {GVAR(fragSimComplexity)> 0}) then { - _projectile addEventHandler ["SubmunitionCreated", {_this call FUNC(submunition)}]; -}; - -private _shouldSpall = _ammo call FUNC(shouldSpall); - -if (GVAR(spallEnabled) && {_shouldSpall}) then -{_projectile addEventHandler [ - "HitPart", - { - if (isServer) then { - [LINKFUNC(doSpall), _this] call CBA_fnc_execNextFrame; - } else { - [QGVAR(spall_eh), [_this]] call CBA_fnc_serverEvent; - }; - } - ]; -}; \ No newline at end of file diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index 37be4c00242..14502036c51 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -24,16 +24,14 @@ if (_ammo isEqualTo "" || {isNull _projectile}) exitWith { }; private _shouldFrag = _ammo call FUNC(shouldFrag); -_shouldFrag params ["_doFrag"]; - if (_doFrag) then { - // wait for frag damage to kill units before spawning fragments _projectile addEventHandler [ "Explode", { params ["_proj"]; private _shotParents = getShotParents _proj; private _ammo = typeOf _proj; + // wait for frag damage to kill units before spawning fragments if (isServer) then { [ FUNC(doFrag), @@ -51,7 +49,6 @@ if (_doFrag) then { private _shouldSpall = _ammo call FUNC(shouldSpall); - if (GVAR(spallEnabled) && {_shouldSpall}) then { _projectile addEventHandler [ diff --git a/addons/frag/functions/fnc_shouldFrag.sqf b/addons/frag/functions/fnc_shouldFrag.sqf index fbfb32b9f8c..1a5a92c119d 100644 --- a/addons/frag/functions/fnc_shouldFrag.sqf +++ b/addons/frag/functions/fnc_shouldFrag.sqf @@ -8,9 +8,7 @@ * 0: _ammo - cfgAmmo type of ammo to check * * Return Value: - * _shouldFrag - * 0 - Should the specific round fragment - * 1 - Does the munition have a child submunition + * _shouldFrag Should the specific round fragment * * Example: * ["B_556x45_Ball"] call ace_frag_fnc_shouldFrag; @@ -23,8 +21,8 @@ params ["_ammo"]; private _shouldFrag = GVAR(shouldFragCache) get _ammo; if !(isNil "_shouldFrag") exitWith {_shouldFrag}; -// two arguments, 1st for munition should frag, 2nd for -_shouldFrag = [true, false]; + +_shouldFrag = true; private _skip = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(skip)); private _force = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(force)); @@ -35,21 +33,9 @@ private _indirectRange = getNumber(configFile >> "cfgAmmo" >> _ammo >> "indirect if (_skip == 1 || (_force == 0 && {_explosive < 0.5 || {_indirectHit < 3 || {_indirectRange < 5 && _indirectHit < _indirectRange}}})) then { TRACE_5("No frag",_ammo,_skip, _explosive, _indirectRange, _indirectHit); - _shouldFrag set [0, false]; + _shouldFrag = false; }; -/*if (GVAR(fragSimComplexity) > 1) then { - private _hasSubmunit = if (isText (configFile >> "cfgAmmo" >> _ammo >> "submunitionAmmo")) then { - "" isNotEqualTo getText (configFile >> "cfgAmmo" >> _ammo >> "submunitionAmmo"); - } else - { - [] isNotEqualTo getArray (configFile >> "cfgAmmo" >> _ammo >> "submunitionAmmo"); - }; - - _shouldFrag set [1, _hasSubmunit]; - TRACE_2("Submunition" ,_ammo, _hasSubmunit); -};*/ - GVAR(shouldFragCache) set [_ammo, _shouldFrag]; _shouldFrag \ No newline at end of file diff --git a/addons/frag/functions/fnc_submunition.sqf b/addons/frag/functions/fnc_submunition.sqf deleted file mode 100644 index ed046151e38..00000000000 --- a/addons/frag/functions/fnc_submunition.sqf +++ /dev/null @@ -1,40 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Lambda.Tiger - * This function adds event handlers for submunition fragmentation. - * It begins by confirming fragmentation and submunition fragmentation is - * enabled, requests cached (or live calculated) ammo information array. - * and uses that information to add event handlers as needed to the given - * submunition. - * - * Arguments: - * Inherits from BI SubmunitionCraeted EH - * - * Return Value: - * none - * - * Example: - * ["", _submunitionProjectile] call ace_frag_submunition - * - * Public: No - */ - -if !GVAR(enabled) exitWith {}; -// params ["_projectile", "_submunitionProjectile", "_pos", "_velocity"]; -params ["", "_submunitionProjectile"]; - -private _shouldFrag = GVAR(shouldFragCache) getOrDefaultCall [typeOf _submunitionProjectile, FUNC(shouldFrag), true]; -_shouldFrag params ["_doFrag", "_doSubmunit"]; - - -if (_doFrag) then { - _submunitionProjectile addEventHandler ["Explode", {[_this, true] call FUNC(doFrag)}]; -}; - -if (_doSubmunit) then { - _submunitionProjectile addEventHandler ["SubmunitionCreated", {_this call FUNC(submunition)}]; -}; - -#ifdef DEBUG_MODE_DRAW - [_submunitionProjectile] call FUNC(dev_addRound); -#endif \ No newline at end of file diff --git a/addons/frag/initSettings.inc.sqf b/addons/frag/initSettings.inc.sqf index 6d44d8061a4..29841cae577 100644 --- a/addons/frag/initSettings.inc.sqf +++ b/addons/frag/initSettings.inc.sqf @@ -28,17 +28,14 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; [ QGVAR(fragSimComplexity), "LIST", [LSTRING(FragMode), LSTRING(FragMode_Desc)], -// ["Fragmentation mode", "Sets how fragments are generated"], [_category, LSTRING(Frag)], [[2, 1, 0], [LSTRING(FragMode_Opt2),LSTRING(FragMode_Opt1),LSTRING(FragMode_Opt0)], 2], -// [[2, 1, 0], ["Targeted & random fragmentation","Random fragmentation","Unit targeted fragmentation"], 2], true ] call CBA_fnc_addSetting; [ QGVAR(atLeastOne), "CHECKBOX", [LSTRING(MinFrag), LSTRING(MinFrag_Desc)], -// ["At least one round hit", "Spawn at least one fragment for units in fragmentation range, up to maximum fragments"], [_category, LSTRING(Frag)], true ] call CBA_fnc_addSetting; @@ -46,7 +43,6 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; [ QGVAR(BlackList), "EDITBOX", [LSTRING(DefBlackList), LSTRING(DefBlackList_Desc)], -// ["Fragmentation BlackList", "Array of ammo classnames strings to blackist fragmentation for."], [_category, LSTRING(Frag)], QUOTE(['B_556x45_Ball']), true, From 5e46c8d1efc59aff579e4af38b499e5b0c5f11e0 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 10 Jan 2024 20:19:05 -0600 Subject: [PATCH 056/282] fixing PBO project gripe --- addons/frag/cfgAmmoFragSpawner.hpp | 2 -- addons/frag/cfgAmmoSpall.hpp | 1 - 2 files changed, 3 deletions(-) diff --git a/addons/frag/cfgAmmoFragSpawner.hpp b/addons/frag/cfgAmmoFragSpawner.hpp index 3b6a507603c..2a00068da1f 100644 --- a/addons/frag/cfgAmmoFragSpawner.hpp +++ b/addons/frag/cfgAmmoFragSpawner.hpp @@ -1,5 +1,4 @@ class GVAR(spawnbase) : B_65x39_Caseless { - access = 2; deleteParentWhenTriggered = 1; submunitionConeType[] = {"random", 25}; submunitionAmmo[] = {QGVAR(tiny), 3, QGVAR(tiny_HD), 3, QGVAR(small), 4, QGVAR(small_HD), 4, QGVAR(medium_HD), 5}; @@ -220,7 +219,6 @@ class GVAR(def_small_5_top) : GVAR(def_small_5) { * Targeted fragment spawner, for when multiple fragments are spawned (1-3) */ class GVAR(spawnbase_targeted) : GVAR(spawnbase) { - access = 2; submunitionConeType[] = {"random", 2}; submunitionConeAngle = 2; submunitionInitSpeed = 0; diff --git a/addons/frag/cfgAmmoSpall.hpp b/addons/frag/cfgAmmoSpall.hpp index 21e58347e3d..f38fca70b70 100644 --- a/addons/frag/cfgAmmoSpall.hpp +++ b/addons/frag/cfgAmmoSpall.hpp @@ -1,5 +1,4 @@ class GVAR(spallBase) : B_65x39_Caseless { - access = 3; submunitionAmmo[] = {QGVAR(small),4,QGVAR(medium),3,QGVAR(large),2,QGVAR(huge),1}; submunitionConeType[] = {"random", 20}; submunitionConeAngle = 40; From 8ec812b97d03881ee00885bf8f2c7556163936e0 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 10 Jan 2024 20:32:07 -0600 Subject: [PATCH 057/282] Fixed config spacing and multiple defines of classes --- addons/frag/CfgAmmo.hpp | 5 + addons/frag/cfgAmmoBaseEH.hpp | 13 +- addons/frag/cfgAmmoFragParameters.hpp | 10 +- addons/frag/cfgAmmoFragSpawner.hpp | 214 +++++++++++++------------- addons/frag/cfgAmmoSpall.hpp | 52 +++---- 5 files changed, 143 insertions(+), 151 deletions(-) diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index 911e18cb309..4e1f621e43f 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -4,6 +4,11 @@ #define ACE_FRAG_RM_EH class EventHandlers {\ delete ADDON;\ } +#define ACE_FRAG_ADD_EH class EventHandlers {\ + class ADDON {\ + init = QUOTE(_this call FUNC(initRound););\ + };\ +} class CfgAmmo { class B_65x39_Caseless; diff --git a/addons/frag/cfgAmmoBaseEH.hpp b/addons/frag/cfgAmmoBaseEH.hpp index b8a1596af64..a889faf4961 100644 --- a/addons/frag/cfgAmmoBaseEH.hpp +++ b/addons/frag/cfgAmmoBaseEH.hpp @@ -1,9 +1,3 @@ -#define ACE_FRAG_ADD_EH class EventHandlers {\ - class ADDON {\ - init = QUOTE(_this call FUNC(initRound););\ - };\ -} - class BombCore; class Bo_Mk82: BombCore { ACE_FRAG_ADD_EH; @@ -13,12 +7,7 @@ class Bo_Mk82: BombCore { class BulletCore; class BulletBase: BulletCore { ACE_FRAG_ADD_EH; -}; - -class Grenade; -class GrenadeHand: Grenade { - ACE_FRAG_ADD_EH; -}; +} class GrenadeCore; class GrenadeBase: GrenadeCore { diff --git a/addons/frag/cfgAmmoFragParameters.hpp b/addons/frag/cfgAmmoFragParameters.hpp index 87f93d174b2..7430aa7b86d 100644 --- a/addons/frag/cfgAmmoFragParameters.hpp +++ b/addons/frag/cfgAmmoFragParameters.hpp @@ -1,6 +1,5 @@ // ~~~~ Bombs: -class ammo_Bomb_LaserGuidedBase; class Bo_GBU12_LGB: ammo_Bomb_LaserGuidedBase { GVAR(enabled) = 1; @@ -21,7 +20,7 @@ class Bomb_04_F: ammo_Bomb_LaserGuidedBase { GVAR(gurney_c) = 2320; GVAR(gurney_k) = "1/2"; }; -class BombCore; + class Bo_Mk82: BombCore { GVAR(enabled) = 1; @@ -34,9 +33,10 @@ class Bo_Mk82: BombCore { }; // ~~~~ Grenades: -class GrenadeBase; class Grenade; class GrenadeHand: Grenade { + ACE_FRAG_ADD_EH; + GVAR(enabled) = 1; GVAR(skip) = 0; @@ -97,7 +97,6 @@ class ACE_G40mm_HE_VOG25P: G_40mm_HE { // ~~~~ RPGs: -class MissileBase; class R_PG32V_F; class R_TBG32V_F: R_PG32V_F { // Thermobaric GVAR(enabled) = 1; @@ -152,7 +151,7 @@ class M_AT: M_PG_AT { // DAR (Hydra 70) GVAR(gurney_c) = 2700; GVAR(gurney_k) = "1/2"; }; -class RocketBase; + class R_80mm_HE: RocketBase { GVAR(skip) = 1; }; @@ -204,7 +203,6 @@ class Missile_AA_04_F: MissileBase { }; // curator ammo entries -class ShellBase; class Sh_125mm_HEAT; class Sh_155mm_AMOS: ShellBase { // Source: http://www.globalsecurity.org/military/systems/munitions/m795.htm diff --git a/addons/frag/cfgAmmoFragSpawner.hpp b/addons/frag/cfgAmmoFragSpawner.hpp index 2a00068da1f..81263d6cc82 100644 --- a/addons/frag/cfgAmmoFragSpawner.hpp +++ b/addons/frag/cfgAmmoFragSpawner.hpp @@ -1,4 +1,4 @@ -class GVAR(spawnbase) : B_65x39_Caseless { +class GVAR(spawnbase): B_65x39_Caseless { deleteParentWhenTriggered = 1; submunitionConeType[] = {"random", 25}; submunitionAmmo[] = {QGVAR(tiny), 3, QGVAR(tiny_HD), 3, QGVAR(small), 4, QGVAR(small_HD), 4, QGVAR(medium_HD), 5}; @@ -16,42 +16,42 @@ class GVAR(spawnbase) : B_65x39_Caseless { /* * Default frag, spawning 10 fragments */ -class GVAR(def_10) : GVAR(spawnbase) { +class GVAR(def_10): GVAR(spawnbase) { submunitionConeType[] = {"random", 10}; }; -class GVAR(def_10_lo) : GVAR(def_10) { +class GVAR(def_10_lo): GVAR(def_10) { submunitionConeAngle = 85; }; -class GVAR(def_10_mid) : GVAR(def_10) { +class GVAR(def_10_mid): GVAR(def_10) { submunitionConeAngle = 85; triggerSpeedCoef[] = {-1.5, 1.5}; }; -class GVAR(def_10_hi) : GVAR(def_10) { +class GVAR(def_10_hi): GVAR(def_10) { submunitionConeAngle = 80; triggerSpeedCoef[] = {-1.5, -0.75}; }; -class GVAR(def_10_top) : GVAR(def_10) { +class GVAR(def_10_top): GVAR(def_10) { submunitionConeAngle = 60; triggerSpeedCoef[] = {-1.5, -0.75}; }; /* * Default frag, spawning 15 fragments */ -class GVAR(def_15) : GVAR(spawnbase) { +class GVAR(def_15): GVAR(spawnbase) { submunitionConeType[] = {"random", 15}; }; -class GVAR(def_15_lo) : GVAR(def_15) { +class GVAR(def_15_lo): GVAR(def_15) { submunitionConeAngle = 85; }; -class GVAR(def_15_mid) : GVAR(def_15) { +class GVAR(def_15_mid): GVAR(def_15) { submunitionConeAngle = 85; triggerSpeedCoef[] = {-1.5, 1.5}; }; -class GVAR(def_15_hi) : GVAR(def_15) { +class GVAR(def_15_hi): GVAR(def_15) { submunitionConeAngle = 80; triggerSpeedCoef[] = {-1.5, -0.75}; }; -class GVAR(def_15_top) : GVAR(def_15) { +class GVAR(def_15_top): GVAR(def_15) { submunitionConeAngle = 60; triggerSpeedCoef[] = {-1.5, -0.75}; }; @@ -59,21 +59,21 @@ class GVAR(def_15_top) : GVAR(def_15) { /* * Default frag, spawning 5 fragments */ -class GVAR(def_5) : GVAR(spawnbase) { +class GVAR(def_5): GVAR(spawnbase) { submunitionConeType[] = {"random", 5}; }; -class GVAR(def_5_lo) : GVAR(def_5) { +class GVAR(def_5_lo): GVAR(def_5) { submunitionConeAngle = 85; }; -class GVAR(def_5_mid) : GVAR(def_5) { +class GVAR(def_5_mid): GVAR(def_5) { submunitionConeAngle = 85; triggerSpeedCoef[] = {-1.5, 1.5}; }; -class GVAR(def_5_hi) : GVAR(def_5) { +class GVAR(def_5_hi): GVAR(def_5) { submunitionConeAngle = 80; triggerSpeedCoef[] = {-1.5, -0.75}; }; -class GVAR(def_5_top) : GVAR(def_5) { +class GVAR(def_5_top): GVAR(def_5) { submunitionConeAngle = 60; triggerSpeedCoef[] = {-1.5, -0.75}; }; @@ -81,22 +81,22 @@ class GVAR(def_5_top) : GVAR(def_5) { /* * Default frag, spawning tiny fragments only */ -class GVAR(def_tiny_15) : GVAR(spawnbase) { +class GVAR(def_tiny_15): GVAR(spawnbase) { submunitionConeType[] = {"random", 15}; submunitionAmmo = QGVAR(tiny); }; -class GVAR(def_tiny_15_lo) : GVAR(def_tiny_15) { +class GVAR(def_tiny_15_lo): GVAR(def_tiny_15) { submunitionConeAngle = 85; }; -class GVAR(def_tiny_15_mid) : GVAR(def_tiny_15) { +class GVAR(def_tiny_15_mid): GVAR(def_tiny_15) { submunitionConeAngle = 85; triggerSpeedCoef[] = {-1.5, 1.5}; }; -class GVAR(def_tiny_15_hi) : GVAR(def_tiny_15) { +class GVAR(def_tiny_15_hi): GVAR(def_tiny_15) { submunitionConeAngle = 80; triggerSpeedCoef[] = {-1.5, -0.75}; }; -class GVAR(def_tiny_15_top) : GVAR(def_tiny_15) { +class GVAR(def_tiny_15_top): GVAR(def_tiny_15) { submunitionConeAngle = 60; triggerSpeedCoef[] = {-1.5, -0.75}; }; @@ -104,22 +104,22 @@ class GVAR(def_tiny_15_top) : GVAR(def_tiny_15) { /* * Default frag, spawning 10 tiny fragments only */ -class GVAR(def_tiny_10) : GVAR(spawnbase) { +class GVAR(def_tiny_10): GVAR(spawnbase) { submunitionConeType[] = {"random", 10}; submunitionAmmo = QGVAR(tiny); }; -class GVAR(def_tiny_10_lo) : GVAR(def_tiny_10) { +class GVAR(def_tiny_10_lo): GVAR(def_tiny_10) { submunitionConeAngle = 85; }; -class GVAR(def_tiny_10_mid) : GVAR(def_tiny_10) { +class GVAR(def_tiny_10_mid): GVAR(def_tiny_10) { submunitionConeAngle = 85; triggerSpeedCoef[] = {-1.5, 1.5}; }; -class GVAR(def_tiny_10_hi) : GVAR(def_tiny_10) { +class GVAR(def_tiny_10_hi): GVAR(def_tiny_10) { submunitionConeAngle = 80; triggerSpeedCoef[] = {-1.5, -0.75}; }; -class GVAR(def_tiny_10_top) : GVAR(def_tiny_10) { +class GVAR(def_tiny_10_top): GVAR(def_tiny_10) { submunitionConeAngle = 60; triggerSpeedCoef[] = {-1.5, -0.75}; }; @@ -127,22 +127,22 @@ class GVAR(def_tiny_10_top) : GVAR(def_tiny_10) { /* * Default frag, spawning 15 tiny fragments only */ -class GVAR(def_tiny_5) : GVAR(spawnbase) { +class GVAR(def_tiny_5): GVAR(spawnbase) { submunitionConeType[] = {"random", 5}; submunitionAmmo = QGVAR(tiny); }; -class GVAR(def_tiny_5_lo) : GVAR(def_tiny_5) { +class GVAR(def_tiny_5_lo): GVAR(def_tiny_5) { submunitionConeAngle = 85; }; -class GVAR(def_tiny_5_mid) : GVAR(def_tiny_5) { +class GVAR(def_tiny_5_mid): GVAR(def_tiny_5) { submunitionConeAngle = 85; triggerSpeedCoef[] = {-1.5, 1.5}; }; -class GVAR(def_tiny_5_hi) : GVAR(def_tiny_5) { +class GVAR(def_tiny_5_hi): GVAR(def_tiny_5) { submunitionConeAngle = 80; triggerSpeedCoef[] = {-1.5, -0.75}; }; -class GVAR(def_tiny_5_top) : GVAR(def_tiny_5) { +class GVAR(def_tiny_5_top): GVAR(def_tiny_5) { submunitionConeAngle = 60; triggerSpeedCoef[] = {-1.5, -0.75}; }; @@ -150,22 +150,22 @@ class GVAR(def_tiny_5_top) : GVAR(def_tiny_5) { /* * Default frag, spawning 15 tiny fragments only */ -class GVAR(def_small_15) : GVAR(spawnbase) { +class GVAR(def_small_15): GVAR(spawnbase) { submunitionConeType[] = {"random", 15}; submunitionAmmo = QGVAR(small); }; -class GVAR(def_small_15_lo) : GVAR(def_small_15) { +class GVAR(def_small_15_lo): GVAR(def_small_15) { submunitionConeAngle = 815; }; -class GVAR(def_small_15_mid) : GVAR(def_small_15) { +class GVAR(def_small_15_mid): GVAR(def_small_15) { submunitionConeAngle = 815; triggerSpeedCoef[] = {-1.15, 1.15}; }; -class GVAR(def_small_15_hi) : GVAR(def_small_15) { +class GVAR(def_small_15_hi): GVAR(def_small_15) { submunitionConeAngle = 80; triggerSpeedCoef[] = {-1.15, -0.715}; }; -class GVAR(def_small_15_top) : GVAR(def_small_15) { +class GVAR(def_small_15_top): GVAR(def_small_15) { submunitionConeAngle = 60; triggerSpeedCoef[] = {-1.15, -0.715}; }; @@ -173,44 +173,44 @@ class GVAR(def_small_15_top) : GVAR(def_small_15) { /* * Default frag, spawning 10 small fragments only */ -class GVAR(def_small_10) : GVAR(spawnbase) { +class GVAR(def_small_10): GVAR(spawnbase) { submunitionConeType[] = {"random", 10}; submunitionAmmo = QGVAR(small); }; -class GVAR(def_small_10_lo) : GVAR(def_small_10) { +class GVAR(def_small_10_lo): GVAR(def_small_10) { submunitionConeAngle = 810; }; -class GVAR(def_small_10_mid) : GVAR(def_small_10) { +class GVAR(def_small_10_mid): GVAR(def_small_10) { submunitionConeAngle = 810; triggerSpeedCoef[] = {-1.10, 1.10}; }; -class GVAR(def_small_10_hi) : GVAR(def_small_10) { +class GVAR(def_small_10_hi): GVAR(def_small_10) { submunitionConeAngle = 80; triggerSpeedCoef[] = {-1.10, -0.710}; }; -class GVAR(def_small_10_top) : GVAR(def_small_10) { +class GVAR(def_small_10_top): GVAR(def_small_10) { submunitionConeAngle = 60; triggerSpeedCoef[] = {-1.10, -0.710}; }; /* * Default frag, spawning small fragments only */ -class GVAR(def_small_5) : GVAR(spawnbase) { +class GVAR(def_small_5): GVAR(spawnbase) { submunitionConeType[] = {"random", 5}; submunitionAmmo = QGVAR(small); }; -class GVAR(def_small_5_lo) : GVAR(def_small_5) { +class GVAR(def_small_5_lo): GVAR(def_small_5) { submunitionConeAngle = 85; }; -class GVAR(def_small_5_mid) : GVAR(def_small_5) { +class GVAR(def_small_5_mid): GVAR(def_small_5) { submunitionConeAngle = 85; triggerSpeedCoef[] = {-1.5, 1.5}; }; -class GVAR(def_small_5_hi) : GVAR(def_small_5) { +class GVAR(def_small_5_hi): GVAR(def_small_5) { submunitionConeAngle = 80; triggerSpeedCoef[] = {-1.5, -0.75}; }; -class GVAR(def_small_5_top) : GVAR(def_small_5) { +class GVAR(def_small_5_top): GVAR(def_small_5) { submunitionConeAngle = 60; triggerSpeedCoef[] = {-1.5, -0.75}; }; @@ -218,318 +218,318 @@ class GVAR(def_small_5_top) : GVAR(def_small_5) { /* * Targeted fragment spawner, for when multiple fragments are spawned (1-3) */ -class GVAR(spawnbase_targeted) : GVAR(spawnbase) { +class GVAR(spawnbase_targeted): GVAR(spawnbase) { submunitionConeType[] = {"random", 2}; submunitionConeAngle = 2; submunitionInitSpeed = 0; triggerSpeedCoef[] = {0.5, 1}; }; -class GVAR(tiny_spawner_2_short) : GVAR(spawnbase_targeted) { +class GVAR(tiny_spawner_2_short): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(tiny); submunitionConeAngle = 4.5; submunitionConeType[] = {"random", 2}; }; -class GVAR(tiny_spawner_2_mid) : GVAR(spawnbase_targeted) { +class GVAR(tiny_spawner_2_mid): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(tiny); submunitionConeAngle = 2; submunitionConeType[] = {"random", 2}; }; -class GVAR(tiny_spawner_2_far) : GVAR(spawnbase_targeted) { +class GVAR(tiny_spawner_2_far): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(tiny); submunitionConeAngle = 0.9; submunitionConeType[] = {"random", 2}; }; -class GVAR(tiny_spawner_3_short) : GVAR(spawnbase_targeted) { +class GVAR(tiny_spawner_3_short): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(tiny); submunitionConeAngle = 4.5; submunitionConeType[] = {"random", 3}; }; -class GVAR(tiny_spawner_3_mid) : GVAR(spawnbase_targeted) { +class GVAR(tiny_spawner_3_mid): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(tiny); submunitionConeAngle = 2; submunitionConeType[] = {"random", 3}; }; -class GVAR(tiny_spawner_3_far) : GVAR(spawnbase_targeted) { +class GVAR(tiny_spawner_3_far): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(tiny); submunitionConeAngle = 0.9; submunitionConeType[] = {"random", 3}; }; -class GVAR(tiny_HD_spawner_2_short) : GVAR(spawnbase_targeted) { +class GVAR(tiny_HD_spawner_2_short): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(tiny_HD); submunitionConeAngle = 4.5; submunitionConeType[] = {"random", 2}; }; -class GVAR(tiny_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { +class GVAR(tiny_HD_spawner_2_mid): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(tiny_HD); submunitionConeAngle = 2; submunitionConeType[] = {"random", 2}; }; -class GVAR(tiny_HD_spawner_2_far) : GVAR(spawnbase_targeted) { +class GVAR(tiny_HD_spawner_2_far): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(tiny_HD); submunitionConeAngle = 0.9; submunitionConeType[] = {"random", 2}; }; -class GVAR(tiny_HD_spawner_3_short) : GVAR(spawnbase_targeted) { +class GVAR(tiny_HD_spawner_3_short): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(tiny_HD); submunitionConeAngle = 4.5; submunitionConeType[] = {"random", 3}; }; -class GVAR(tiny_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { +class GVAR(tiny_HD_spawner_3_mid): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(tiny_HD); submunitionConeAngle = 2; submunitionConeType[] = {"random", 3}; }; -class GVAR(tiny_HD_spawner_3_far) : GVAR(spawnbase_targeted) { +class GVAR(tiny_HD_spawner_3_far): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(tiny_HD); submunitionConeAngle = 0.9; submunitionConeType[] = {"random", 3}; }; -class GVAR(small_spawner_2_short) : GVAR(spawnbase_targeted) { +class GVAR(small_spawner_2_short): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(small); submunitionConeAngle = 4.5; submunitionConeType[] = {"random", 2}; }; -class GVAR(small_spawner_2_mid) : GVAR(spawnbase_targeted) { +class GVAR(small_spawner_2_mid): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(small); submunitionConeAngle = 2; submunitionConeType[] = {"random", 2}; }; -class GVAR(small_spawner_2_far) : GVAR(spawnbase_targeted) { +class GVAR(small_spawner_2_far): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(small); submunitionConeAngle = 0.9; submunitionConeType[] = {"random", 2}; }; -class GVAR(small_spawner_3_short) : GVAR(spawnbase_targeted) { +class GVAR(small_spawner_3_short): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(small); submunitionConeAngle = 4.5; submunitionConeType[] = {"random", 3}; }; -class GVAR(small_spawner_3_mid) : GVAR(spawnbase_targeted) { +class GVAR(small_spawner_3_mid): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(small); submunitionConeAngle = 2; submunitionConeType[] = {"random", 3}; }; -class GVAR(small_spawner_3_far) : GVAR(spawnbase_targeted) { +class GVAR(small_spawner_3_far): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(small); submunitionConeAngle = 0.9; submunitionConeType[] = {"random", 3}; }; -class GVAR(small_HD_spawner_2_short) : GVAR(spawnbase_targeted) { +class GVAR(small_HD_spawner_2_short): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(small_HD); submunitionConeAngle = 4.5; submunitionConeType[] = {"random", 2}; }; -class GVAR(small_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { +class GVAR(small_HD_spawner_2_mid): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(small_HD); submunitionConeAngle = 2; submunitionConeType[] = {"random", 2}; }; -class GVAR(small_HD_spawner_2_far) : GVAR(spawnbase_targeted) { +class GVAR(small_HD_spawner_2_far): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(small_HD); submunitionConeAngle = 0.9; submunitionConeType[] = {"random", 2}; }; -class GVAR(small_HD_spawner_3_short) : GVAR(spawnbase_targeted) { +class GVAR(small_HD_spawner_3_short): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(small_HD); submunitionConeAngle = 4.5; submunitionConeType[] = {"random", 3}; }; -class GVAR(small_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { +class GVAR(small_HD_spawner_3_mid): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(small_HD); submunitionConeAngle = 2; submunitionConeType[] = {"random", 3}; }; -class GVAR(small_HD_spawner_3_far) : GVAR(spawnbase_targeted) { +class GVAR(small_HD_spawner_3_far): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(small_HD); submunitionConeAngle = 0.9; submunitionConeType[] = {"random", 3}; }; -class GVAR(medium_spawner_2_short) : GVAR(spawnbase_targeted) { +class GVAR(medium_spawner_2_short): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(medium); submunitionConeAngle = 4.5; submunitionConeType[] = {"random", 2}; }; -class GVAR(medium_spawner_2_mid) : GVAR(spawnbase_targeted) { +class GVAR(medium_spawner_2_mid): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(medium); submunitionConeAngle = 2; submunitionConeType[] = {"random", 2}; }; -class GVAR(medium_spawner_2_far) : GVAR(spawnbase_targeted) { +class GVAR(medium_spawner_2_far): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(medium); submunitionConeAngle = 0.9; submunitionConeType[] = {"random", 2}; }; -class GVAR(medium_spawner_3_short) : GVAR(spawnbase_targeted) { +class GVAR(medium_spawner_3_short): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(medium); submunitionConeAngle = 4.5; submunitionConeType[] = {"random", 3}; }; -class GVAR(medium_spawner_3_mid) : GVAR(spawnbase_targeted) { +class GVAR(medium_spawner_3_mid): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(medium); submunitionConeAngle = 2; submunitionConeType[] = {"random", 3}; }; -class GVAR(medium_spawner_3_far) : GVAR(spawnbase_targeted) { +class GVAR(medium_spawner_3_far): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(medium); submunitionConeAngle = 0.9; submunitionConeType[] = {"random", 3}; }; -class GVAR(medium_HD_spawner_2_short) : GVAR(spawnbase_targeted) { +class GVAR(medium_HD_spawner_2_short): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(medium_HD); submunitionConeAngle = 4.5; submunitionConeType[] = {"random", 2}; }; -class GVAR(medium_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { +class GVAR(medium_HD_spawner_2_mid): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(medium_HD); submunitionConeAngle = 2; submunitionConeType[] = {"random", 2}; }; -class GVAR(medium_HD_spawner_2_far) : GVAR(spawnbase_targeted) { +class GVAR(medium_HD_spawner_2_far): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(medium_HD); submunitionConeAngle = 0.9; submunitionConeType[] = {"random", 2}; }; -class GVAR(medium_HD_spawner_3_short) : GVAR(spawnbase_targeted) { +class GVAR(medium_HD_spawner_3_short): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(medium_HD); submunitionConeAngle = 4.5; submunitionConeType[] = {"random", 3}; }; -class GVAR(medium_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { +class GVAR(medium_HD_spawner_3_mid): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(medium_HD); submunitionConeAngle = 2; submunitionConeType[] = {"random", 3}; }; -class GVAR(medium_HD_spawner_3_far) : GVAR(spawnbase_targeted) { +class GVAR(medium_HD_spawner_3_far): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(medium_HD); submunitionConeAngle = 0.9; submunitionConeType[] = {"random", 3}; }; -class GVAR(large_spawner_2_short) : GVAR(spawnbase_targeted) { +class GVAR(large_spawner_2_short): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(large); submunitionConeAngle = 4.5; submunitionConeType[] = {"random", 2}; }; -class GVAR(large_spawner_2_mid) : GVAR(spawnbase_targeted) { +class GVAR(large_spawner_2_mid): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(large); submunitionConeAngle = 2; submunitionConeType[] = {"random", 2}; }; -class GVAR(large_spawner_2_far) : GVAR(spawnbase_targeted) { +class GVAR(large_spawner_2_far): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(large); submunitionConeAngle = 0.9; submunitionConeType[] = {"random", 2}; }; -class GVAR(large_spawner_3_short) : GVAR(spawnbase_targeted) { +class GVAR(large_spawner_3_short): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(large); submunitionConeAngle = 4.5; submunitionConeType[] = {"random", 3}; }; -class GVAR(large_spawner_3_mid) : GVAR(spawnbase_targeted) { +class GVAR(large_spawner_3_mid): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(large); submunitionConeAngle = 2; submunitionConeType[] = {"random", 3}; }; -class GVAR(large_spawner_3_far) : GVAR(spawnbase_targeted) { +class GVAR(large_spawner_3_far): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(large); submunitionConeAngle = 0.9; submunitionConeType[] = {"random", 3}; }; -class GVAR(large_HD_spawner_2_short) : GVAR(spawnbase_targeted) { +class GVAR(large_HD_spawner_2_short): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(large_HD); submunitionConeAngle = 4.5; submunitionConeType[] = {"random", 2}; }; -class GVAR(large_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { +class GVAR(large_HD_spawner_2_mid): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(large_HD); submunitionConeAngle = 2; submunitionConeType[] = {"random", 2}; }; -class GVAR(large_HD_spawner_2_far) : GVAR(spawnbase_targeted) { +class GVAR(large_HD_spawner_2_far): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(large_HD); submunitionConeAngle = 0.9; submunitionConeType[] = {"random", 2}; }; -class GVAR(large_HD_spawner_3_short) : GVAR(spawnbase_targeted) { +class GVAR(large_HD_spawner_3_short): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(large_HD); submunitionConeAngle = 4.5; submunitionConeType[] = {"random", 3}; }; -class GVAR(large_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { +class GVAR(large_HD_spawner_3_mid): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(large_HD); submunitionConeAngle = 2; submunitionConeType[] = {"random", 3}; }; -class GVAR(large_HD_spawner_3_far) : GVAR(spawnbase_targeted) { +class GVAR(large_HD_spawner_3_far): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(large_HD); submunitionConeAngle = 0.9; submunitionConeType[] = {"random", 3}; }; -class GVAR(huge_spawner_2_short) : GVAR(spawnbase_targeted) { +class GVAR(huge_spawner_2_short): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(huge); submunitionConeAngle = 4.5; submunitionConeType[] = {"random", 2}; }; -class GVAR(huge_spawner_2_mid) : GVAR(spawnbase_targeted) { +class GVAR(huge_spawner_2_mid): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(huge); submunitionConeAngle = 2; submunitionConeType[] = {"random", 2}; }; -class GVAR(huge_spawner_2_far) : GVAR(spawnbase_targeted) { +class GVAR(huge_spawner_2_far): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(huge); submunitionConeAngle = 0.9; submunitionConeType[] = {"random", 2}; }; -class GVAR(huge_spawner_3_short) : GVAR(spawnbase_targeted) { +class GVAR(huge_spawner_3_short): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(huge); submunitionConeAngle = 4.5; submunitionConeType[] = {"random", 3}; }; -class GVAR(huge_spawner_3_mid) : GVAR(spawnbase_targeted) { +class GVAR(huge_spawner_3_mid): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(huge); submunitionConeAngle = 2; submunitionConeType[] = {"random", 3}; }; -class GVAR(huge_spawner_3_far) : GVAR(spawnbase_targeted) { +class GVAR(huge_spawner_3_far): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(huge); submunitionConeAngle = 0.9; submunitionConeType[] = {"random", 3}; }; -class GVAR(huge_HD_spawner_2_short) : GVAR(spawnbase_targeted) { +class GVAR(huge_HD_spawner_2_short): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(huge_HD); submunitionConeAngle = 4.5; submunitionConeType[] = {"random", 2}; }; -class GVAR(huge_HD_spawner_2_mid) : GVAR(spawnbase_targeted) { +class GVAR(huge_HD_spawner_2_mid): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(huge_HD); submunitionConeAngle = 2; submunitionConeType[] = {"random", 2}; }; -class GVAR(huge_HD_spawner_2_far) : GVAR(spawnbase_targeted) { +class GVAR(huge_HD_spawner_2_far): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(huge_HD); submunitionConeAngle = 0.9; submunitionConeType[] = {"random", 2}; }; -class GVAR(huge_HD_spawner_3_short) : GVAR(spawnbase_targeted) { +class GVAR(huge_HD_spawner_3_short): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(huge_HD); submunitionConeAngle = 4.5; submunitionConeType[] = {"random", 3}; }; -class GVAR(huge_HD_spawner_3_mid) : GVAR(spawnbase_targeted) { +class GVAR(huge_HD_spawner_3_mid): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(huge_HD); submunitionConeAngle = 2; submunitionConeType[] = {"random", 3}; }; -class GVAR(huge_HD_spawner_3_far) : GVAR(spawnbase_targeted) { +class GVAR(huge_HD_spawner_3_far): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(huge_HD); submunitionConeAngle = 0.9; submunitionConeType[] = {"random", 3}; diff --git a/addons/frag/cfgAmmoSpall.hpp b/addons/frag/cfgAmmoSpall.hpp index f38fca70b70..8cf258824ed 100644 --- a/addons/frag/cfgAmmoSpall.hpp +++ b/addons/frag/cfgAmmoSpall.hpp @@ -1,4 +1,4 @@ -class GVAR(spallBase) : B_65x39_Caseless { +class GVAR(spallBase): B_65x39_Caseless { submunitionAmmo[] = {QGVAR(small),4,QGVAR(medium),3,QGVAR(large),2,QGVAR(huge),1}; submunitionConeType[] = {"random", 20}; submunitionConeAngle = 40; @@ -16,27 +16,27 @@ class GVAR(spallBase) : B_65x39_Caseless { /* * ground */ -class GVAR(ground_spall_tiny) : GVAR(spallBase) { +class GVAR(ground_spall_tiny): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 9, QGVAR(small), 1}; submunitionConeType[] = {"poissondisccenter", 4}; }; -class GVAR(ground_spall_small) : GVAR(spallBase) { +class GVAR(ground_spall_small): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(small), 4,QGVAR(medium), 1}; submunitionConeType[] = {"poissondisccenter", 6}; }; -class GVAR(ground_spall_medium) : GVAR(spallBase) { +class GVAR(ground_spall_medium): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(small), 2, QGVAR(small_HD), 1,QGVAR(medium), 3, QGVAR(medium_HD), 1, QGVAR(large), 2}; submunitionConeType[] = {"poissondisccenter", 15}; }; -class GVAR(ground_spall_large) : GVAR(spallBase) { +class GVAR(ground_spall_large): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 3, QGVAR(tiny_HD), 3, QGVAR(small), 4, QGVAR(small_HD), 4, QGVAR(medium_HD), 5, QGVAR(large), 1, QGVAR(large_HD), 2}; submunitionConeType[] = {"poissondisccenter", 15}; }; -class GVAR(ground_spall_huge) : GVAR(spallBase) { +class GVAR(ground_spall_huge): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 3, QGVAR(tiny_HD), 3, QGVAR(small), 4, QGVAR(small_HD), 4, QGVAR(medium), 5, QGVAR(large), 1, QGVAR(large_HD), 2}; submunitionConeType[] = {"poissondisccenter", 20}; }; @@ -45,27 +45,27 @@ class GVAR(ground_spall_huge) : GVAR(spallBase) { /* * rock */ -class GVAR(rock_spall_tiny) : GVAR(spallBase) { +class GVAR(rock_spall_tiny): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(small), 4, QGVAR(medium_HD), 1}; submunitionConeType[] = {"poissondisccenter", 4}; }; -class GVAR(rock_spall_small) : GVAR(spallBase) { +class GVAR(rock_spall_small): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(small), 4, QGVAR(medium), 1}; submunitionConeType[] = {"poissondisccenter", 5}; }; -class GVAR(rock_spall_medium) : GVAR(spallBase) { +class GVAR(rock_spall_medium): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(small), 4, QGVAR(medium), 1, QGVAR(medium_HD), 2, QGVAR(large_HD), 1}; submunitionConeType[] = {"poissondisccenter", 7}; }; -class GVAR(rock_spall_large) : GVAR(spallBase) { +class GVAR(rock_spall_large): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(small), 5, QGVAR(medium), 2, QGVAR(large), 1}; submunitionConeType[] = {"poissondisccenter", 10}; }; -class GVAR(rock_spall_huge) : GVAR(spallBase) { +class GVAR(rock_spall_huge): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(small), 5, QGVAR(medium), 2, QGVAR(large), 1, QGVAR(huge_HD), 1}; submunitionConeType[] = {"poissondisccenter", 13}; }; @@ -74,27 +74,27 @@ class GVAR(rock_spall_huge) : GVAR(spallBase) { /* * wood */ -class GVAR(wood_spall_tiny) : GVAR(spallBase) { +class GVAR(wood_spall_tiny): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 2, QGVAR(small), 4}; submunitionConeType[] = {"poissondisccenter", 4}; }; -class GVAR(wood_spall_small) : GVAR(spallBase) { +class GVAR(wood_spall_small): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 2, QGVAR(small), 4, QGVAR(medium), 1}; submunitionConeType[] = {"poissondisccenter", 6}; }; -class GVAR(wood_spall_medium) : GVAR(spallBase) { +class GVAR(wood_spall_medium): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 2, QGVAR(small), 2, QGVAR(medium), 2, QGVAR(medium_HD), 1, QGVAR(large_HD), 1}; submunitionConeType[] = {"poissondisccenter", 8}; }; -class GVAR(wood_spall_large) : GVAR(spallBase) { +class GVAR(wood_spall_large): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 1, QGVAR(small), 3, QGVAR(medium), 2, QGVAR(large_HD), 2, QGVAR(huge_HD), 1}; submunitionConeType[] = {"poissondisccenter", 10}; }; -class GVAR(wood_spall_huge) : GVAR(spallBase) { +class GVAR(wood_spall_huge): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 1, QGVAR(small), 3, QGVAR(medium), 2, QGVAR(large_HD), 2, QGVAR(huge_HD), 1}; submunitionConeType[] = {"poissondisccenter", 12}; }; @@ -103,27 +103,27 @@ class GVAR(wood_spall_huge) : GVAR(spallBase) { /* * concrete */ -class GVAR(concrete_spall_tiny) : GVAR(spallBase) { +class GVAR(concrete_spall_tiny): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 6, QGVAR(tiny_HD), 3, QGVAR(small), 1}; submunitionConeType[] = {"poissondisccenter", 4}; }; -class GVAR(concrete_spall_small) : GVAR(spallBase) { +class GVAR(concrete_spall_small): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 4, QGVAR(tiny_HD), 2, QGVAR(small), 2, QGVAR(medium), 1}; submunitionConeType[] = {"poissondisccenter", 6}; }; -class GVAR(concrete_spall_medium) : GVAR(spallBase) { +class GVAR(concrete_spall_medium): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 6, QGVAR(tiny_HD), 1, QGVAR(small), 4, QGVAR(medium), 5, QGVAR(large_HD), 1}; submunitionConeType[] = {"poissondisccenter", 9}; }; -class GVAR(concrete_spall_large) : GVAR(spallBase) { +class GVAR(concrete_spall_large): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 6, QGVAR(small), 4, QGVAR(medium), 3, QGVAR(large), 1, QGVAR(large_HD), 2}; submunitionConeType[] = {"poissondisccenter", 12}; }; -class GVAR(concrete_spall_huge) : GVAR(spallBase) { +class GVAR(concrete_spall_huge): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 8, QGVAR(small), 4, QGVAR(medium), 3, QGVAR(large), 1, QGVAR(large_HD), 1, QGVAR(huge_HD), 1}; submunitionConeType[] = {"poissondisccenter", 18}; }; @@ -132,27 +132,27 @@ class GVAR(concrete_spall_huge) : GVAR(spallBase) { /* * metal */ -class GVAR(metal_spall_tiny) : GVAR(spallBase) { +class GVAR(metal_spall_tiny): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 9, QGVAR(small), 1}; submunitionConeType[] = {"poissondisccenter", 4}; }; -class GVAR(metal_spall_small) : GVAR(spallBase) { +class GVAR(metal_spall_small): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 4, QGVAR(small), 2, QGVAR(medium), 1}; submunitionConeType[] = {"poissondisccenter", 6}; }; -class GVAR(metal_spall_medium) : GVAR(spallBase) { +class GVAR(metal_spall_medium): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 5, QGVAR(small), 4, QGVAR(medium), 2, QGVAR(large), 1}; submunitionConeType[] = {"poissondisccenter", 8}; }; -class GVAR(metal_spall_large) : GVAR(spallBase) { +class GVAR(metal_spall_large): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 4, QGVAR(small), 3, QGVAR(medium), 2, QGVAR(large), 1, QGVAR(huge), 1}; submunitionConeType[] = {"poissondisccenter", 12}; }; -class GVAR(metal_spall_huge) : GVAR(spallBase) { +class GVAR(metal_spall_huge): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 8, QGVAR(small), 3, QGVAR(medium), 2, QGVAR(large), 3, QGVAR(huge), 1}; submunitionConeType[] = {"poissondisccenter", 18}; }; \ No newline at end of file From 312da1a6c3942fa61d77fc633751e468e29f8618 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 10 Jan 2024 20:39:10 -0600 Subject: [PATCH 058/282] Deleted a semicolon --- addons/frag/cfgAmmoBaseEH.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/cfgAmmoBaseEH.hpp b/addons/frag/cfgAmmoBaseEH.hpp index a889faf4961..4cd1dd6665f 100644 --- a/addons/frag/cfgAmmoBaseEH.hpp +++ b/addons/frag/cfgAmmoBaseEH.hpp @@ -7,7 +7,7 @@ class Bo_Mk82: BombCore { class BulletCore; class BulletBase: BulletCore { ACE_FRAG_ADD_EH; -} +}; class GrenadeCore; class GrenadeBase: GrenadeCore { From 55d973153f71bc24b69976944d58a15c9d2d227f Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 10 Jan 2024 21:26:02 -0600 Subject: [PATCH 059/282] Fine toothed comb time --- addons/frag/cfgAmmoBaseEH.hpp | 5 ----- addons/frag/cfgAmmoFragParameters.hpp | 3 +++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/addons/frag/cfgAmmoBaseEH.hpp b/addons/frag/cfgAmmoBaseEH.hpp index 4cd1dd6665f..0ec8c9cbb71 100644 --- a/addons/frag/cfgAmmoBaseEH.hpp +++ b/addons/frag/cfgAmmoBaseEH.hpp @@ -1,8 +1,3 @@ -class BombCore; -class Bo_Mk82: BombCore { - ACE_FRAG_ADD_EH; -}; - // We need this since autocannons generally inherit from BulletBase class BulletCore; class BulletBase: BulletCore { diff --git a/addons/frag/cfgAmmoFragParameters.hpp b/addons/frag/cfgAmmoFragParameters.hpp index 7430aa7b86d..3e003444062 100644 --- a/addons/frag/cfgAmmoFragParameters.hpp +++ b/addons/frag/cfgAmmoFragParameters.hpp @@ -21,7 +21,10 @@ class Bomb_04_F: ammo_Bomb_LaserGuidedBase { GVAR(gurney_k) = "1/2"; }; +class BombCore; class Bo_Mk82: BombCore { + ACE_FRAG_ADD_EH; + GVAR(enabled) = 1; GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; From 9e67e31118c93b009e771164d382ca0a892a473a Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 10 Jan 2024 22:12:37 -0600 Subject: [PATCH 060/282] fixed formatting --- addons/frag/cfgAmmoFragParameters.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/frag/cfgAmmoFragParameters.hpp b/addons/frag/cfgAmmoFragParameters.hpp index 3e003444062..4bb20c22dc4 100644 --- a/addons/frag/cfgAmmoFragParameters.hpp +++ b/addons/frag/cfgAmmoFragParameters.hpp @@ -38,7 +38,7 @@ class Bo_Mk82: BombCore { // ~~~~ Grenades: class Grenade; class GrenadeHand: Grenade { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH; GVAR(enabled) = 1; @@ -278,6 +278,6 @@ class ModuleOrdnanceHowitzer_F_ammo: Sh_155mm_AMOS { }; // Special class Default; -class Laserbeam : Default { +class Laserbeam: Default { GVAR(skip) = 1; }; From b1d54a1907703b7752b6e1ce2a6764016647a193 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 11 Jan 2024 14:01:50 -0600 Subject: [PATCH 061/282] Fixed names and updated formatting --- addons/frag/XEH_postInit.sqf | 2 +- addons/frag/XEH_preInit.sqf | 4 ++-- addons/frag/XEH_preStart.sqf | 2 +- addons/frag/config.cpp | 2 +- addons/frag/functions/fnc_addBlackList.sqf | 2 +- addons/frag/functions/fnc_dev_addRound.sqf | 2 +- addons/frag/functions/fnc_dev_clearTraces.sqf | 2 +- addons/frag/functions/fnc_dev_drawTrace.sqf | 2 +- addons/frag/functions/fnc_dev_fired.sqf | 2 +- addons/frag/functions/fnc_dev_fragCalcDump.sqf | 2 +- addons/frag/functions/fnc_dev_sphereDraw.sqf | 2 +- addons/frag/functions/fnc_dev_switchUnitHandle.sqf | 2 +- addons/frag/functions/fnc_dev_trackHitBox.sqf | 2 +- addons/frag/functions/fnc_dev_trackObj.sqf | 2 +- addons/frag/functions/fnc_doFrag.sqf | 2 +- addons/frag/functions/fnc_doFragRandom.sqf | 2 +- addons/frag/functions/fnc_doFragTargeted.sqf | 2 +- addons/frag/functions/fnc_doReflections.sqf | 2 +- addons/frag/functions/fnc_doSpall.sqf | 2 +- addons/frag/functions/fnc_getFragInfo.sqf | 2 +- addons/frag/functions/fnc_getMaterialInfo.sqf | 6 +++--- addons/frag/functions/fnc_initBlackList.sqf | 2 +- addons/frag/functions/fnc_initMaterialCache.sqf | 4 ++-- addons/frag/functions/fnc_initRound.sqf | 2 +- addons/frag/functions/fnc_shouldFrag.sqf | 2 +- addons/frag/functions/fnc_shouldSpall.sqf | 2 +- addons/frag/functions/script_component.hpp | 1 - 27 files changed, 30 insertions(+), 31 deletions(-) delete mode 100644 addons/frag/functions/script_component.hpp diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index 063060551b8..a6e97c85dbf 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" ["CBA_settingsInitialized", { if (isServer) then { diff --git a/addons/frag/XEH_preInit.sqf b/addons/frag/XEH_preInit.sqf index 0356a4e7395..1db6baf3114 100644 --- a/addons/frag/XEH_preInit.sqf +++ b/addons/frag/XEH_preInit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" ADDON = false; @@ -7,7 +7,7 @@ PREP_RECOMPILE_START; PREP_RECOMPILE_END; -GVAR(materialSpallCache) = createHashMap; +GVAR(spallMaterialCache) = createHashMap; GVAR(spallRoundCache) = createHashMap; GVAR(lastSpallTime) = -2; diff --git a/addons/frag/XEH_preStart.sqf b/addons/frag/XEH_preStart.sqf index 022888575ed..32f7ab0eadf 100644 --- a/addons/frag/XEH_preStart.sqf +++ b/addons/frag/XEH_preStart.sqf @@ -1,3 +1,3 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" #include "XEH_PREP.hpp" diff --git a/addons/frag/config.cpp b/addons/frag/config.cpp index f3b409dbd03..3728090f430 100644 --- a/addons/frag/config.cpp +++ b/addons/frag/config.cpp @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" class CfgPatches { class ADDON { diff --git a/addons/frag/functions/fnc_addBlackList.sqf b/addons/frag/functions/fnc_addBlackList.sqf index 3308351064e..9e912ecd2c4 100644 --- a/addons/frag/functions/fnc_addBlackList.sqf +++ b/addons/frag/functions/fnc_addBlackList.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jaynus, NouberNou, Lambda.Tiger * Adds a round to the blacklist (will be ignored). diff --git a/addons/frag/functions/fnc_dev_addRound.sqf b/addons/frag/functions/fnc_dev_addRound.sqf index 332f2e8dc3f..b8d7a27b234 100644 --- a/addons/frag/functions/fnc_dev_addRound.sqf +++ b/addons/frag/functions/fnc_dev_addRound.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Lambda.Tiger * This function adds a round to be traced diff --git a/addons/frag/functions/fnc_dev_clearTraces.sqf b/addons/frag/functions/fnc_dev_clearTraces.sqf index eabdeaeb314..27cd0fe4b6e 100644 --- a/addons/frag/functions/fnc_dev_clearTraces.sqf +++ b/addons/frag/functions/fnc_dev_clearTraces.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Lambda.Tiger * Cleares all dev spheres and traces diff --git a/addons/frag/functions/fnc_dev_drawTrace.sqf b/addons/frag/functions/fnc_dev_drawTrace.sqf index 72fd7cd4527..f2500e89ad9 100644 --- a/addons/frag/functions/fnc_dev_drawTrace.sqf +++ b/addons/frag/functions/fnc_dev_drawTrace.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Lambda.Tiger * Per frame function to draw all dev traces diff --git a/addons/frag/functions/fnc_dev_fired.sqf b/addons/frag/functions/fnc_dev_fired.sqf index 3570035bb2c..842ba0a1e2d 100644 --- a/addons/frag/functions/fnc_dev_fired.sqf +++ b/addons/frag/functions/fnc_dev_fired.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Lambda.Tiger * Add fired rounds to dev track. diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf index d95f622d47d..90a2aa6607b 100644 --- a/addons/frag/functions/fnc_dev_fragCalcDump.sqf +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Lambda.Tiger, based on fnc_dev_debugAmmo by "ACE-Team" * Dumps all ammo types to see if there's any reason to spawn fragments diff --git a/addons/frag/functions/fnc_dev_sphereDraw.sqf b/addons/frag/functions/fnc_dev_sphereDraw.sqf index b578138e1d0..0484f0ff8df 100644 --- a/addons/frag/functions/fnc_dev_sphereDraw.sqf +++ b/addons/frag/functions/fnc_dev_sphereDraw.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Lambda.Tiger * Add a colored sphere at a specified point diff --git a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf index 6c05a13699c..2c73a3b8c0a 100644 --- a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf +++ b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Lambda.Tiger * Handle for debug actions when switching units diff --git a/addons/frag/functions/fnc_dev_trackHitBox.sqf b/addons/frag/functions/fnc_dev_trackHitBox.sqf index 2d42657b57b..51df83d6e0f 100644 --- a/addons/frag/functions/fnc_dev_trackHitBox.sqf +++ b/addons/frag/functions/fnc_dev_trackHitBox.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Lambda.Tiger * Add a hitbox outline to an object diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index 34f927dd983..8221067ec12 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Lambda.Tiger * This function adds an object to have it's course tracked (every frame). diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 5b6d5b5d4de..e3cf7d153c3 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jaynus, NouberNou, Lambda.Tiger * This function handles creating both random and targeted fragments as well diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index f095e3fd438..5d9405e08f5 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jaynus, NouberNou, Lambda.Tiger * This function creates fragments randomly spreading out from an explosion to diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index f0fa8019ef8..1c5ec735d5d 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jaynus, NouberNou, Lambda.Tiger * This function creates fragments targeted at specific entities, up to diff --git a/addons/frag/functions/fnc_doReflections.sqf b/addons/frag/functions/fnc_doReflections.sqf index 7b16385d756..023a283e81b 100644 --- a/addons/frag/functions/fnc_doReflections.sqf +++ b/addons/frag/functions/fnc_doReflections.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: ACE-Team * Dev things diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index 5a30c0bb742..f77e072f67c 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jaynus, NouberNou, Lambda.Tiger, * This function creates spalling if the hit slowed the speed down enough. diff --git a/addons/frag/functions/fnc_getFragInfo.sqf b/addons/frag/functions/fnc_getFragInfo.sqf index d34da541551..72f7da98055 100644 --- a/addons/frag/functions/fnc_getFragInfo.sqf +++ b/addons/frag/functions/fnc_getFragInfo.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Jaynus, NouberNou, Lambda.Tiger * This function returns fragmentation parameters for a specific diff --git a/addons/frag/functions/fnc_getMaterialInfo.sqf b/addons/frag/functions/fnc_getMaterialInfo.sqf index 34d401a1a26..e670b79159f 100644 --- a/addons/frag/functions/fnc_getMaterialInfo.sqf +++ b/addons/frag/functions/fnc_getMaterialInfo.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Lambda.Tiger * This function returns a classification of material type based @@ -18,7 +18,7 @@ params ["_surfType"]; -private _material = GVAR(materialSpallCache) get _surfType; +private _material = GVAR(spallMaterialCache) get _surfType; TRACE_2("materialCache",_surfType,_material); if !(isNil "_material") exitWith { @@ -52,7 +52,7 @@ _material = switch (true) do { default { "ground" }; }; -GVAR(materialSpallCache) set [_surfType, _material]; +GVAR(spallMaterialCache) set [_surfType, _material]; TRACE_2("materialCacheSet",_surfType,_material); _material \ No newline at end of file diff --git a/addons/frag/functions/fnc_initBlackList.sqf b/addons/frag/functions/fnc_initBlackList.sqf index b67c0a31d93..6ba2a7066fc 100644 --- a/addons/frag/functions/fnc_initBlackList.sqf +++ b/addons/frag/functions/fnc_initBlackList.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Lambda.Tiger * Adds setting defined blacklisted rounds to blacklist diff --git a/addons/frag/functions/fnc_initMaterialCache.sqf b/addons/frag/functions/fnc_initMaterialCache.sqf index d0cdc0e8332..4aae38d7c3b 100644 --- a/addons/frag/functions/fnc_initMaterialCache.sqf +++ b/addons/frag/functions/fnc_initMaterialCache.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Lambda.Tiger * For performance, we load a bunch of vanilla materials preemptively @@ -15,7 +15,7 @@ * Public: No */ -GVAR(materialSpallCache) = createHashMapFromArray [ +GVAR(spallMaterialCache) = createHashMapFromArray [ ["a3\data_f\penetration\armour.bisurf","metal"], ["a3\data_f\penetration\armour_plate.bisurf","metal"], ["a3\data_f\penetration\armour_plate_100mm.bisurf","metal"], diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index 14502036c51..a9c692e7f4f 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Lambda.Tiger * This function adds rounds using their config init EH diff --git a/addons/frag/functions/fnc_shouldFrag.sqf b/addons/frag/functions/fnc_shouldFrag.sqf index 1a5a92c119d..f40d94bb9f4 100644 --- a/addons/frag/functions/fnc_shouldFrag.sqf +++ b/addons/frag/functions/fnc_shouldFrag.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Lambda.Tiger * This function checks whether an ammunition type should cause fragmentation diff --git a/addons/frag/functions/fnc_shouldSpall.sqf b/addons/frag/functions/fnc_shouldSpall.sqf index 8eae8a81a55..9813481b1fd 100644 --- a/addons/frag/functions/fnc_shouldSpall.sqf +++ b/addons/frag/functions/fnc_shouldSpall.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Lambda.Tiger * This function checks whether an ammunition type should cause spalling diff --git a/addons/frag/functions/script_component.hpp b/addons/frag/functions/script_component.hpp deleted file mode 100644 index 83123137512..00000000000 --- a/addons/frag/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\frag\script_component.hpp" \ No newline at end of file From 231359ec4ede54ad9a7f46b95d12261605e5fdc1 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 11 Jan 2024 14:39:43 -0600 Subject: [PATCH 062/282] Over zealous fixing script_component.hpp paths --- addons/frag/config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/config.cpp b/addons/frag/config.cpp index 3728090f430..f3b409dbd03 100644 --- a/addons/frag/config.cpp +++ b/addons/frag/config.cpp @@ -1,4 +1,4 @@ -#include "..\script_component.hpp" +#include "script_component.hpp" class CfgPatches { class ADDON { From d7f2f673f3107a95920bb2240e501b1c1f987da5 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 11 Jan 2024 15:44:01 -0600 Subject: [PATCH 063/282] fixed a few more script_comps --- addons/frag/XEH_postInit.sqf | 2 +- addons/frag/XEH_preStart.sqf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index a6e97c85dbf..063060551b8 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -1,4 +1,4 @@ -#include "..\script_component.hpp" +#include "script_component.hpp" ["CBA_settingsInitialized", { if (isServer) then { diff --git a/addons/frag/XEH_preStart.sqf b/addons/frag/XEH_preStart.sqf index 32f7ab0eadf..022888575ed 100644 --- a/addons/frag/XEH_preStart.sqf +++ b/addons/frag/XEH_preStart.sqf @@ -1,3 +1,3 @@ -#include "..\script_component.hpp" +#include "script_component.hpp" #include "XEH_PREP.hpp" From e290fd7c04a6837b850448d19fdc20a4b3bf29b2 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 11 Jan 2024 15:44:15 -0600 Subject: [PATCH 064/282] Fixed MP compat issue --- addons/frag/CfgAmmo.hpp | 2 +- addons/frag/XEH_preInit.sqf | 2 +- addons/frag/functions/fnc_initRound.sqf | 33 ++++++++----------------- addons/frag/initSettings.inc.sqf | 3 ++- 4 files changed, 14 insertions(+), 26 deletions(-) diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index 4e1f621e43f..6334c537021 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -6,7 +6,7 @@ } #define ACE_FRAG_ADD_EH class EventHandlers {\ class ADDON {\ - init = QUOTE(_this call FUNC(initRound););\ + init = QUOTE(if (isServer) then {_this call FUNC(initRound);};);\ };\ } diff --git a/addons/frag/XEH_preInit.sqf b/addons/frag/XEH_preInit.sqf index 1db6baf3114..c13f60edb31 100644 --- a/addons/frag/XEH_preInit.sqf +++ b/addons/frag/XEH_preInit.sqf @@ -1,4 +1,4 @@ -#include "..\script_component.hpp" +#include "script_component.hpp" ADDON = false; diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index a9c692e7f4f..6dfa4de4869 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -18,6 +18,7 @@ params [ ["_projectile", objNull, [objNull]] ]; + private _ammo = typeOf _projectile; if (_ammo isEqualTo "" || {isNull _projectile}) exitWith { TRACE_2("bad ammo or projectile",_ammo,_projectile); @@ -32,17 +33,10 @@ if (_doFrag) then { private _shotParents = getShotParents _proj; private _ammo = typeOf _proj; // wait for frag damage to kill units before spawning fragments - if (isServer) then { - [ - FUNC(doFrag), - _this + [_ammo, _shotParents] - ] call CBA_fnc_execNextFrame; - } else { - [ - QGVAR(frag_eh), - _this + [_ammo, _shotParents] - ] call CBA_fnc_serverEvent; - }; + [ + FUNC(doFrag), + _this + [_ammo, _shotParents] + ] call CBA_fnc_execNextFrame; } ]; }; @@ -61,17 +55,10 @@ if (GVAR(spallEnabled) && {_shouldSpall}) then private _shotPrnt = getShotParents _proj; private _ammo = typeOf _proj; private _vUp = vectorUp _proj; - if (isServer) then { - [ - LINKFUNC(doSpall), - [_proj, _hitObj, _posASL, _vel, _sNorm, _surfType, _ammo, _shotPrnt, _vUp] - ] call CBA_fnc_execNextFrame; - } else { - [ - QGVAR(spall_eh), - [_proj, _hitObj, _posASL, _vel, _sNorm, _surfType, _ammo, _shotPrnt, _vUp] - ] call CBA_fnc_serverEvent; - }; - } + [ + QGVAR(spall_eh), + [_proj, _hitObj, _posASL, _vel, _sNorm, _surfType, _ammo, _shotPrnt, _vUp] + ] call CBA_fnc_serverEvent; + }; ]; }; \ No newline at end of file diff --git a/addons/frag/initSettings.inc.sqf b/addons/frag/initSettings.inc.sqf index 29841cae577..5d51dc00bb6 100644 --- a/addons/frag/initSettings.inc.sqf +++ b/addons/frag/initSettings.inc.sqf @@ -37,7 +37,8 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; QGVAR(atLeastOne), "CHECKBOX", [LSTRING(MinFrag), LSTRING(MinFrag_Desc)], [_category, LSTRING(Frag)], - true + false, + true ] call CBA_fnc_addSetting; [ From fbc710ce474c2bedcac2c8ef151b3f281bd5952f Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 11 Jan 2024 15:47:48 -0600 Subject: [PATCH 065/282] Removed tabs --- addons/frag/functions/fnc_initRound.sqf | 2 +- addons/frag/initSettings.inc.sqf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index 6dfa4de4869..bab13a28e8d 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -59,6 +59,6 @@ if (GVAR(spallEnabled) && {_shouldSpall}) then QGVAR(spall_eh), [_proj, _hitObj, _posASL, _vel, _sNorm, _surfType, _ammo, _shotPrnt, _vUp] ] call CBA_fnc_serverEvent; - }; + }; ]; }; \ No newline at end of file diff --git a/addons/frag/initSettings.inc.sqf b/addons/frag/initSettings.inc.sqf index 5d51dc00bb6..cf8f533ccce 100644 --- a/addons/frag/initSettings.inc.sqf +++ b/addons/frag/initSettings.inc.sqf @@ -38,7 +38,7 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; [LSTRING(MinFrag), LSTRING(MinFrag_Desc)], [_category, LSTRING(Frag)], false, - true + true ] call CBA_fnc_addSetting; [ From 1cf901703a0d11dcaec6aa772ca13225d3bee6ff Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 11 Jan 2024 16:13:02 -0600 Subject: [PATCH 066/282] Fixed a few issues script errors that went under the radar until now --- addons/frag/XEH_postInit.sqf | 11 ----------- addons/frag/functions/fnc_initRound.sqf | 4 ++-- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index 063060551b8..92708f0e055 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -2,19 +2,10 @@ ["CBA_settingsInitialized", { if (isServer) then { - [QGVAR(frag_eh), LINKFUNC(doFrag)] call CBA_fnc_addEventHandler; - [QGVAR(spall_eh), LINKFUNC(doFragMomentum)] call CBA_fnc_addEventHandler; [] call FUNC(initBlackList); [] call FUNC(initMaterialCache); }; - /*if (hasInterface) then { - ["ace_firedPlayer", LINKFUNC(fired)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler; - }; - - ["ace_firedNonPlayer", LINKFUNC(fired)] call CBA_fnc_addEventHandler; - ["ace_firedNonPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler;*/ #ifdef DEBUG_MODE_DRAW if (hasInterface && GVAR(debugOptions)) then { @@ -27,8 +18,6 @@ }] call CBA_fnc_addEventHandler; -// Debug stuff: - #ifdef LOG_FRAG_INFO [true, true, 30] call FUNC(dev_debugAmmo); #endif diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index bab13a28e8d..f8fa2a4df6c 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -58,7 +58,7 @@ if (GVAR(spallEnabled) && {_shouldSpall}) then [ QGVAR(spall_eh), [_proj, _hitObj, _posASL, _vel, _sNorm, _surfType, _ammo, _shotPrnt, _vUp] - ] call CBA_fnc_serverEvent; - }; + ] call CBA_fnc_execNextFrame; + } ]; }; \ No newline at end of file From 40810f282fdc399e71e3ecd82c3e79277c4144e1 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 11 Jan 2024 17:58:47 -0600 Subject: [PATCH 067/282] Updated debug dump functions for ease of use --- addons/frag/functions/fnc_dev_debugAmmo.sqf | 79 +++++++++---------- .../frag/functions/fnc_dev_fragCalcDump.sqf | 30 ++----- 2 files changed, 46 insertions(+), 63 deletions(-) diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index ec52b4b39f6..5053f3c65bc 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -1,81 +1,78 @@ #define DEBUG_MODE_FULL #include "..\script_component.hpp" /* - * Author: ACE-Team - * + * Author: ACE-Team, Lambda.Tiger + * This function will dump every ammo config that would generate ace_frag + * fragements that doesn't have * * Arguments: - * None + * 0: Log ammo types that wouldn't normall frag + * 1: Force a CSV format * * Return Value: * None * * Example: - * call ace_frag_fnc_dev_debugAmmo + * [] call ace_frag_fnc_dev_debugAmmo * * Public: No */ params [ - ["_debugMissing", true, [false]], ["_debugForce", false, [false]], - ["_debugSkippedFragPower", 30, [0]] + ["_csvFormat", false, [false]] ]; diag_log text format ["~~~~~~~~~~~~~Start [%1]~~~~~~~~~~~~~", _this]; -private _allMagsConfigs = configProperties [configFile >> "CfgMagazines", "isClass _x", true]; +private _allAmmoConfigs = configProperties [configFile >> "cfgAmmo", "isClass _x && !('ace_frag' in configName _x)", true]; private _processedCfgAmmos = []; +if (_csvFormat) then { + diag_log text format ["ammo,gurney_c,gurney_m,gurney_k,gurney_gC,_fragTypes,_fragCount"]; +}; + +private _printCount = 0; + { - private _ammo = toLower getText (_x >> "ammo"); + private _ammo = tolower configName _x; if (_ammo != "" && {!(_ammo in _processedCfgAmmos)}) then { _processedCfgAmmos pushBack _ammo; //Ignore mines/bombs - if (_ammo isKindOf "TimeBombCore") exitWith {}; - - _ammoConfig = configFile >> "CfgAmmo" >> _ammo; + //if (_ammo isKindOf "TimeBombCore") exitWith {}; - //Read configs and test if it would actually cause a frag, using same logic as FUNC(pfhRound) - private _skip = getNumber (_ammoConfig >> QGVAR(skip)); - private _explosive = getNumber (_ammoConfig >> "explosive"); - private _indirectRange = getNumber (_ammoConfig >> "indirectHitRange"); - private _force = getNumber (_ammoConfig >> QGVAR(force)); - private _fragPower = getNumber (_ammoConfig >> "indirecthit") * (sqrt ((getNumber (_ammoConfig >> "indirectHitRange")))); + private _ammoConfig = _x; + private _shoulFrag = [_ammo] call FUNC(shouldFrag); - private _shouldAdd = (_skip == 0) && {(_force == 1) || {_explosive > 0.5 && {_indirectRange >= 4.5} && {_fragPower >= 35}}}; - - if (_shouldAdd) then { - if (_debugForce && {((getNumber(_ammoConfig >> "hit")) < 5) || {_fragPower < 10}}) then { - diag_log text format ["Ammo [%1] from Mag [%2] - Weak but will still frag!", _ammo, configName _x]; - diag_log text format [" - _force=%1,_fragPower=%2", _force, _fragPower]; - }; + if (_shoulFrag || _debugForce) then { private _warn = false; - - _fragTypes = getArray (_ammoConfig >> QGVAR(CLASSES)); + private _fragTypes = getArray (_ammoConfig >> QGVAR(CLASSES)); if (_fragTypes isEqualTo []) then {_warn = true;}; - _c = getNumber(_ammoConfig >> QGVAR(CHARGE)); + private _c = getNumber(_ammoConfig >> QGVAR(CHARGE)); if (_c == 0) then {_warn = true;}; - _m = getNumber(_ammoConfig >> QGVAR(METAL)); + private _m = getNumber(_ammoConfig >> QGVAR(METAL)); if (_m == 0) then {_warn = true;}; - _k = getNumber(_ammoConfig >> QGVAR(GURNEY_K)); + private _k = getNumber(_ammoConfig >> QGVAR(GURNEY_K)); if (_k == 0) then {_warn = true;}; - _gC = getNumber(_ammoConfig >> QGVAR(GURNEY_C)); + private _gC = getNumber(_ammoConfig >> QGVAR(GURNEY_C)); if (_gC == 0) then {_warn = true;}; - - if (_debugMissing && {_warn}) then { - diag_log text format ["Ammo [%1] from Mag [%2] MISSING frag configs:", _ammo, configName _x]; - diag_log text format [" - _c=%1,_m=%2,_k=%3,_gC=%4,_fragTypes=%5", _c, _m, _k, _gC, _fragTypes]; - }; - } else { - if ((_fragPower > _debugSkippedFragPower) && {isArray (_ammoConfig >> QGVAR(CLASSES))}) then { - diag_log text format ["Ammo [%1] from Mag [%2] has frag configs but will NOT frag:", _ammo, configName _x]; - diag_log text format ["- skip=%1,explosive=%2,indirectHitRange=%3,force=%4,fragPower=%5", _skip, _explosive, _indirectRange, _force, _fragPower]; + private _fragCount = getNumber (_ammoConfig >> QGVAR(fragCount)); + if (_fragCount == 0) then {_fragCount = 200; _warn = true;}; + + if (_warn) then { + INC(_printCount); + if (_csvFormat) then { + diag_log text format ["%7,%1,%2,%3,%4,%5,%6", _c, _m, _k, _gC, _fragTypes, _fragCount, _ammo]; + } else { + diag_log text format ["Ammo [%1] MISSING frag configs:", _ammo]; + diag_log text format [" _c=%1,_m=%2,_k=%3,_gC=%4,_fragTypes=%5,_fragCount=%6", _c, _m, _k, _gC, _fragTypes, _fragCount]; + }; }; }; }; -} forEach _allMagsConfigs; +} forEach _allAmmoConfigs; -diag_log text format ["~~~~~~~~~~~~~End [%1-%2]~~~~~~~~~~~~~", count _allMagsConfigs, count _processedCfgAmmos]; +diag_log text format ["~~~~~~~~~~~~~~End [%1-%2]~~~~~~~~~~~~~~", count _allAmmoConfigs, count _processedCfgAmmos]; +diag_log text format ["~~~~~~~~~~~~~~Printed: %1~~~~~~~~~~~", _printCount]; diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf index 90a2aa6607b..2ccc1fbab7a 100644 --- a/addons/frag/functions/fnc_dev_fragCalcDump.sqf +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -2,7 +2,8 @@ /* * Author: Lambda.Tiger, based on fnc_dev_debugAmmo by "ACE-Team" * Dumps all ammo types to see if there's any reason to spawn fragments - * given power, distance, and lifetime of each fragement + * given power, distance, and lifetime of each fragement. Good for grasping + * the values used in shouldFrag to cull non-fragementing rounds * * Arguments: * 0: _dispAll - Display rounds that will never frag (power < 5). @@ -22,7 +23,7 @@ params [["_dispAll", false, [false]], ["_minFrgPowRng", 35, [123]]]; #define DT 0.01 -private _allMagsConfigs = configProperties [configFile >> "cfgAmmo", "isClass _x && !('ace' in configName _x)", true]; +private _allAmmoConfigs = configProperties [configFile >> "cfgAmmo", "isClass _x && !('ace_frag' in configName _x)", true]; private _processedCfgAmmos = []; @@ -38,21 +39,9 @@ diag_log text "//****************** fragCalcDump Beg ******************//"; // calculating hit range - - private _skip = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(skip)); - private _force = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(force)); - private _explosive = getNumber (configFile >> "cfgAmmo" >> _ammo >> "explosive"); - private _indirectHit = getNumber(configFile >> "cfgAmmo" >> _ammo >> "indirectHit"); - private _indirectRange = getNumber(configFile >> "cfgAmmo" >> _ammo >> "indirectHitRange"); - - _shouldFrag = if (_skip == 1 || (_force == 0 && {_explosive < 0.5 || {_indirectHit < 3 - || {_indirectRange < 5 && _indirectHit < _indirectRange}}})) then { - false; - } else { - true; - }; + _shouldFrag = [_ammo] call FUNC(shouldFrag); - // Gunery equation from frago + // Gunery equation private _c = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(CHARGE)); if (_c == 0) then {_c = 1;}; private _m = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(METAL)); @@ -62,7 +51,7 @@ diag_log text "//****************** fragCalcDump Beg ******************//"; private _gC = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(GURNEY_C)); if (_gC == 0) then {_gC = 2440;}; private _fragCount = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(fragCount)); - if (_fragCount == 0) then {_fragCount = 200; _warn = true}; + if (_fragCount == 0) then {_fragCount = 200;}; private _velocity = 0.8 * _gC * sqrt (_c /(_m + _c * _k)); // number of shrapnel to send a direction @@ -71,20 +60,17 @@ diag_log text "//****************** fragCalcDump Beg ******************//"; if (_nSkip || _dispALl) then { - diag_log text format ["Ammo type: %1", _ammo]; + diag_log text format ["Ammo type: %1 | Should frag: %2", _ammo, _shouldFrag]; diag_log text format [" Indirect hit range: %1", _indirectHitRange]; diag_log text format [" Frag sqrtPower: %1", _fragPowerSqrt]; diag_log text format [" Frag range: %1", _fragRange]; diag_log text format [" Frag speed range: %1", _fragPowerSpeedRange]; diag_log text format [" Number frags: %1", _count]; - diag_log text " ~~~ Fragments ~~~"; - - INC(_nPrinted); }; _processedCfgAmmos pushBack _ammo; -} forEach _allMagsConfigs; +} forEach _allAmmoConfigs; diag_log text "//****************** fragCalcDump End ******************//"; diag_log text format ["//********************** printed %1 *********************//", _nPrinted]; \ No newline at end of file From 3d3fb434a727efc1531c2c350008c9ad4447f79b Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Fri, 12 Jan 2024 01:49:25 -0600 Subject: [PATCH 068/282] Someday I will not accidentally hit a key an break things --- addons/frag/functions/fnc_initRound.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index f8fa2a4df6c..4b8e2edd1a7 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -56,7 +56,7 @@ if (GVAR(spallEnabled) && {_shouldSpall}) then private _ammo = typeOf _proj; private _vUp = vectorUp _proj; [ - QGVAR(spall_eh), + GVAR(spall_eh), [_proj, _hitObj, _posASL, _vel, _sNorm, _surfType, _ammo, _shotPrnt, _vUp] ] call CBA_fnc_execNextFrame; } From 2805699c0c469231c6a4c329ae31ee6a8f236908 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Fri, 12 Jan 2024 01:50:01 -0600 Subject: [PATCH 069/282] Working updating all previously unused/undefined vanilla round definitions --- addons/frag/cfgAmmoFragParameters.hpp | 173 ++++++++++++++++++-- addons/frag/functions/fnc_dev_debugAmmo.sqf | 54 ++++-- addons/frag/functions/fnc_doFrag.sqf | 10 +- addons/frag/functions/fnc_getFragInfo.sqf | 2 +- 4 files changed, 203 insertions(+), 36 deletions(-) diff --git a/addons/frag/cfgAmmoFragParameters.hpp b/addons/frag/cfgAmmoFragParameters.hpp index 4bb20c22dc4..60e5707c189 100644 --- a/addons/frag/cfgAmmoFragParameters.hpp +++ b/addons/frag/cfgAmmoFragParameters.hpp @@ -1,8 +1,65 @@ +// ~~~~ Autocannons +class B_19mm_HE: BulletBase { + GVAR(skip) = 1; +}; +class B_20mm: BulletBase { + // Used in Weisel/AWC Nyx, which makes it a Rheinmetall Mk 20 Rh-202 + // http://www.navweaps.com/Weapons/WNGER_20mm-65_mk20.php + // total mass of 134g probably not enough to do anything + /*GVAR(fragCount) = 20; + GVAR(metal) = ; + GVAR(charge) = ; + GVAR(gurney_c) = ; + GVAR(gurney_k) = "1/2";*/ + GVAR(skip) = 1; +}; +class B_30mm_HE: B_19mm { + // Used in Gorgon (Pandur II), assuming it's a L21A1 RARDEN, specifically HEI-T due to tracers + // https://ordtech-industries.com/30x170-mm-ammunition-for-cannons-oerlikon-kcb-hispano-hs831l-l21-rarden/ + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(tiny), QGVAR(small)}; + GVAR(fragCount) = 100; + GVAR(metal) = 320; + GVAR(charge) = 25; + GVAR(gurney_c) = 2547; // Hexal det. velocity / 3 + GVAR(gurney_k) = "1/2"; +}; +class B_30mm_MP: B_30mm_HE { + // Used in Mora (FV510 Warrior), assuming it's a Mk44 Bushmaster II, specifically HEI-T due to tracers + // http://www.navweaps.com/Weapons/WNUS_30mm_BushmasterII.php + GVAR(classes)[] = {QGVAR(tiny), QGVAR(small)}; + GVAR(fragCount) = 100; // assumed based on https://www.youtube.com/watch?v=c5SsspD0MeU + GVAR(metal) = 388; + GVAR(charge) = 56; + GVAR(gurney_c) = 2600; // guessed + GVAR(gurney_k) = "1/2"; +}; +class B_40mm_GPR: B_30mm_HE { + // Based on noted 40mm Autocannons, base ROF, and ammo names, looks to be a CTAS40, specifically GPR-PD-T + // https://www.cta-international.com/ammunition/ + // https://ndiastorage.blob.core.usgovcloudapi.net/ndia/2002/gun/leslie.pdf + GVAR(classes)[] = {QGVAR(tiny), QGVAR(small)}; + GVAR(fragCount) = 250; + GVAR(metal) = 750; + GVAR(charge) = 120; + GVAR(gurney_c) = 2700; // guessed + GVAR(gurney_k) = "1/2"; +}; +class B_35mm_AA: BulletBase { + // Gepard uses an Oerlikon GDF and the AA vehicles mimics it like it + // https://en.wikipedia.org/wiki/Oerlikon_GDF#Ammunition + // https://www.nammo.com/product/our-products/ammunition/medium-caliber-ammunition/35-mm-series/35-mm-x-228-hei-sd-and-hei-t-sd/ + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(tiny), QGVAR(tiny), QGVAR(small)}; + GVAR(fragCount) = 175; + GVAR(metal) = 400; + GVAR(charge) = 98; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/2"; +}; // ~~~~ Bombs: class Bo_GBU12_LGB: ammo_Bomb_LaserGuidedBase { - GVAR(enabled) = 1; - GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; GVAR(fragCount) = 17500; GVAR(metal) = 140000; @@ -11,8 +68,6 @@ class Bo_GBU12_LGB: ammo_Bomb_LaserGuidedBase { GVAR(gurney_k) = "1/2"; }; class Bomb_04_F: ammo_Bomb_LaserGuidedBase { - GVAR(enabled) = 1; - GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; GVAR(fragCount) = 17500; GVAR(metal) = 140000; @@ -25,8 +80,6 @@ class BombCore; class Bo_Mk82: BombCore { ACE_FRAG_ADD_EH; - GVAR(enabled) = 1; - GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; GVAR(fragCount) = 17500; GVAR(metal) = 140000; @@ -37,11 +90,12 @@ class Bo_Mk82: BombCore { // ~~~~ Grenades: class Grenade; +class ACE_FlashlightProxy_White: Grenade { + ACE_FRAG_RM_EH; + GVAR(skip) = 1; +}; class GrenadeHand: Grenade { ACE_FRAG_ADD_EH; - - GVAR(enabled) = 1; - GVAR(skip) = 0; GVAR(force) = 1; /* @@ -56,14 +110,15 @@ class GrenadeHand: Grenade { GVAR(gurney_k) = "3/5"; // Gurney shape factor, in this case a sphere. See: http://en.wikipedia.org/wiki/Gurney_equations }; class GrenadeHand_stone: GrenadeHand { + ACE_FRAG_RM_EH; GVAR(skip) = 1; }; class SmokeShell: GrenadeHand { + ACE_FRAG_RM_EH; GVAR(skip) = 1; }; class G_40mm_HE: GrenadeBase { // Source: http://www.inetres.com/gp/military/infantry/grenade/40mm_ammo.html#M441 - GVAR(enabled) = 1; GVAR(force) = 1; GVAR(classes)[] = {QGVAR(small)}; @@ -75,8 +130,6 @@ class G_40mm_HE: GrenadeBase { }; class G_40mm_HEDP: G_40mm_HE { // Source: http://www.inetres.com/gp/military/infantry/grenade/40mm_ammo.html#M433 - GVAR(enabled) = 1; - GVAR(classes)[] = {QGVAR(small_HD)}; GVAR(fragCount) = 270; // seems to have greater framentation ability, but lower range per source GVAR(metal) = 200; @@ -88,21 +141,64 @@ class G_40mm_HEDP: G_40mm_HE { class ACE_G_40mm_HEDP: G_40mm_HEDP {}; class ACE_G_40mm_HE: G_40mm_HE {}; class ACE_G_40mm_Practice: ACE_G_40mm_HE { + ACE_FRAG_RM_EH; GVAR(skip) = 1; GVAR(force) = 0; EGVAR(vehicle_damage,incendiary) = 0; }; -// What is this even? -class ACE_G40mm_HE_VOG25P: G_40mm_HE { - GVAR(skip) = 0; - GVAR(force) = 1; + +// ~~~~ Mines & UXO +class Drone_explosive_ammo: MineBase { + ACE_FRAG_RM_EH; + GVAR(skip) = 1; }; +class APERSMine_Range_Ammo; +class UXO1_Ammo_Base_F: APERSMine_Range_Ammo { + // https://www.globalsecurity.org/military/systems/munitions/blu-97.htm + // https://military-history.fandom.com/wiki/BLU-97/B_Combined_Effects_Bomb + GVAR(force) = 0; + GVAR(classes)[] = {QGVAR(small), QGVAR(small), QGVAR(medium)}; + GVAR(fragCount) = 300; + GVAR(metal) = 1253; + GVAR(charge) = 287; + GVAR(gurney_c) = 2900; + GVAR(gurney_k) = "1/2"; + +}; +class APERSMineDispenser_Mine_Ammo: APERSMine_Range_Ammo { + ACE_FRAG_RM_EH; + GVAR(skip) = 1; +}; + +class UXO_deploy_base_f: SubmunitionBase { + ACE_FRAG_RM_EH; + GVAR(skip) = 1; +}; + +class ClaymoreDirectionalMine_Remote_Ammo: DirectionalBombBase { + ACE_FRAG_RM_EH; + GVAR(skip) = 1; +}; + +class SatchelCharge_Remote_Ammo: PipeBombBase { + ACE_FRAG_RM_EH; + GVAR(skip) = 1; +}; + +class DemoCharge_Remote_Ammo: PipeBombBase { + ACE_FRAG_RM_EH; + GVAR(skip) = 1; +}; + +class BombDemine_01_Ammo_F: BombCore { + ACE_FRAG_RM_EH; + GVAR(skip) = 1; +}; // ~~~~ RPGs: class R_PG32V_F; class R_TBG32V_F: R_PG32V_F { // Thermobaric - GVAR(enabled) = 1; GVAR(fragCount) = 200; GVAR(metal) = 400; GVAR(charge) = 210; @@ -205,7 +301,28 @@ class Missile_AA_04_F: MissileBase { GVAR(skip) = 1; }; -// curator ammo entries +// Based on Metis-M missiles +class M_Vorona_HEAT: MissileBase { + // tandem shaped charges + GVAR(skip) = 1; +}; +class M_Vorona_HE: M_Vorona_HEAT { + // All signs point to this being a thermobaric round so low frag count + GVAR(skip) = 0; + GVAR(fragCount) = 200; + GVAR(metal) = 13800; + GVAR(charge) = 4950; + GVAR(gurney_c) = 2800; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(tiny)}; +}; + +class M_NLAW_AT_F: MissileBase { + ACE_FRAG_RM_EH; + GVAR(skip) = 1; +}; + +/// ~~~~ Shell class Sh_125mm_HEAT; class Sh_155mm_AMOS: ShellBase { // Source: http://www.globalsecurity.org/military/systems/munitions/m795.htm @@ -276,8 +393,28 @@ class ModuleOrdnanceHowitzer_F_ammo: Sh_155mm_AMOS { GVAR(gurney_c) = 2320; GVAR(gurney_k) = "1/2"; }; +class ammo_Penetrator_Base: ShellBase { + GVAR(skip) = 1; +}; + // Special class Default; class Laserbeam: Default { + ACE_FRAG_RM_EH; GVAR(skip) = 1; }; + +class FuelExplosion: Default { + ACE_FRAG_RM_EH; + GVAR(skip) = 1; +}; + +class HelicopterExploSmall: ShellBase { + ACE_FRAG_RM_EH; + GVAR(skip) = 1; +}; + +class LightningBolt: ShellBase { + ACE_FRAG_RM_EH; + GVAR(skip) = 1; +}; \ No newline at end of file diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index 5053f3c65bc..e4124b467ff 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -3,11 +3,13 @@ /* * Author: ACE-Team, Lambda.Tiger * This function will dump every ammo config that would generate ace_frag - * fragements that doesn't have + * fragements that could be fired from a weapon * * Arguments: * 0: Log ammo types that wouldn't normall frag - * 1: Force a CSV format + * 1: Only export ammo classes of classes referenced in cfgAmmo + * and their submunitions. + * 2: Force a CSV format * * Return Value: * None @@ -17,32 +19,54 @@ * * Public: No */ - params [ ["_debugForce", false, [false]], + ["_onlyShotAmmoTypes", false, [false]], ["_csvFormat", false, [false]] ]; diag_log text format ["~~~~~~~~~~~~~Start [%1]~~~~~~~~~~~~~", _this]; +if (_csvFormat) then { + diag_log text format ["ammo,gurney_c,gurney_m,gurney_k,gurney_gC,fragTypes,fragCount,Inheritance"]; +}; -private _allAmmoConfigs = configProperties [configFile >> "cfgAmmo", "isClass _x && !('ace_frag' in configName _x)", true]; -private _processedCfgAmmos = []; +private _allAmmoConfigs = []; +if (_onlyShotAmmoTypes) then { + private _searchFunc = { + params [ + ["_ammo", "", [""]] + ]; + if (_ammo isEqualTo "" || {_ammo in _allAmmoConfigs}) exitWith {}; + _allAmmoConfigs pushBack _ammo; + private _subMunit = toLower getText (configFile >> "cfgAmmo" >> _ammo >> "submunitionAmmo"); + if (_subMunit isNotEqualTo "") then { + _subMunit = getArray (configFile >> "cfgAmmo" >> _ammo >> "submunitionAmmo"); + for "_i" from 0 to count _subMunit - 1 do { + if (_i mod 2 == 0) then { + [toLower (_subMunit#_i)] call _searchFunc; + }; + }; + } else { + [toLower _subMunit] call _searchFunc; + }; + }; + private _allMagazineConfigs = configProperties [configFile >> "cfgMagazines", "isClass _x", true]; -if (_csvFormat) then { - diag_log text format ["ammo,gurney_c,gurney_m,gurney_k,gurney_gC,_fragTypes,_fragCount"]; + { + [toLower getText (_x >> "ammo")] call _searchFunc; + } forEach _allMagazineConfigs; +} else { + _allAmmoConfigs = configProperties [configFile >> "cfgAmmo", "isClass _x && !('ace_frag' in configName _x)", true] apply {configName _x}; }; +private _processedCfgAmmos = []; private _printCount = 0; - { - private _ammo = tolower configName _x; + private _ammo = _x; if (_ammo != "" && {!(_ammo in _processedCfgAmmos)}) then { _processedCfgAmmos pushBack _ammo; - //Ignore mines/bombs - //if (_ammo isKindOf "TimeBombCore") exitWith {}; - - private _ammoConfig = _x; + private _ammoConfig = (configFile >> "cfgAmmo" >> _ammo); private _shoulFrag = [_ammo] call FUNC(shouldFrag); if (_shoulFrag || _debugForce) then { @@ -64,7 +88,7 @@ private _printCount = 0; if (_warn) then { INC(_printCount); if (_csvFormat) then { - diag_log text format ["%7,%1,%2,%3,%4,%5,%6", _c, _m, _k, _gC, _fragTypes, _fragCount, _ammo]; + diag_log text format ["%7,%1,%2,%3,%4,%5,%6,%8", _c, _m, _k, _gC, _fragTypes, _fragCount, _ammo, [_ammoConfig, true] call BIS_fnc_returnParents]; } else { diag_log text format ["Ammo [%1] MISSING frag configs:", _ammo]; diag_log text format [" _c=%1,_m=%2,_k=%3,_gC=%4,_fragTypes=%5,_fragCount=%6", _c, _m, _k, _gC, _fragTypes, _fragCount]; @@ -75,4 +99,4 @@ private _printCount = 0; } forEach _allAmmoConfigs; diag_log text format ["~~~~~~~~~~~~~~End [%1-%2]~~~~~~~~~~~~~~", count _allAmmoConfigs, count _processedCfgAmmos]; -diag_log text format ["~~~~~~~~~~~~~~Printed: %1~~~~~~~~~~~", _printCount]; +diag_log text format ["~~~~~~~~~~~~~~Printed: %1~~~~~~~~~~~", _printCount]; \ No newline at end of file diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index e3cf7d153c3..fb255d20978 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -38,14 +38,20 @@ private _timeSince = CBA_missionTime - GVAR(lastFragTime); if (_ammo isEqualTo "" || {_posASL isEqualTo [0,0,0] || _timeSince < ACE_FRAG_HOLDOFF}) exitWith { TRACE_3("timeExit",_timeSince,CBA_missionTime,GVAR(lastFragTime)); }; -GVAR(lastFragTime) = CBA_missionTime; -private _maxFrags = round (linearConversion [0.1, 1.5, _timeSince, ACE_FRAG_COUNT_MIN, ACE_FRAG_COUNT_MAX, true]); +private _maxFrags = round linearConversion [0.1, 1.5, _timeSince, ACE_FRAG_COUNT_MIN, ACE_FRAG_COUNT_MAX, true]; TRACE_3("",_timeSince,CBA_missionTime,_maxFrags); private _ammoArr = [_ammo] call FUNC(getFragInfo); _ammoArr params ["_fragRange", "_fragVel", "_fragTypes", "_modFragCount"]; +if (_modFragCount < 10) then { + _maxFrags = _modFragCount*4; + GVAR(lastFragTime) = CBA_missionTime - 0.1; +} else { + GVAR(lastFragTime) = CBA_missionTime; +}; + private _heightAGL = (ASLToAGL _posASL)#2; if (_heightAGL < 0.25) then { _posASL = _posASL vectorAdd [0, 0, 0.25]; diff --git a/addons/frag/functions/fnc_getFragInfo.sqf b/addons/frag/functions/fnc_getFragInfo.sqf index 72f7da98055..e407fb19efc 100644 --- a/addons/frag/functions/fnc_getFragInfo.sqf +++ b/addons/frag/functions/fnc_getFragInfo.sqf @@ -79,7 +79,7 @@ if (_warn) then { * of spherical fragmentation */ _ammoInfo = [ - sqrt (_fragCount / (4 * pi * 0.005)), + sqrt (_fragCount / (4 * pi * 0.01)), 0.8 * _gC * sqrt (_c / (_m + _c * _k)), _fragTypes, _fragCount / 4 / pi From b62bec11f2b1184bfa4451c216bd10fa6f5dda10 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Fri, 12 Jan 2024 01:52:01 -0600 Subject: [PATCH 070/282] Missed part of a config --- addons/frag/cfgAmmoFragParameters.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/cfgAmmoFragParameters.hpp b/addons/frag/cfgAmmoFragParameters.hpp index 60e5707c189..ba9673b3d57 100644 --- a/addons/frag/cfgAmmoFragParameters.hpp +++ b/addons/frag/cfgAmmoFragParameters.hpp @@ -13,7 +13,7 @@ class B_20mm: BulletBase { GVAR(gurney_k) = "1/2";*/ GVAR(skip) = 1; }; -class B_30mm_HE: B_19mm { +class B_30mm_HE: B_19mm_HE { // Used in Gorgon (Pandur II), assuming it's a L21A1 RARDEN, specifically HEI-T due to tracers // https://ordtech-industries.com/30x170-mm-ammunition-for-cannons-oerlikon-kcb-hispano-hs831l-l21-rarden/ GVAR(skip) = 0; From ad1916f513db4a33aa86b73b338285044ea6e0e8 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Fri, 12 Jan 2024 01:54:58 -0600 Subject: [PATCH 071/282] Blacklisting error --- addons/frag/functions/fnc_addBlackList.sqf | 2 +- addons/frag/functions/fnc_initBlackList.sqf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/frag/functions/fnc_addBlackList.sqf b/addons/frag/functions/fnc_addBlackList.sqf index 9e912ecd2c4..37643cbf9bb 100644 --- a/addons/frag/functions/fnc_addBlackList.sqf +++ b/addons/frag/functions/fnc_addBlackList.sqf @@ -18,4 +18,4 @@ params ["_proj"]; TRACE_1("addBlackList",_round); -GVAR(shouldFragCache) set [typeOf _ammo, [false, false]]; \ No newline at end of file +GVAR(shouldFragCache) set [typeOf _ammo, false]; \ No newline at end of file diff --git a/addons/frag/functions/fnc_initBlackList.sqf b/addons/frag/functions/fnc_initBlackList.sqf index 6ba2a7066fc..92b3f760d35 100644 --- a/addons/frag/functions/fnc_initBlackList.sqf +++ b/addons/frag/functions/fnc_initBlackList.sqf @@ -44,7 +44,7 @@ for "_i" from 0 to _items - 1 do { continue; }; - GVAR(shouldFragCache) set [_convArray#_i, [false, false]]; + GVAR(shouldFragCache) set [_convArray#_i, false]; }; From 21c72313f446ed6a7a3b6e5f92c2ad1a1bd9019e Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Fri, 12 Jan 2024 02:08:41 -0600 Subject: [PATCH 072/282] Adding useful TRACE statement --- addons/frag/functions/fnc_initRound.sqf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index 4b8e2edd1a7..2431431b1cc 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -14,6 +14,7 @@ * * Public: No */ + TRACE_1("",_this); params [ ["_projectile", objNull, [objNull]] ]; @@ -25,7 +26,7 @@ if (_ammo isEqualTo "" || {isNull _projectile}) exitWith { }; private _shouldFrag = _ammo call FUNC(shouldFrag); -if (_doFrag) then { +if (_shouldFrag && GVAR(enabled)) then { _projectile addEventHandler [ "Explode", { From fb8f0103325bf7e88ff709c06b17f5d19b55abe9 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Fri, 12 Jan 2024 20:27:07 -0600 Subject: [PATCH 073/282] made default frag info (when not defined) perform more middle of the road for munitions --- addons/frag/functions/fnc_addBlackList.sqf | 14 +++++++++++--- addons/frag/functions/fnc_getFragInfo.sqf | 4 ++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/addons/frag/functions/fnc_addBlackList.sqf b/addons/frag/functions/fnc_addBlackList.sqf index 37643cbf9bb..3766df13e83 100644 --- a/addons/frag/functions/fnc_addBlackList.sqf +++ b/addons/frag/functions/fnc_addBlackList.sqf @@ -1,10 +1,10 @@ #include "..\script_component.hpp" /* * Author: Jaynus, NouberNou, Lambda.Tiger - * Adds a round to the blacklist (will be ignored). + * Adds a round type to the blacklist (will be ignored). * * Arguments: - * 0: Projectile + * 0: Projectile or classname * * Return Value: * None @@ -18,4 +18,12 @@ params ["_proj"]; TRACE_1("addBlackList",_round); -GVAR(shouldFragCache) set [typeOf _ammo, false]; \ No newline at end of file +switch (typeName _proj) do { + case "OBJECT": { + GVAR(shouldFragCache) set [typeOf _proj, false]; + }; + case "STRING": { + GVAR(shouldFragCache) set [_proj, false]; + }; + default { }; +}; \ No newline at end of file diff --git a/addons/frag/functions/fnc_getFragInfo.sqf b/addons/frag/functions/fnc_getFragInfo.sqf index e407fb19efc..0f04208b7c8 100644 --- a/addons/frag/functions/fnc_getFragInfo.sqf +++ b/addons/frag/functions/fnc_getFragInfo.sqf @@ -64,7 +64,7 @@ if (_k == 0) then {_k = 0.8; _warn = true;}; private _gC = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(GURNEY_C)); if (_gC == 0) then {_gC = 2440; _warn = true;}; private _fragCount = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(fragCount)); -if (_fragCount == 0) then {_fragCount = 200; _warn = true;}; +if (_fragCount == 0) then {_fragCount = 400; _warn = true;}; if (_warn) then { INFO_1("Ammo class %1 lacks proper explosive properties definitions for frag!",_ammo); @@ -79,7 +79,7 @@ if (_warn) then { * of spherical fragmentation */ _ammoInfo = [ - sqrt (_fragCount / (4 * pi * 0.01)), + sqrt (_fragCount / (4 * pi * 0.005)), 0.8 * _gC * sqrt (_c / (_m + _c * _k)), _fragTypes, _fragCount / 4 / pi From b836708237e57f6ef6cd510a792372090dd954ac Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Fri, 12 Jan 2024 20:28:45 -0600 Subject: [PATCH 074/282] Updated all vanilla classes with ace_frag parameter entries --- addons/frag/CfgAmmo.hpp | 4 +- addons/frag/cfgAmmoBaseEH.hpp | 3 +- addons/frag/cfgAmmoFragParameters.hpp | 389 ++++++++++++++++++++++---- 3 files changed, 332 insertions(+), 64 deletions(-) diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index 6334c537021..3552424d14c 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -1,10 +1,10 @@ #define BASE_DRAG -0.01 #define HD_MULT 5 #define BASE_DRAG_HD (BASE_DRAG * HD_MULT) -#define ACE_FRAG_RM_EH class EventHandlers {\ +#define ACE_FRAG_RM_EH class EventHandlers: EventHandlers {\ delete ADDON;\ } -#define ACE_FRAG_ADD_EH class EventHandlers {\ +#define ACE_FRAG_ADD_EH class EventHandlers: EventHandlers {\ class ADDON {\ init = QUOTE(if (isServer) then {_this call FUNC(initRound);};);\ };\ diff --git a/addons/frag/cfgAmmoBaseEH.hpp b/addons/frag/cfgAmmoBaseEH.hpp index 0ec8c9cbb71..0c10d4848b0 100644 --- a/addons/frag/cfgAmmoBaseEH.hpp +++ b/addons/frag/cfgAmmoBaseEH.hpp @@ -22,6 +22,7 @@ class MissileBase: MissileCore { class RocketCore; class RocketBase: RocketCore { ACE_FRAG_ADD_EH; + GVAR(skip) = 1; }; class ArtilleryRocketCore: RocketCore { @@ -35,7 +36,7 @@ class ShellBase: ShellCore { class ShotDeployCore; class ShotDeployBase: ShotDeployCore { - ACE_FRAG_ADD_EH; + GVAR(skip) = 1; }; class ShotgunCore; diff --git a/addons/frag/cfgAmmoFragParameters.hpp b/addons/frag/cfgAmmoFragParameters.hpp index ba9673b3d57..bb99bac7537 100644 --- a/addons/frag/cfgAmmoFragParameters.hpp +++ b/addons/frag/cfgAmmoFragParameters.hpp @@ -31,6 +31,16 @@ class B_30mm_MP: B_30mm_HE { GVAR(fragCount) = 100; // assumed based on https://www.youtube.com/watch?v=c5SsspD0MeU GVAR(metal) = 388; GVAR(charge) = 56; + GVAR(gurney_c) = 2600; + GVAR(gurney_k) = "1/2"; +}; +class Gatling_30mm_HE_Plane_CAS_01_F; +class Cannon_30mm_HE_Plane_CAS_02_F: Gatling_30mm_HE_Plane_CAS_01_F { + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(tiny), QGVAR(small)}; + GVAR(fragCount) = 100; + GVAR(metal) = 388; + GVAR(charge) = 56; GVAR(gurney_c) = 2600; // guessed GVAR(gurney_k) = "1/2"; }; @@ -39,7 +49,7 @@ class B_40mm_GPR: B_30mm_HE { // https://www.cta-international.com/ammunition/ // https://ndiastorage.blob.core.usgovcloudapi.net/ndia/2002/gun/leslie.pdf GVAR(classes)[] = {QGVAR(tiny), QGVAR(small)}; - GVAR(fragCount) = 250; + GVAR(fragCount) = 250; GVAR(metal) = 750; GVAR(charge) = 120; GVAR(gurney_c) = 2700; // guessed @@ -57,6 +67,10 @@ class B_35mm_AA: BulletBase { GVAR(gurney_c) = 2700; GVAR(gurney_k) = "1/2"; }; +class UnderwaterMine_Range_Ammo: MineBase { + ACE_FRAG_RM_EH; + GVAR(skip) = 1; +}; // ~~~~ Bombs: class Bo_GBU12_LGB: ammo_Bomb_LaserGuidedBase { @@ -65,7 +79,15 @@ class Bo_GBU12_LGB: ammo_Bomb_LaserGuidedBase { GVAR(metal) = 140000; GVAR(charge) = 87000; GVAR(gurney_c) = 2320; - GVAR(gurney_k) = "1/2"; + GVAR(gurney_k) = "3/5"; +}; +class Bomb_03_F: ammo_Bomb_LaserGuidedBase { + GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; + GVAR(fragCount) = 17500; + GVAR(metal) = 150000; + GVAR(charge) = 100000; + GVAR(gurney_c) = 2320; + GVAR(gurney_k) = "3/5"; }; class Bomb_04_F: ammo_Bomb_LaserGuidedBase { GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; @@ -73,7 +95,19 @@ class Bomb_04_F: ammo_Bomb_LaserGuidedBase { GVAR(metal) = 140000; GVAR(charge) = 87000; GVAR(gurney_c) = 2320; - GVAR(gurney_k) = "1/2"; + GVAR(gurney_k) = "3/5"; +}; +class ammo_Bomb_SmallDiameterBase: ammo_Bomb_LaserGuidedBase { + GVAR(skip) = 1; +}; +class ammo_Bomb_SDB: ammo_Bomb_SmallDiameterBase { + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; + GVAR(fragCount) = 17500; + GVAR(metal) = 113000; + GVAR(charge) = 16000; + GVAR(gurney_c) = 2830; + GVAR(gurney_k) = "3/5"; }; class BombCore; @@ -88,6 +122,34 @@ class Bo_Mk82: BombCore { GVAR(gurney_k) = "1/2"; }; +class Mo_cluster_AP: ShellBase { + GVAR(skip) = 1; + GVAR(force) = 0; +}; +class Mo_cluster_Bomb_01_F: Mo_cluster_AP { // Mk 118 Rockeye + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(small)}; + GVAR(fragCount) = 200; + GVAR(metal) = 400; + GVAR(charge) = 180; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/2"; +}; +class Mo_cluster_Bomb_02_F: Mo_cluster_Bomb_01_F { // ShOAB-0.5 + GVAR(classes)[] = {QGVAR(small)}; + GVAR(fragCount) = 304; + GVAR(metal) = 400; + GVAR(charge) = 100; + GVAR(gurney_c) = 2700; +}; +class Mo_cluster_Bomb_03_F: Mo_cluster_Bomb_01_F { // idk, @lambda.tiger on the ace discord if you find out + GVAR(classes)[] = {QGVAR(small)}; + GVAR(fragCount) = 200; + GVAR(metal) = 400; + GVAR(charge) = 140; + GVAR(gurney_c) = 2400; +}; + // ~~~~ Grenades: class Grenade; class ACE_FlashlightProxy_White: Grenade { @@ -104,10 +166,10 @@ class GrenadeHand: Grenade { */ GVAR(classes)[] = {QGVAR(tiny)}; GVAR(fragCount) = 1000; - GVAR(metal) = 210; // metal in grams - GVAR(charge) = 185; // explosive in grams - GVAR(gurney_c) = 2843; // Gurney velocity constant for explosive type. See: http://en.wikipedia.org/wiki/Gurney_equations - GVAR(gurney_k) = "3/5"; // Gurney shape factor, in this case a sphere. See: http://en.wikipedia.org/wiki/Gurney_equations + GVAR(metal) = 210; // metal in grams + GVAR(charge) = 185; // explosive in grams + GVAR(gurney_c) = 2843; // Gurney velocity constant for explosive type. See: http://en.wikipedia.org/wiki/Gurney_equations + GVAR(gurney_k) = "3/5"; // Gurney shape factor, in this case a sphere. See: http://en.wikipedia.org/wiki/Gurney_equations }; class GrenadeHand_stone: GrenadeHand { ACE_FRAG_RM_EH; @@ -148,24 +210,98 @@ class ACE_G_40mm_Practice: ACE_G_40mm_HE { }; // ~~~~ Mines & UXO -class Drone_explosive_ammo: MineBase { +class ATMine_Range_Ammo: MineBase { ACE_FRAG_RM_EH; GVAR(skip) = 1; }; -class APERSMine_Range_Ammo; -class UXO1_Ammo_Base_F: APERSMine_Range_Ammo { - // https://www.globalsecurity.org/military/systems/munitions/blu-97.htm - // https://military-history.fandom.com/wiki/BLU-97/B_Combined_Effects_Bomb +class APERSMine_Range_Ammo: MineBase { // VS-50 + GVAR(skip) = 0; GVAR(force) = 0; - GVAR(classes)[] = {QGVAR(small), QGVAR(small), QGVAR(medium)}; - GVAR(fragCount) = 300; - GVAR(metal) = 1253; - GVAR(charge) = 287; - GVAR(gurney_c) = 2900; - GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(tiny), QGVAR(tiny), QGVAR(small)}; + GVAR(fragCount) = 500; + GVAR(metal) = 100; + GVAR(charge) = 50; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/3"; +}; + +class APERSBoundingMine_Range_Ammo: MineBase { + GVAR(skip) = 0; + GVAR(force) = 0; + GVAR(classes)[] = {QGVAR(tiny)}; + GVAR(fragCount) = 200; + GVAR(metal) = 80; + GVAR(charge) = 170; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "3/5"; +}; + +class SLAMDirectionalMine_Wire_Ammo: DirectionalBombBase { + ACE_FRAG_RM_EH; + GVAR(skip) = 1; +}; + +class APERSTripMine_Wire_Ammo: DirectionalBombBase { + GVAR(skip) = 0; + GVAR(force) = 0; + GVAR(classes)[] = {QGVAR(tiny)}; + GVAR(fragCount) = 800; + GVAR(metal) = 210; + GVAR(charge) = 185; + GVAR(gurney_c) = 2843; + GVAR(gurney_k) = "3/5"; +}; + +class IEDUrbanBig_Remote_Ammo: PipeBombBase { + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; + GVAR(fragCount) = 2000; + GVAR(metal) = 36000; + GVAR(charge) = 9979; + GVAR(gurney_c) = 2440; + GVAR(gurney_k) = "3/5"; +}; +class IEDLandBig_Remote_Ammo: PipeBombBase { + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; + GVAR(fragCount) = 2000; + GVAR(metal) = 36000; + GVAR(charge) = 9979; + GVAR(gurney_c) = 2440; + GVAR(gurney_k) = "3/5"; +}; +class IEDUrbanSmall_Remote_Ammo: PipeBombBase { + GVAR(skip) = 0; + GVAR(fragCount) = 1200; + GVAR(metal) = 23000; + GVAR(charge) = 3148; + GVAR(gurney_c) = 2830; + GVAR(gurney_k) = "3/5"; + GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium_HD)}; +}; +class IEDLandSmall_Remote_Ammo: PipeBombBase { + GVAR(skip) = 0; + GVAR(fragCount) = 1200; + GVAR(metal) = 23000; + GVAR(charge) = 3148; + GVAR(gurney_c) = 2830; + GVAR(gurney_k) = "3/5"; + GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium_HD)}; +}; + +class UXO1_Ammo_Base_F: APERSMine_Range_Ammo { // Mk 118 Rockeye + GVAR(skip) = 0; + GVAR(force) = 0; + GVAR(classes)[] = {QGVAR(small)}; + GVAR(fragCount) = 200; + GVAR(metal) = 400; + GVAR(charge) = 180; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/2"; }; + class APERSMineDispenser_Mine_Ammo: APERSMine_Range_Ammo { ACE_FRAG_RM_EH; GVAR(skip) = 1; @@ -191,15 +327,38 @@ class DemoCharge_Remote_Ammo: PipeBombBase { GVAR(skip) = 1; }; +class Drone_explosive_ammo: MineBase { + GVAR(skip) = 1; +}; + class BombDemine_01_Ammo_F: BombCore { + GVAR(skip) = 1; +}; + +class BombDemine_01_SubAmmo_F: ShellBase { ACE_FRAG_RM_EH; GVAR(skip) = 1; }; -// ~~~~ RPGs: -class R_PG32V_F; +// ~~~~ Rockets: +class R_PG7_F: RocketBase { + GVAR(skip) = 0; + GVAR(force) = 0; + GVAR(classes)[] = {QGVAR(tiny), QGVAR(small)}; + GVAR(fragCount) = 400; + GVAR(metal) = 100; + GVAR(charge) = 560; + GVAR(gurney_c) = 2730; + GVAR(gurney_k) = "1/2"; +}; +class R_PG32V_F: RocketBase { + ACE_FRAG_RM_EH; + GVAR(skip) = 1; +}; class R_TBG32V_F: R_PG32V_F { // Thermobaric - GVAR(fragCount) = 200; + ACE_FRAG_ADD_EH; + GVAR(skip) = 0; + GVAR(fragCount) = 200; GVAR(metal) = 400; GVAR(charge) = 210; GVAR(gurney_c) = 2800; @@ -212,10 +371,9 @@ class M_Titan_AA: MissileBase { class M_Titan_AT: MissileBase { GVAR(skip) = 1; }; -class M_Titan_AP: M_Titan_AT { // "anti personnel" +class M_Titan_AP: M_Titan_AT { GVAR(skip) = 0; GVAR(fragCount) = 800; // guesstimate / provides ~80 m frag range - GVAR(enabled) = 1; GVAR(metal) = 400; GVAR(charge) = 210; GVAR(gurney_c) = 2800; @@ -223,40 +381,81 @@ class M_Titan_AP: M_Titan_AT { // "anti personnel" GVAR(classes)[] = {QGVAR(medium_HD)}; }; -// https://ofb.gov.in/product/products/product-details/84-mm-he-round-ffv-441-b -// https://armypubs.army.mil/epubs/DR_pubs/DR_a/pdf/web/ARN18072_TC%203-22x84%20FINAL%20WEB.pdf (page 99, Table A-6. HE 441D RS, 84-mm projectile) -class R_MRAAWS_HEAT_F; -class R_MRAAWS_HE_F: R_MRAAWS_HEAT_F { - GVAR(enabled) = 1; - GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) +class M_SPG9_HEAT: RocketBase { + GVAR(skip) = 0; + GVAR(fragCount) = 200; + GVAR(metal) = 4150; + GVAR(charge) = 340; + GVAR(gurney_c) = 2970; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(small_HD), QGVAR(medium_HD)}; +}; +class M_SPG9_HE: M_SPG9_HEAT { + GVAR(fragCount) = 800; + GVAR(metal) = 4695; + GVAR(charge) = 655; + GVAR(gurney_c) = 2800; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(small), QGVAR(tiny), QGVAR(small), QGVAR(medium_HD)}; +}; + + +// https://armypubs.army.mil/epubs/DR_pubs/DR_a/pdf/web/ARN18072_TC%203-22x84%20FINAL%20WEB.pdf +class R_MRAAWS_HEAT_F: RocketBase { // Table A-20. HEAT 751 + GVAR(skip) = 0; + GVAR(fragCount) = 500; + GVAR(metal) = 2265; + GVAR(charge) = 635; + GVAR(gurney_c) = 2970; + GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(small)}; + +}; +class R_MRAAWS_HEAT55_F: R_MRAAWS_HEAT_F { // Table A-16. HEAT 551C + GVAR(fragCount) = 300; + GVAR(metal) = 1940; + GVAR(charge) = 460; +}; +class R_MRAAWS_HE_F: R_MRAAWS_HEAT_F { // Table A-6. HE 441D RS + GVAR(fragCount) = 800; GVAR(metal) = 2300; GVAR(charge) = 590; GVAR(gurney_c) = 2800; - GVAR(gurney_k) = "1/2"; + GVAR(gurney_k) = "3/5"; GVAR(classes)[] = {QGVAR(small)}; }; +class R_230mm_fly: RocketBase { + GVAR(skip) = 0; + GVAR(fragCount) = 17500; + GVAR(metal) = 150000; + GVAR(charge) = 100000; + GVAR(gurney_c) = 2320; + GVAR(gurney_k) = "3/5"; + GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; +}; -// ~~~~ Missiles: -class M_PG_AT; -class M_AT: M_PG_AT { // DAR (Hydra 70) - // Source: http://fas.org/man/dod-101/sys/missile/hydra-70.htm - GVAR(enabled) = 1; - +class M_PG_AT: MissileBase { // DAGR M247 warhead + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(tiny), QGVAR(small), QGVAR(small), QGVAR(medium)}; + GVAR(fragCount) = 700; // guesstimate / provides ~80 m frag range (1% chance to hit) + GVAR(metal) = 3085; + GVAR(charge) = 910; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/2"; +}; +class M_AT: M_PG_AT { // DAR (Hydra 70) M151 warhead GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) GVAR(metal) = 3850; GVAR(charge) = 1040; GVAR(gurney_c) = 2700; - GVAR(gurney_k) = "1/2"; }; -class R_80mm_HE: RocketBase { - GVAR(skip) = 1; -}; +// ~~~~ Missiles: class Missile_AGM_02_F: MissileBase { // Source: http://fas.org/man/dod-101/sys/smart/agm-65.htm - GVAR(enabled) = 1; + GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; GVAR(fragCount) = 1600; // guesstimate / provides ~112 m frag range (1% chance to hit) @@ -266,7 +465,7 @@ class Missile_AGM_02_F: MissileBase { GVAR(gurney_k) = "1/2"; }; class Rocket_04_HE_F: MissileBase { // Shrieker (Hydra 70) - GVAR(enabled) = 1; + GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) GVAR(metal) = 3850; @@ -275,7 +474,7 @@ class Rocket_04_HE_F: MissileBase { // Shrieker (Hydra 70) GVAR(gurney_k) = "1/2"; }; class M_Scalpel_AT: MissileBase { // 9K121 Vikhr - GVAR(enabled) = 1; + GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium_HD)}; GVAR(fragCount) = 800; // guesstimate based on frag jacket, provides ~80 m frag range (1% chance to hit) GVAR(metal) = 10000; @@ -285,7 +484,7 @@ class M_Scalpel_AT: MissileBase { // 9K121 Vikhr }; class ACE_Hellfire_AGM114K: M_Scalpel_AT { // Source: http://www.designation-systems.net/dusrm/m-114.html - GVAR(enabled) = 1; + GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; GVAR(fragCount) = 350; // guesstimate based on frag jacket, provides ~50 m frag range (1% chance to hit) @@ -294,14 +493,70 @@ class ACE_Hellfire_AGM114K: M_Scalpel_AT { GVAR(gurney_c) = 2700; GVAR(gurney_k) = "1/2"; }; + +class ammo_Missile_CruiseBase: MissileBase { + GVAR(skip) = 1; +}; +class ammo_missile_cruise_01: ammo_Missile_CruiseBase { + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(large)}; + GVAR(fragCount) = 20000; + GVAR(metal) = 700000; + GVAR(charge) = 110000; + GVAR(gurney_c) = 2600; + GVAR(gurney_k) = "3/5"; +}; +class ammo_Missile_Cruise_01_Cluster: ammo_missile_cruise_01 { + ACE_FRAG_RM_EH; +}; + +class ammo_Missile_AntiRadiationBase: MissileBase { + GVAR(skip) = 1; + GVAR(gurney_k) = "1/2"; + GVAR(gurney_c) = 2400; +}; +class ammo_Missile_HARM: ammo_Missile_AntiRadiationBase { + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(large)}; + GVAR(fragCount) = 5000; + GVAR(metal) = 58000; + GVAR(charge) = 10000; +}; +class ammo_Missile_KH58: ammo_Missile_AntiRadiationBase { + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(large)}; + GVAR(fragCount) = 7500; + GVAR(metal) = 129000; + GVAR(charge) = 20000; +}; + + +// No AA fragging class M_Air_AA: MissileBase { GVAR(skip) = 1; + ACE_FRAG_RM_EH; }; class Missile_AA_04_F: MissileBase { GVAR(skip) = 1; + ACE_FRAG_RM_EH; +}; +class ammo_Missile_LongRangeAABase: MissileBase { + GVAR(skip) = 1; + ACE_FRAG_RM_EH; +}; +class ammo_Missile_MediumRangeAABase: MissileBase { + GVAR(skip) = 1; + ACE_FRAG_RM_EH; +}; +class ammo_Missile_ShortRangeAABase: MissileBase { + GVAR(skip) = 1; + ACE_FRAG_RM_EH; +}; +class m_70mm_saami: RocketBase { + GVAR(skip) = 1; + ACE_FRAG_RM_EH; }; -// Based on Metis-M missiles class M_Vorona_HEAT: MissileBase { // tandem shaped charges GVAR(skip) = 1; @@ -309,7 +564,7 @@ class M_Vorona_HEAT: MissileBase { class M_Vorona_HE: M_Vorona_HEAT { // All signs point to this being a thermobaric round so low frag count GVAR(skip) = 0; - GVAR(fragCount) = 200; + GVAR(fragCount) = 200; GVAR(metal) = 13800; GVAR(charge) = 4950; GVAR(gurney_c) = 2800; @@ -317,6 +572,10 @@ class M_Vorona_HE: M_Vorona_HEAT { GVAR(classes)[] = {QGVAR(tiny)}; }; +class M_127mm_Firefist_AT: RocketBase { + GVAR(skip) = 1; +}; + class M_NLAW_AT_F: MissileBase { ACE_FRAG_RM_EH; GVAR(skip) = 1; @@ -326,7 +585,7 @@ class M_NLAW_AT_F: MissileBase { class Sh_125mm_HEAT; class Sh_155mm_AMOS: ShellBase { // Source: http://www.globalsecurity.org/military/systems/munitions/m795.htm - GVAR(enabled) = 1; + GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; GVAR(fragCount) = 3250; // http://18.195.19.6/bitstream/handle/20.500.12242/1200/15-01916.pdf?sequence=1&isAllowed=y @@ -337,7 +596,7 @@ class Sh_155mm_AMOS: ShellBase { }; class Sh_82mm_AMOS: Sh_155mm_AMOS { //http://65.175.100.54/uxofiles/mulvaney/techdatasheets/81mm-HE-M821.pdf - GVAR(enabled) = 1; + GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; GVAR(fragCount) = 1600; // based on mass and fragment energy/count @@ -347,7 +606,7 @@ class Sh_82mm_AMOS: Sh_155mm_AMOS { GVAR(gurney_k) = "1/2"; }; class ModuleOrdnanceMortar_F_Ammo: Sh_82mm_AMOS { - GVAR(enabled) = 1; + GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; GVAR(metal) = 800; @@ -356,9 +615,7 @@ class ModuleOrdnanceMortar_F_Ammo: Sh_82mm_AMOS { GVAR(gurney_k) = "1/2"; }; class Sh_105mm_HEAT_MP: Sh_125mm_HEAT { - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium), QGVAR(medium_HD)}; GVAR(fragCount) = 1600; // based on mass and fragment energy/count GVAR(metal) = 11400; GVAR(charge) = 7100; @@ -366,17 +623,24 @@ class Sh_105mm_HEAT_MP: Sh_125mm_HEAT { GVAR(gurney_k) = "1/2"; }; class Sh_120mm_HE: ShellBase { - GVAR(enabled) = 1; - - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 2000; + GVAR(skip) = 0; + GVAR(fragCount) = 2000; GVAR(metal) = 23000; GVAR(charge) = 3148; GVAR(gurney_c) = 2830; GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; +}; +class Sh_120mm_HEAT_MP: ShellBase { + GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium), QGVAR(medium_HD)}; + GVAR(fragCount) = 1000; + GVAR(metal) = 5000; + GVAR(charge) = 2500; + GVAR(gurney_c) = 2500; + GVAR(gurney_k) = "1/2"; }; class Sh_125mm_HE: Sh_120mm_HE { - GVAR(enabled) = 1; + GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; GVAR(metal) = 16000; @@ -385,7 +649,7 @@ class Sh_125mm_HE: Sh_120mm_HE { GVAR(gurney_k) = "1/2"; }; class ModuleOrdnanceHowitzer_F_ammo: Sh_155mm_AMOS { - GVAR(enabled) = 1; + GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; GVAR(metal) = 1950; @@ -397,15 +661,13 @@ class ammo_Penetrator_Base: ShellBase { GVAR(skip) = 1; }; -// Special +// ~~~~ Special class Default; class Laserbeam: Default { - ACE_FRAG_RM_EH; GVAR(skip) = 1; }; class FuelExplosion: Default { - ACE_FRAG_RM_EH; GVAR(skip) = 1; }; @@ -417,4 +679,9 @@ class HelicopterExploSmall: ShellBase { class LightningBolt: ShellBase { ACE_FRAG_RM_EH; GVAR(skip) = 1; +}; + +class M_Mo_82mm_AT: MissileBase { + ACE_FRAG_RM_EH; + GVAR(skip) = 1; }; \ No newline at end of file From 12c5a69d237e39089eaa33d6919b050dac622095 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Fri, 12 Jan 2024 20:36:02 -0600 Subject: [PATCH 075/282] missed inheritance check --- addons/frag/CfgAmmo.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index 3552424d14c..804c055f452 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -4,7 +4,7 @@ #define ACE_FRAG_RM_EH class EventHandlers: EventHandlers {\ delete ADDON;\ } -#define ACE_FRAG_ADD_EH class EventHandlers: EventHandlers {\ +#define ACE_FRAG_ADD_EH class EventHandlers {\ class ADDON {\ init = QUOTE(if (isServer) then {_this call FUNC(initRound);};);\ };\ From 6257dd3ee2ce7ba7f2b6c38018661c3f293d5465 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Fri, 12 Jan 2024 21:19:18 -0600 Subject: [PATCH 076/282] We love config inheritance --- addons/frag/CfgAmmo.hpp | 11 +++++++++-- addons/frag/cfgAmmoBaseEH.hpp | 26 +++++++++++++------------- addons/frag/cfgAmmoFragParameters.hpp | 13 ++++++++----- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index 804c055f452..b737b40220b 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -2,9 +2,16 @@ #define HD_MULT 5 #define BASE_DRAG_HD (BASE_DRAG * HD_MULT) #define ACE_FRAG_RM_EH class EventHandlers: EventHandlers {\ - delete ADDON;\ + class ADDON {\ + init = "";\ + };\ +} +#define ACE_FRAG_ADD_EH_BASE class EventHandlers {\ + class ADDON {\ + init = QUOTE(if (isServer) then {_this call FUNC(initRound);};);\ + };\ } -#define ACE_FRAG_ADD_EH class EventHandlers {\ +#define ACE_FRAG_ADD_EH class EventHandlers: EventHandlers {\ class ADDON {\ init = QUOTE(if (isServer) then {_this call FUNC(initRound);};);\ };\ diff --git a/addons/frag/cfgAmmoBaseEH.hpp b/addons/frag/cfgAmmoBaseEH.hpp index 0c10d4848b0..dade166b3d2 100644 --- a/addons/frag/cfgAmmoBaseEH.hpp +++ b/addons/frag/cfgAmmoBaseEH.hpp @@ -1,37 +1,37 @@ // We need this since autocannons generally inherit from BulletBase class BulletCore; class BulletBase: BulletCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH_BASE; }; class GrenadeCore; class GrenadeBase: GrenadeCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH_BASE; }; class LaserBombCore; class ammo_Bomb_LaserGuidedBase: LaserBombCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH_BASE; }; class MissileCore; class MissileBase: MissileCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH_BASE; }; class RocketCore; class RocketBase: RocketCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH_BASE; GVAR(skip) = 1; }; class ArtilleryRocketCore: RocketCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH_BASE; }; class ShellCore; class ShellBase: ShellCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH_BASE; }; class ShotDeployCore; @@ -41,30 +41,30 @@ class ShotDeployBase: ShotDeployCore { class ShotgunCore; class ShotgunBase: ShotgunCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH_BASE; }; class SubmunitionCore; class SubmunitionBase: SubmunitionCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH_BASE; }; class BoundingMineCore; class BoundingMineBase: BoundingMineCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH_BASE; }; class PipeBombCore; class PipeBombBase: PipeBombCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH_BASE; }; class DirectionalBombCore; class DirectionalBombBase: DirectionalBombCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH_BASE; }; class MineCore; class MineBase: MineCore { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH_BASE; }; \ No newline at end of file diff --git a/addons/frag/cfgAmmoFragParameters.hpp b/addons/frag/cfgAmmoFragParameters.hpp index bb99bac7537..4e40e039bca 100644 --- a/addons/frag/cfgAmmoFragParameters.hpp +++ b/addons/frag/cfgAmmoFragParameters.hpp @@ -112,8 +112,7 @@ class ammo_Bomb_SDB: ammo_Bomb_SmallDiameterBase { class BombCore; class Bo_Mk82: BombCore { - ACE_FRAG_ADD_EH; - + ACE_FRAG_ADD_EH_BASE; GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; GVAR(fragCount) = 17500; GVAR(metal) = 140000; @@ -153,11 +152,10 @@ class Mo_cluster_Bomb_03_F: Mo_cluster_Bomb_01_F { // idk, @lambda.tiger on the // ~~~~ Grenades: class Grenade; class ACE_FlashlightProxy_White: Grenade { - ACE_FRAG_RM_EH; GVAR(skip) = 1; }; class GrenadeHand: Grenade { - ACE_FRAG_ADD_EH; + ACE_FRAG_ADD_EH_BASE; GVAR(skip) = 0; GVAR(force) = 1; /* @@ -201,7 +199,9 @@ class G_40mm_HEDP: G_40mm_HE { }; class ACE_G_40mm_HEDP: G_40mm_HEDP {}; -class ACE_G_40mm_HE: G_40mm_HE {}; +class ACE_G_40mm_HE: G_40mm_HE { + class EventHandlers; +}; class ACE_G_40mm_Practice: ACE_G_40mm_HE { ACE_FRAG_RM_EH; GVAR(skip) = 1; @@ -216,6 +216,7 @@ class ATMine_Range_Ammo: MineBase { }; class APERSMine_Range_Ammo: MineBase { // VS-50 + class EventHandlers: EventHandlers; GVAR(skip) = 0; GVAR(force) = 0; GVAR(classes)[] = {QGVAR(tiny), QGVAR(tiny), QGVAR(small)}; @@ -495,9 +496,11 @@ class ACE_Hellfire_AGM114K: M_Scalpel_AT { }; class ammo_Missile_CruiseBase: MissileBase { + class EventHandlers: EventHandlers; GVAR(skip) = 1; }; class ammo_missile_cruise_01: ammo_Missile_CruiseBase { + class EventHandlers: EventHandlers; GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(large)}; GVAR(fragCount) = 20000; From 735d04e2489869d406eeb3391cafe134bd673a58 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Fri, 12 Jan 2024 22:21:56 -0600 Subject: [PATCH 077/282] Fixed all inhertance issues --- addons/frag/CfgAmmo.hpp | 3 ++- addons/frag/cfgAmmoFragParameters.hpp | 12 ++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index b737b40220b..06e3420c28d 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -18,7 +18,8 @@ } class CfgAmmo { - class B_65x39_Caseless; + // break EventHandlers inheritance on purpose to get it out of the frag & spall types + class B_65x39_Caseless; class GVAR(base): B_65x39_Caseless { ACE_damageType = "grenade"; // compatibility with medical_damage, shrapnel should produce grenade wounds diff --git a/addons/frag/cfgAmmoFragParameters.hpp b/addons/frag/cfgAmmoFragParameters.hpp index 4e40e039bca..eb4c9b6444d 100644 --- a/addons/frag/cfgAmmoFragParameters.hpp +++ b/addons/frag/cfgAmmoFragParameters.hpp @@ -178,9 +178,10 @@ class SmokeShell: GrenadeHand { GVAR(skip) = 1; }; class G_40mm_HE: GrenadeBase { + class EventHandlers: EventHandlers; // Source: http://www.inetres.com/gp/military/infantry/grenade/40mm_ammo.html#M441 - GVAR(force) = 1; - + GVAR(skip) = 1; + GVAR(force) = 0; GVAR(classes)[] = {QGVAR(small)}; GVAR(fragCount) = 800; // guess based on probability hit of 1% GVAR(metal) = 200; @@ -189,6 +190,7 @@ class G_40mm_HE: GrenadeBase { GVAR(gurney_k) = "3/5"; // interior fragmenter/charge is a sphere }; class G_40mm_HEDP: G_40mm_HE { + class EventHandlers: EventHandlers; // Source: http://www.inetres.com/gp/military/infantry/grenade/40mm_ammo.html#M433 GVAR(classes)[] = {QGVAR(small_HD)}; GVAR(fragCount) = 270; // seems to have greater framentation ability, but lower range per source @@ -198,9 +200,11 @@ class G_40mm_HEDP: G_40mm_HE { GVAR(gurney_k) = "1/2"; }; -class ACE_G_40mm_HEDP: G_40mm_HEDP {}; +class ACE_G_40mm_HEDP: G_40mm_HEDP { + class EventHandlers: EventHandlers; +}; class ACE_G_40mm_HE: G_40mm_HE { - class EventHandlers; + class EventHandlers: EventHandlers; }; class ACE_G_40mm_Practice: ACE_G_40mm_HE { ACE_FRAG_RM_EH; From ef8a73df0cdf13d2c06c69d0deab5903c728cad8 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Fri, 12 Jan 2024 22:31:51 -0600 Subject: [PATCH 078/282] Changed an attempt to break inheritance and just did it the normal way. --- addons/frag/CfgAmmo.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index 06e3420c28d..4a0ce0bd91b 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -18,8 +18,9 @@ } class CfgAmmo { - // break EventHandlers inheritance on purpose to get it out of the frag & spall types - class B_65x39_Caseless; + class B_65x39_Caseless: BulletBase { + class EventHandlers: EventHandlers; + }; class GVAR(base): B_65x39_Caseless { ACE_damageType = "grenade"; // compatibility with medical_damage, shrapnel should produce grenade wounds From a589f904cfa0830ccc5c36a28df302820114fab5 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 13 Jan 2024 00:11:37 -0600 Subject: [PATCH 079/282] Made configs easier to follow and hopefully fixed inheritance issue --- addons/frag/CfgAmmo.hpp | 7 ++++--- addons/frag/cfgAmmoBaseEH.hpp | 2 +- addons/frag/cfgAmmoFragParameters.hpp | 18 +++++++++--------- addons/frag/cfgAmmoSpall.hpp | 2 +- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index 4a0ce0bd91b..0f02600fbb4 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -18,10 +18,12 @@ } class CfgAmmo { + + #include "cfgAmmoBaseEH.hpp" + class B_65x39_Caseless: BulletBase { class EventHandlers: EventHandlers; }; - class GVAR(base): B_65x39_Caseless { ACE_damageType = "grenade"; // compatibility with medical_damage, shrapnel should produce grenade wounds timeToLive = 4; @@ -99,8 +101,7 @@ class CfgAmmo { caliber = 2.8; }; - #include "cfgAmmoBaseEH.hpp" #include "cfgAmmoSpall.hpp" - #include "cfgAmmoFragParameters.hpp" #include "cfgAmmoFragSpawner.hpp" + #include "cfgAmmoFragParameters.hpp" }; \ No newline at end of file diff --git a/addons/frag/cfgAmmoBaseEH.hpp b/addons/frag/cfgAmmoBaseEH.hpp index dade166b3d2..e648ba2e951 100644 --- a/addons/frag/cfgAmmoBaseEH.hpp +++ b/addons/frag/cfgAmmoBaseEH.hpp @@ -1,5 +1,5 @@ // We need this since autocannons generally inherit from BulletBase -class BulletCore; +class BulletCore; class BulletBase: BulletCore { ACE_FRAG_ADD_EH_BASE; }; diff --git a/addons/frag/cfgAmmoFragParameters.hpp b/addons/frag/cfgAmmoFragParameters.hpp index eb4c9b6444d..766bed06715 100644 --- a/addons/frag/cfgAmmoFragParameters.hpp +++ b/addons/frag/cfgAmmoFragParameters.hpp @@ -52,7 +52,7 @@ class B_40mm_GPR: B_30mm_HE { GVAR(fragCount) = 250; GVAR(metal) = 750; GVAR(charge) = 120; - GVAR(gurney_c) = 2700; // guessed + GVAR(gurney_c) = 2700; // guessed GVAR(gurney_k) = "1/2"; }; class B_35mm_AA: BulletBase { @@ -405,7 +405,7 @@ class M_SPG9_HE: M_SPG9_HEAT { }; -// https://armypubs.army.mil/epubs/DR_pubs/DR_a/pdf/web/ARN18072_TC%203-22x84%20FINAL%20WEB.pdf +// https://armypubs.army.mil/epubs/DR_pubs/DR_a/pdf/web/ARN18072_TC%203-22x84%20FINAL%20WEB.pdf class R_MRAAWS_HEAT_F: RocketBase { // Table A-20. HEAT 751 GVAR(skip) = 0; GVAR(fragCount) = 500; @@ -443,7 +443,7 @@ class R_230mm_fly: RocketBase { class M_PG_AT: MissileBase { // DAGR M247 warhead GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(tiny), QGVAR(small), QGVAR(small), QGVAR(medium)}; - GVAR(fragCount) = 700; // guesstimate / provides ~80 m frag range (1% chance to hit) + GVAR(fragCount) = 700; // guesstimate / provides ~80 m frag range (1% chance to hit) GVAR(metal) = 3085; GVAR(charge) = 910; GVAR(gurney_c) = 2700; @@ -451,7 +451,7 @@ class M_PG_AT: MissileBase { // DAGR M247 warhead }; class M_AT: M_PG_AT { // DAR (Hydra 70) M151 warhead GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) + GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) GVAR(metal) = 3850; GVAR(charge) = 1040; GVAR(gurney_c) = 2700; @@ -463,7 +463,7 @@ class Missile_AGM_02_F: MissileBase { GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 1600; // guesstimate / provides ~112 m frag range (1% chance to hit) + GVAR(fragCount) = 1600; // guesstimate / provides ~112 m frag range (1% chance to hit) GVAR(metal) = 56250; GVAR(charge) = 39000; GVAR(gurney_c) = 2700; @@ -472,7 +472,7 @@ class Missile_AGM_02_F: MissileBase { class Rocket_04_HE_F: MissileBase { // Shrieker (Hydra 70) GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) + GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) GVAR(metal) = 3850; GVAR(charge) = 1040; GVAR(gurney_c) = 2700; @@ -481,7 +481,7 @@ class Rocket_04_HE_F: MissileBase { // Shrieker (Hydra 70) class M_Scalpel_AT: MissileBase { // 9K121 Vikhr GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 800; // guesstimate based on frag jacket, provides ~80 m frag range (1% chance to hit) + GVAR(fragCount) = 800; // guesstimate based on frag jacket, provides ~80 m frag range (1% chance to hit) GVAR(metal) = 10000; GVAR(charge) = 3000; GVAR(gurney_c) = 2700; @@ -492,7 +492,7 @@ class ACE_Hellfire_AGM114K: M_Scalpel_AT { GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 350; // guesstimate based on frag jacket, provides ~50 m frag range (1% chance to hit) + GVAR(fragCount) = 350; // guesstimate based on frag jacket, provides ~50 m frag range (1% chance to hit) GVAR(metal) = 8000; GVAR(charge) = 2400; GVAR(gurney_c) = 2700; @@ -588,7 +588,7 @@ class M_NLAW_AT_F: MissileBase { GVAR(skip) = 1; }; -/// ~~~~ Shell +// ~~~~ Shell class Sh_125mm_HEAT; class Sh_155mm_AMOS: ShellBase { // Source: http://www.globalsecurity.org/military/systems/munitions/m795.htm diff --git a/addons/frag/cfgAmmoSpall.hpp b/addons/frag/cfgAmmoSpall.hpp index 8cf258824ed..36cba405eaf 100644 --- a/addons/frag/cfgAmmoSpall.hpp +++ b/addons/frag/cfgAmmoSpall.hpp @@ -5,7 +5,7 @@ class GVAR(spallBase): B_65x39_Caseless { submunitionDirectionType = "SubmunitionModelDirection"; triggerTime = 0; submunitionInitialOffset[] = {0,0,0}; - submunitionInitSpeed = 0; + submunitionInitSpeed = 0; triggerSpeedCoef[] = {0.75,1.25}; deleteParentWhenTriggered = 1; submunitionParentSpeedCoef = 1; From fbcf196402788337ca59030a94992ea6f9e323dc Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 13 Jan 2024 00:35:22 -0600 Subject: [PATCH 080/282] Attempt to clean up formatting onall files --- addons/frag/XEH_postInit.sqf | 8 ++- addons/frag/config.cpp | 2 +- addons/frag/functions/fnc_dev_addRound.sqf | 4 +- addons/frag/functions/fnc_dev_debugAmmo.sqf | 9 +-- addons/frag/functions/fnc_dev_drawTrace.sqf | 10 ++-- addons/frag/functions/fnc_dev_fired.sqf | 2 +- .../frag/functions/fnc_dev_fragCalcDump.sqf | 10 ++-- addons/frag/functions/fnc_dev_sphereDraw.sqf | 6 +- .../functions/fnc_dev_switchUnitHandle.sqf | 4 +- addons/frag/functions/fnc_dev_trackHitBox.sqf | 22 +++---- addons/frag/functions/fnc_dev_trackObj.sqf | 11 ++-- addons/frag/functions/fnc_doFrag.sqf | 20 +++---- addons/frag/functions/fnc_doFragRandom.sqf | 14 ++--- addons/frag/functions/fnc_doFragTargeted.sqf | 59 +++++++++---------- addons/frag/functions/fnc_doSpall.sqf | 28 +++++---- addons/frag/functions/fnc_getFragInfo.sqf | 14 ++--- addons/frag/functions/fnc_getMaterialInfo.sqf | 18 +++--- addons/frag/functions/fnc_initBlackList.sqf | 5 +- .../frag/functions/fnc_initMaterialCache.sqf | 7 ++- addons/frag/functions/fnc_initRound.sqf | 9 ++- addons/frag/functions/fnc_shouldFrag.sqf | 12 ++-- addons/frag/functions/fnc_shouldSpall.sqf | 8 +-- addons/frag/initSettings.inc.sqf | 4 +- addons/frag/script_component.hpp | 2 +- addons/frag/stringtable.xml | 4 +- 25 files changed, 149 insertions(+), 143 deletions(-) diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index 92708f0e055..1d2b3af2673 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -1,11 +1,12 @@ #include "script_component.hpp" -["CBA_settingsInitialized", { +[ + "CBA_settingsInitialized", + { if (isServer) then { [] call FUNC(initBlackList); [] call FUNC(initMaterialCache); }; - #ifdef DEBUG_MODE_DRAW if (hasInterface && GVAR(debugOptions)) then { @@ -15,7 +16,8 @@ [objNull, ace_player] call FUNC(dev_switchUnitHandle); }; #endif -}] call CBA_fnc_addEventHandler; + } +] call CBA_fnc_addEventHandler; #ifdef LOG_FRAG_INFO diff --git a/addons/frag/config.cpp b/addons/frag/config.cpp index f3b409dbd03..0a36ad8d171 100644 --- a/addons/frag/config.cpp +++ b/addons/frag/config.cpp @@ -16,4 +16,4 @@ class CfgPatches { #include "CfgEventhandlers.hpp" #include "CfgAmmo.hpp" -#include "ACE_Settings.hpp" +#include "ACE_Settings.hpp" \ No newline at end of file diff --git a/addons/frag/functions/fnc_dev_addRound.sqf b/addons/frag/functions/fnc_dev_addRound.sqf index b8d7a27b234..235a9903d86 100644 --- a/addons/frag/functions/fnc_dev_addRound.sqf +++ b/addons/frag/functions/fnc_dev_addRound.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: Lambda.Tiger - * This function adds a round to be traced + * This function adds a round to be traced * * Arguments: * 0: Projectile @@ -55,7 +55,7 @@ if (_sidePlayer) then if (!_addEHs) exitWith {}; -// Add hitpart eventHandler +// Add hitpart eventHandler _proj addEventHandler [ "HitPart", { diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index e4124b467ff..90f26f1922c 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -2,12 +2,12 @@ #include "..\script_component.hpp" /* * Author: ACE-Team, Lambda.Tiger - * This function will dump every ammo config that would generate ace_frag + * This function will dump every ammo config that would generate ace_frag * fragements that could be fired from a weapon * * Arguments: * 0: Log ammo types that wouldn't normall frag - * 1: Only export ammo classes of classes referenced in cfgAmmo + * 1: Only export ammo classes of classes referenced in cfgAmmo * and their submunitions. * 2: Force a CSV format * @@ -30,6 +30,7 @@ if (_csvFormat) then { diag_log text format ["ammo,gurney_c,gurney_m,gurney_k,gurney_gC,fragTypes,fragCount,Inheritance"]; }; +// Gather all configs, either those that could be created from firing or all classes private _allAmmoConfigs = []; if (_onlyShotAmmoTypes) then { private _searchFunc = { @@ -61,7 +62,7 @@ if (_onlyShotAmmoTypes) then { private _processedCfgAmmos = []; private _printCount = 0; -{ +{ // Begin forEach to check each ammo type private _ammo = _x; if (_ammo != "" && {!(_ammo in _processedCfgAmmos)}) then { _processedCfgAmmos pushBack _ammo; @@ -84,7 +85,7 @@ private _printCount = 0; if (_gC == 0) then {_warn = true;}; private _fragCount = getNumber (_ammoConfig >> QGVAR(fragCount)); if (_fragCount == 0) then {_fragCount = 200; _warn = true;}; - + if (_warn) then { INC(_printCount); if (_csvFormat) then { diff --git a/addons/frag/functions/fnc_dev_drawTrace.sqf b/addons/frag/functions/fnc_dev_drawTrace.sqf index f2500e89ad9..2dcea81256f 100644 --- a/addons/frag/functions/fnc_dev_drawTrace.sqf +++ b/addons/frag/functions/fnc_dev_drawTrace.sqf @@ -1,7 +1,8 @@ #include "..\script_component.hpp" +#define HB_DRAW_ARRS [[3 , 2 , 1 , 5 , 6 , 7 , 3 , 0 , 4 , 5], [0, 1], [2, 6], [7, 4]] /* * Author: Lambda.Tiger - * Per frame function to draw all dev traces + * Per frame function to draw all dev traces * * Arguments: * none @@ -16,7 +17,6 @@ private _deleteArr = []; { - // leave if trace is not to be drawn if (count (_y#1) > 1) then { for "_j" from 1 to count (_y#1) - 1 do @@ -27,8 +27,6 @@ private _deleteArr = []; } forEach GVAR(dev_trackLines); if (GVAR(drawHitBox)) then { - - #define HB_DRAW_ARRS [[3,2,1,5,6,7,3,0,4,5],[0,1],[2,6],[7,4]] _deleteArr = []; { _y params ["_obj", "_pts", "_color"]; @@ -37,7 +35,7 @@ if (GVAR(drawHitBox)) then { _deleteArr pushBack _x; continue; }; - + { for "_i" from 1 to count _x -1 do { @@ -46,7 +44,7 @@ if (GVAR(drawHitBox)) then { } forEach HB_DRAW_ARRS; } forEach GVAR(dev_hitBoxes); - + for "_i" from 0 to count _deleteArr - 1 do { GVAR(dev_hitBoxes) deleteAt (_deleteArr#_i); diff --git a/addons/frag/functions/fnc_dev_fired.sqf b/addons/frag/functions/fnc_dev_fired.sqf index 842ba0a1e2d..b04b07ea6bb 100644 --- a/addons/frag/functions/fnc_dev_fired.sqf +++ b/addons/frag/functions/fnc_dev_fired.sqf @@ -2,7 +2,7 @@ /* * Author: Lambda.Tiger * Add fired rounds to dev track. - * + * * Arguments: * None. Parameters inherited from EFUNC(common,firedEH) * diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf index 2ccc1fbab7a..7b382fa073d 100644 --- a/addons/frag/functions/fnc_dev_fragCalcDump.sqf +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -8,7 +8,7 @@ * Arguments: * 0: _dispAll - Display rounds that will never frag (power < 5). * Default value false - * 1: _minFrgPowRng - minimum range for sqrt power calculation + * 1: _minFrgPowRng - minimum range for sqrt power calculation * * Return Value: * None @@ -34,13 +34,13 @@ diag_log text "//****************** fragCalcDump Beg ******************//"; // Processing ammo types { private _ammo = toLower configName _x; - + if (_ammo == "" || {_ammo in _processedCfgAmmos} ) then {continue}; // calculating hit range _shouldFrag = [_ammo] call FUNC(shouldFrag); - + // Gunery equation private _c = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(CHARGE)); if (_c == 0) then {_c = 1;}; @@ -52,7 +52,7 @@ diag_log text "//****************** fragCalcDump Beg ******************//"; if (_gC == 0) then {_gC = 2440;}; private _fragCount = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(fragCount)); if (_fragCount == 0) then {_fragCount = 200;}; - + private _velocity = 0.8 * _gC * sqrt (_c /(_m + _c * _k)); // number of shrapnel to send a direction private _count = ceil (random (sqrt (_m / 1000))); @@ -68,7 +68,7 @@ diag_log text "//****************** fragCalcDump Beg ******************//"; diag_log text format [" Number frags: %1", _count]; INC(_nPrinted); }; - + _processedCfgAmmos pushBack _ammo; } forEach _allAmmoConfigs; diff --git a/addons/frag/functions/fnc_dev_sphereDraw.sqf b/addons/frag/functions/fnc_dev_sphereDraw.sqf index 0484f0ff8df..c56716f20d6 100644 --- a/addons/frag/functions/fnc_dev_sphereDraw.sqf +++ b/addons/frag/functions/fnc_dev_sphereDraw.sqf @@ -16,7 +16,7 @@ * Public: No */ params [ - ["_posASL", [0,0,0], [[]], [2,3]], + ["_posASL", [0, 0, 0], [[]], [2,3]], ["_color", "(1,0,0,0.5)", [""]] ]; @@ -30,7 +30,7 @@ if (count _posASL < 3) then if (_color select [0,1] != "(") then { - switch (toLower _color) do + switch (toLower _color) do { case "blue": { _color = "(0,0,0.8,0.5)"; }; case "black": { _color = "(1,1,1,0.5)"; }; @@ -46,7 +46,7 @@ private _clrStr = "#(argb,8,8,3)color" + _color; private _sphere = "Sign_Sphere25cm_F" createVehicle [1,2,34]; _sphere setObjectTexture [0, _clrStr]; -_sphere setPosASL _posASL; +_sphere setPosASL _posASL; GVAR(dev_eventSpheres) pushBack _sphere; _sphere; \ No newline at end of file diff --git a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf index 2c73a3b8c0a..510e5b02e5e 100644 --- a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf +++ b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: Lambda.Tiger - * Handle for debug actions when switching units + * Handle for debug actions when switching units * * Arguments: * 0: Last unit @@ -37,7 +37,7 @@ _aID = _cVic addAction false, // hideOnUse "", // shortcut "true", // condition - 8 + 8 ]; missionNamespace getVariable [QGVAR(dev_clearTraceAction), _aID]; \ No newline at end of file diff --git a/addons/frag/functions/fnc_dev_trackHitBox.sqf b/addons/frag/functions/fnc_dev_trackHitBox.sqf index 51df83d6e0f..a4522d771ed 100644 --- a/addons/frag/functions/fnc_dev_trackHitBox.sqf +++ b/addons/frag/functions/fnc_dev_trackHitBox.sqf @@ -22,18 +22,20 @@ params [ if (isNull _obj) exitWith {}; +// Grab the right hitBox private _box = []; if (_obj isKindOf "CAManBase") then { if (vehicle _obj == _obj) then { - _box = 0 boundingBox _obj; + _box = 0 boundingBox _obj; } else { - _box = boundingBoxReal [_obj, "Geometry"]; + _box = boundingBoxReal [_obj, "Geometry"]; }; } else { _box = boundingBoxReal [_obj, "FireGeometry"]; }; _box params ["_lowP","_upP"]; +// adjust with stance private _stance = stance _obj; switch (true) do { case (_stance isEqualTo "STAND"): {_upP set [2, 1.9];}; @@ -47,18 +49,19 @@ if (GVAR(dbgSphere) && {_addSphere && {vehicle _obj isEqualTo _obj}}) then { _centerSphere disableCollisionWith vehicle _obj; _centerSphere attachTo [_obj, _obj worldToModel _centerPoint]; }; + +// create an optimized outline private _p1 = _upP; private _p7 = _lowP; - private _points =[ _upP, - [_p1#0,_p7#1,_p1#2], - [_p7#0,_p7#1,_p1#2], - [_p7#0,_p1#1,_p1#2], - [_p1#0,_p1#1,_p7#2], - [_p1#0,_p7#1,_p7#2], + [_p1#0, _p7#1, _p1#2], + [_p7#0, _p7#1, _p1#2], + [_p7#0, _p1#1, _p1#2], + [_p1#0, _p1#1, _p7#2], + [_p1#0, _p7#1, _p7#2], _lowP, - [_p7#0,_p1#1,_p7#2] + [_p7#0, _p1#1, _p7#2] ]; _color = switch (side _obj) do { @@ -66,6 +69,5 @@ _color = switch (side _obj) do { case resistance: {[0, 1, 0, 1]}; default {[0, 0, 1, 1]}; }; -//TRACE_3("box params", _obj, _points, _color); GVAR(dev_hitBoxes) set [getObjectID _obj, [_obj, _points, _color]]; \ No newline at end of file diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index 8221067ec12..80a70f222bf 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -22,8 +22,8 @@ params [ ["_isProj", false, [false]] ]; TRACE_4("devDraw",_this,_obj,_color,_isProj); -// track round on each frame -// Create entry in position array from hashmap + +// pick color and add it to the array private _colorArray = switch (toLower _color) do { case "purple": {[0.8, 0, 0.8, 1]}; case "blue": {[0, 0, 0.8, 1]}; @@ -47,7 +47,7 @@ GVAR(dev_trackLines) set [getObjectID _obj, [1, [getposATL _obj], _colorArray]]; [_h] call CBA_fnc_removePerFrameHandler; }; private _arr = GVAR(dev_trackLines) getOrDefault [(getObjectID _obj), -1]; - + if (typeName _arr isEqualTo "SCALAR") exitWith { [_h] call CBA_fnc_removePerFrameHandler; }; @@ -61,10 +61,9 @@ GVAR(dev_trackLines) set [getObjectID _obj, [1, [getposATL _obj], _colorArray]]; [_obj] ] call CBA_fnc_addPerFrameHandler; +// Projectile eventhandlers that add spheres and points for more accurate round tracking if (!_isProj) exitWith {}; - -// Add hitpart eventHandler _obj addEventHandler [ "HitPart", { @@ -78,7 +77,6 @@ _obj addEventHandler [ } ]; -// Add explode eventHandler _obj addEventHandler [ "Explode", { @@ -92,7 +90,6 @@ _obj addEventHandler [ } ]; -// Add deflected eventHandler _obj addEventHandler [ "Deflected", { diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index fb255d20978..e9d10c6b2f1 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -10,7 +10,7 @@ * 2: velocity of projectile * 3: projectile cfgAmmo classname * 4: getShotParents of projectile at EH - * + * * Return Value: * None * @@ -21,21 +21,23 @@ */ TRACE_1("",_this); params [ - ["_proj", objNull, [objNull]], - ["_posASL", [0,0,0], [[]], [3]], - ["_vel", [0,0,0] , [[]], [3]], + ["_proj", objNull, [objNull]], + ["_posASL", [0, 0, 0], [[]], [3]], + ["_vel", [0, 0, 0] , [[]], [3]], ["_ammo", "", [""]], ["_shotParents", [objNull, objNull], [[]]] ]; +// Check for vehicle holdoff timeout private _shotParentVic = _shotParents#0; if (_shotParentVic getVariable [QGVAR(nextFragTime), -1] > CBA_missionTime) exitWith { TRACE_1("vehicleTimeExit",_shotParentVic); }; _shotParentVic setVariable [QGVAR(nextFragTime), CBA_missionTime + ACE_FRAG_HOLDOFF_VEHICLE]; +// Check normal round timeout and adjust _max frags private _timeSince = CBA_missionTime - GVAR(lastFragTime); -if (_ammo isEqualTo "" || {_posASL isEqualTo [0,0,0] || _timeSince < ACE_FRAG_HOLDOFF}) exitWith { +if (_ammo isEqualTo "" || {_posASL isEqualTo [0, 0, 0] || _timeSince < ACE_FRAG_HOLDOFF}) exitWith { TRACE_3("timeExit",_timeSince,CBA_missionTime,GVAR(lastFragTime)); }; private _maxFrags = round linearConversion [0.1, 1.5, _timeSince, ACE_FRAG_COUNT_MIN, ACE_FRAG_COUNT_MAX, true]; @@ -44,14 +46,14 @@ TRACE_3("",_timeSince,CBA_missionTime,_maxFrags); private _ammoArr = [_ammo] call FUNC(getFragInfo); _ammoArr params ["_fragRange", "_fragVel", "_fragTypes", "_modFragCount"]; - +// For low frag rounds limit the # of frags if (_modFragCount < 10) then { _maxFrags = _modFragCount*4; GVAR(lastFragTime) = CBA_missionTime - 0.1; } else { GVAR(lastFragTime) = CBA_missionTime; }; - +// Offset for ground clearance private _heightAGL = (ASLToAGL _posASL)#2; if (_heightAGL < 0.25) then { _posASL = _posASL vectorAdd [0, 0, 0.25]; @@ -64,8 +66,4 @@ if (_fragRange > 3 && _timeSince > ACE_FRAG_HOLDOFF*1.5 && GVAR(fragSimComplexit if (_timeSince > 0.2 && {GVAR(fragSimComplexity) > 0}) then { [_posASL, _vel, _heightAGL, _fragTypes, _maxFrags, _shotParents] call FUNC(doFragRandom); -}; - -if (GVAR(reflectionsEnabled)) then { - [_posASL, _shellType] call FUNC(doReflections); }; \ No newline at end of file diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index 5d9405e08f5..2f5b53ff802 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -3,7 +3,7 @@ * Author: Jaynus, NouberNou, Lambda.Tiger * This function creates fragments randomly spreading out from an explosion to * a maximum of 15 - * + * * Arguments: * 0: Position of fragmenting projectile ASL * 1: Velocity of the fragmenting projectile @@ -11,7 +11,7 @@ * 3: Type of fragments to generate * 4: Remaining fragment budget * 5: Shot parent - * + * * Return Value: * None * @@ -22,10 +22,10 @@ */ params [ - "_posASL", - ["_projVel", [0,0,0]], + "_posASL", + ["_projVel", [0,0,0]], ["_heightAGL", 2, [123]], - ["_fragType", [], [[]]], + ["_fragType", [], [[]]], ["_fragCnt", 10, [123]], ["_shotPrnt", [objNull, objNull], [[]], [2]] ]; @@ -38,7 +38,7 @@ private _hMode = switch (true) do { default {"_mid"}; }; -private _type = if (count _fragType > 0 && +private _type = if (count _fragType > 0 && {"ace_frag_tiny" isEqualTo (_fragType#0)}) then { QGVAR(def_tiny_) } else { @@ -71,4 +71,4 @@ _fragSpawner addEventHandler [ if (GVAR(dbgSphere)) then { [_posASL] call FUNC(dev_sphereDraw); }; -#endif \ No newline at end of file +#endif \ No newline at end of file diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index 1c5ec735d5d..29241f469f6 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -1,9 +1,9 @@ #include "..\script_component.hpp" /* * Author: Jaynus, NouberNou, Lambda.Tiger - * This function creates fragments targeted at specific entities, up to - * a configured maximum - * + * This function creates fragments targeted at specific entities, up to + * a configured maximum + * * Arguments: * 0: Position of fragmenting projectile ASL * 1: Velocity of the fragmenting projectile @@ -12,9 +12,9 @@ * 4: Types of fragments * 5: A modified parameter used to calulate whether a framgent hits * 6: Shot parent - * + * * Return Value: - * None + * Number of fragments created * * Example: * [getPosASL _proj, velocity _proj, 50, 50, [], 1, [player, player]] call ace_frag_fnc_doFragTargeted; @@ -53,7 +53,7 @@ if (_objects isEqualTo []) exitWith { // grab crews and add them in so that targets stay approx. sorted by distance { private _crew = (crew _x); - if (count _crew > 1) then { + if (count _crew > 1) then { private _arr = [_x]; { _arr pushBackUnique _x; @@ -62,23 +62,22 @@ if (_objects isEqualTo []) exitWith { _objects set [_forEachIndex, _arr]; }; } forEach _objects; -_objects = flatten _objects; // flatten out sub arrays +_objects = flatten _objects; TRACE_3("Targets found", _posASL, _fragRange, count _objects); // limit number of fragments per direction (2D) to 10 using _fragArcs private _fragArcs = createHashMap; -private _fragCount = 0; // limit of # of fragments to _maxFrags -{ +private _fragCount = 0; +{ // Begin of forEach iterating on _objects if (!alive _x) then {continue}; private _target = _x; #ifdef DEBUG_MODE_DRAWFRAG [_target, false] call FUNC(dev_trackHitBox); #endif - - // Calculate volume and height of target - private _vol = 1.5; - private _height = 0; + + // Estimate volume and height of target + private _height = 0.5; private _crossSectionArea = 1; private _isPerson = _target isKindOf "CAManBase"; if (_isPerson) then { @@ -86,24 +85,24 @@ private _fragCount = 0; // limit of # of fragments to _maxFrags switch (true) do { case (_stance isEqualTo "STAND"): {_height = 1.9; _crossSectionArea = 1.5;}; case (_stance isEqualTo "CROUCH"): {_height = 1.2; _crossSectionArea = 1;}; - default {_height = 0.5; _crossSectionArea = 0.75;}; + default {_crossSectionArea = 0.75;}; }; } else { private _boxParams = boundingBoxReal [_target, "FireGeometry"]; _boxParams params ["_pointA", "_pointB"]; private _dims = _pointB vectorDiff _pointA; - _vol = (_dims#0) * (_dims#1) * (_dims#2); - _crossSectionArea = (_dims#1)*(_dims#2); + if (_dims#0 * _dims#1 * _dims#2 <= 0.5) then {continue}; + _crossSectionArea = _dims#1 * _dims#2; _height = _dims#2; }; - - if (_vol <= 0.5) then {continue}; // too small => exit + + private _distance = _target distance _posASL; - + // calculate chance to be hit by a fragment - private _fragChance = _crossSectionArea*_modFragCount/(_distance^2); + private _fragChance = _crossSectionArea * _modFragCount / _distance^2; private _count = if (_fragChance > 1) then { 3 min (floor _fragChance); } else { @@ -111,12 +110,11 @@ private _fragCount = 0; // limit of # of fragments to _maxFrags }; if (_count == 0) then {TRACE_2("fragments",_fragChance,_count); continue}; - // Approximate offset to hit including speed & gravity + // Approximate offset to hit including speed & gravity private _locFragVel = _fragVel * (1 - random 0.5); private _tof = _distance / _locFragVel; - private _targetPos = (velocity _target vectorMultiply _tof) vectorAdd [0, 0, 9.81 / 2 * _tof ^ 2]; - - // handle limiting fragments per dewgree arc + + // handle limiting fragments per degree arc private _dir = floor (_posASL getDir _target); private _fragPerArc = _fragArcs getOrDefault [_dir, 0]; if (_fragPerArc > 10) then { @@ -125,13 +123,14 @@ private _fragCount = 0; // limit of # of fragments to _maxFrags _fragArcs set [_dir, _fragPerArc + _count]; }; - // actual target pos for fragment to hit + // target pos for fragment to hit + private _targetPos = (velocity _target vectorMultiply _tof) vectorAdd [0, 0, 9.81 / 2 * _tof ^ 2]; if _isPerson then { private _hitPoint = selectRandom ACE_FRAG_HITPOINTS; private _hitPointPos = _target selectionPosition [_hitPoint, "HitPoints", "AveragePoint"]; - _targetPos = _target modelToWorldWorld _hitPointPos; + _targetPos = _target modelToWorldWorld _hitPointPos vectorAdd _targetPos; } else { - _targetPos = getPosASL _target vectorAdd [ + _targetPos = _targetPos vectorAdd getPosASL _target vectorAdd [ -0.5 + random 1, -0.5 + random 1, (0.1 + random 0.4) * _height @@ -147,9 +146,8 @@ private _fragCount = 0; // limit of # of fragments to _maxFrags default {"_far"}; }); }; - TRACE_4("fragments",_fragSpawner,_fragChance,_distance,_locFragVel); - + // Create fragment private _vecDir = _posASL vectorFromTo _targetPos; private _fragObj = createVehicle [_fragSpawner, ASLtoATL _posASL, [], 0, "CAN_COLLIDE"]; @@ -169,8 +167,9 @@ private _fragCount = 0; // limit of # of fragments to _maxFrags break }; } forEach _objects; + #ifdef DEBUG_MODE_FULL systemChat ("fragCount cnt: " + str _fragCount); -#endif TRACE_1("fragCount",_fragCount); +#endif _fragCount \ No newline at end of file diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index f77e072f67c..1bdf13e7a45 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -2,11 +2,11 @@ /* * Author: Jaynus, NouberNou, Lambda.Tiger, * This function creates spalling if the hit slowed the speed down enough. - * + * * Arguments: * Arguments are the same as BI's "HitPart" EH: * https://community.bistudio.com/wiki/Arma_3:_Event_Handlers#HitPart - * + * * Return Value: * None * @@ -30,7 +30,7 @@ params [ if (CBA_missionTime - GVAR(lastSpallTime) < ACE_FRAG_SPALL_HOLDOFF || _lPosASL isEqualTo [0,0,0] || - {isNull _hitObj || {_hitObj isKindOf "man" || + {isNull _hitObj || {_hitObj isKindOf "man" || {_ammo isEqualTo ""}}}) exitWith { TRACE_4("time/invldHit",CBA_missionTime,GVAR(lastSpallTime),_hitObj,_lPosASL); }; @@ -38,12 +38,12 @@ if (CBA_missionTime - GVAR(lastSpallTime) < ACE_FRAG_SPALL_HOLDOFF || private _material = [_surfaceType] call FUNC(getMaterialInfo); if (_material isEqualTo "ground") then { #ifdef DEBUG_MODE_FULL - systemChat "ground spall"; // really shouldn't happen + systemChat "ground spall"; #endif }; private _vel = if (alive _projectile) then { - velocity _projectile; + velocity _projectile; } else { [0, 0, 0] }; @@ -52,7 +52,7 @@ private _vel = if (alive _projectile) then { private _dV = vectorMagnitude _lVel - vectorMagnitude _vel; private _caliber = getNumber (configFile >> "cfgAmmo" >> _ammo >> "caliber"); // scaled momentum change made on caliber-mass assumption ~sqrt(2)/20 * caliber ~= mass -private _deltaMomentum = 0.0707 * _caliber * sqrt( _dV ) * GVAR(SpallIntensity); +private _deltaMomentum = 0.0707 * _caliber * sqrt( _dV ) * GVAR(SpallIntensity); TRACE_3("found speed",_dV,_caliber,_deltaMomentum); if (_deltaMomentum < 2) exitWith { @@ -62,20 +62,22 @@ if (_deltaMomentum < 2) exitWith { private _lVelUnit = vectorNormalized _lVel; private _unitStep = _lVelUnit vectorMultiply 0.05; -private _spallPos = +_lPosASL; if (terrainIntersectASL [_lPosASL vectorAdd _unitStep, _lPosASL]) exitWith { TRACE_3("terrainIntersect",_lPosASL,_unitStep,_lPosASL); -}; +}; // Passed all exitWiths GVAR(lastSpallTime) = CBA_missionTime; -// check for less than 30 between norm and projectile (120 of 90 deg offset) -if (120 > acos ((vectorNormalized _lVelUnit) vectorDotProduct _sNorm)) then { +/* + * Improve performance of finding otherside of object on shallow angle + * impacts. 120 degrees due to 90 degree offset with _lVelUnit into object. + */ +private _spallPos = +_lPosASL; +if (120 > acos ( _lVelUnit vectorDotProduct _sNorm)) then { _spallPos = _spallPos vectorAdd (_unitStep vectorMultiply 5); }; - -for "_i" from 1 to 20 do +for "_i" from 1 to 20 do { private _nPos = _spallPos vectorAdd _unitStep; if (!lineIntersects [_spallPos, _nPos]) then { @@ -93,7 +95,7 @@ if GVAR(dbgSphere) then { }; #endif -private _spawnSize = switch (true) do +private _spawnSize = switch (true) do { case (_deltaMomentum < 3): { "_spall_tiny" }; case (_deltaMomentum < 5): { "_spall_small" }; diff --git a/addons/frag/functions/fnc_getFragInfo.sqf b/addons/frag/functions/fnc_getFragInfo.sqf index 0f04208b7c8..6bcde43713f 100644 --- a/addons/frag/functions/fnc_getFragInfo.sqf +++ b/addons/frag/functions/fnc_getFragInfo.sqf @@ -3,16 +3,16 @@ * Author: Jaynus, NouberNou, Lambda.Tiger * This function returns fragmentation parameters for a specific * ammo type. - * + * * Arguments: * 0: _ammo - cfgAmmo type of ammo to check - * + * * Return Value: * _ammoInfo * 0: _fragRange - search range for fragments * 1: _fragVel - gurney equation calculated velocity * 2: _fragTypes - array of fragment types - * 3: _fragCount - modified frag count used under assumptions + * 3: _fragCount - modified frag count used under assumptions * of spherical fragmentation * * Example: @@ -25,7 +25,7 @@ params ["_ammo"]; private _ammoInfo = GVAR(fragInfoCache) get _ammo; -if !(isNil "_ammoInfo") exitWith {_ammoInfo}; +if (!isNil "_ammoInfo") exitWith {_ammoInfo}; private _fragTypes = []; private _warn = false; @@ -37,7 +37,7 @@ if (isArray (configFile >> "cfgAmmo" >> _ammo >> QGVAR(CLASSES))) then { /************ Gurney equation notes *****************//* * see https://en.wikipedia.org/wiki/Gurney_equations - * + * * GURNEY_K is the constant added to _m/_c * GURNEY_C = sqrt(2E) * @@ -71,11 +71,11 @@ if (_warn) then { }; /********************** _ammoInfo format *************************//* - * 0: _fragRange - search range for fragments, calculated with + * 0: _fragRange - search range for fragments, calculated with * a 0.5% chance to hit as the minimum * 1: _fragVel - gurney equation calculated velocity * 2: _fragTypes - array of fragment types - * 3: _fragCount - modified frag count used under assumptions + * 3: _fragCount - modified frag count used under assumptions * of spherical fragmentation */ _ammoInfo = [ diff --git a/addons/frag/functions/fnc_getMaterialInfo.sqf b/addons/frag/functions/fnc_getMaterialInfo.sqf index e670b79159f..9f954bba48a 100644 --- a/addons/frag/functions/fnc_getMaterialInfo.sqf +++ b/addons/frag/functions/fnc_getMaterialInfo.sqf @@ -1,14 +1,14 @@ #include "..\script_component.hpp" /* * Author: Lambda.Tiger - * This function returns a classification of material type based + * This function returns a classification of material type based * on the surface hit. - * + * * Arguments: - * 0: surfacetype - either a cfgSurfaces path .bisurf filepath - * + * 0: surfacetype - either a cfgSurfaces path .bisurf filepath + * * Return Value: - * _material - Material categories as expanded on in line 43 below + * _material - Material categories as expanded on in line 44 below * * Example: * [_surfaceType] call ace_frag_fnc_getFragInfo; @@ -21,12 +21,15 @@ params ["_surfType"]; private _material = GVAR(spallMaterialCache) get _surfType; TRACE_2("materialCache",_surfType,_material); -if !(isNil "_material") exitWith { +if (!isNil "_material") exitWith { _material }; - +// Use 'soundEnviron' or 'soundHit' to extract approx material if (isClass (configFile >> "CfgSurfaces" >> _surfType)) then { _material = getText (configFile >> "CfgSurfaces" >> _surfType >> "soundEnviron"); + if (_material isEqualTo "" || {_material isEqualTo "empty"}) then { + _material = getText (configFile >> "CfgSurfaces" >> _surfType >> "soundhit"); + }; } else { // Messy way when a surface isn't added to cfgSurfaces private _surfFileText = tolower preprocessFile _surfType; _surfFileText = _surfFileText regexReplace ["[^a-z0-9]", ""]; @@ -38,7 +41,6 @@ if (isClass (configFile >> "CfgSurfaces" >> _surfType)) then { }; TRACE_1("materialSubString",_material); - _material = switch (true) do { case ("dirt" in _material); case ("grass" in _material): { "ground" }; diff --git a/addons/frag/functions/fnc_initBlackList.sqf b/addons/frag/functions/fnc_initBlackList.sqf index 92b3f760d35..a79ed223ae2 100644 --- a/addons/frag/functions/fnc_initBlackList.sqf +++ b/addons/frag/functions/fnc_initBlackList.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: Lambda.Tiger - * Adds setting defined blacklisted rounds to blacklist + * Adds setting defined blacklisted rounds to blacklist * * Arguments: * Mne @@ -21,13 +21,14 @@ if (!ADDON) then { [FUNC(initBlackList), [], 1] call CBA_fnc_waitAndExecute; }; -// could improve text parsing +// could improve text parsing of CBA setting string private _convArray = parseSimpleArray GVAR(BlackList); if (count _convArray == 0 ) exitWith { TRACE_1("Empty blacklist", _convArray); }; +// Add CBA setting blacklist to blacklist and log errors private _errors = 0; private _items = count _convArray; for "_i" from 0 to _items - 1 do { diff --git a/addons/frag/functions/fnc_initMaterialCache.sqf b/addons/frag/functions/fnc_initMaterialCache.sqf index 4aae38d7c3b..9e56b3dafff 100644 --- a/addons/frag/functions/fnc_initMaterialCache.sqf +++ b/addons/frag/functions/fnc_initMaterialCache.sqf @@ -1,11 +1,12 @@ #include "..\script_component.hpp" /* * Author: Lambda.Tiger - * For performance, we load a bunch of vanilla materials preemptively - * + * For performance, we load a bunch of vanilla materials preemptively into + * the spall material cache + * * Arguments: * none - * + * * Return Value: * none * diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index 2431431b1cc..caa5bd2dda0 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -5,7 +5,7 @@ * Arguments: * 0: _projectile - The object created - * + * * Return Value: * None * @@ -30,7 +30,7 @@ if (_shouldFrag && GVAR(enabled)) then { _projectile addEventHandler [ "Explode", { - params ["_proj"]; + params ["_proj", "_posASL"]; private _shotParents = getShotParents _proj; private _ammo = typeOf _proj; // wait for frag damage to kill units before spawning fragments @@ -38,13 +38,16 @@ if (_shouldFrag && GVAR(enabled)) then { FUNC(doFrag), _this + [_ammo, _shotParents] ] call CBA_fnc_execNextFrame; + if (GVAR(reflectionsEnabled)) then { + [_posASL, _ammo] call FUNC(doReflections); + }; } ]; }; private _shouldSpall = _ammo call FUNC(shouldSpall); -if (GVAR(spallEnabled) && {_shouldSpall}) then +if (GVAR(spallEnabled) && {_shouldSpall}) then { _projectile addEventHandler [ "HitPart", diff --git a/addons/frag/functions/fnc_shouldFrag.sqf b/addons/frag/functions/fnc_shouldFrag.sqf index f40d94bb9f4..de9e04b0926 100644 --- a/addons/frag/functions/fnc_shouldFrag.sqf +++ b/addons/frag/functions/fnc_shouldFrag.sqf @@ -3,10 +3,10 @@ * Author: Lambda.Tiger * This function checks whether an ammunition type should cause fragmentation * and whether any submunitions exist - * + * * Arguments: * 0: _ammo - cfgAmmo type of ammo to check - * + * * Return Value: * _shouldFrag Should the specific round fragment * @@ -20,17 +20,17 @@ params ["_ammo"]; private _shouldFrag = GVAR(shouldFragCache) get _ammo; -if !(isNil "_shouldFrag") exitWith {_shouldFrag}; +if (!isNil "_shouldFrag") exitWith {_shouldFrag}; _shouldFrag = true; private _skip = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(skip)); private _force = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(force)); private _explosive = getNumber (configFile >> "cfgAmmo" >> _ammo >> "explosive"); -private _indirectHit = getNumber(configFile >> "cfgAmmo" >> _ammo >> "indirectHit"); -private _indirectRange = getNumber(configFile >> "cfgAmmo" >> _ammo >> "indirectHitRange"); +private _indirectHit = getNumber (configFile >> "cfgAmmo" >> _ammo >> "indirectHit"); +private _indirectRange = getNumber (configFile >> "cfgAmmo" >> _ammo >> "indirectHitRange"); -if (_skip == 1 || (_force == 0 && {_explosive < 0.5 || {_indirectHit < 3 +if (_skip == 1 || (_force == 0 && {_explosive < 0.5 || {_indirectHit < 3 || {_indirectRange < 5 && _indirectHit < _indirectRange}}})) then { TRACE_5("No frag",_ammo,_skip, _explosive, _indirectRange, _indirectHit); _shouldFrag = false; diff --git a/addons/frag/functions/fnc_shouldSpall.sqf b/addons/frag/functions/fnc_shouldSpall.sqf index 9813481b1fd..393e2984c83 100644 --- a/addons/frag/functions/fnc_shouldSpall.sqf +++ b/addons/frag/functions/fnc_shouldSpall.sqf @@ -2,13 +2,13 @@ /* * Author: Lambda.Tiger * This function checks whether an ammunition type should cause spalling - * + * * * Arguments: * 0: _ammo - cfgAmmo type of ammo to check - * + * * Return Value: - * Whether the round type would spall when hitting an object + * Whether the round type would spall when hitting an object * * Example: * ["B_556x45_Ball"] call ace_frag_fnc_shouldSpall; @@ -20,7 +20,7 @@ params ["_ammo"]; private _shouldSpall = GVAR(spallRoundCache) get _ammo; -if !(isNil "_shouldSpall") exitWith {_shouldSpall}; +if (!isNil "_shouldSpall") exitWith {_shouldSpall}; private _caliber = getNumber (configFile >> "CfgAmmo" >> _ammo >> "caliber"); private _explosive = getNumber (configFile >> "CfgAmmo" >> _ammo >> "explosive"); diff --git a/addons/frag/initSettings.inc.sqf b/addons/frag/initSettings.inc.sqf index cf8f533ccce..c45702130b0 100644 --- a/addons/frag/initSettings.inc.sqf +++ b/addons/frag/initSettings.inc.sqf @@ -26,7 +26,7 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; ] call CBA_fnc_addSetting; [ - QGVAR(fragSimComplexity), "LIST", + QGVAR(fragSimComplexity), "LIST", [LSTRING(FragMode), LSTRING(FragMode_Desc)], [_category, LSTRING(Frag)], [[2, 1, 0], [LSTRING(FragMode_Opt2),LSTRING(FragMode_Opt1),LSTRING(FragMode_Opt0)], 2], @@ -34,7 +34,7 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; ] call CBA_fnc_addSetting; [ - QGVAR(atLeastOne), "CHECKBOX", + QGVAR(atLeastOne), "CHECKBOX", [LSTRING(MinFrag), LSTRING(MinFrag_Desc)], [_category, LSTRING(Frag)], false, diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index 50e248fac6a..63cc715fae9 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -24,7 +24,7 @@ #define ACE_FRAG_COUNT_MIN 5 #define ACE_FRAG_COUNT_MAX 50 #define ACE_FRAG_HITPOINTS ["spine1","spine2","spine3","head","leftarm","leftarmroll","leftforearm","rightarm","rightarmroll","rightforearm","pelvis","leftupleg","leftuplegroll","leftlegroll","leftfoot","rightupleg","rightuplegroll","rightleg","rightlegroll","rightfoot"] -#define ACE_FRAG_HITPOINTS_WEIGHTS +#define ACE_FRAG_HITPOINTS_WEIGHTS #ifdef DEBUG_MODE_FULL #define __FADE_TIME 1 diff --git a/addons/frag/stringtable.xml b/addons/frag/stringtable.xml index 2ccec341187..1eac8bcfe8f 100644 --- a/addons/frag/stringtable.xml +++ b/addons/frag/stringtable.xml @@ -253,7 +253,7 @@ (SP 전용) 임무 / 편집자가 다시 시작해야합니다. SP 게임 모드에서만 파편화 및 탄환파편의 시각적 추적을 가능하게 합니다. - (Local only) Frag/Spall Debug Tracing + (SP only) Frag/Spall Debug Tracing (Solo SP) Seguimiento de depuración de Fragmentación/Astillamiento (Tylko SP) Wizualny debug odł./odpr. (Pouze SP) Debug sledování Frag/Úlomků @@ -269,7 +269,7 @@ (僅在單人模式) 碎片/剝落除錯追蹤 - (Local only) Requires a mission/editor restart. Enables visual tracing of fragmentation and spalling rounds in SP game mode only. + (SP only) Requires a mission/editor restart. Enables visual tracing of fragmentation and spalling rounds in SP game mode only. (Solo SP) Requiere un reinicio misión/editor. Permite el seguimiento visual de la fragmentación y astillamientos de los proyectiles en modo SP. (Tylko SP) Wymaga restartu misji/edytora. Aktywuje wizualne śledzenie odłamków oraz odprysków w trybie gry Single Player. (nur SP) Splitter-/Explosions-Debugging From 6ae6b55e650cb326cab7770d00e3c29f6b8224ef Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 13 Jan 2024 00:47:32 -0600 Subject: [PATCH 081/282] Added trailing empty braces for classes that aren't actually changed --- addons/frag/CfgAmmo.hpp | 2 +- addons/frag/cfgAmmoFragParameters.hpp | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index 0f02600fbb4..27290699a5c 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -22,7 +22,7 @@ class CfgAmmo { #include "cfgAmmoBaseEH.hpp" class B_65x39_Caseless: BulletBase { - class EventHandlers: EventHandlers; + class EventHandlers: EventHandlers {}; }; class GVAR(base): B_65x39_Caseless { ACE_damageType = "grenade"; // compatibility with medical_damage, shrapnel should produce grenade wounds diff --git a/addons/frag/cfgAmmoFragParameters.hpp b/addons/frag/cfgAmmoFragParameters.hpp index 766bed06715..46a8db30cfb 100644 --- a/addons/frag/cfgAmmoFragParameters.hpp +++ b/addons/frag/cfgAmmoFragParameters.hpp @@ -178,7 +178,7 @@ class SmokeShell: GrenadeHand { GVAR(skip) = 1; }; class G_40mm_HE: GrenadeBase { - class EventHandlers: EventHandlers; + class EventHandlers: EventHandlers {}; // Source: http://www.inetres.com/gp/military/infantry/grenade/40mm_ammo.html#M441 GVAR(skip) = 1; GVAR(force) = 0; @@ -190,7 +190,7 @@ class G_40mm_HE: GrenadeBase { GVAR(gurney_k) = "3/5"; // interior fragmenter/charge is a sphere }; class G_40mm_HEDP: G_40mm_HE { - class EventHandlers: EventHandlers; + class EventHandlers: EventHandlers {}; // Source: http://www.inetres.com/gp/military/infantry/grenade/40mm_ammo.html#M433 GVAR(classes)[] = {QGVAR(small_HD)}; GVAR(fragCount) = 270; // seems to have greater framentation ability, but lower range per source @@ -201,10 +201,10 @@ class G_40mm_HEDP: G_40mm_HE { }; class ACE_G_40mm_HEDP: G_40mm_HEDP { - class EventHandlers: EventHandlers; + class EventHandlers: EventHandlers {}; }; class ACE_G_40mm_HE: G_40mm_HE { - class EventHandlers: EventHandlers; + class EventHandlers: EventHandlers {}; }; class ACE_G_40mm_Practice: ACE_G_40mm_HE { ACE_FRAG_RM_EH; @@ -220,7 +220,7 @@ class ATMine_Range_Ammo: MineBase { }; class APERSMine_Range_Ammo: MineBase { // VS-50 - class EventHandlers: EventHandlers; + class EventHandlers: EventHandlers {}; GVAR(skip) = 0; GVAR(force) = 0; GVAR(classes)[] = {QGVAR(tiny), QGVAR(tiny), QGVAR(small)}; @@ -500,11 +500,11 @@ class ACE_Hellfire_AGM114K: M_Scalpel_AT { }; class ammo_Missile_CruiseBase: MissileBase { - class EventHandlers: EventHandlers; + class EventHandlers: EventHandlers {}; GVAR(skip) = 1; }; class ammo_missile_cruise_01: ammo_Missile_CruiseBase { - class EventHandlers: EventHandlers; + class EventHandlers: EventHandlers {}; GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(large)}; GVAR(fragCount) = 20000; From fe1850a34adfbdbd690a18caf91cd134e741040c Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sun, 14 Jan 2024 18:46:52 -0600 Subject: [PATCH 082/282] Fixed issue with spalling happening on thin surfaces instead of thicker surfaces hit afterwards --- addons/frag/functions/fnc_doSpall.sqf | 6 +++--- addons/frag/functions/fnc_initRound.sqf | 5 +++-- addons/frag/script_component.hpp | 12 ++---------- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index 1bdf13e7a45..ab404d0c06a 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -73,15 +73,15 @@ GVAR(lastSpallTime) = CBA_missionTime; * Improve performance of finding otherside of object on shallow angle * impacts. 120 degrees due to 90 degree offset with _lVelUnit into object. */ -private _spallPos = +_lPosASL; +private _spallPos = _lPosASL vectorAdd _unitStep; if (120 > acos ( _lVelUnit vectorDotProduct _sNorm)) then { _spallPos = _spallPos vectorAdd (_unitStep vectorMultiply 5); }; -for "_i" from 1 to 20 do +for "_i" from 2 to 20 do { private _nPos = _spallPos vectorAdd _unitStep; if (!lineIntersects [_spallPos, _nPos]) then { - _spallPos = _nPos vectorAdd _unitStep; + _spallPos = _nPos vectorAdd (_unitStep vectorMultiply 2); break }; _spallPos = _nPos; diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index caa5bd2dda0..a542e59ee0e 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -60,9 +60,10 @@ if (GVAR(spallEnabled) && {_shouldSpall}) then private _ammo = typeOf _proj; private _vUp = vectorUp _proj; [ - GVAR(spall_eh), + FUNC(doSpall), [_proj, _hitObj, _posASL, _vel, _sNorm, _surfType, _ammo, _shotPrnt, _vUp] ] call CBA_fnc_execNextFrame; } ]; -}; \ No newline at end of file +}; +TRACE_2("exit",_shouldFrag,_shouldSpall); \ No newline at end of file diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index 63cc715fae9..982997218fa 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -3,8 +3,8 @@ #include "\z\ace\addons\main\script_mod.hpp" // #define LOG_FRAG_INFO -// #define DEBUG_MODE_FULL -// #define DEBUG_MODE_DRAW +#define DEBUG_MODE_FULL +#define DEBUG_MODE_DRAW // #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS @@ -26,14 +26,6 @@ #define ACE_FRAG_HITPOINTS ["spine1","spine2","spine3","head","leftarm","leftarmroll","leftforearm","rightarm","rightarmroll","rightforearm","pelvis","leftupleg","leftuplegroll","leftlegroll","leftfoot","rightupleg","rightuplegroll","rightleg","rightlegroll","rightfoot"] #define ACE_FRAG_HITPOINTS_WEIGHTS -#ifdef DEBUG_MODE_FULL -#define __FADE_TIME 1 -#define __FADE_START 0.5 -#define __FADE_INTERVAL 0.1 -#define __FADE_RATE __FADE_INTERVAL/__FADE_TIME/2 -#define __FADE_INIT (__FADE_TIME+__FADE_START)/__FADE_TIME/2 -#endif - #ifndef GLUE #define GLUE(g1,g2) g1##g2 #endif \ No newline at end of file From e1578188c919aa15512fd6cfa2a1de3a9255de80 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sun, 14 Jan 2024 18:47:18 -0600 Subject: [PATCH 083/282] Made debug mode semi-MP compliant --- addons/frag/functions/fnc_dev_sphereDraw.sqf | 2 +- addons/frag/script_component.hpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/frag/functions/fnc_dev_sphereDraw.sqf b/addons/frag/functions/fnc_dev_sphereDraw.sqf index c56716f20d6..ae9290d111f 100644 --- a/addons/frag/functions/fnc_dev_sphereDraw.sqf +++ b/addons/frag/functions/fnc_dev_sphereDraw.sqf @@ -45,7 +45,7 @@ if (_color select [0,1] != "(") then private _clrStr = "#(argb,8,8,3)color" + _color; private _sphere = "Sign_Sphere25cm_F" createVehicle [1,2,34]; -_sphere setObjectTexture [0, _clrStr]; +_sphere setObjectTextureGlobal [0, _clrStr]; _sphere setPosASL _posASL; GVAR(dev_eventSpheres) pushBack _sphere; diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index 982997218fa..72f4304efa6 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -3,8 +3,8 @@ #include "\z\ace\addons\main\script_mod.hpp" // #define LOG_FRAG_INFO -#define DEBUG_MODE_FULL -#define DEBUG_MODE_DRAW +// #define DEBUG_MODE_FULL +// #define DEBUG_MODE_DRAW // #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS From 3da173e0a937fb144ea94ea923230c9ba79e8b09 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sun, 14 Jan 2024 18:56:57 -0600 Subject: [PATCH 084/282] spall debug sphere improvements --- addons/frag/functions/fnc_doSpall.sqf | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index ab404d0c06a..5adf4d5fdc5 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -69,6 +69,13 @@ if (terrainIntersectASL [_lPosASL vectorAdd _unitStep, _lPosASL]) exitWith { // Passed all exitWiths GVAR(lastSpallTime) = CBA_missionTime; +#ifdef DEBUG_MODE_DRAW +if GVAR(dbgSphere) then { + [_lPosASL vectorAdd _lVelUnit, "orange"] call FUNC(dev_sphereDraw); + [_lPosASL, "yellow"] call FUNC(dev_sphereDraw); +}; +#endif + /* * Improve performance of finding otherside of object on shallow angle * impacts. 120 degrees due to 90 degree offset with _lVelUnit into object. @@ -90,8 +97,6 @@ for "_i" from 2 to 20 do #ifdef DEBUG_MODE_DRAW if GVAR(dbgSphere) then { [_spallPos, "green"] call FUNC(dev_sphereDraw); - [_lPosASL vectorAdd _lVelUnit, "orange"] call FUNC(dev_sphereDraw); - [_lPosASL, "orange"] call FUNC(dev_sphereDraw); }; #endif From eb61f5f7c0cd9784a54bc04513ae73a5c1965756 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sun, 14 Jan 2024 23:08:37 -0600 Subject: [PATCH 085/282] Updated debugging, by default tracking spheres sync properly and messages are a bit clearer --- addons/frag/XEH_postInit.sqf | 2 +- addons/frag/XEH_preInit.sqf | 3 ++- addons/frag/functions/fnc_doFrag.sqf | 4 ++-- addons/frag/functions/fnc_initBlackList.sqf | 4 ++-- addons/frag/functions/fnc_initRound.sqf | 13 +++++++++++-- addons/frag/functions/fnc_shouldSpall.sqf | 8 ++++---- 6 files changed, 22 insertions(+), 12 deletions(-) diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index 1d2b3af2673..b8b6e39f10e 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -9,7 +9,7 @@ }; #ifdef DEBUG_MODE_DRAW - if (hasInterface && GVAR(debugOptions)) then { + if (hasInterface) then { private _h = [LINKFUNC(dev_drawTrace), 0] call CBA_fnc_addPerFrameHandler; missionNamespace setVariable [QGVAR(dev_drawPFEH), _h]; ["unit", LINKFUNC(dev_switchUnitHandle), true] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/frag/XEH_preInit.sqf b/addons/frag/XEH_preInit.sqf index c13f60edb31..371d8c7a6e3 100644 --- a/addons/frag/XEH_preInit.sqf +++ b/addons/frag/XEH_preInit.sqf @@ -8,7 +8,8 @@ PREP_RECOMPILE_END; GVAR(spallMaterialCache) = createHashMap; -GVAR(spallRoundCache) = createHashMap; +GVAR(spallInfoCache) = createHashMap; +GVAR(shouldSpallCache) = createHashMap; GVAR(lastSpallTime) = -2; GVAR(shouldFragCache) = createHashMap; diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index e9d10c6b2f1..e66349a8df0 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -19,7 +19,7 @@ * * Public: No */ -TRACE_1("",_this); +TRACE_1("begin doFrag",_this); params [ ["_proj", objNull, [objNull]], ["_posASL", [0, 0, 0], [[]], [3]], @@ -41,7 +41,7 @@ if (_ammo isEqualTo "" || {_posASL isEqualTo [0, 0, 0] || _timeSince < ACE_FRAG_ TRACE_3("timeExit",_timeSince,CBA_missionTime,GVAR(lastFragTime)); }; private _maxFrags = round linearConversion [0.1, 1.5, _timeSince, ACE_FRAG_COUNT_MIN, ACE_FRAG_COUNT_MAX, true]; -TRACE_3("",_timeSince,CBA_missionTime,_maxFrags); +TRACE_3("willFrag",_timeSince,CBA_missionTime,_maxFrags); private _ammoArr = [_ammo] call FUNC(getFragInfo); diff --git a/addons/frag/functions/fnc_initBlackList.sqf b/addons/frag/functions/fnc_initBlackList.sqf index a79ed223ae2..37e2b1787b5 100644 --- a/addons/frag/functions/fnc_initBlackList.sqf +++ b/addons/frag/functions/fnc_initBlackList.sqf @@ -15,14 +15,14 @@ * Public: No */ -TRACE_1("Beginning blacklist init", GVAR(BlackList)); +TRACE_1("Beginning blacklist init", GVAR(blackList)); if (!ADDON) then { [FUNC(initBlackList), [], 1] call CBA_fnc_waitAndExecute; }; // could improve text parsing of CBA setting string -private _convArray = parseSimpleArray GVAR(BlackList); +private _convArray = parseSimpleArray GVAR(blackList); if (count _convArray == 0 ) exitWith { TRACE_1("Empty blacklist", _convArray); diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index a542e59ee0e..8b25afb3225 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -14,7 +14,7 @@ * * Public: No */ - TRACE_1("",_this); + TRACE_1("ACE_Frag rndInit",_this); params [ ["_projectile", objNull, [objNull]] ]; @@ -59,6 +59,10 @@ if (GVAR(spallEnabled) && {_shouldSpall}) then private _shotPrnt = getShotParents _proj; private _ammo = typeOf _proj; private _vUp = vectorUp _proj; + /* + * Wait a round to see what happens to the round, may result in + * multiple hits / slowdowns getting shunted to the first hit + */ [ FUNC(doSpall), [_proj, _hitObj, _posASL, _vel, _sNorm, _surfType, _ammo, _shotPrnt, _vUp] @@ -66,4 +70,9 @@ if (GVAR(spallEnabled) && {_shouldSpall}) then } ]; }; -TRACE_2("exit",_shouldFrag,_shouldSpall); \ No newline at end of file +#ifdef DEBUG_MODE_DRAW +if (GVAR(debugOptions) && (_shouldFrag || _shouldSpall)) then { + [_projectile, "red", true] call FUNC(dev_trackObj); +}; +#endif +TRACE_2("initExit",_shouldFrag,_shouldSpall); \ No newline at end of file diff --git a/addons/frag/functions/fnc_shouldSpall.sqf b/addons/frag/functions/fnc_shouldSpall.sqf index 393e2984c83..1d77a072568 100644 --- a/addons/frag/functions/fnc_shouldSpall.sqf +++ b/addons/frag/functions/fnc_shouldSpall.sqf @@ -18,16 +18,16 @@ params ["_ammo"]; -private _shouldSpall = GVAR(spallRoundCache) get _ammo; +private _shouldSpall = GVAR(shouldSpallCache) get _ammo; if (!isNil "_shouldSpall") exitWith {_shouldSpall}; private _caliber = getNumber (configFile >> "CfgAmmo" >> _ammo >> "caliber"); private _explosive = getNumber (configFile >> "CfgAmmo" >> _ammo >> "explosive"); -private _idH = getNumber (configFile >> "CfgAmmo" >> _ammo >> "indirectHitRange"); +private _indirectHit = getNumber (configFile >> "CfgAmmo" >> _ammo >> "indirectHitRange"); -_shouldSpall = _caliber >= 2.5 || (_explosive > 0 && _idh >= 1); +_shouldSpall = _caliber * GVAR(spallIntensity) >= 2.5 || (_explosive >= 0.5 && _explosive * _indirectHit * GVAR(spallIntensity) >= 4); -GVAR(spallRoundCache) set [_ammo, _shouldSpall]; +GVAR(shouldSpallCache) set [_ammo, _shouldSpall]; _shouldSpall \ No newline at end of file From d51a9543b96aa022f3142099e51c374c789fab67 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sun, 14 Jan 2024 23:09:08 -0600 Subject: [PATCH 086/282] updated settings defaults --- addons/frag/initSettings.inc.sqf | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/addons/frag/initSettings.inc.sqf b/addons/frag/initSettings.inc.sqf index c45702130b0..0e14fe4daf0 100644 --- a/addons/frag/initSettings.inc.sqf +++ b/addons/frag/initSettings.inc.sqf @@ -30,7 +30,7 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; [LSTRING(FragMode), LSTRING(FragMode_Desc)], [_category, LSTRING(Frag)], [[2, 1, 0], [LSTRING(FragMode_Opt2),LSTRING(FragMode_Opt1),LSTRING(FragMode_Opt0)], 2], - true + 1 ] call CBA_fnc_addSetting; [ @@ -38,23 +38,26 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; [LSTRING(MinFrag), LSTRING(MinFrag_Desc)], [_category, LSTRING(Frag)], false, - true + 1 ] call CBA_fnc_addSetting; [ - QGVAR(BlackList), "EDITBOX", + QGVAR(blackList), "EDITBOX", [LSTRING(DefBlackList), LSTRING(DefBlackList_Desc)], [_category, LSTRING(Frag)], QUOTE(['B_556x45_Ball']), - true, + 1, nil, true ] call CBA_fnc_addSetting; [ - QGVAR(SpallIntensity), "SLIDER", + QGVAR(spallIntensity), "SLIDER", [LSTRING(SpallIntensity), LSTRING(SpallIntensity_Desc)], [_category, LSTRING(Spall)], [0.1, 2, 1, 1], - true + 1, + { + GVAR(shouldSpallCache) = createHashMap; + } ] call CBA_fnc_addSetting; From 97547700d27f640fb1654f5bb1aff2af696d51d9 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sun, 14 Jan 2024 23:10:15 -0600 Subject: [PATCH 087/282] Added spall info caching and made variable name changes for clarity --- addons/frag/XEH_PREP.hpp | 1 + addons/frag/functions/fnc_doSpall.sqf | 52 ++++++++++++++-------- addons/frag/functions/fnc_getSpallInfo.sqf | 35 +++++++++++++++ 3 files changed, 69 insertions(+), 19 deletions(-) create mode 100644 addons/frag/functions/fnc_getSpallInfo.sqf diff --git a/addons/frag/XEH_PREP.hpp b/addons/frag/XEH_PREP.hpp index 326ccc82a52..0dae97ada5f 100644 --- a/addons/frag/XEH_PREP.hpp +++ b/addons/frag/XEH_PREP.hpp @@ -26,6 +26,7 @@ PREP(doFragRandom); PREP(shouldSpall); PREP(doSpall); PREP(getMaterialInfo); +PREP(getSpallInfo); PREP(initMaterialCache); // Explosive Reflection diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index 5adf4d5fdc5..b93e9e0330b 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -15,7 +15,7 @@ * * Public: No */ -TRACE_1("",_this); +TRACE_1("doSpall",_this); params [ "_projectile", ["_hitObj", objNull], @@ -42,20 +42,28 @@ if (_material isEqualTo "ground") then { #endif }; +// Find spall speed / fragment info +[_ammo] call FUNC(getSpallInfo) params ["_caliber", "_explosive", "_indirectHit"]; private _vel = if (alive _projectile) then { - velocity _projectile; + _explosive = 0; // didn't explode + velocity _projectile } else { - [0, 0, 0] + [0, 0, 0]; }; -// Find spall speed / fragment private _dV = vectorMagnitude _lVel - vectorMagnitude _vel; -private _caliber = getNumber (configFile >> "cfgAmmo" >> _ammo >> "caliber"); -// scaled momentum change made on caliber-mass assumption ~sqrt(2)/20 * caliber ~= mass -private _deltaMomentum = 0.0707 * _caliber * sqrt( _dV ) * GVAR(SpallIntensity); -TRACE_3("found speed",_dV,_caliber,_deltaMomentum); +/* + * This is all fudge factor since real spalling is too complex for calculation. + * There are two terms. The first is from round impact, taking a quasi scale + * of sqrt(2)/50 * round caliber * srqt(change in speed). The second term is + * explosive * indirect hit, for any explosive contribution + */ +private _spallPower = (0.02828 * _caliber * sqrt _dV + _explosive * _indirectHit) * GVAR(spallIntensity); +TRACE_3("found speed",_dV,_caliber,_spallPower); +TRACE_3("energy",0.02828*_caliber*sqrt(_dV),_explosive*_indirectHit,0.02828*_caliber*sqrt(_dV)+_explosive*_indirectHit); + -if (_deltaMomentum < 2) exitWith { +if (_spallPower < 2) exitWith { TRACE_1("lowImpulse",_ammo); }; @@ -66,8 +74,6 @@ private _unitStep = _lVelUnit vectorMultiply 0.05; if (terrainIntersectASL [_lPosASL vectorAdd _unitStep, _lPosASL]) exitWith { TRACE_3("terrainIntersect",_lPosASL,_unitStep,_lPosASL); }; -// Passed all exitWiths -GVAR(lastSpallTime) = CBA_missionTime; #ifdef DEBUG_MODE_DRAW if GVAR(dbgSphere) then { @@ -84,16 +90,24 @@ private _spallPos = _lPosASL vectorAdd _unitStep; if (120 > acos ( _lVelUnit vectorDotProduct _sNorm)) then { _spallPos = _spallPos vectorAdd (_unitStep vectorMultiply 5); }; -for "_i" from 2 to 20 do +private _insideObject = true; +for "_i" from 2 to 21 do { private _nPos = _spallPos vectorAdd _unitStep; if (!lineIntersects [_spallPos, _nPos]) then { _spallPos = _nPos vectorAdd (_unitStep vectorMultiply 2); + _insideObject = false; break }; _spallPos = _nPos; }; +if (_insideObject) exitWith { + TRACE_3("insideObj",_lPosASL,_spallPos,alive _projectile); +}; +// Passed all exitWiths +GVAR(lastSpallTime) = CBA_missionTime; + #ifdef DEBUG_MODE_DRAW if GVAR(dbgSphere) then { [_spallPos, "green"] call FUNC(dev_sphereDraw); @@ -102,14 +116,14 @@ if GVAR(dbgSphere) then { private _spawnSize = switch (true) do { - case (_deltaMomentum < 3): { "_spall_tiny" }; - case (_deltaMomentum < 5): { "_spall_small" }; - case (_deltaMomentum < 8): { "_spall_medium" }; - case (_deltaMomentum < 12): { "_spall_large" }; + case (_spallPower < 3): { "_spall_tiny" }; + case (_spallPower < 5): { "_spall_small" }; + case (_spallPower < 8): { "_spall_medium" }; + case (_spallPower < 12): { "_spall_large" }; default { "_spall_huge" }; }; -private _spallSpawner = createVehicle [ +/*private _spallSpawner = createVehicle [ "ace_frag_" + _material + _spawnSize, ASLToATL _spallPos, [], @@ -118,10 +132,10 @@ private _spallSpawner = createVehicle [ ]; _spallSpawner setVectorDirandUp [_lVelUnit, _vUp]; _spallSpawner setVelocity (_lVelUnit vectorMultiply (_dV/2)); -_spallSpawner setShotParents _shotParents; +_spallSpawner setShotParents _shotParents;*/ #ifdef DEBUG_MODE_FULL -systemChat ("bSpd: " + str speed _spallSpawner + ", frag: " + _fragSpawnType + ", dm: " + str _deltaMomentum); +systemChat ("bSpd: " + str speed _spallSpawner + ", frag: " + _fragSpawnType + ", dm: " + str _spallPower); #endif #ifdef DEBUG_MODE_DRAW _spallSpawner addEventHandler [ diff --git a/addons/frag/functions/fnc_getSpallInfo.sqf b/addons/frag/functions/fnc_getSpallInfo.sqf new file mode 100644 index 00000000000..6cb6970c9a5 --- /dev/null +++ b/addons/frag/functions/fnc_getSpallInfo.sqf @@ -0,0 +1,35 @@ +#include "..\script_component.hpp" +/* + * Author: Lambda.Tiger + * This function returns spalling parameters for a specific + * ammo type. + * + * Arguments: + * 0: _ammo - cfgAmmo type of ammo to check + * + * Return Value: + * _ammoInfo + * 0: _caliber - search range for fragments + * 1: _explosive - whether the round is explosive or not + * 2: _indirectHitRange - Indirect hit damage + * + * Example: + * ["B_556x45_Ball"] call ace_frag_fnc_getSpallInfo; + * + * Public: No + */ + +params ["_ammo"]; + +private _ammoInfo = GVAR(spallInfoCache) get _ammo; + +if (!isNil "_ammoInfo") exitWith {_ammoInfo}; + +private _caliber = getNumber (configFile >> "CfgAmmo" >> _ammo >> "caliber"); +private _explosive = 1 min getNumber (configFile >> "CfgAmmo" >> _ammo >> "explosive"); +private _indirectHit = getNumber (configFile >> "CfgAmmo" >> _ammo >> "indirectHitRange"); +private _ammoInfo = [_caliber, _explosive, _indirectHit]; + +GVAR(spallInfoCache) set [_ammo, _ammoInfo]; + +_ammoInfo \ No newline at end of file From 5273b002f912c846039e69ab73b454397ab881d9 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 01:18:47 -0600 Subject: [PATCH 088/282] Replaced a magic number --- addons/frag/functions/fnc_doSpall.sqf | 7 +++---- addons/frag/script_component.hpp | 6 ++++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index b93e9e0330b..a12e0b47c9e 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -58,9 +58,8 @@ private _dV = vectorMagnitude _lVel - vectorMagnitude _vel; * of sqrt(2)/50 * round caliber * srqt(change in speed). The second term is * explosive * indirect hit, for any explosive contribution */ -private _spallPower = (0.02828 * _caliber * sqrt _dV + _explosive * _indirectHit) * GVAR(spallIntensity); +private _spallPower = (ACE_FRAG_ROUND_COEF * _caliber * sqrt _dV + _explosive * _indirectHit) * GVAR(spallIntensity); TRACE_3("found speed",_dV,_caliber,_spallPower); -TRACE_3("energy",0.02828*_caliber*sqrt(_dV),_explosive*_indirectHit,0.02828*_caliber*sqrt(_dV)+_explosive*_indirectHit); if (_spallPower < 2) exitWith { @@ -123,7 +122,7 @@ private _spawnSize = switch (true) do default { "_spall_huge" }; }; -/*private _spallSpawner = createVehicle [ +private _spallSpawner = createVehicle [ "ace_frag_" + _material + _spawnSize, ASLToATL _spallPos, [], @@ -132,7 +131,7 @@ private _spawnSize = switch (true) do ]; _spallSpawner setVectorDirandUp [_lVelUnit, _vUp]; _spallSpawner setVelocity (_lVelUnit vectorMultiply (_dV/2)); -_spallSpawner setShotParents _shotParents;*/ +_spallSpawner setShotParents _shotParents; #ifdef DEBUG_MODE_FULL systemChat ("bSpd: " + str speed _spallSpawner + ", frag: " + _fragSpawnType + ", dm: " + str _spallPower); diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index 72f4304efa6..14b91808a09 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -3,8 +3,8 @@ #include "\z\ace\addons\main\script_mod.hpp" // #define LOG_FRAG_INFO -// #define DEBUG_MODE_FULL -// #define DEBUG_MODE_DRAW +#define DEBUG_MODE_FULL +#define DEBUG_MODE_DRAW // #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS @@ -25,6 +25,8 @@ #define ACE_FRAG_COUNT_MAX 50 #define ACE_FRAG_HITPOINTS ["spine1","spine2","spine3","head","leftarm","leftarmroll","leftforearm","rightarm","rightarmroll","rightforearm","pelvis","leftupleg","leftuplegroll","leftlegroll","leftfoot","rightupleg","rightuplegroll","rightleg","rightlegroll","rightfoot"] #define ACE_FRAG_HITPOINTS_WEIGHTS +// sqrt(2)/50 +#define ACE_FRAG_ROUND_COEF 0.02828427 #ifndef GLUE #define GLUE(g1,g2) g1##g2 From 63cd1ed06a57cccabdf4fbed14874c43e10ad126 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 01:33:25 -0600 Subject: [PATCH 089/282] Last commit had debug staements uncommented --- addons/frag/script_component.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index 14b91808a09..f9006a249e5 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -3,8 +3,8 @@ #include "\z\ace\addons\main\script_mod.hpp" // #define LOG_FRAG_INFO -#define DEBUG_MODE_FULL -#define DEBUG_MODE_DRAW +// #define DEBUG_MODE_FULL +// #define DEBUG_MODE_DRAW // #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS From f28d5d23720f64928d5879431dc3bb75f76224bf Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 13:13:59 -0600 Subject: [PATCH 090/282] Reswept dev functions to match ACE code guidelines --- addons/frag/functions/fnc_dev_addRound.sqf | 76 ++++++++----------- addons/frag/functions/fnc_dev_clearTraces.sqf | 7 +- addons/frag/functions/fnc_dev_debugAmmo.sqf | 16 ++-- addons/frag/functions/fnc_dev_drawTrace.sqf | 33 ++++---- addons/frag/functions/fnc_dev_fired.sqf | 5 +- .../frag/functions/fnc_dev_fragCalcDump.sqf | 55 +++++--------- addons/frag/functions/fnc_dev_sphereDraw.sqf | 18 ++--- .../functions/fnc_dev_switchUnitHandle.sqf | 22 ++++-- addons/frag/functions/fnc_dev_trackHitBox.sqf | 38 +++++----- addons/frag/functions/fnc_dev_trackObj.sqf | 68 ++++++++--------- 10 files changed, 153 insertions(+), 185 deletions(-) diff --git a/addons/frag/functions/fnc_dev_addRound.sqf b/addons/frag/functions/fnc_dev_addRound.sqf index 235a9903d86..b88d5745045 100644 --- a/addons/frag/functions/fnc_dev_addRound.sqf +++ b/addons/frag/functions/fnc_dev_addRound.sqf @@ -12,87 +12,77 @@ * None * * Example: - * [_proj, false, false] call ace_frag_dev_addRound; + * [_projectile, false, false] call ace_frag_dev_addRound; * * Public: No */ params [ - "_proj", - ["_addEHs", true, [true]], - ["_sidePlayer", true, [true]] + "_projectile", + ["_addProjectileEventHandlers", true, [true]], + ["_isSidePlayer", true, [true]] ]; // track round on each frame // Create entry in position array from hashmap -if (_sidePlayer) then -{ - GVAR(dev_trackLines) set [getObjectID _proj, [1, [getposATL _proj], [0, 0, 1, 1]]]; -} else -{ - GVAR(dev_trackLines) set [getObjectID _proj, [1, [getposATL _proj], [1, 0, 0, 1]]]; +if (_isSidePlayer) then { + GVAR(dev_trackLines) set [getObjectID _projectile, [[getposATL _projectile], [0, 0, 1, 1]]]; +} else { + GVAR(dev_trackLines) set [getObjectID _projectile, [[getposATL _projectile], [1, 0, 0, 1]]]; }; // eventhandler to track round and cleanup when round is "dead" [ { if (isGamePaused) exitWith {}; - params ["_par", "_h"]; - _par params ["_proj"]; - if (!alive _proj) exitWith - { - [_h] call CBA_fnc_removePerFrameHandler; - }; - private _arr = GVAR(dev_trackLines) getOrDefault [(getObjectID _proj), -1]; - if (typeName _arr == "SCALAR") exitWith {}; - (_arr#1) pushBack getPosATL _proj; - if (_arr#0 <= 0) exitWith - { - [_h] call CBA_fnc_removePerFrameHandler; + params ["_par", "_handle"]; + _par params ["_projectile"]; + if (!alive _projectile) exitWith { + [_handle] call CBA_fnc_removePerFrameHandler; }; + private _projectileArray = GVAR(dev_trackLines) getOrDefault [(getObjectID _projectile), -1]; + if (typeName _projectileArray == "SCALAR") exitWith {}; + (_projectileArray#0) pushBack getPosATL _projectile; }, 0, - [_proj] + [_projectile] ] call CBA_fnc_addPerFrameHandler; -if (!_addEHs) exitWith {}; +if (!_addProjectileEventHandlers) exitWith {}; // Add hitpart eventHandler -_proj addEventHandler [ +_projectile addEventHandler [ "HitPart", { - params ["_proj", "", "", "_posASL"]; - private _arr = (GVAR(dev_trackLines) get (getObjectID _proj))#1; - _arr pushBack ASLtoATL _posASL; - if (GVAR(dbgSphere)) then - { + params ["_projectile", "", "", "_posASL"]; + private _posArr = (GVAR(dev_trackLines) get (getObjectID _projectile))#0; + _posArr pushBack ASLtoATL _posASL; + if (GVAR(dbgSphere)) then { [_posASL, "green"] call FUNC(dev_sphereDraw); }; } ]; // Add explode eventHandler -_proj addEventHandler [ +_projectile addEventHandler [ "Explode", { - params ["_proj", "_posASL"]; - private _arr = (GVAR(dev_trackLines) get (getObjectID _proj))#1; - _arr pushBack ASLtoATL _posASL; - if (GVAR(dbgSphere)) then - { + params ["_projectile", "_posASL"]; + private _posArr = (GVAR(dev_trackLines) get (getObjectID _projectile))#0; + _posArr pushBack ASLtoATL _posASL; + if (GVAR(dbgSphere)) then { [_posASL, "red"] call FUNC(dev_sphereDraw); }; } ]; // Add deflected eventHandler -_proj addEventHandler [ +_projectile addEventHandler [ "Deflected", { - params ["_proj", "_posASL"]; - private _arr = (GVAR(dev_trackLines) get (getObjectID _proj))#1; - _arr pushBack ASLtoATL _posASL; - if (GVAR(dbgSphere)) then - { + params ["_projectile", "_posASL"]; + private _posArr = (GVAR(dev_trackLines) get (getObjectID _projectile))#0; + _posArr pushBack ASLtoATL _posASL; + if (GVAR(dbgSphere)) then { [_posASL, "blue"] call FUNC(dev_sphereDraw); }; } -]; \ No newline at end of file +]; diff --git a/addons/frag/functions/fnc_dev_clearTraces.sqf b/addons/frag/functions/fnc_dev_clearTraces.sqf index 27cd0fe4b6e..132d3be0860 100644 --- a/addons/frag/functions/fnc_dev_clearTraces.sqf +++ b/addons/frag/functions/fnc_dev_clearTraces.sqf @@ -14,11 +14,10 @@ * * Public: No */ -GVAR(dev_trackLines) = createHashMap; -for "_i" from 0 to count GVAR(dev_eventSpheres) - 1 do -{ +for "_i" from 0 to count GVAR(dev_eventSpheres) - 1 do { deleteVehicle (GVAR(dev_eventSpheres)#_i); }; -GVAR(dev_eventSpheres) = +[]; +GVAR(dev_eventSpheres) = []; +GVAR(dev_trackLines) = createHashMap; GVAR(dev_hitBoxes) = createHashMap; \ No newline at end of file diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index 90f26f1922c..e543f43af55 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -9,7 +9,7 @@ * 0: Log ammo types that wouldn't normall frag * 1: Only export ammo classes of classes referenced in cfgAmmo * and their submunitions. - * 2: Force a CSV format + * 2: Force a CSV format on debug print * * Return Value: * None @@ -20,7 +20,7 @@ * Public: No */ params [ - ["_debugForce", false, [false]], + ["_logAll", false, [false]], ["_onlyShotAmmoTypes", false, [false]], ["_csvFormat", false, [false]] ]; @@ -33,7 +33,7 @@ if (_csvFormat) then { // Gather all configs, either those that could be created from firing or all classes private _allAmmoConfigs = []; if (_onlyShotAmmoTypes) then { - private _searchFunc = { + private _configSearchFunc = { params [ ["_ammo", "", [""]] ]; @@ -44,17 +44,17 @@ if (_onlyShotAmmoTypes) then { _subMunit = getArray (configFile >> "cfgAmmo" >> _ammo >> "submunitionAmmo"); for "_i" from 0 to count _subMunit - 1 do { if (_i mod 2 == 0) then { - [toLower (_subMunit#_i)] call _searchFunc; + [toLower (_subMunit#_i)] call _configSearchFunc; }; }; } else { - [toLower _subMunit] call _searchFunc; + [toLower _subMunit] call _configSearchFunc; }; }; private _allMagazineConfigs = configProperties [configFile >> "cfgMagazines", "isClass _x", true]; { - [toLower getText (_x >> "ammo")] call _searchFunc; + [toLower getText (_x >> "ammo")] call _configSearchFunc; } forEach _allMagazineConfigs; } else { _allAmmoConfigs = configProperties [configFile >> "cfgAmmo", "isClass _x && !('ace_frag' in configName _x)", true] apply {configName _x}; @@ -70,7 +70,7 @@ private _printCount = 0; private _ammoConfig = (configFile >> "cfgAmmo" >> _ammo); private _shoulFrag = [_ammo] call FUNC(shouldFrag); - if (_shoulFrag || _debugForce) then { + if (_shoulFrag || _logAll) then { private _warn = false; private _fragTypes = getArray (_ammoConfig >> QGVAR(CLASSES)); @@ -100,4 +100,4 @@ private _printCount = 0; } forEach _allAmmoConfigs; diag_log text format ["~~~~~~~~~~~~~~End [%1-%2]~~~~~~~~~~~~~~", count _allAmmoConfigs, count _processedCfgAmmos]; -diag_log text format ["~~~~~~~~~~~~~~Printed: %1~~~~~~~~~~~", _printCount]; \ No newline at end of file +diag_log text format ["~~~~~~~~~~~~~~Printed: %1~~~~~~~~~~~", _printCount]; diff --git a/addons/frag/functions/fnc_dev_drawTrace.sqf b/addons/frag/functions/fnc_dev_drawTrace.sqf index 2dcea81256f..41d717c4e80 100644 --- a/addons/frag/functions/fnc_dev_drawTrace.sqf +++ b/addons/frag/functions/fnc_dev_drawTrace.sqf @@ -1,5 +1,5 @@ #include "..\script_component.hpp" -#define HB_DRAW_ARRS [[3 , 2 , 1 , 5 , 6 , 7 , 3 , 0 , 4 , 5], [0, 1], [2, 6], [7, 4]] +#define HITBOX_DRAW_PATH [[3 , 2 , 1 , 5 , 6 , 7 , 3 , 0 , 4 , 5], [0, 1], [2, 6], [7, 4]] /* * Author: Lambda.Tiger * Per frame function to draw all dev traces @@ -15,38 +15,33 @@ * Public: No */ -private _deleteArr = []; { - if (count (_y#1) > 1) then - { - for "_j" from 1 to count (_y#1) - 1 do - { - drawLine3D [_y#1#(_j-1), _y#1#_j, _y#2]; + _y params ["_posArray", "_color"] + if (count (_posArray) > 1) then { + for "_j" from 1 to count _posArray - 1 do { + drawLine3D [_posArray#(_j-1), _posArray#_j, _color]; }; }; } forEach GVAR(dev_trackLines); if (GVAR(drawHitBox)) then { - _deleteArr = []; + private _deleteArr = []; { - _y params ["_obj", "_pts", "_color"]; - if (!alive _obj) then - { + _y params ["_object", "_boxPoints", "_color"]; + if (!alive _object) then { _deleteArr pushBack _x; continue; }; { - for "_i" from 1 to count _x -1 do - { - drawLine3D [_obj modelToWorld (_pts#(_x#_i)), _obj modelToWorld (_pts#(_x#(_i-1))), _color]; + for "_i" from 1 to count _x -1 do { + drawLine3D [_object modelToWorld (_boxPoints#(_x#_i)), _object modelToWorld (_boxPoints#(_x#(_i-1))), _color]; }; - } forEach HB_DRAW_ARRS; + } forEach HITBOX_DRAW_PATH; } forEach GVAR(dev_hitBoxes); - for "_i" from 0 to count _deleteArr - 1 do { - GVAR(dev_hitBoxes) deleteAt (_deleteArr#_i); - }; -}; \ No newline at end of file + GVAR(dev_hitBoxes) deleteAt _x; + } forEach _deleteArr; +}; diff --git a/addons/frag/functions/fnc_dev_fired.sqf b/addons/frag/functions/fnc_dev_fired.sqf index b04b07ea6bb..aa5e59a33a1 100644 --- a/addons/frag/functions/fnc_dev_fired.sqf +++ b/addons/frag/functions/fnc_dev_fired.sqf @@ -14,5 +14,6 @@ * * Public: No */ - -[_projectile, true, ((side _unit) getFriend (side ACE_player)) >= 0.6] call FUNC(dev_addRound); \ No newline at end of file +//IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; +TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +[_projectile, true, ((side _unit) getFriend (side ACE_player)) >= 0.6] call FUNC(dev_addRound); diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf index 7b382fa073d..cad51f98e9e 100644 --- a/addons/frag/functions/fnc_dev_fragCalcDump.sqf +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -2,13 +2,13 @@ /* * Author: Lambda.Tiger, based on fnc_dev_debugAmmo by "ACE-Team" * Dumps all ammo types to see if there's any reason to spawn fragments - * given power, distance, and lifetime of each fragement. Good for grasping - * the values used in shouldFrag to cull non-fragementing rounds + * given hit power and distance. Good for grasping the values used in + * shouldFrag to cull non-fragementing rounds * * Arguments: - * 0: _dispAll - Display rounds that will never frag (power < 5). + * 0: _logAll - Display rounds that will never frag (power < 5). * Default value false - * 1: _minFrgPowRng - minimum range for sqrt power calculation + * 1: _minFragPower - minimum range for sqrt power calculation * * Return Value: * None @@ -19,53 +19,40 @@ * Public: No */ -params [["_dispAll", false, [false]], ["_minFrgPowRng", 35, [123]]]; +params [ + ["_logAll", false, [false]], + ["_minFragPower", 35, [123]] +]; -#define DT 0.01 private _allAmmoConfigs = configProperties [configFile >> "cfgAmmo", "isClass _x && !('ace_frag' in configName _x)", true]; private _processedCfgAmmos = []; - - private _nPrinted = 0; diag_log text "//****************** fragCalcDump Beg ******************//"; -// Processing ammo types -{ +{ // Begin _allAmmoConfigs forEach private _ammo = toLower configName _x; - if (_ammo == "" || {_ammo in _processedCfgAmmos} ) then {continue}; - - - // calculating hit range - _shouldFrag = [_ammo] call FUNC(shouldFrag); + if (_ammo == "" || {_ammo in _processedCfgAmmos} ) then { continue }; - // Gunery equation - private _c = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(CHARGE)); - if (_c == 0) then {_c = 1;}; - private _m = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(METAL)); - if (_m == 0) then {_m = 2;}; - private _k = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(GURNEY_K)); - if (_k == 0) then {_k = 0.8;}; - private _gC = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(GURNEY_C)); - if (_gC == 0) then {_gC = 2440;}; - private _fragCount = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(fragCount)); - if (_fragCount == 0) then {_fragCount = 200;}; - private _velocity = 0.8 * _gC * sqrt (_c /(_m + _c * _k)); - // number of shrapnel to send a direction - private _count = ceil (random (sqrt (_m / 1000))); - private _fragPowerSpeedRange = [0.5, 1] vectorMultiply _fragPower; + private _shouldFrag = [_ammo] call FUNC(shouldFrag); + if (_nSkip || _logAll) then { + private _fragInfo = [_ammo] call FUNC(getFragInfo); + _fragInfo params ["_fragRange", "_fragMaxVelocity", "", "_modifiedFragCount"] + private _fragCount = 4 * pi* _modifiedFragCount; + private _indirectHitRange = getNumber (configFile >> "cfgAmmo" >> _ammo >> "indirectHitRange"); + private _indirectHit = getNumber (configFile >> "cfgAmmo" >> _ammo >> "indirectHit"); + private _fragPowerSpeedRange = [0.5, 1] vectorMultiply _fragMaxVelocity; - if (_nSkip || _dispALl) then - { diag_log text format ["Ammo type: %1 | Should frag: %2", _ammo, _shouldFrag]; diag_log text format [" Indirect hit range: %1", _indirectHitRange]; + diag_log text format [" Indirect hit: %1", _indirectHit]; diag_log text format [" Frag sqrtPower: %1", _fragPowerSqrt]; diag_log text format [" Frag range: %1", _fragRange]; diag_log text format [" Frag speed range: %1", _fragPowerSpeedRange]; - diag_log text format [" Number frags: %1", _count]; + diag_log text format [" Number frags: %1", _fragCount]; INC(_nPrinted); }; @@ -73,4 +60,4 @@ diag_log text "//****************** fragCalcDump Beg ******************//"; } forEach _allAmmoConfigs; diag_log text "//****************** fragCalcDump End ******************//"; -diag_log text format ["//********************** printed %1 *********************//", _nPrinted]; \ No newline at end of file +diag_log text format ["//********************** printed %1 *********************//", _nPrinted]; diff --git a/addons/frag/functions/fnc_dev_sphereDraw.sqf b/addons/frag/functions/fnc_dev_sphereDraw.sqf index ae9290d111f..3ed344a8977 100644 --- a/addons/frag/functions/fnc_dev_sphereDraw.sqf +++ b/addons/frag/functions/fnc_dev_sphereDraw.sqf @@ -20,18 +20,15 @@ params [ ["_color", "(1,0,0,0.5)", [""]] ]; -if (count _posASL < 3) then -{ +if (count _posASL < 3) then { _posASL pushBack 0; _posASL = ASLtoATL _posASL; _posASL set [2, 0]; _posASL = ATLtoASL _posASL; }; -if (_color select [0,1] != "(") then -{ - switch (toLower _color) do - { +if (_color select [0,1] != "(") then { + switch (toLower _color) do { case "blue": { _color = "(0,0,0.8,0.5)"; }; case "black": { _color = "(1,1,1,0.5)"; }; case "white": { _color = "(0,0,0,0.5)"; }; @@ -42,11 +39,10 @@ if (_color select [0,1] != "(") then default { _color = "(0.8,0.8,0,0.5)";}; }; }; -private _clrStr = "#(argb,8,8,3)color" + _color; +private _colorString = "#(argb,8,8,3)color" + _color; -private _sphere = "Sign_Sphere25cm_F" createVehicle [1,2,34]; -_sphere setObjectTextureGlobal [0, _clrStr]; -_sphere setPosASL _posASL; +private _sphere = createVehicle ["Sign_Sphere25cm_F", ASLtoATL _posASL, [], 0, "CAN_COLLIDE"]; +_sphere setObjectTextureGlobal [0, _colorString]; GVAR(dev_eventSpheres) pushBack _sphere; -_sphere; \ No newline at end of file +_sphere; diff --git a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf index 510e5b02e5e..9d9050b042e 100644 --- a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf +++ b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf @@ -15,20 +15,26 @@ * * Public: No */ -params ["_lVic", "_cVic"]; +params ["_lastUnit", "_currentUnit"]; -if (_cVic isEqualTo objNull || {!local _cVic || _lVic isEqualTo _cVic}) exitWith {}; +if (_currentUnit isEqualTo objNull || {_lastUnit isEqualTo _currentUnit}) exitWith {}; +if (!local _currentUnit) exitWith { + [ + {local _currentUnit}, + FUNC(dev_switchUnitHandle), + _this, + 5 + ] call CBA_fnc_waitUntilAndExecute; +}; private _aID = missionNamespace getVariable [QGVAR(dev_clearTraceAction), -1]; -if (_aID > -1 && {_lVic isNotEqualTo objNull}) then -{ - _lVic removeAction _aID; +if (_aID > -1 && {_lastUnit isNotEqualTo objNull}) then { + _lastUnit removeAction _aID; }; -_aID = _cVic addAction -[ +_aID = _currentUnit addAction [ "Reset Lines", FUNC(dev_clearTraces), nil, // arguments @@ -40,4 +46,4 @@ _aID = _cVic addAction 8 ]; -missionNamespace getVariable [QGVAR(dev_clearTraceAction), _aID]; \ No newline at end of file +missionNamespace getVariable [QGVAR(dev_clearTraceAction), _aID]; diff --git a/addons/frag/functions/fnc_dev_trackHitBox.sqf b/addons/frag/functions/fnc_dev_trackHitBox.sqf index a4522d771ed..447db9eca20 100644 --- a/addons/frag/functions/fnc_dev_trackHitBox.sqf +++ b/addons/frag/functions/fnc_dev_trackHitBox.sqf @@ -4,8 +4,8 @@ * Add a hitbox outline to an object * * Arguments: - * 0: Object to draw hitbox - * 1: Add center sphere + * 0 : Object to draw hitbox + * 1 : Add sphere at object origin * * Return Value: * None @@ -16,44 +16,44 @@ * Public: No */ params [ - ["_obj", objNull, [objNull]], - ["_addSphere", true, [false]] + ["_object", objNull, [objNull]], + ["_addSphere", true, [turretLocal]] ]; -if (isNull _obj) exitWith {}; +if (isNull _object) exitWith {}; // Grab the right hitBox private _box = []; -if (_obj isKindOf "CAManBase") then { - if (vehicle _obj == _obj) then { - _box = 0 boundingBox _obj; +if (_object isKindOf "CAManBase") then { + if (isNull objectParent _object) then { + _box = 0 boundingBox _object; } else { - _box = boundingBoxReal [_obj, "Geometry"]; + _box = boundingBoxReal [_object, "Geometry"]; }; } else { - _box = boundingBoxReal [_obj, "FireGeometry"]; + _box = boundingBoxReal [_object, "FireGeometry"]; }; _box params ["_lowP","_upP"]; // adjust with stance -private _stance = stance _obj; +private _stance = stance _object; switch (true) do { case (_stance isEqualTo "STAND"): {_upP set [2, 1.9];}; case (_stance isEqualTo "CROUCH"): {_upP set [2, 1.3];}; case (_stance isEqualTo "PRONE"): {_upP set [2, 0.8];}; }; -private _centerPoint = ASLToAGL getPosASL _obj; +private _centerPoint = ASLToAGL getPosASL _object; -if (GVAR(dbgSphere) && {_addSphere && {vehicle _obj isEqualTo _obj}}) then { - private _centerSphere = [getPosASL _obj, "yellow"] call FUNC(dev_sphereDraw); - _centerSphere disableCollisionWith vehicle _obj; - _centerSphere attachTo [_obj, _obj worldToModel _centerPoint]; +if (GVAR(dbgSphere) && {_addSphere && {isNull objectParent _object}}) then { + private _centerSphere = [getPosASL _object, "yellow"] call FUNC(dev_sphereDraw); + _centerSphere disableCollisionWith vehicle _object; + _centerSphere attachTo [_object, _object worldToModel _centerPoint]; }; // create an optimized outline private _p1 = _upP; private _p7 = _lowP; -private _points =[ +private _points = [ _upP, [_p1#0, _p7#1, _p1#2], [_p7#0, _p7#1, _p1#2], @@ -64,10 +64,10 @@ private _points =[ [_p7#0, _p1#1, _p7#2] ]; -_color = switch (side _obj) do { +_color = switch (side _object) do { case east: {[1, 0, 0, 1]}; case resistance: {[0, 1, 0, 1]}; default {[0, 0, 1, 1]}; }; -GVAR(dev_hitBoxes) set [getObjectID _obj, [_obj, _points, _color]]; \ No newline at end of file +GVAR(dev_hitBoxes) set [getObjectID _object, [_object, _points, _color]]; diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index 80a70f222bf..62e750703ff 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -4,9 +4,9 @@ * This function adds an object to have it's course tracked (every frame). * * Arguments: - * 0: Object to draw hitbox - * 1: Color of trace - * 2: Whether the object is a projectile + * 0 : Object to draw hitbox + * 1 : Color of trace + * 2 : Whether the object is a projectile * * Return Value: * None @@ -17,11 +17,11 @@ * Public: No */ params [ - "_obj", + "_object", ["_color", "blue", ["blue"]], ["_isProj", false, [false]] ]; -TRACE_4("devDraw",_this,_obj,_color,_isProj); +TRACE_3("devDraw",_object,_color,_isProj); // pick color and add it to the array private _colorArray = switch (toLower _color) do { @@ -33,72 +33,66 @@ private _colorArray = switch (toLower _color) do { case "red": {[0.8, 0, 0, 1]}; case "black": {[1, 1, 1, 1]}; case "white": {[0, 0, 0, 1]}; - default {[0, 0.8, 0.8, 1]}; + default {[0, 0.8, 0.8, 1]}; }; -GVAR(dev_trackLines) set [getObjectID _obj, [1, [getposATL _obj], _colorArray]]; +GVAR(dev_trackLines) set [getObjectID _object, [1, [getposATL _object], _colorArray]]; // eventhandler to track round and cleanup when round is "dead" [ { if (isGamePaused) exitWith {}; - params ["_par", "_h"]; - _par params ["_obj"]; - if (!alive _obj) exitWith { - [_h] call CBA_fnc_removePerFrameHandler; + params ["_par", "_handle"]; + _par params ["_object"]; + if (!alive _object) exitWith { + [_handle] call CBA_fnc_removePerFrameHandler; }; - private _arr = GVAR(dev_trackLines) getOrDefault [(getObjectID _obj), -1]; + private _arr = GVAR(dev_trackLines) getOrDefault [(getObjectID _object), -1]; if (typeName _arr isEqualTo "SCALAR") exitWith { - [_h] call CBA_fnc_removePerFrameHandler; + [_handle] call CBA_fnc_removePerFrameHandler; }; - (_arr#1) pushBack getPosATL _obj; - if (_arr#0 <= 0) exitWith { - [_h] call CBA_fnc_removePerFrameHandler; - }; + (_arr#0) pushBack getPosATL _object; }, 0, - [_obj] + [_object] ] call CBA_fnc_addPerFrameHandler; // Projectile eventhandlers that add spheres and points for more accurate round tracking if (!_isProj) exitWith {}; -_obj addEventHandler [ +_object addEventHandler [ "HitPart", { - params ["_proj", "", "", "_posASL"]; - private _arr = (GVAR(dev_trackLines) get (getObjectID _proj))#1; - _arr pushBack ASLtoATL _posASL; - if (GVAR(dbgSphere)) then - { + params ["_projectile", "", "", "_posASL"]; + private _posArr = (GVAR(dev_trackLines) get (getObjectID _projectile))#0; + _posArr pushBack ASLtoATL _posASL; + if (GVAR(dbgSphere)) then { [_posASL, "green"] call FUNC(dev_sphereDraw); }; } ]; -_obj addEventHandler [ +_object addEventHandler [ "Explode", { - params ["_proj", "_posASL"]; - private _arr = (GVAR(dev_trackLines) get (getObjectID _proj))#1; - _arr pushBack ASLtoATL _posASL; - if (GVAR(dbgSphere)) then - { + params ["_projectile", "_posASL"]; + private _posArr = (GVAR(dev_trackLines) get (getObjectID _projectile))#0; + _posArr pushBack ASLtoATL _posASL; + if (GVAR(dbgSphere)) then { [_posASL, "red"] call FUNC(dev_sphereDraw); }; } ]; -_obj addEventHandler [ +_object addEventHandler [ "Deflected", { - params ["_proj", "_posASL"]; - private _arr = (GVAR(dev_trackLines) get (getObjectID _proj))#1; - _arr pushBack ASLtoATL _posASL; - if (GVAR(dbgSphere)) then - { + params ["_projectile", "_posASL"]; + private _posArr = (GVAR(dev_trackLines) get (getObjectID _projectile))#0; + _posArr pushBack ASLtoATL _posASL; + if (GVAR(dbgSphere)) then { [_posASL, "blue"] call FUNC(dev_sphereDraw); }; } -]; \ No newline at end of file +]; From 0e1bd6ab0ef5e05d2346e5ae082965fffc1dce2d Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 13:37:12 -0600 Subject: [PATCH 091/282] Got a little overzealous pruning & expanding variable names in the dev functions --- addons/frag/functions/fnc_dev_debugAmmo.sqf | 6 +++--- addons/frag/functions/fnc_dev_fragCalcDump.sqf | 8 +++----- addons/frag/functions/fnc_dev_trackHitBox.sqf | 4 ++-- addons/frag/functions/fnc_dev_trackObj.sqf | 6 +++--- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index e543f43af55..f83b80e6401 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -6,10 +6,10 @@ * fragements that could be fired from a weapon * * Arguments: - * 0: Log ammo types that wouldn't normall frag + * 0: Log ammo types that wouldn't normall frag * 1: Only export ammo classes of classes referenced in cfgAmmo - * and their submunitions. - * 2: Force a CSV format on debug print + * and their submunitions. + * 2: Force a CSV format on debug print * * Return Value: * None diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf index cad51f98e9e..07c4f6ccb86 100644 --- a/addons/frag/functions/fnc_dev_fragCalcDump.sqf +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -6,9 +6,8 @@ * shouldFrag to cull non-fragementing rounds * * Arguments: - * 0: _logAll - Display rounds that will never frag (power < 5). - * Default value false - * 1: _minFragPower - minimum range for sqrt power calculation + * 0: Display rounds that will never frag (power < 5). + * Default value false * * Return Value: * None @@ -20,8 +19,7 @@ */ params [ - ["_logAll", false, [false]], - ["_minFragPower", 35, [123]] + ["_logAll", false, [false]] ]; diff --git a/addons/frag/functions/fnc_dev_trackHitBox.sqf b/addons/frag/functions/fnc_dev_trackHitBox.sqf index 447db9eca20..ba136bbd46c 100644 --- a/addons/frag/functions/fnc_dev_trackHitBox.sqf +++ b/addons/frag/functions/fnc_dev_trackHitBox.sqf @@ -4,8 +4,8 @@ * Add a hitbox outline to an object * * Arguments: - * 0 : Object to draw hitbox - * 1 : Add sphere at object origin + * 0 Object to draw hitbox : + * 1: Add sphere at object origin * * Return Value: * None diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index 62e750703ff..e62fcb9ca41 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -4,9 +4,9 @@ * This function adds an object to have it's course tracked (every frame). * * Arguments: - * 0 : Object to draw hitbox - * 1 : Color of trace - * 2 : Whether the object is a projectile + * 0: Object to draw hitbox + * 1: Color of trace + * 2: Whether the object is a projectile * * Return Value: * None From 62a82ec71d252de7aead0163c907a12fc1b80d47 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 13:39:19 -0600 Subject: [PATCH 092/282] added trailing newlines --- addons/frag/functions/fnc_getMaterialInfo.sqf | 2 +- addons/frag/functions/fnc_getSpallInfo.sqf | 2 +- addons/frag/functions/fnc_initBlackList.sqf | 5 ++--- addons/frag/functions/fnc_initMaterialCache.sqf | 2 +- addons/frag/functions/fnc_initRound.sqf | 2 +- addons/frag/functions/fnc_shouldFrag.sqf | 2 +- addons/frag/functions/fnc_shouldSpall.sqf | 2 +- 7 files changed, 8 insertions(+), 9 deletions(-) diff --git a/addons/frag/functions/fnc_getMaterialInfo.sqf b/addons/frag/functions/fnc_getMaterialInfo.sqf index 9f954bba48a..21a94ac2676 100644 --- a/addons/frag/functions/fnc_getMaterialInfo.sqf +++ b/addons/frag/functions/fnc_getMaterialInfo.sqf @@ -57,4 +57,4 @@ _material = switch (true) do { GVAR(spallMaterialCache) set [_surfType, _material]; TRACE_2("materialCacheSet",_surfType,_material); -_material \ No newline at end of file +_material diff --git a/addons/frag/functions/fnc_getSpallInfo.sqf b/addons/frag/functions/fnc_getSpallInfo.sqf index 6cb6970c9a5..7126803933d 100644 --- a/addons/frag/functions/fnc_getSpallInfo.sqf +++ b/addons/frag/functions/fnc_getSpallInfo.sqf @@ -32,4 +32,4 @@ private _ammoInfo = [_caliber, _explosive, _indirectHit]; GVAR(spallInfoCache) set [_ammo, _ammoInfo]; -_ammoInfo \ No newline at end of file +_ammoInfo diff --git a/addons/frag/functions/fnc_initBlackList.sqf b/addons/frag/functions/fnc_initBlackList.sqf index 37e2b1787b5..79d3c86a72d 100644 --- a/addons/frag/functions/fnc_initBlackList.sqf +++ b/addons/frag/functions/fnc_initBlackList.sqf @@ -4,7 +4,7 @@ * Adds setting defined blacklisted rounds to blacklist * * Arguments: - * Mne + * None * * Return Value: * None @@ -48,5 +48,4 @@ for "_i" from 0 to _items - 1 do { GVAR(shouldFragCache) set [_convArray#_i, false]; }; - -INFO_2("Initialized blacklist. Total items found: %1, number of items failed: %2", _items, _errors); \ No newline at end of file +INFO_2("Initialized blacklist. Total items found: %1, number of items failed: %2", _items, _errors); diff --git a/addons/frag/functions/fnc_initMaterialCache.sqf b/addons/frag/functions/fnc_initMaterialCache.sqf index 9e56b3dafff..81ec5220cb9 100644 --- a/addons/frag/functions/fnc_initMaterialCache.sqf +++ b/addons/frag/functions/fnc_initMaterialCache.sqf @@ -94,4 +94,4 @@ GVAR(spallMaterialCache) = createHashMapFromArray [ ["a3\data_f\penetration\weapon_plate.bisurf","metal"], ["a3\data_f\penetration\wood.bisurf","wood"], ["a3\data_f\penetration\wood_plate.bisurf","wood"] -]; \ No newline at end of file +]; diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index 8b25afb3225..377a5b74ca7 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -75,4 +75,4 @@ if (GVAR(debugOptions) && (_shouldFrag || _shouldSpall)) then { [_projectile, "red", true] call FUNC(dev_trackObj); }; #endif -TRACE_2("initExit",_shouldFrag,_shouldSpall); \ No newline at end of file +TRACE_2("initExit",_shouldFrag,_shouldSpall); diff --git a/addons/frag/functions/fnc_shouldFrag.sqf b/addons/frag/functions/fnc_shouldFrag.sqf index de9e04b0926..37805be7bb6 100644 --- a/addons/frag/functions/fnc_shouldFrag.sqf +++ b/addons/frag/functions/fnc_shouldFrag.sqf @@ -38,4 +38,4 @@ if (_skip == 1 || (_force == 0 && {_explosive < 0.5 || {_indirectHit < 3 GVAR(shouldFragCache) set [_ammo, _shouldFrag]; -_shouldFrag \ No newline at end of file +_shouldFrag diff --git a/addons/frag/functions/fnc_shouldSpall.sqf b/addons/frag/functions/fnc_shouldSpall.sqf index 1d77a072568..1ece3ba0c8a 100644 --- a/addons/frag/functions/fnc_shouldSpall.sqf +++ b/addons/frag/functions/fnc_shouldSpall.sqf @@ -30,4 +30,4 @@ _shouldSpall = _caliber * GVAR(spallIntensity) >= 2.5 || (_explosive >= 0.5 && _ GVAR(shouldSpallCache) set [_ammo, _shouldSpall]; -_shouldSpall \ No newline at end of file +_shouldSpall From 83bbc3070bc3144b585f65cbafd333f659269680 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 13:40:03 -0600 Subject: [PATCH 093/282] Update addons/frag/functions/fnc_dev_trackObj.sqf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jouni Järvinen --- addons/frag/functions/fnc_dev_trackObj.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index 80a70f222bf..42990425da5 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -24,7 +24,7 @@ params [ TRACE_4("devDraw",_this,_obj,_color,_isProj); // pick color and add it to the array -private _colorArray = switch (toLower _color) do { +private _colorArray = switch (toLowerANSI _color) do { case "purple": {[0.8, 0, 0.8, 1]}; case "blue": {[0, 0, 0.8, 1]}; case "green": {[0, 0.8, 0, 1]}; From b2c0f5720dfe1d3e23e74b9d20ca7256b4bdc03b Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 13:41:07 -0600 Subject: [PATCH 094/282] skip prepping dev functions that aren't used when not dev compiled --- addons/frag/XEH_PREP.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/addons/frag/XEH_PREP.hpp b/addons/frag/XEH_PREP.hpp index 0dae97ada5f..01d75186696 100644 --- a/addons/frag/XEH_PREP.hpp +++ b/addons/frag/XEH_PREP.hpp @@ -1,7 +1,6 @@ // dev +#ifdef DEBUG_MODE_DRAW PREP(dev_fired); -PREP(dev_fragCalcDump); -PREP(dev_debugAmmo); PREP(dev_trackHitBox); PREP(dev_sphereDraw); PREP(dev_addRound); @@ -9,6 +8,9 @@ PREP(dev_trackObj); PREP(dev_drawTrace); PREP(dev_clearTraces); PREP(dev_switchUnitHandle); +#endif +PREP(dev_fragCalcDump); +PREP(dev_debugAmmo); // Base PREP(initRound); From eeb08c3f055f2ae0743d75c7a1b553ab1ede0388 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 13:42:45 -0600 Subject: [PATCH 095/282] Made variable names more verbose and added trailing newlines --- addons/frag/XEH_postInit.sqf | 4 +- addons/frag/functions/fnc_addBlackList.sqf | 10 +-- addons/frag/functions/fnc_doFrag.sqf | 10 +-- addons/frag/functions/fnc_doFragRandom.sqf | 17 +++-- addons/frag/functions/fnc_doFragTargeted.sqf | 57 +++++++++-------- addons/frag/functions/fnc_doSpall.sqf | 66 ++++++++++---------- addons/frag/functions/fnc_getFragInfo.sqf | 52 +++++++-------- addons/frag/script_component.hpp | 9 +-- 8 files changed, 114 insertions(+), 111 deletions(-) diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index b8b6e39f10e..f0cbd532ded 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -10,8 +10,8 @@ #ifdef DEBUG_MODE_DRAW if (hasInterface) then { - private _h = [LINKFUNC(dev_drawTrace), 0] call CBA_fnc_addPerFrameHandler; - missionNamespace setVariable [QGVAR(dev_drawPFEH), _h]; + private _handle = [LINKFUNC(dev_drawTrace), 0] call CBA_fnc_addPerFrameHandler; + missionNamespace setVariable [QGVAR(dev_drawPFEH), _handle]; ["unit", LINKFUNC(dev_switchUnitHandle), true] call CBA_fnc_addPlayerEventHandler; [objNull, ace_player] call FUNC(dev_switchUnitHandle); }; diff --git a/addons/frag/functions/fnc_addBlackList.sqf b/addons/frag/functions/fnc_addBlackList.sqf index 3766df13e83..ecb6af71e2d 100644 --- a/addons/frag/functions/fnc_addBlackList.sqf +++ b/addons/frag/functions/fnc_addBlackList.sqf @@ -15,15 +15,15 @@ * Public: No */ -params ["_proj"]; +params ["_projectile"]; TRACE_1("addBlackList",_round); -switch (typeName _proj) do { +switch (typeName _projectile) do { case "OBJECT": { - GVAR(shouldFragCache) set [typeOf _proj, false]; + GVAR(shouldFragCache) set [typeOf _projectile, false]; }; case "STRING": { - GVAR(shouldFragCache) set [_proj, false]; + GVAR(shouldFragCache) set [_projectile, false]; }; default { }; -}; \ No newline at end of file +}; diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index e66349a8df0..41d97f4a533 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -15,15 +15,15 @@ * None * * Example: - * [[_proj, getPosASL _proj, velocity _proj]] call ace_frag_fnc_doFrag; + * [_projectile, getPosASL _projectile, velocity _projectile, typeOf _projectile, getShotParents _projectile] call ace_frag_fnc_doFrag; * * Public: No */ TRACE_1("begin doFrag",_this); params [ - ["_proj", objNull, [objNull]], + "", ["_posASL", [0, 0, 0], [[]], [3]], - ["_vel", [0, 0, 0] , [[]], [3]], + ["_velocity", [0, 0, 0] , [[]], [3]], ["_ammo", "", [""]], ["_shotParents", [objNull, objNull], [[]]] ]; @@ -65,5 +65,5 @@ if (_fragRange > 3 && _timeSince > ACE_FRAG_HOLDOFF*1.5 && GVAR(fragSimComplexit }; if (_timeSince > 0.2 && {GVAR(fragSimComplexity) > 0}) then { - [_posASL, _vel, _heightAGL, _fragTypes, _maxFrags, _shotParents] call FUNC(doFragRandom); -}; \ No newline at end of file + [_posASL, _velocity, _heightAGL, _fragTypes, _maxFrags, _shotParents] call FUNC(doFragRandom); +}; diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index 2f5b53ff802..b956bc36cc1 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -8,28 +8,27 @@ * 0: Position of fragmenting projectile ASL * 1: Velocity of the fragmenting projectile * 2: Height (AGL) of the fragmenting projectile - * 3: Type of fragments to generate + * 3: Type of fragments to generate * 4: Remaining fragment budget - * 5: Shot parent + * 5: Shot parents * * Return Value: * None * * Example: - * [getPosASL _proj, velocity _proj, 50, 50, [], 1, [player, player]] call ace_frag_fnc_doFragRandom; + * [getPosASL _proj, 800, 50, 50, [], 1, [player, player]] call ace_frag_fnc_doFragRandom; * * Public: No */ - params [ "_posASL", - ["_projVel", [0,0,0]], + ["_fragVelocity", [0,0,0]], ["_heightAGL", 2, [123]], ["_fragType", [], [[]]], ["_fragCnt", 10, [123]], - ["_shotPrnt", [objNull, objNull], [[]], [2]] + ["_shotParents", [objNull, objNull], [[]], [2]] ]; -TRACE_5("fnc_doFragRandom", _posASL, _projVel, _heightAGL, _fragType, _fragCnt); +TRACE_5("fnc_doFragRandom", _posASL, _fragVelocity, _heightAGL, _fragType, _fragCnt); // See cfgAmmoFragSpawner for different frag types private _hMode = switch (true) do { @@ -54,7 +53,7 @@ _fragCnt = switch (true) do { // Spawn the fragment spawner private _fragSpawner = createVehicle [_type + _fragCnt + _hMode, ASLToATL _posASL, [], 0, "CAN_COLLIDE"]; _fragSpawner setVectorDirandUp [[0,0,1], [1,0,0]]; -_fragSpawner setVelocity _projVel; +_fragSpawner setVelocity _fragVelocity; _fragSpawner setShotParents _shotParents; #ifdef DEBUG_MODE_FULL @@ -71,4 +70,4 @@ _fragSpawner addEventHandler [ if (GVAR(dbgSphere)) then { [_posASL] call FUNC(dev_sphereDraw); }; -#endif \ No newline at end of file +#endif diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index 29241f469f6..a46ee65ed3f 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -24,14 +24,14 @@ params [ "_posASL", - ["_fragVel", 800, [123]], + ["_fragVelocity", 800, [123]], ["_fragRange", 50, [123]], ["_maxFrags", 20, [123]], ["_fragTypes", [], [[]]], ["_modFragCount", 1, [123]], - ["_shotPrnt", [objNull, objNull], [[]], [2]] + ["_shotParents", [objNull, objNull], [[]], [2]] ]; -TRACE_5("fnc_doFragTargeted", _posASL, _fragRange, _maxFrags, _fragTypes, _modFragCount); +TRACE_5("fnc_doFragTargeted",_posASL,_fragRange,_maxFrags,_fragTypes,_modFragCount); if (_fragTypes isEqualTo []) then { _fragTypes = [ @@ -45,14 +45,14 @@ if (_fragTypes isEqualTo []) then { private _objects = (ASLToATL _posASL) nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], _fragRange]; if (_objects isEqualTo []) exitWith { - TRACE_2("No nearby targets", _posASL, _fragRange); + TRACE_2("No nearby targets",_posASL,_fragRange); 0; }; // grab crews and add them in so that targets stay approx. sorted by distance { - private _crew = (crew _x); + private _crew = crew _x; if (count _crew > 1) then { private _arr = [_x]; { @@ -63,11 +63,11 @@ if (_objects isEqualTo []) exitWith { }; } forEach _objects; _objects = flatten _objects; -TRACE_3("Targets found", _posASL, _fragRange, count _objects); +TRACE_3("Targets found",_posASL,_fragRange,count _objects); // limit number of fragments per direction (2D) to 10 using _fragArcs private _fragArcs = createHashMap; -private _fragCount = 0; +private _totalFragCount = 0; { // Begin of forEach iterating on _objects if (!alive _x) then {continue}; private _target = _x; @@ -103,16 +103,15 @@ private _fragCount = 0; // calculate chance to be hit by a fragment private _fragChance = _crossSectionArea * _modFragCount / _distance^2; - private _count = if (_fragChance > 1) then { + private _fragCount = if (_fragChance > 1) then { 3 min (floor _fragChance); } else { [0, 1] select (GVAR(atLeastOne) || {random 1 < _fragChance}); }; - if (_count == 0) then {TRACE_2("fragments",_fragChance,_count); continue}; - - // Approximate offset to hit including speed & gravity - private _locFragVel = _fragVel * (1 - random 0.5); - private _tof = _distance / _locFragVel; + if (_fragCount == 0) then { + TRACE_2("fragments",_fragChance,_fragCount); + continue + }; // handle limiting fragments per degree arc private _dir = floor (_posASL getDir _target); @@ -120,11 +119,15 @@ private _fragCount = 0; if (_fragPerArc > 10) then { continue; } else { - _fragArcs set [_dir, _fragPerArc + _count]; + _fragArcs set [_dir, _fragPerArc + _fragCount]; }; + // Approximate offset to hit including speed & gravity + private _locFragVel = _fragVelocity * (1 - random 0.5); + private _timeOfFlight = _distance / _locFragVel; + // target pos for fragment to hit - private _targetPos = (velocity _target vectorMultiply _tof) vectorAdd [0, 0, 9.81 / 2 * _tof ^ 2]; + private _targetPos = (velocity _target vectorMultiply _timeOfFlight) vectorAdd [0, 0, ACE_FRAG_HALF_GRAVITY_APPROX * _timeOfFlight ^ 2]; if _isPerson then { private _hitPoint = selectRandom ACE_FRAG_HITPOINTS; private _hitPointPos = _target selectionPosition [_hitPoint, "HitPoints", "AveragePoint"]; @@ -139,8 +142,8 @@ private _fragCount = 0; // select a fragment / submunition frag spawner private _fragSpawner = selectRandom _fragTypes; - if (_count > 1) then { - _fragSpawner = _fragSpawner + "_spawner_" + str _count + (switch (true) do { + if (_fragCount > 1) then { + _fragSpawner = _fragSpawner + "_spawner_" + str _fragCount + (switch (true) do { case (_distance < 10): {"_short"}; case (_distance < 20): {"_mid"}; default {"_far"}; @@ -149,11 +152,11 @@ private _fragCount = 0; TRACE_4("fragments",_fragSpawner,_fragChance,_distance,_locFragVel); // Create fragment - private _vecDir = _posASL vectorFromTo _targetPos; + private _vectorDir = _posASL vectorFromTo _targetPos; private _fragObj = createVehicle [_fragSpawner, ASLtoATL _posASL, [], 0, "CAN_COLLIDE"]; - _fragObj setVectorDir _vecDir; - _fragObj setVelocity (_vecDir vectorMultiply _locFragVel); - _fragObj setShotParents _shotPrnt; + _fragObj setVectorDir _vectorDir; + _fragObj setVelocity (_vectorDir vectorMultiply _locFragVel); + _fragObj setShotParents _shotParents; #ifdef DEBUG_MODE_DRAW [_fragObj, "purple", true] call FUNC(dev_trackObj); if (GVAR(dbgSphere)) then { @@ -161,15 +164,15 @@ private _fragCount = 0; }; #endif - _fragCount = _fragCount + _count; - if (_fragCount >= _maxFrags) then { - TRACE_2("maxFrags", _fragCount, _maxFrags); + _totalFragCount = _totalFragCount + _fragCount; + if (_totalFragCount >= _maxFrags) then { + TRACE_2("maxFrags", _totalFragCount, _maxFrags); break }; } forEach _objects; #ifdef DEBUG_MODE_FULL -systemChat ("fragCount cnt: " + str _fragCount); -TRACE_1("fragCount",_fragCount); +systemChat ("fragCount cnt: " + str _totalFragCount); +TRACE_1("fragCount",_totalFragCount); #endif -_fragCount \ No newline at end of file +_totalFragCount diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index a12e0b47c9e..8a65e60e8b1 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -18,21 +18,21 @@ TRACE_1("doSpall",_this); params [ "_projectile", - ["_hitObj", objNull], - ["_lPosASL", [0, 0, 0]], - ["_lVel", [0, 0, 0]], - ["_sNorm", [0, 0, 0]], + ["_objectHit", objNull], + ["_lastPosASL", [0, 0, 0]], + ["_lastVelocity", [0, 0, 0]], + ["_surfaceNorm", [0, 0, 0]], ["_surfaceType", ""], ["_ammo", "", [""]], ["_shotParents", [objNull, objNull], [[]]], - ["_vUp", [0,0,1]] + ["_vectorUp", [0,0,1]] ]; if (CBA_missionTime - GVAR(lastSpallTime) < ACE_FRAG_SPALL_HOLDOFF || - _lPosASL isEqualTo [0,0,0] || - {isNull _hitObj || {_hitObj isKindOf "man" || + _lastPosASL isEqualTo [0,0,0] || + {isNull _objectHit || {_objectHit isKindOf "man" || {_ammo isEqualTo ""}}}) exitWith { - TRACE_4("time/invldHit",CBA_missionTime,GVAR(lastSpallTime),_hitObj,_lPosASL); + TRACE_4("time/invldHit",CBA_missionTime,GVAR(lastSpallTime),_objectHit,_lastPosASL); }; private _material = [_surfaceType] call FUNC(getMaterialInfo); @@ -45,21 +45,21 @@ if (_material isEqualTo "ground") then { // Find spall speed / fragment info [_ammo] call FUNC(getSpallInfo) params ["_caliber", "_explosive", "_indirectHit"]; private _vel = if (alive _projectile) then { - _explosive = 0; // didn't explode + _explosive = 0; // didn't explode since it's alive a frame later velocity _projectile } else { [0, 0, 0]; }; -private _dV = vectorMagnitude _lVel - vectorMagnitude _vel; +private _velocityChange = vectorMagnitude _lastVelocity - vectorMagnitude _vel; /* * This is all fudge factor since real spalling is too complex for calculation. * There are two terms. The first is from round impact, taking a quasi scale * of sqrt(2)/50 * round caliber * srqt(change in speed). The second term is * explosive * indirect hit, for any explosive contribution */ -private _spallPower = (ACE_FRAG_ROUND_COEF * _caliber * sqrt _dV + _explosive * _indirectHit) * GVAR(spallIntensity); -TRACE_3("found speed",_dV,_caliber,_spallPower); +private _spallPower = (ACE_FRAG_ROUND_COEF * _caliber * sqrt _velocityChange + _explosive * _indirectHit) * GVAR(spallIntensity); +TRACE_3("found speed",_velocityChange,_caliber,_spallPower); if (_spallPower < 2) exitWith { @@ -67,49 +67,49 @@ if (_spallPower < 2) exitWith { }; -private _lVelUnit = vectorNormalized _lVel; -private _unitStep = _lVelUnit vectorMultiply 0.05; +private _lastVelocityUnit = vectorNormalized _lastVelocity; +private _deltaStep = _lastVelocityUnit vectorMultiply 0.05; -if (terrainIntersectASL [_lPosASL vectorAdd _unitStep, _lPosASL]) exitWith { - TRACE_3("terrainIntersect",_lPosASL,_unitStep,_lPosASL); +if (terrainIntersectASL [_lastPosASL vectorAdd _deltaStep, _lastPosASL]) exitWith { + TRACE_2("terrainIntersect",_lastPosASL,_deltaStep); }; #ifdef DEBUG_MODE_DRAW if GVAR(dbgSphere) then { - [_lPosASL vectorAdd _lVelUnit, "orange"] call FUNC(dev_sphereDraw); - [_lPosASL, "yellow"] call FUNC(dev_sphereDraw); + [_lastPosASL vectorAdd _lastVelocityUnit, "orange"] call FUNC(dev_sphereDraw); + [_lastPosASL, "yellow"] call FUNC(dev_sphereDraw); }; #endif /* * Improve performance of finding otherside of object on shallow angle - * impacts. 120 degrees due to 90 degree offset with _lVelUnit into object. + * impacts. 120 degrees due to 90 degree offset with _lastVelocityUnit into object. */ -private _spallPos = _lPosASL vectorAdd _unitStep; -if (120 > acos ( _lVelUnit vectorDotProduct _sNorm)) then { - _spallPos = _spallPos vectorAdd (_unitStep vectorMultiply 5); +private _spallPosASL = _lastPosASL vectorAdd _deltaStep; +if (120 > acos ( _lastVelocityUnit vectorDotProduct _surfaceNorm)) then { + _spallPosASL = _spallPosASL vectorAdd (_deltaStep vectorMultiply 5); }; private _insideObject = true; for "_i" from 2 to 21 do { - private _nPos = _spallPos vectorAdd _unitStep; - if (!lineIntersects [_spallPos, _nPos]) then { - _spallPos = _nPos vectorAdd (_unitStep vectorMultiply 2); + private _nPos = _spallPosASL vectorAdd _deltaStep; + if (!lineIntersects [_spallPosASL, _nPos]) then { + _spallPosASL = _nPos vectorAdd (_deltaStep vectorMultiply 2); _insideObject = false; break }; - _spallPos = _nPos; + _spallPosASL = _nPos; }; if (_insideObject) exitWith { - TRACE_3("insideObj",_lPosASL,_spallPos,alive _projectile); + TRACE_3("insideObj",_lastPosASL,_spallPosASL,alive _projectile); }; // Passed all exitWiths GVAR(lastSpallTime) = CBA_missionTime; #ifdef DEBUG_MODE_DRAW if GVAR(dbgSphere) then { - [_spallPos, "green"] call FUNC(dev_sphereDraw); + [_spallPosASL, "green"] call FUNC(dev_sphereDraw); }; #endif @@ -124,17 +124,17 @@ private _spawnSize = switch (true) do private _spallSpawner = createVehicle [ "ace_frag_" + _material + _spawnSize, - ASLToATL _spallPos, + ASLToATL _spallPosASL, [], 0, "CAN_COLLIDE" ]; -_spallSpawner setVectorDirandUp [_lVelUnit, _vUp]; -_spallSpawner setVelocity (_lVelUnit vectorMultiply (_dV/2)); +_spallSpawner setVectorDirandUp [_lastVelocityUnit, _vectorUp]; +_spallSpawner setVelocity (_lastVelocityUnit vectorMultiply (_velocityChange/ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF)); _spallSpawner setShotParents _shotParents; #ifdef DEBUG_MODE_FULL -systemChat ("bSpd: " + str speed _spallSpawner + ", frag: " + _fragSpawnType + ", dm: " + str _spallPower); +systemChat ("spd: " + str speed _spallSpawner + ", spawner: " + _fragSpawnType + ", spallPow: " + str _spallPower); #endif #ifdef DEBUG_MODE_DRAW _spallSpawner addEventHandler [ @@ -144,4 +144,4 @@ _spallSpawner addEventHandler [ [_subProj] call FUNC(dev_addRound); } ]; -#endif \ No newline at end of file +#endif diff --git a/addons/frag/functions/fnc_getFragInfo.sqf b/addons/frag/functions/fnc_getFragInfo.sqf index 6bcde43713f..088e19f9676 100644 --- a/addons/frag/functions/fnc_getFragInfo.sqf +++ b/addons/frag/functions/fnc_getFragInfo.sqf @@ -9,11 +9,11 @@ * * Return Value: * _ammoInfo - * 0: _fragRange - search range for fragments - * 1: _fragVel - gurney equation calculated velocity - * 2: _fragTypes - array of fragment types + * 0: _fragRange - search range for fragments + * 1: _fragVel - gurney equation calculated velocity + * 2: _fragTypes - array of fragment types * 3: _fragCount - modified frag count used under assumptions - * of spherical fragmentation +* of spherical fragmentation * * Example: * ["B_556x45_Ball"] call ace_frag_fnc_getFragInfo; @@ -38,31 +38,31 @@ if (isArray (configFile >> "cfgAmmo" >> _ammo >> QGVAR(CLASSES))) then { /************ Gurney equation notes *****************//* * see https://en.wikipedia.org/wiki/Gurney_equations * - * GURNEY_K is the constant added to _m/_c + * GURNEY_K is the geometry constant added to _metalMass/_chargeMass * GURNEY_C = sqrt(2E) * - * _c = 185; - grams of comp-b - * _m = 210; - grams of fragmentating metal - * _k = 3/5; - spherical K factor - * _gC = 2843; - Gurney constant of comp-b in /ms + * _chargeMass = 185; - grams of comp-b + * _metalMass = 210; - grams of fragmentating metal + * _geometryCoefficient = 3/5; - spherical K factor + * _gurneyConstant = 2843; - Gurney constant of comp-b in /ms * - * _c = 429; - grams of tritonal - * _m = 496; - grams of fragmentating metal - * _k = 1/2; - cylindrical K factor - * _gC = 2320; - Gurney constant of tritonal in m/s + * _chargeMass = 429; - grams of tritonal + * _metalMass = 496; - grams of fragmentating metal + * _geometryCoefficient = 1/2; - cylindrical K factor + * _gurneyConstant = 2320; - Gurney constant of tritonal in m/s * Equation - 0.8 for empirical 80% speed - * 0.8 * (((_m / _c) + _k) ^ - (1 / 2)) * _gC; - * or 0.8 * _gC * sqrt (_c /(_m + _c * _k)); (slightly faster to compute) + * 0.8 * (((_metalMass / _chargeMass) + _geometryCoefficient) ^ - (1 / 2)) * _gurneyConstant; + * or 0.8 * _gurneyConstant * sqrt (_chargeMass /(_metalMass + _chargeMass * _geometryCoefficient)); (slightly faster to compute) */ -private _c = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(CHARGE)); -if (_c == 0) then {_c = 1; _warn = true;}; -private _m = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(METAL)); -if (_m == 0) then {_m = 2; _warn = true;}; -private _k = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(GURNEY_K)); -if (_k == 0) then {_k = 0.8; _warn = true;}; -private _gC = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(GURNEY_C)); -if (_gC == 0) then {_gC = 2440; _warn = true;}; +private _chargeMass = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(CHARGE)); +if (_chargeMass == 0) then {_chargeMass = 1; _warn = true;}; +private _metalMass = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(METAL)); +if (_metalMass == 0) then {_metalMass = 2; _warn = true;}; +private _geometryCoefficient = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(GURNEY_K)); +if (_geometryCoefficient == 0) then {_geometryCoefficient = 0.8; _warn = true;}; +private _gurneyConstant = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(GURNEY_C)); +if (_gurneyConstant == 0) then {_gurneyConstant = 2440; _warn = true;}; private _fragCount = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(fragCount)); if (_fragCount == 0) then {_fragCount = 400; _warn = true;}; @@ -79,11 +79,11 @@ if (_warn) then { * of spherical fragmentation */ _ammoInfo = [ - sqrt (_fragCount / (4 * pi * 0.005)), - 0.8 * _gC * sqrt (_c / (_m + _c * _k)), + sqrt (_fragCount / (4 * pi * ACE_FRAG_MIN_FRAG_HIT_CHANCE)), + 0.8 * _gurneyConstant * sqrt (_chargeMass / (_metalMass + _chargeMass * _geometryCoefficient)), _fragTypes, _fragCount / 4 / pi ]; GVAR(fragInfoCache) set [_ammo, _ammoInfo]; -_ammoInfo \ No newline at end of file +_ammoInfo diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index f9006a249e5..f4355816905 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -27,7 +27,8 @@ #define ACE_FRAG_HITPOINTS_WEIGHTS // sqrt(2)/50 #define ACE_FRAG_ROUND_COEF 0.02828427 - -#ifndef GLUE -#define GLUE(g1,g2) g1##g2 -#endif \ No newline at end of file +// half of gravity approx 9.81/2 +#define ACE_FRAG_HALF_GRAVITY_APPROX 4.905 +// stop searching at 0.5% chance to hit +#define ACE_FRAG_MIN_FRAG_HIT_CHANCE 0.005 +#define ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF 2 From 1e0e744593aed7a078df712cdf17688091d65c4f Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 13:43:31 -0600 Subject: [PATCH 096/282] Misspelled normally in dev_debugAmmo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jouni Järvinen --- addons/frag/functions/fnc_dev_debugAmmo.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index 90f26f1922c..3a25e8ec6f2 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -6,7 +6,7 @@ * fragements that could be fired from a weapon * * Arguments: - * 0: Log ammo types that wouldn't normall frag + * 0: Log ammo types that wouldn't normally frag * 1: Only export ammo classes of classes referenced in cfgAmmo * and their submunitions. * 2: Force a CSV format From 4bd866b97d7f346915ad5f832bd5a75622646d4e Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 13:55:01 -0600 Subject: [PATCH 097/282] Merged commits --- addons/frag/functions/fnc_dev_debugAmmo.sqf | 4 ++-- addons/frag/functions/fnc_dev_trackObj.sqf | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index f83b80e6401..75604d41103 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -3,10 +3,10 @@ /* * Author: ACE-Team, Lambda.Tiger * This function will dump every ammo config that would generate ace_frag - * fragements that could be fired from a weapon + * fragments that could be fired from a weapon * * Arguments: - * 0: Log ammo types that wouldn't normall frag + * 0: Log ammo types that wouldn't normally frag * 1: Only export ammo classes of classes referenced in cfgAmmo * and their submunitions. * 2: Force a CSV format on debug print diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index e62fcb9ca41..40b2d3cc668 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -24,7 +24,7 @@ params [ TRACE_3("devDraw",_object,_color,_isProj); // pick color and add it to the array -private _colorArray = switch (toLower _color) do { +private _colorArray = switch (toLowerANSI _color) do { case "purple": {[0.8, 0, 0.8, 1]}; case "blue": {[0, 0, 0.8, 1]}; case "green": {[0, 0.8, 0, 1]}; From 3f45f7735b6b6c50f01d6fcb50db08f20548c0c4 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 13:55:15 -0600 Subject: [PATCH 098/282] Convereted toLower to toLowerANSI --- addons/frag/functions/fnc_dev_debugAmmo.sqf | 8 ++++---- addons/frag/functions/fnc_dev_fragCalcDump.sqf | 2 +- addons/frag/functions/fnc_dev_sphereDraw.sqf | 2 +- addons/frag/functions/fnc_getMaterialInfo.sqf | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index 75604d41103..62b770f28b9 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -39,22 +39,22 @@ if (_onlyShotAmmoTypes) then { ]; if (_ammo isEqualTo "" || {_ammo in _allAmmoConfigs}) exitWith {}; _allAmmoConfigs pushBack _ammo; - private _subMunit = toLower getText (configFile >> "cfgAmmo" >> _ammo >> "submunitionAmmo"); + private _subMunit = toLowerANSI getText (configFile >> "cfgAmmo" >> _ammo >> "submunitionAmmo"); if (_subMunit isNotEqualTo "") then { _subMunit = getArray (configFile >> "cfgAmmo" >> _ammo >> "submunitionAmmo"); for "_i" from 0 to count _subMunit - 1 do { if (_i mod 2 == 0) then { - [toLower (_subMunit#_i)] call _configSearchFunc; + [toLowerANSI (_subMunit#_i)] call _configSearchFunc; }; }; } else { - [toLower _subMunit] call _configSearchFunc; + [toLowerANSI _subMunit] call _configSearchFunc; }; }; private _allMagazineConfigs = configProperties [configFile >> "cfgMagazines", "isClass _x", true]; { - [toLower getText (_x >> "ammo")] call _configSearchFunc; + [toLowerANSI getText (_x >> "ammo")] call _configSearchFunc; } forEach _allMagazineConfigs; } else { _allAmmoConfigs = configProperties [configFile >> "cfgAmmo", "isClass _x && !('ace_frag' in configName _x)", true] apply {configName _x}; diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf index 07c4f6ccb86..c51125eff48 100644 --- a/addons/frag/functions/fnc_dev_fragCalcDump.sqf +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -30,7 +30,7 @@ private _nPrinted = 0; diag_log text "//****************** fragCalcDump Beg ******************//"; { // Begin _allAmmoConfigs forEach - private _ammo = toLower configName _x; + private _ammo = toLowerANSI configName _x; if (_ammo == "" || {_ammo in _processedCfgAmmos} ) then { continue }; diff --git a/addons/frag/functions/fnc_dev_sphereDraw.sqf b/addons/frag/functions/fnc_dev_sphereDraw.sqf index 3ed344a8977..123c64ba944 100644 --- a/addons/frag/functions/fnc_dev_sphereDraw.sqf +++ b/addons/frag/functions/fnc_dev_sphereDraw.sqf @@ -28,7 +28,7 @@ if (count _posASL < 3) then { }; if (_color select [0,1] != "(") then { - switch (toLower _color) do { + switch (toLowerANSI _color) do { case "blue": { _color = "(0,0,0.8,0.5)"; }; case "black": { _color = "(1,1,1,0.5)"; }; case "white": { _color = "(0,0,0,0.5)"; }; diff --git a/addons/frag/functions/fnc_getMaterialInfo.sqf b/addons/frag/functions/fnc_getMaterialInfo.sqf index 21a94ac2676..37140469db8 100644 --- a/addons/frag/functions/fnc_getMaterialInfo.sqf +++ b/addons/frag/functions/fnc_getMaterialInfo.sqf @@ -31,7 +31,7 @@ if (isClass (configFile >> "CfgSurfaces" >> _surfType)) then { _material = getText (configFile >> "CfgSurfaces" >> _surfType >> "soundhit"); }; } else { // Messy way when a surface isn't added to cfgSurfaces - private _surfFileText = tolower preprocessFile _surfType; + private _surfFileText = toLowerANSI preprocessFile _surfType; _surfFileText = _surfFileText regexReplace ["[^a-z0-9]", ""]; private _idx = 12 + (_surfFileText find "soundenviron"); if (_surfFileText select [_idx, 5] isEqualTo "empty") then { From 0f82f599552ece10e0a1ee7db6072f9ce5a4f000 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 14:08:27 -0600 Subject: [PATCH 099/282] typos from last commit --- addons/frag/functions/fnc_dev_drawTrace.sqf | 2 +- addons/frag/functions/fnc_dev_fragCalcDump.sqf | 2 +- addons/frag/functions/fnc_dev_trackHitBox.sqf | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/frag/functions/fnc_dev_drawTrace.sqf b/addons/frag/functions/fnc_dev_drawTrace.sqf index 41d717c4e80..7f7ff82dae3 100644 --- a/addons/frag/functions/fnc_dev_drawTrace.sqf +++ b/addons/frag/functions/fnc_dev_drawTrace.sqf @@ -16,7 +16,7 @@ */ { - _y params ["_posArray", "_color"] + _y params ["_posArray", "_color"]; if (count (_posArray) > 1) then { for "_j" from 1 to count _posArray - 1 do { drawLine3D [_posArray#(_j-1), _posArray#_j, _color]; diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf index c51125eff48..b7278ca3103 100644 --- a/addons/frag/functions/fnc_dev_fragCalcDump.sqf +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -38,7 +38,7 @@ diag_log text "//****************** fragCalcDump Beg ******************//"; private _shouldFrag = [_ammo] call FUNC(shouldFrag); if (_nSkip || _logAll) then { private _fragInfo = [_ammo] call FUNC(getFragInfo); - _fragInfo params ["_fragRange", "_fragMaxVelocity", "", "_modifiedFragCount"] + _fragInfo params ["_fragRange", "_fragMaxVelocity", "", "_modifiedFragCount"]; private _fragCount = 4 * pi* _modifiedFragCount; private _indirectHitRange = getNumber (configFile >> "cfgAmmo" >> _ammo >> "indirectHitRange"); private _indirectHit = getNumber (configFile >> "cfgAmmo" >> _ammo >> "indirectHit"); diff --git a/addons/frag/functions/fnc_dev_trackHitBox.sqf b/addons/frag/functions/fnc_dev_trackHitBox.sqf index ba136bbd46c..ecc9f06958b 100644 --- a/addons/frag/functions/fnc_dev_trackHitBox.sqf +++ b/addons/frag/functions/fnc_dev_trackHitBox.sqf @@ -17,7 +17,7 @@ */ params [ ["_object", objNull, [objNull]], - ["_addSphere", true, [turretLocal]] + ["_addSphere", true, [true]] ]; if (isNull _object) exitWith {}; @@ -44,7 +44,7 @@ switch (true) do { }; private _centerPoint = ASLToAGL getPosASL _object; -if (GVAR(dbgSphere) && {_addSphere && {isNull objectParent _object}}) then { +if (GVAR(dbgSphere) && {_addSphere && {isNull objectParent _object}}) then { private _centerSphere = [getPosASL _object, "yellow"] call FUNC(dev_sphereDraw); _centerSphere disableCollisionWith vehicle _object; _centerSphere attachTo [_object, _object worldToModel _centerPoint]; From e073d36a2fa5785b3baf6d51f75125a7e1d4b888 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 14:09:20 -0600 Subject: [PATCH 100/282] trailing spaces --- addons/frag/CfgAmmo.hpp | 2 +- addons/frag/README.md | 2 +- addons/frag/cfgAmmoBaseEH.hpp | 2 +- addons/frag/cfgAmmoFragParameters.hpp | 2 +- addons/frag/cfgAmmoFragSpawner.hpp | 2 +- addons/frag/cfgAmmoSpall.hpp | 2 +- addons/frag/config.cpp | 2 +- addons/frag/initSettingsDebug.inc.sqf | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index 27290699a5c..63b63fd72f1 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -104,4 +104,4 @@ class CfgAmmo { #include "cfgAmmoSpall.hpp" #include "cfgAmmoFragSpawner.hpp" #include "cfgAmmoFragParameters.hpp" -}; \ No newline at end of file +}; diff --git a/addons/frag/README.md b/addons/frag/README.md index e5c9a35a05d..797e652b207 100644 --- a/addons/frag/README.md +++ b/addons/frag/README.md @@ -1,4 +1,4 @@ ace_frag ======== -Explosive fragmentation, round spalling, and explosive reflection \ No newline at end of file +Explosive fragmentation, round spalling, and explosive reflection diff --git a/addons/frag/cfgAmmoBaseEH.hpp b/addons/frag/cfgAmmoBaseEH.hpp index e648ba2e951..b02b1b7c6fa 100644 --- a/addons/frag/cfgAmmoBaseEH.hpp +++ b/addons/frag/cfgAmmoBaseEH.hpp @@ -67,4 +67,4 @@ class DirectionalBombBase: DirectionalBombCore { class MineCore; class MineBase: MineCore { ACE_FRAG_ADD_EH_BASE; -}; \ No newline at end of file +}; diff --git a/addons/frag/cfgAmmoFragParameters.hpp b/addons/frag/cfgAmmoFragParameters.hpp index 46a8db30cfb..b60cd178107 100644 --- a/addons/frag/cfgAmmoFragParameters.hpp +++ b/addons/frag/cfgAmmoFragParameters.hpp @@ -691,4 +691,4 @@ class LightningBolt: ShellBase { class M_Mo_82mm_AT: MissileBase { ACE_FRAG_RM_EH; GVAR(skip) = 1; -}; \ No newline at end of file +}; diff --git a/addons/frag/cfgAmmoFragSpawner.hpp b/addons/frag/cfgAmmoFragSpawner.hpp index 81263d6cc82..13e5bbe23c4 100644 --- a/addons/frag/cfgAmmoFragSpawner.hpp +++ b/addons/frag/cfgAmmoFragSpawner.hpp @@ -533,4 +533,4 @@ class GVAR(huge_HD_spawner_3_far): GVAR(spawnbase_targeted) { submunitionAmmo = QGVAR(huge_HD); submunitionConeAngle = 0.9; submunitionConeType[] = {"random", 3}; -}; \ No newline at end of file +}; diff --git a/addons/frag/cfgAmmoSpall.hpp b/addons/frag/cfgAmmoSpall.hpp index 36cba405eaf..a773cfc659c 100644 --- a/addons/frag/cfgAmmoSpall.hpp +++ b/addons/frag/cfgAmmoSpall.hpp @@ -155,4 +155,4 @@ class GVAR(metal_spall_large): GVAR(spallBase) { class GVAR(metal_spall_huge): GVAR(spallBase) { submunitionAmmo[] = {QGVAR(tiny), 8, QGVAR(small), 3, QGVAR(medium), 2, QGVAR(large), 3, QGVAR(huge), 1}; submunitionConeType[] = {"poissondisccenter", 18}; -}; \ No newline at end of file +}; diff --git a/addons/frag/config.cpp b/addons/frag/config.cpp index 0a36ad8d171..f3b409dbd03 100644 --- a/addons/frag/config.cpp +++ b/addons/frag/config.cpp @@ -16,4 +16,4 @@ class CfgPatches { #include "CfgEventhandlers.hpp" #include "CfgAmmo.hpp" -#include "ACE_Settings.hpp" \ No newline at end of file +#include "ACE_Settings.hpp" diff --git a/addons/frag/initSettingsDebug.inc.sqf b/addons/frag/initSettingsDebug.inc.sqf index 09072683af4..e775a6d9e60 100644 --- a/addons/frag/initSettingsDebug.inc.sqf +++ b/addons/frag/initSettingsDebug.inc.sqf @@ -22,4 +22,4 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; [LSTRING(DrawHitBox), LSTRING(DrawHitBox_Desc)], [_category, LSTRING(Debug)], true -] call CBA_fnc_addSetting; \ No newline at end of file +] call CBA_fnc_addSetting; From a0812371c97c5d5eafb3f02e2af7bd689da5c0f8 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 14:27:29 -0600 Subject: [PATCH 101/282] missed a trailing space --- addons/frag/functions/fnc_dev_clearTraces.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_dev_clearTraces.sqf b/addons/frag/functions/fnc_dev_clearTraces.sqf index 132d3be0860..fd6e3ea224d 100644 --- a/addons/frag/functions/fnc_dev_clearTraces.sqf +++ b/addons/frag/functions/fnc_dev_clearTraces.sqf @@ -20,4 +20,4 @@ for "_i" from 0 to count GVAR(dev_eventSpheres) - 1 do { GVAR(dev_eventSpheres) = []; GVAR(dev_trackLines) = createHashMap; -GVAR(dev_hitBoxes) = createHashMap; \ No newline at end of file +GVAR(dev_hitBoxes) = createHashMap; From ff462333cb4deac6105bcceac3f39144716c956d Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 14:39:41 -0600 Subject: [PATCH 102/282] Comment & documentation spelling and grammar improved --- addons/frag/functions/fnc_dev_addRound.sqf | 6 +++--- addons/frag/functions/fnc_dev_clearTraces.sqf | 2 +- addons/frag/functions/fnc_dev_fragCalcDump.sqf | 2 +- addons/frag/functions/fnc_dev_trackHitBox.sqf | 4 ++-- addons/frag/functions/fnc_dev_trackObj.sqf | 8 ++++---- addons/frag/functions/fnc_doFrag.sqf | 2 +- addons/frag/functions/fnc_doFragTargeted.sqf | 2 +- addons/frag/functions/fnc_getFragInfo.sqf | 4 ++-- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/addons/frag/functions/fnc_dev_addRound.sqf b/addons/frag/functions/fnc_dev_addRound.sqf index b88d5745045..c723f2e760c 100644 --- a/addons/frag/functions/fnc_dev_addRound.sqf +++ b/addons/frag/functions/fnc_dev_addRound.sqf @@ -29,7 +29,7 @@ if (_isSidePlayer) then { } else { GVAR(dev_trackLines) set [getObjectID _projectile, [[getposATL _projectile], [1, 0, 0, 1]]]; }; -// eventhandler to track round and cleanup when round is "dead" +// event handler to track round and cleanup when round is "dead" [ { if (isGamePaused) exitWith {}; @@ -48,7 +48,7 @@ if (_isSidePlayer) then { if (!_addProjectileEventHandlers) exitWith {}; -// Add hitpart eventHandler +// Add hitPart eventHandler _projectile addEventHandler [ "HitPart", { @@ -61,7 +61,7 @@ _projectile addEventHandler [ } ]; -// Add explode eventHandler +// Add explode event handler _projectile addEventHandler [ "Explode", { diff --git a/addons/frag/functions/fnc_dev_clearTraces.sqf b/addons/frag/functions/fnc_dev_clearTraces.sqf index fd6e3ea224d..d9bd8a35575 100644 --- a/addons/frag/functions/fnc_dev_clearTraces.sqf +++ b/addons/frag/functions/fnc_dev_clearTraces.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: Lambda.Tiger - * Cleares all dev spheres and traces + * Clears all dev spheres and traces * * Arguments: * None diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf index b7278ca3103..3e0a6972bbc 100644 --- a/addons/frag/functions/fnc_dev_fragCalcDump.sqf +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -3,7 +3,7 @@ * Author: Lambda.Tiger, based on fnc_dev_debugAmmo by "ACE-Team" * Dumps all ammo types to see if there's any reason to spawn fragments * given hit power and distance. Good for grasping the values used in - * shouldFrag to cull non-fragementing rounds + * shouldFrag to cull non-fragmenting rounds * * Arguments: * 0: Display rounds that will never frag (power < 5). diff --git a/addons/frag/functions/fnc_dev_trackHitBox.sqf b/addons/frag/functions/fnc_dev_trackHitBox.sqf index ecc9f06958b..63d58f614f4 100644 --- a/addons/frag/functions/fnc_dev_trackHitBox.sqf +++ b/addons/frag/functions/fnc_dev_trackHitBox.sqf @@ -1,10 +1,10 @@ #include "..\script_component.hpp" /* * Author: Lambda.Tiger - * Add a hitbox outline to an object + * Add a hit box outline to an object * * Arguments: - * 0 Object to draw hitbox : + * 0: Object to draw the hit box of : * 1: Add sphere at object origin * * Return Value: diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index 40b2d3cc668..55630f2994f 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -4,9 +4,9 @@ * This function adds an object to have it's course tracked (every frame). * * Arguments: - * 0: Object to draw hitbox + * 0: Object to draw track OBJECT> * 1: Color of trace - * 2: Whether the object is a projectile + * 2: Whether the object is a projectile or whether to add projectile EHs * * Return Value: * None @@ -37,7 +37,7 @@ private _colorArray = switch (toLowerANSI _color) do { }; GVAR(dev_trackLines) set [getObjectID _object, [1, [getposATL _object], _colorArray]]; -// eventhandler to track round and cleanup when round is "dead" +// event handler to track round and cleanup when round is "dead" [ { if (isGamePaused) exitWith {}; @@ -58,7 +58,7 @@ GVAR(dev_trackLines) set [getObjectID _object, [1, [getposATL _object], _colorAr [_object] ] call CBA_fnc_addPerFrameHandler; -// Projectile eventhandlers that add spheres and points for more accurate round tracking +// Projectile event handlers that add spheres and points for more accurate round tracking if (!_isProj) exitWith {}; _object addEventHandler [ diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 41d97f4a533..492b7ab8a86 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -28,7 +28,7 @@ params [ ["_shotParents", [objNull, objNull], [[]]] ]; -// Check for vehicle holdoff timeout +// Check for vehicle hold-off timeout private _shotParentVic = _shotParents#0; if (_shotParentVic getVariable [QGVAR(nextFragTime), -1] > CBA_missionTime) exitWith { TRACE_1("vehicleTimeExit",_shotParentVic); diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index a46ee65ed3f..ddbc2c72bec 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -10,7 +10,7 @@ * 2: Maximum range of fragments to calculate * 3: Maximum number of fragments to produce * 4: Types of fragments - * 5: A modified parameter used to calulate whether a framgent hits + * 5: A modified parameter used to calculate whether a fragment hits * 6: Shot parent * * Return Value: diff --git a/addons/frag/functions/fnc_getFragInfo.sqf b/addons/frag/functions/fnc_getFragInfo.sqf index 088e19f9676..f7e6ddf3f47 100644 --- a/addons/frag/functions/fnc_getFragInfo.sqf +++ b/addons/frag/functions/fnc_getFragInfo.sqf @@ -42,12 +42,12 @@ if (isArray (configFile >> "cfgAmmo" >> _ammo >> QGVAR(CLASSES))) then { * GURNEY_C = sqrt(2E) * * _chargeMass = 185; - grams of comp-b - * _metalMass = 210; - grams of fragmentating metal + * _metalMass = 210; - grams of metal are accelerated by explosion * _geometryCoefficient = 3/5; - spherical K factor * _gurneyConstant = 2843; - Gurney constant of comp-b in /ms * * _chargeMass = 429; - grams of tritonal - * _metalMass = 496; - grams of fragmentating metal + * _metalMass = 496; - grams of metal are accelerated by explosion * _geometryCoefficient = 1/2; - cylindrical K factor * _gurneyConstant = 2320; - Gurney constant of tritonal in m/s * Equation - 0.8 for empirical 80% speed From 54c4f45cf9768327dd5bbb44e57c176b10e93076 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 15:18:42 -0600 Subject: [PATCH 103/282] possilbe "magic number" cleanup and formatting --- addons/frag/functions/fnc_dev_drawTrace.sqf | 2 +- .../functions/fnc_dev_switchUnitHandle.sqf | 12 +++---- addons/frag/functions/fnc_doFrag.sqf | 32 +++++++++---------- addons/frag/functions/fnc_doFragRandom.sqf | 12 +++---- addons/frag/functions/fnc_getMaterialInfo.sqf | 9 ++++-- addons/frag/functions/fnc_initRound.sqf | 3 +- addons/frag/script_component.hpp | 3 ++ 7 files changed, 39 insertions(+), 34 deletions(-) diff --git a/addons/frag/functions/fnc_dev_drawTrace.sqf b/addons/frag/functions/fnc_dev_drawTrace.sqf index 7f7ff82dae3..94ea9ad75d6 100644 --- a/addons/frag/functions/fnc_dev_drawTrace.sqf +++ b/addons/frag/functions/fnc_dev_drawTrace.sqf @@ -1,5 +1,5 @@ #include "..\script_component.hpp" -#define HITBOX_DRAW_PATH [[3 , 2 , 1 , 5 , 6 , 7 , 3 , 0 , 4 , 5], [0, 1], [2, 6], [7, 4]] +#define HITBOX_DRAW_PATH [[3, 2, 1, 5, 6, 7, 3, 0, 4, 5], [0, 1], [2, 6], [7, 4]] /* * Author: Lambda.Tiger * Per frame function to draw all dev traces diff --git a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf index 9d9050b042e..5c377e0b29f 100644 --- a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf +++ b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf @@ -37,12 +37,12 @@ if (_aID > -1 && {_lastUnit isNotEqualTo objNull}) then { _aID = _currentUnit addAction [ "Reset Lines", FUNC(dev_clearTraces), - nil, // arguments - 1.5, // priority - true, // showWindow - false, // hideOnUse - "", // shortcut - "true", // condition + nil, + 1.5, + true, + false, + "", + "true", 8 ]; diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 492b7ab8a86..b703d134330 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -36,34 +36,34 @@ if (_shotParentVic getVariable [QGVAR(nextFragTime), -1] > CBA_missionTime) exit _shotParentVic setVariable [QGVAR(nextFragTime), CBA_missionTime + ACE_FRAG_HOLDOFF_VEHICLE]; // Check normal round timeout and adjust _max frags -private _timeSince = CBA_missionTime - GVAR(lastFragTime); -if (_ammo isEqualTo "" || {_posASL isEqualTo [0, 0, 0] || _timeSince < ACE_FRAG_HOLDOFF}) exitWith { - TRACE_3("timeExit",_timeSince,CBA_missionTime,GVAR(lastFragTime)); +private _timeSinceLastFrag = CBA_missionTime - GVAR(lastFragTime); +if (_ammo isEqualTo "" || {_posASL isEqualTo [0, 0, 0] || _timeSinceLastFrag < ACE_FRAG_HOLDOFF}) exitWith { + TRACE_3("timeExit",_timeSinceLastFrag,CBA_missionTime,GVAR(lastFragTime)); }; -private _maxFrags = round linearConversion [0.1, 1.5, _timeSince, ACE_FRAG_COUNT_MIN, ACE_FRAG_COUNT_MAX, true]; -TRACE_3("willFrag",_timeSince,CBA_missionTime,_maxFrags); +private _maxFragCount = round linearConversion [0.1, 1.5, _timeSinceLastFrag, ACE_FRAG_COUNT_MIN, ACE_FRAG_COUNT_MAX, true]; +TRACE_3("willFrag",_timeSinceLastFrag,CBA_missionTime,_maxFragCount); private _ammoArr = [_ammo] call FUNC(getFragInfo); _ammoArr params ["_fragRange", "_fragVel", "_fragTypes", "_modFragCount"]; -// For low frag rounds limit the # of frags +// For low frag rounds limit the # of frags created if (_modFragCount < 10) then { - _maxFrags = _modFragCount*4; - GVAR(lastFragTime) = CBA_missionTime - 0.1; + _maxFragCount = _modFragCount * ACE_FRAG_LOW_FRAG_COEFF; + GVAR(lastFragTime) = CBA_missionTime - ACE_FRAG_LOW_FRAG_HOLDOFF_REDUCTION; } else { GVAR(lastFragTime) = CBA_missionTime; }; // Offset for ground clearance -private _heightAGL = (ASLToAGL _posASL)#2; -if (_heightAGL < 0.25) then { - _posASL = _posASL vectorAdd [0, 0, 0.25]; +private _heightATL = (ASLToATL _posASL)#2; +if (_heightATL < ACE_FRAG_MIN_GROUND_OFFSET) then { + _posASL = _posASL vectorAdd [0, 0, ACE_FRAG_MIN_GROUND_OFFSET]; }; -TRACE_3("fnc_doFragTargeted IF", _fragRange, _timeSince, GVAR(fragSimComplexity)); -if (_fragRange > 3 && _timeSince > ACE_FRAG_HOLDOFF*1.5 && GVAR(fragSimComplexity) != 1) then { - _maxFrags = _maxFrags - ([_posASL, _fragVel, _fragRange, _maxFrags, _fragTypes, _modFragCount, _shotParents] call FUNC(doFragTargeted)); +TRACE_3("fnc_doFragTargeted IF", _fragRange, _timeSinceLastFrag, GVAR(fragSimComplexity)); +if (GVAR(fragSimComplexity) != 1 && _fragRange > 3) then { + _maxFragCount = _maxFragCount - ([_posASL, _fragVel, _fragRange, _maxFragCount, _fragTypes, _modFragCount, _shotParents] call FUNC(doFragTargeted)); }; -if (_timeSince > 0.2 && {GVAR(fragSimComplexity) > 0}) then { - [_posASL, _velocity, _heightAGL, _fragTypes, _maxFrags, _shotParents] call FUNC(doFragRandom); +if (GVAR(fragSimComplexity) > 0) then { + [_posASL, _velocity, _heightATL, _fragTypes, _maxFragCount, _shotParents] call FUNC(doFragRandom); }; diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index b956bc36cc1..698b720ce68 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -25,10 +25,10 @@ params [ ["_fragVelocity", [0,0,0]], ["_heightAGL", 2, [123]], ["_fragType", [], [[]]], - ["_fragCnt", 10, [123]], + ["_maxFragCount", 10, [123]], ["_shotParents", [objNull, objNull], [[]], [2]] ]; -TRACE_5("fnc_doFragRandom", _posASL, _fragVelocity, _heightAGL, _fragType, _fragCnt); +TRACE_6("doFragRandom",_posASL,_fragVelocity,_heightAGL,_fragType,_maxFragCount,_shotParents); // See cfgAmmoFragSpawner for different frag types private _hMode = switch (true) do { @@ -44,14 +44,14 @@ private _type = if (count _fragType > 0 && QGVAR(def_small_) }; -_fragCnt = switch (true) do { - case (_fragCnt <= 5): {"5"}; - case (_fragCnt <= 10): {"10"}; +_maxFragCount = switch (true) do { + case (_maxFragCount <= 5): {"5"}; + case (_maxFragCount <= 10): {"10"}; default {"15"}; }; // Spawn the fragment spawner -private _fragSpawner = createVehicle [_type + _fragCnt + _hMode, ASLToATL _posASL, [], 0, "CAN_COLLIDE"]; +private _fragSpawner = createVehicle [_type + _maxFragCount + _hMode, ASLToATL _posASL, [], 0, "CAN_COLLIDE"]; _fragSpawner setVectorDirandUp [[0,0,1], [1,0,0]]; _fragSpawner setVelocity _fragVelocity; _fragSpawner setShotParents _shotParents; diff --git a/addons/frag/functions/fnc_getMaterialInfo.sqf b/addons/frag/functions/fnc_getMaterialInfo.sqf index 37140469db8..d644ded9201 100644 --- a/addons/frag/functions/fnc_getMaterialInfo.sqf +++ b/addons/frag/functions/fnc_getMaterialInfo.sqf @@ -1,4 +1,7 @@ #include "..\script_component.hpp" +#define ACE_FRAG_SOUNDENVIRON_STR_LEN 12 +#define ACE_FRAG_SOUNDGIT_STR_LEN 8 +#define ACE_FRAG_MATERIAL_SEARCH_LEN 10 /* * Author: Lambda.Tiger * This function returns a classification of material type based @@ -33,11 +36,11 @@ if (isClass (configFile >> "CfgSurfaces" >> _surfType)) then { } else { // Messy way when a surface isn't added to cfgSurfaces private _surfFileText = toLowerANSI preprocessFile _surfType; _surfFileText = _surfFileText regexReplace ["[^a-z0-9]", ""]; - private _idx = 12 + (_surfFileText find "soundenviron"); + private _idx = ACE_FRAG_SOUNDENVIRON_STR_LEN + (_surfFileText find "soundenviron"); if (_surfFileText select [_idx, 5] isEqualTo "empty") then { - _idx = 8 + (_surfFileText find "soundhit"); + _idx = ACE_FRAG_SOUNDGIT_STR_LEN + (_surfFileText find "soundhit"); }; - _material = _surfFileText select [_idx, 10]; + _material = _surfFileText select [_idx, ACE_FRAG_MATERIAL_SEARCH_LEN]; }; TRACE_1("materialSubString",_material); diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index 377a5b74ca7..4c4f41f19ea 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -47,8 +47,7 @@ if (_shouldFrag && GVAR(enabled)) then { private _shouldSpall = _ammo call FUNC(shouldSpall); -if (GVAR(spallEnabled) && {_shouldSpall}) then -{ +if (GVAR(spallEnabled) && {_shouldSpall}) then { _projectile addEventHandler [ "HitPart", { diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index f4355816905..a3d571bcaca 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -31,4 +31,7 @@ #define ACE_FRAG_HALF_GRAVITY_APPROX 4.905 // stop searching at 0.5% chance to hit #define ACE_FRAG_MIN_FRAG_HIT_CHANCE 0.005 +#define ACE_FRAG_MIN_GROUND_OFFSET 0.25 +#define ACE_FRAG_LOW_FRAG_COEFF 4 +#define ACE_FRAG_LOW_FRAG_HOLDOFF_REDUCTION 4 #define ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF 2 From 22e26ee4525a1411a68bb5da0bc5c3f8ad1581fd Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 15:23:12 -0600 Subject: [PATCH 104/282] change of switch statements as referenced here https://github.com/acemod/ACE3/pull/9728#discussion_r1452728046 --- addons/frag/functions/fnc_dev_trackHitBox.sqf | 9 ++++----- addons/frag/functions/fnc_doFragTargeted.sqf | 7 +++---- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/addons/frag/functions/fnc_dev_trackHitBox.sqf b/addons/frag/functions/fnc_dev_trackHitBox.sqf index 63d58f614f4..ae1a12e9bf3 100644 --- a/addons/frag/functions/fnc_dev_trackHitBox.sqf +++ b/addons/frag/functions/fnc_dev_trackHitBox.sqf @@ -36,11 +36,10 @@ if (_object isKindOf "CAManBase") then { _box params ["_lowP","_upP"]; // adjust with stance -private _stance = stance _object; -switch (true) do { - case (_stance isEqualTo "STAND"): {_upP set [2, 1.9];}; - case (_stance isEqualTo "CROUCH"): {_upP set [2, 1.3];}; - case (_stance isEqualTo "PRONE"): {_upP set [2, 0.8];}; +switch (stance _object) do { + case ("STAND"): {_upP set [2, 1.9];}; + case ("CROUCH"): {_upP set [2, 1.3];}; + case ("PRONE"): {_upP set [2, 0.8];}; }; private _centerPoint = ASLToAGL getPosASL _object; diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index ddbc2c72bec..9143a53c74d 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -81,10 +81,9 @@ private _totalFragCount = 0; private _crossSectionArea = 1; private _isPerson = _target isKindOf "CAManBase"; if (_isPerson) then { - private _stance = stance _target; - switch (true) do { - case (_stance isEqualTo "STAND"): {_height = 1.9; _crossSectionArea = 1.5;}; - case (_stance isEqualTo "CROUCH"): {_height = 1.2; _crossSectionArea = 1;}; + switch (stance _target) do { + case ("STAND"): {_height = 1.9; _crossSectionArea = 1.5;}; + case ("CROUCH"): {_height = 1.2; _crossSectionArea = 1;}; default {_crossSectionArea = 0.75;}; }; } else { From ced7aeb50c47900437375cc15d2761615722f724 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 15:24:11 -0600 Subject: [PATCH 105/282] Deleted whitespace in doFrag Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_doFrag.sqf | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index b703d134330..b721a951ebb 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -43,7 +43,6 @@ if (_ammo isEqualTo "" || {_posASL isEqualTo [0, 0, 0] || _timeSinceLastFrag < A private _maxFragCount = round linearConversion [0.1, 1.5, _timeSinceLastFrag, ACE_FRAG_COUNT_MIN, ACE_FRAG_COUNT_MAX, true]; TRACE_3("willFrag",_timeSinceLastFrag,CBA_missionTime,_maxFragCount); - private _ammoArr = [_ammo] call FUNC(getFragInfo); _ammoArr params ["_fragRange", "_fragVel", "_fragTypes", "_modFragCount"]; // For low frag rounds limit the # of frags created From 7581a480eba9534ae527e97c6c912a2ce10ec11c Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 15:24:47 -0600 Subject: [PATCH 106/282] Optimized isNull check Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_dev_switchUnitHandle.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf index 5c377e0b29f..e99fb334e2f 100644 --- a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf +++ b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf @@ -30,7 +30,7 @@ if (!local _currentUnit) exitWith { private _aID = missionNamespace getVariable [QGVAR(dev_clearTraceAction), -1]; -if (_aID > -1 && {_lastUnit isNotEqualTo objNull}) then { +if (_aID > -1 && {!isNull _lastUnit}) then { _lastUnit removeAction _aID; }; From ea654c8e5634713938ddfa3235ad5d81681b6fb6 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 15:36:58 -0600 Subject: [PATCH 107/282] Capitalized config entries --- addons/frag/CfgAmmo.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index 63b63fd72f1..36b9be58ad0 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -19,7 +19,7 @@ class CfgAmmo { - #include "cfgAmmoBaseEH.hpp" + #include "CfgAmmoBaseEH.hpp" class B_65x39_Caseless: BulletBase { class EventHandlers: EventHandlers {}; @@ -101,7 +101,7 @@ class CfgAmmo { caliber = 2.8; }; - #include "cfgAmmoSpall.hpp" - #include "cfgAmmoFragSpawner.hpp" - #include "cfgAmmoFragParameters.hpp" + #include "CfgAmmoSpall.hpp" + #include "CfgAmmoFragSpawner.hpp" + #include "CfgAmmoFragParameters.hpp" }; From 4dee712d706c81db490738c51d6bda8273b246a7 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 15:37:18 -0600 Subject: [PATCH 108/282] fixed example syntax --- addons/frag/functions/fnc_dev_clearTraces.sqf | 2 +- addons/frag/functions/fnc_dev_debugAmmo.sqf | 2 +- addons/frag/functions/fnc_initBlackList.sqf | 2 +- addons/frag/functions/fnc_initMaterialCache.sqf | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/frag/functions/fnc_dev_clearTraces.sqf b/addons/frag/functions/fnc_dev_clearTraces.sqf index d9bd8a35575..e8ebfb2b143 100644 --- a/addons/frag/functions/fnc_dev_clearTraces.sqf +++ b/addons/frag/functions/fnc_dev_clearTraces.sqf @@ -10,7 +10,7 @@ * None * * Example: - * [] call ace_frag_fnc_dev_clearTraces; + * call ace_frag_fnc_dev_clearTraces; * * Public: No */ diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index 62b770f28b9..0047a179506 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -15,7 +15,7 @@ * None * * Example: - * [] call ace_frag_fnc_dev_debugAmmo + * call ace_frag_fnc_dev_debugAmmo * * Public: No */ diff --git a/addons/frag/functions/fnc_initBlackList.sqf b/addons/frag/functions/fnc_initBlackList.sqf index 79d3c86a72d..f95cd09ec52 100644 --- a/addons/frag/functions/fnc_initBlackList.sqf +++ b/addons/frag/functions/fnc_initBlackList.sqf @@ -10,7 +10,7 @@ * None * * Example: - * [] call ace_frag_fnc_addBlackList + * call ace_frag_fnc_addBlackList * * Public: No */ diff --git a/addons/frag/functions/fnc_initMaterialCache.sqf b/addons/frag/functions/fnc_initMaterialCache.sqf index 81ec5220cb9..cde98f9fa1a 100644 --- a/addons/frag/functions/fnc_initMaterialCache.sqf +++ b/addons/frag/functions/fnc_initMaterialCache.sqf @@ -11,7 +11,7 @@ * none * * Example: - * [] call initMaterialCache; + * call initMaterialCache; * * Public: No */ From 81d477e911b3d37bb4fe208ab4091e74c145e1f3 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 15:37:32 -0600 Subject: [PATCH 109/282] fixed call syntax --- addons/frag/XEH_postInit.sqf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index f0cbd532ded..ff100aa4fef 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -4,18 +4,18 @@ "CBA_settingsInitialized", { if (isServer) then { - [] call FUNC(initBlackList); - [] call FUNC(initMaterialCache); + call FUNC(initBlackList); + call FUNC(initMaterialCache); }; -#ifdef DEBUG_MODE_DRAW + #ifdef DEBUG_MODE_DRAW if (hasInterface) then { private _handle = [LINKFUNC(dev_drawTrace), 0] call CBA_fnc_addPerFrameHandler; missionNamespace setVariable [QGVAR(dev_drawPFEH), _handle]; ["unit", LINKFUNC(dev_switchUnitHandle), true] call CBA_fnc_addPlayerEventHandler; [objNull, ace_player] call FUNC(dev_switchUnitHandle); }; -#endif + #endif } ] call CBA_fnc_addEventHandler; From 29d3d4c19fec79eb433701bf6974648ba29efdf1 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 15:39:27 -0600 Subject: [PATCH 110/282] alphabetized PREP instead of categorizing it --- addons/frag/XEH_PREP.hpp | 43 +++++++++++++++------------------------- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/addons/frag/XEH_PREP.hpp b/addons/frag/XEH_PREP.hpp index 01d75186696..9565d3e983d 100644 --- a/addons/frag/XEH_PREP.hpp +++ b/addons/frag/XEH_PREP.hpp @@ -1,37 +1,26 @@ -// dev -#ifdef DEBUG_MODE_DRAW +PREP(addBlackList); +PREP(dev_addRound); +PREP(dev_clearTraces); +PREP(dev_debugAmmo); +PREP(dev_drawTrace); PREP(dev_fired); +PREP(dev_fragCalcDump); PREP(dev_trackHitBox); -PREP(dev_sphereDraw); -PREP(dev_addRound); PREP(dev_trackObj); -PREP(dev_drawTrace); -PREP(dev_clearTraces); +PREP(dev_sphereDraw); PREP(dev_switchUnitHandle); -#endif -PREP(dev_fragCalcDump); -PREP(dev_debugAmmo); - -// Base -PREP(initRound); - -// Frag -PREP(addBlackList); -PREP(initBlackList); -PREP(shouldFrag); -PREP(getFragInfo); +PREP(doExplosions); PREP(doFrag); -PREP(doFragTargeted); PREP(doFragRandom); - -// Spall -PREP(shouldSpall); +PREP(doFragTargeted); +PREP(doReflections); PREP(doSpall); +PREP(findReflections); PREP(getMaterialInfo); PREP(getSpallInfo); +PREP(getFragInfo); +PREP(initBlackList); PREP(initMaterialCache); - -// Explosive Reflection -PREP(findReflections); -PREP(doExplosions); -PREP(doReflections); +PREP(initRound); +PREP(shouldFrag); +PREP(shouldSpall); \ No newline at end of file From c7a2769bdd80ec30de84fd59bbcd8d727c9806d3 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 16:05:58 -0600 Subject: [PATCH 111/282] Really obvious isNull instead of isEqualTo Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_dev_switchUnitHandle.sqf | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf index e99fb334e2f..8afdf53428d 100644 --- a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf +++ b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf @@ -17,8 +17,7 @@ */ params ["_lastUnit", "_currentUnit"]; - -if (_currentUnit isEqualTo objNull || {_lastUnit isEqualTo _currentUnit}) exitWith {}; +if (isNull _currentUnit || {_lastUnit isEqualTo _currentUnit}) exitWith {}; if (!local _currentUnit) exitWith { [ {local _currentUnit}, From 8683e0aa56b1219f241170e21b681f0be5488b4d Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 16:10:01 -0600 Subject: [PATCH 112/282] Fixed array of double spaced format errors --- addons/frag/CfgAmmo.hpp | 2 +- addons/frag/XEH_PREP.hpp | 2 +- addons/frag/cfgAmmoFragSpawner.hpp | 2 +- addons/frag/functions/fnc_dev_debugAmmo.sqf | 2 +- addons/frag/functions/fnc_dev_fragCalcDump.sqf | 2 +- addons/frag/functions/fnc_dev_sphereDraw.sqf | 4 ++-- addons/frag/functions/fnc_dev_trackHitBox.sqf | 6 +++--- addons/frag/functions/fnc_doFragTargeted.sqf | 4 ++-- addons/frag/functions/fnc_doSpall.sqf | 6 +++--- addons/frag/functions/fnc_getFragInfo.sqf | 2 +- addons/frag/functions/fnc_getMaterialInfo.sqf | 2 +- addons/frag/functions/fnc_shouldFrag.sqf | 2 +- addons/frag/script_component.hpp | 6 +++--- 13 files changed, 21 insertions(+), 21 deletions(-) diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index 36b9be58ad0..a8db2b0b6fb 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -78,7 +78,7 @@ class CfgAmmo { }; class GVAR(large_HD): GVAR(large) { - hit = 28; + hit = 28; indirectHit = 2; indirectHitRange = 0.25; airFriction = QUOTE(BASE_DRAG_HD*0.65); diff --git a/addons/frag/XEH_PREP.hpp b/addons/frag/XEH_PREP.hpp index 9565d3e983d..f87756ea137 100644 --- a/addons/frag/XEH_PREP.hpp +++ b/addons/frag/XEH_PREP.hpp @@ -23,4 +23,4 @@ PREP(initBlackList); PREP(initMaterialCache); PREP(initRound); PREP(shouldFrag); -PREP(shouldSpall); \ No newline at end of file +PREP(shouldSpall); diff --git a/addons/frag/cfgAmmoFragSpawner.hpp b/addons/frag/cfgAmmoFragSpawner.hpp index 13e5bbe23c4..867766f72c4 100644 --- a/addons/frag/cfgAmmoFragSpawner.hpp +++ b/addons/frag/cfgAmmoFragSpawner.hpp @@ -193,7 +193,7 @@ class GVAR(def_small_10_top): GVAR(def_small_10) { triggerSpeedCoef[] = {-1.10, -0.710}; }; /* - * Default frag, spawning small fragments only + * Default frag, spawning small fragments only */ class GVAR(def_small_5): GVAR(spawnbase) { submunitionConeType[] = {"random", 5}; diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index 0047a179506..14c5891a018 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -89,7 +89,7 @@ private _printCount = 0; if (_warn) then { INC(_printCount); if (_csvFormat) then { - diag_log text format ["%7,%1,%2,%3,%4,%5,%6,%8", _c, _m, _k, _gC, _fragTypes, _fragCount, _ammo, [_ammoConfig, true] call BIS_fnc_returnParents]; + diag_log text format ["%7,%1,%2,%3,%4,%5,%6,%8", _c, _m, _k, _gC, _fragTypes, _fragCount, _ammo, [_ammoConfig, true] call BIS_fnc_returnParents]; } else { diag_log text format ["Ammo [%1] MISSING frag configs:", _ammo]; diag_log text format [" _c=%1,_m=%2,_k=%3,_gC=%4,_fragTypes=%5,_fragCount=%6", _c, _m, _k, _gC, _fragTypes, _fragCount]; diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf index 3e0a6972bbc..ef92cd9c77e 100644 --- a/addons/frag/functions/fnc_dev_fragCalcDump.sqf +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -57,5 +57,5 @@ diag_log text "//****************** fragCalcDump Beg ******************//"; _processedCfgAmmos pushBack _ammo; } forEach _allAmmoConfigs; -diag_log text "//****************** fragCalcDump End ******************//"; +diag_log text "//****************** fragCalcDump End ******************//"; diag_log text format ["//********************** printed %1 *********************//", _nPrinted]; diff --git a/addons/frag/functions/fnc_dev_sphereDraw.sqf b/addons/frag/functions/fnc_dev_sphereDraw.sqf index 123c64ba944..5eb8e30b00c 100644 --- a/addons/frag/functions/fnc_dev_sphereDraw.sqf +++ b/addons/frag/functions/fnc_dev_sphereDraw.sqf @@ -36,12 +36,12 @@ if (_color select [0,1] != "(") then { case "green": { _color = "(0,0.8,0,0.5)"; }; case "yellow": { _color = "(0.8,0.8,0,0.5)"; }; case "orange": { _color = "(0.8,0.518,0,0.5)"; }; - default { _color = "(0.8,0.8,0,0.5)";}; + default { _color = "(0.8,0.8,0,0.5)";}; }; }; private _colorString = "#(argb,8,8,3)color" + _color; -private _sphere = createVehicle ["Sign_Sphere25cm_F", ASLtoATL _posASL, [], 0, "CAN_COLLIDE"]; +private _sphere = createVehicle ["Sign_Sphere25cm_F", ASLtoATL _posASL, [], 0, "CAN_COLLIDE"]; _sphere setObjectTextureGlobal [0, _colorString]; GVAR(dev_eventSpheres) pushBack _sphere; diff --git a/addons/frag/functions/fnc_dev_trackHitBox.sqf b/addons/frag/functions/fnc_dev_trackHitBox.sqf index ae1a12e9bf3..d23776070b3 100644 --- a/addons/frag/functions/fnc_dev_trackHitBox.sqf +++ b/addons/frag/functions/fnc_dev_trackHitBox.sqf @@ -24,14 +24,14 @@ if (isNull _object) exitWith {}; // Grab the right hitBox private _box = []; -if (_object isKindOf "CAManBase") then { +if (_object isKindOf "CAManBase") then { if (isNull objectParent _object) then { _box = 0 boundingBox _object; } else { - _box = boundingBoxReal [_object, "Geometry"]; + _box = boundingBoxReal [_object, "Geometry"]; }; } else { - _box = boundingBoxReal [_object, "FireGeometry"]; + _box = boundingBoxReal [_object, "FireGeometry"]; }; _box params ["_lowP","_upP"]; diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index 9143a53c74d..17d7d8b8aa2 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -26,7 +26,7 @@ params [ "_posASL", ["_fragVelocity", 800, [123]], ["_fragRange", 50, [123]], - ["_maxFrags", 20, [123]], + ["_maxFrags", 20, [123]], ["_fragTypes", [], [[]]], ["_modFragCount", 1, [123]], ["_shotParents", [objNull, objNull], [[]], [2]] @@ -87,7 +87,7 @@ private _totalFragCount = 0; default {_crossSectionArea = 0.75;}; }; } else { - private _boxParams = boundingBoxReal [_target, "FireGeometry"]; + private _boxParams = boundingBoxReal [_target, "FireGeometry"]; _boxParams params ["_pointA", "_pointB"]; private _dims = _pointB vectorDiff _pointA; if (_dims#0 * _dims#1 * _dims#2 <= 0.5) then {continue}; diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index 8a65e60e8b1..64c040b3bab 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -37,9 +37,9 @@ if (CBA_missionTime - GVAR(lastSpallTime) < ACE_FRAG_SPALL_HOLDOFF || private _material = [_surfaceType] call FUNC(getMaterialInfo); if (_material isEqualTo "ground") then { -#ifdef DEBUG_MODE_FULL + #ifdef DEBUG_MODE_FULL systemChat "ground spall"; -#endif + #endif }; // Find spall speed / fragment info @@ -58,7 +58,7 @@ private _velocityChange = vectorMagnitude _lastVelocity - vectorMagnitude _vel; * of sqrt(2)/50 * round caliber * srqt(change in speed). The second term is * explosive * indirect hit, for any explosive contribution */ -private _spallPower = (ACE_FRAG_ROUND_COEF * _caliber * sqrt _velocityChange + _explosive * _indirectHit) * GVAR(spallIntensity); +private _spallPower = (ACE_FRAG_ROUND_COEF * _caliber * sqrt _velocityChange + _explosive * _indirectHit) * GVAR(spallIntensity); TRACE_3("found speed",_velocityChange,_caliber,_spallPower); diff --git a/addons/frag/functions/fnc_getFragInfo.sqf b/addons/frag/functions/fnc_getFragInfo.sqf index f7e6ddf3f47..b76e6e9ed87 100644 --- a/addons/frag/functions/fnc_getFragInfo.sqf +++ b/addons/frag/functions/fnc_getFragInfo.sqf @@ -30,7 +30,7 @@ if (!isNil "_ammoInfo") exitWith {_ammoInfo}; private _fragTypes = []; private _warn = false; if (isArray (configFile >> "cfgAmmo" >> _ammo >> QGVAR(CLASSES))) then { - _fragTypes = getArray (configFile >> "cfgAmmo" >> _ammo >> QGVAR(CLASSES)); + _fragTypes = getArray (configFile >> "cfgAmmo" >> _ammo >> QGVAR(CLASSES)); } else { _warn = true; }; diff --git a/addons/frag/functions/fnc_getMaterialInfo.sqf b/addons/frag/functions/fnc_getMaterialInfo.sqf index d644ded9201..54d01cc103d 100644 --- a/addons/frag/functions/fnc_getMaterialInfo.sqf +++ b/addons/frag/functions/fnc_getMaterialInfo.sqf @@ -36,7 +36,7 @@ if (isClass (configFile >> "CfgSurfaces" >> _surfType)) then { } else { // Messy way when a surface isn't added to cfgSurfaces private _surfFileText = toLowerANSI preprocessFile _surfType; _surfFileText = _surfFileText regexReplace ["[^a-z0-9]", ""]; - private _idx = ACE_FRAG_SOUNDENVIRON_STR_LEN + (_surfFileText find "soundenviron"); + private _idx = ACE_FRAG_SOUNDENVIRON_STR_LEN + (_surfFileText find "soundenviron"); if (_surfFileText select [_idx, 5] isEqualTo "empty") then { _idx = ACE_FRAG_SOUNDGIT_STR_LEN + (_surfFileText find "soundhit"); }; diff --git a/addons/frag/functions/fnc_shouldFrag.sqf b/addons/frag/functions/fnc_shouldFrag.sqf index 37805be7bb6..d957781f10a 100644 --- a/addons/frag/functions/fnc_shouldFrag.sqf +++ b/addons/frag/functions/fnc_shouldFrag.sqf @@ -30,7 +30,7 @@ private _explosive = getNumber (configFile >> "cfgAmmo" >> _ammo >> "explosive") private _indirectHit = getNumber (configFile >> "cfgAmmo" >> _ammo >> "indirectHit"); private _indirectRange = getNumber (configFile >> "cfgAmmo" >> _ammo >> "indirectHitRange"); -if (_skip == 1 || (_force == 0 && {_explosive < 0.5 || {_indirectHit < 3 +if (_skip == 1 || (_force == 0 && {_explosive < 0.5 || {_indirectHit < 3 || {_indirectRange < 5 && _indirectHit < _indirectRange}}})) then { TRACE_5("No frag",_ammo,_skip, _explosive, _indirectRange, _indirectHit); _shouldFrag = false; diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index a3d571bcaca..800a9552089 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -23,11 +23,11 @@ #define ACE_FRAG_SPALL_HOLDOFF 0.25 #define ACE_FRAG_COUNT_MIN 5 #define ACE_FRAG_COUNT_MAX 50 -#define ACE_FRAG_HITPOINTS ["spine1","spine2","spine3","head","leftarm","leftarmroll","leftforearm","rightarm","rightarmroll","rightforearm","pelvis","leftupleg","leftuplegroll","leftlegroll","leftfoot","rightupleg","rightuplegroll","rightleg","rightlegroll","rightfoot"] +#define ACE_FRAG_HITPOINTS ["spine1","spine2","spine3","head","leftarm","leftarmroll","leftforearm","rightarm","rightarmroll","rightforearm","pelvis","leftupleg","leftuplegroll","leftlegroll","leftfoot","rightupleg","rightuplegroll","rightleg","rightlegroll","rightfoot"] #define ACE_FRAG_HITPOINTS_WEIGHTS -// sqrt(2)/50 +// sqrt(2)/50 #define ACE_FRAG_ROUND_COEF 0.02828427 -// half of gravity approx 9.81/2 +// half of gravity approx 9.81/2 #define ACE_FRAG_HALF_GRAVITY_APPROX 4.905 // stop searching at 0.5% chance to hit #define ACE_FRAG_MIN_FRAG_HIT_CHANCE 0.005 From fa4de59a25e311f97cd5e6ee8d434cd69b6815a0 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 16:10:48 -0600 Subject: [PATCH 113/282] renamed files to fit proper format --- addons/frag/{cfgAmmoBaseEH.hpp => CfgAmmoBaseEH.hpp} | 0 .../frag/{cfgAmmoFragParameters.hpp => CfgAmmoFragParameters.hpp} | 0 addons/frag/{cfgAmmoFragSpawner.hpp => CfgAmmoFragSpawner.hpp} | 0 addons/frag/{cfgAmmoSpall.hpp => CfgAmmoSpall.hpp} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename addons/frag/{cfgAmmoBaseEH.hpp => CfgAmmoBaseEH.hpp} (100%) rename addons/frag/{cfgAmmoFragParameters.hpp => CfgAmmoFragParameters.hpp} (100%) rename addons/frag/{cfgAmmoFragSpawner.hpp => CfgAmmoFragSpawner.hpp} (100%) rename addons/frag/{cfgAmmoSpall.hpp => CfgAmmoSpall.hpp} (100%) diff --git a/addons/frag/cfgAmmoBaseEH.hpp b/addons/frag/CfgAmmoBaseEH.hpp similarity index 100% rename from addons/frag/cfgAmmoBaseEH.hpp rename to addons/frag/CfgAmmoBaseEH.hpp diff --git a/addons/frag/cfgAmmoFragParameters.hpp b/addons/frag/CfgAmmoFragParameters.hpp similarity index 100% rename from addons/frag/cfgAmmoFragParameters.hpp rename to addons/frag/CfgAmmoFragParameters.hpp diff --git a/addons/frag/cfgAmmoFragSpawner.hpp b/addons/frag/CfgAmmoFragSpawner.hpp similarity index 100% rename from addons/frag/cfgAmmoFragSpawner.hpp rename to addons/frag/CfgAmmoFragSpawner.hpp diff --git a/addons/frag/cfgAmmoSpall.hpp b/addons/frag/CfgAmmoSpall.hpp similarity index 100% rename from addons/frag/cfgAmmoSpall.hpp rename to addons/frag/CfgAmmoSpall.hpp From 054b9cda2367f481e66677af914870008237adcf Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 16:13:48 -0600 Subject: [PATCH 114/282] fixed more spacing issues --- addons/frag/CfgAmmoFragParameters.hpp | 8 ++++---- addons/frag/functions/fnc_dev_trackObj.sqf | 14 +++++++------- addons/frag/functions/fnc_doFragTargeted.sqf | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/addons/frag/CfgAmmoFragParameters.hpp b/addons/frag/CfgAmmoFragParameters.hpp index b60cd178107..11285095955 100644 --- a/addons/frag/CfgAmmoFragParameters.hpp +++ b/addons/frag/CfgAmmoFragParameters.hpp @@ -164,10 +164,10 @@ class GrenadeHand: Grenade { */ GVAR(classes)[] = {QGVAR(tiny)}; GVAR(fragCount) = 1000; - GVAR(metal) = 210; // metal in grams - GVAR(charge) = 185; // explosive in grams - GVAR(gurney_c) = 2843; // Gurney velocity constant for explosive type. See: http://en.wikipedia.org/wiki/Gurney_equations - GVAR(gurney_k) = "3/5"; // Gurney shape factor, in this case a sphere. See: http://en.wikipedia.org/wiki/Gurney_equations + GVAR(metal) = 210; // metal in grams + GVAR(charge) = 185; // explosive in grams + GVAR(gurney_c) = 2843; // Gurney velocity constant for explosive type. See: http://en.wikipedia.org/wiki/Gurney_equations + GVAR(gurney_k) = "3/5"; // Gurney shape factor, in this case a sphere. See: http://en.wikipedia.org/wiki/Gurney_equations }; class GrenadeHand_stone: GrenadeHand { ACE_FRAG_RM_EH; diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index 55630f2994f..d6334db9add 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -26,14 +26,14 @@ TRACE_3("devDraw",_object,_color,_isProj); // pick color and add it to the array private _colorArray = switch (toLowerANSI _color) do { case "purple": {[0.8, 0, 0.8, 1]}; - case "blue": {[0, 0, 0.8, 1]}; - case "green": {[0, 0.8, 0, 1]}; + case "blue": {[0, 0, 0.8, 1]}; + case "green": {[0, 0.8, 0, 1]}; case "orange": {[0.8, 0.518, 0, 1]}; - case "yellow": {[0.8, 0.8, 0, 1] }; - case "red": {[0.8, 0, 0, 1]}; - case "black": {[1, 1, 1, 1]}; - case "white": {[0, 0, 0, 1]}; - default {[0, 0.8, 0.8, 1]}; + case "yellow": {[0.8, 0.8, 0, 1]}; + case "red": {[0.8, 0, 0, 1]}; + case "black": {[1, 1, 1, 1]}; + case "white": {[0, 0, 0, 1]}; + default {[0, 0.8, 0.8, 1]}; }; GVAR(dev_trackLines) set [getObjectID _object, [1, [getposATL _object], _colorArray]]; diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index 17d7d8b8aa2..c6a2cbf95ee 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -128,7 +128,7 @@ private _totalFragCount = 0; // target pos for fragment to hit private _targetPos = (velocity _target vectorMultiply _timeOfFlight) vectorAdd [0, 0, ACE_FRAG_HALF_GRAVITY_APPROX * _timeOfFlight ^ 2]; if _isPerson then { - private _hitPoint = selectRandom ACE_FRAG_HITPOINTS; + private _hitPoint = selectRandom ACE_FRAG_HITPOINTS; private _hitPointPos = _target selectionPosition [_hitPoint, "HitPoints", "AveragePoint"]; _targetPos = _target modelToWorldWorld _hitPointPos vectorAdd _targetPos; } else { From c05be02530cabb6afe3fb235f6b7a0685f8efc94 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 16:27:29 -0600 Subject: [PATCH 115/282] formatting --- addons/frag/functions/fnc_doFrag.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index b721a951ebb..16fdbeadc0e 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -29,7 +29,7 @@ params [ ]; // Check for vehicle hold-off timeout -private _shotParentVic = _shotParents#0; +_shotParents params ["_shotParentVic"]; if (_shotParentVic getVariable [QGVAR(nextFragTime), -1] > CBA_missionTime) exitWith { TRACE_1("vehicleTimeExit",_shotParentVic); }; From 3957a0751fad179896de9a433d8f5fd7b3a4b3eb Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 16:30:50 -0600 Subject: [PATCH 116/282] Fixed debug mode init, a few things pointed out by johnb432 that I was dumb not to do --- addons/frag/XEH_postInit.sqf | 13 +++++++++---- addons/frag/XEH_preInit.sqf | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index ff100aa4fef..f431919de6b 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -10,10 +10,15 @@ #ifdef DEBUG_MODE_DRAW if (hasInterface) then { - private _handle = [LINKFUNC(dev_drawTrace), 0] call CBA_fnc_addPerFrameHandler; - missionNamespace setVariable [QGVAR(dev_drawPFEH), _handle]; - ["unit", LINKFUNC(dev_switchUnitHandle), true] call CBA_fnc_addPlayerEventHandler; - [objNull, ace_player] call FUNC(dev_switchUnitHandle); + GVAR(dev_drawPFEH) = [ + LINKFUNC(dev_drawTrace), + 0 + ] call CBA_fnc_addPerFrameHandler; + [ + "unit", + LINKFUNC(dev_switchUnitHandle), + true + ] call CBA_fnc_addPlayerEventHandler; }; #endif } diff --git a/addons/frag/XEH_preInit.sqf b/addons/frag/XEH_preInit.sqf index 371d8c7a6e3..abfa7262713 100644 --- a/addons/frag/XEH_preInit.sqf +++ b/addons/frag/XEH_preInit.sqf @@ -24,6 +24,7 @@ GVAR(dev_trackLines) = createHashMap; GVAR(dev_hitBoxes) = createHashMap; GVAR(dev_failedToDelete) = 0; GVAR(dev_eventSpheres) = []; +GVAR(dev_drawPFEH) = -1; #include "initSettingsDebug.inc.sqf" #endif From 3874146b236a7e5893a431dcf751ace0c8c71a3c Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 16:32:43 -0600 Subject: [PATCH 117/282] formatting --- addons/frag/functions/fnc_dev_switchUnitHandle.sqf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf index 8afdf53428d..d2aed63c45f 100644 --- a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf +++ b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf @@ -28,12 +28,12 @@ if (!local _currentUnit) exitWith { }; -private _aID = missionNamespace getVariable [QGVAR(dev_clearTraceAction), -1]; -if (_aID > -1 && {!isNull _lastUnit}) then { - _lastUnit removeAction _aID; +private _actionID = missionNamespace getVariable [QGVAR(dev_clearTraceAction), -1]; +if (_actionID > -1 && {!isNull _lastUnit}) then { + _lastUnit removeAction _actionID; }; -_aID = _currentUnit addAction [ +_actionID = _currentUnit addAction [ "Reset Lines", FUNC(dev_clearTraces), nil, @@ -45,4 +45,4 @@ _aID = _currentUnit addAction [ 8 ]; -missionNamespace getVariable [QGVAR(dev_clearTraceAction), _aID]; +missionNamespace getVariable [QGVAR(dev_clearTraceAction), _actionID]; From 133f0b1da466e4e1b9e5a88a1cbf559d65908567 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 17:36:02 -0600 Subject: [PATCH 118/282] Updated type checks in line with recommendation from johnb432 --- addons/frag/functions/fnc_dev_addRound.sqf | 6 +++--- addons/frag/functions/fnc_dev_trackObj.sqf | 6 +++--- addons/frag/functions/fnc_initBlackList.sqf | 13 ++++++------- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/addons/frag/functions/fnc_dev_addRound.sqf b/addons/frag/functions/fnc_dev_addRound.sqf index c723f2e760c..67ac2c8318e 100644 --- a/addons/frag/functions/fnc_dev_addRound.sqf +++ b/addons/frag/functions/fnc_dev_addRound.sqf @@ -33,13 +33,13 @@ if (_isSidePlayer) then { [ { if (isGamePaused) exitWith {}; - params ["_par", "_handle"]; - _par params ["_projectile"]; + params ["_params", "_handle"]; + _params params ["_projectile"]; if (!alive _projectile) exitWith { [_handle] call CBA_fnc_removePerFrameHandler; }; private _projectileArray = GVAR(dev_trackLines) getOrDefault [(getObjectID _projectile), -1]; - if (typeName _projectileArray == "SCALAR") exitWith {}; + if (_projectileArray isEqualType 0) exitWith {}; (_projectileArray#0) pushBack getPosATL _projectile; }, 0, diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index d6334db9add..ea3aa3146fd 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -41,14 +41,14 @@ GVAR(dev_trackLines) set [getObjectID _object, [1, [getposATL _object], _colorAr [ { if (isGamePaused) exitWith {}; - params ["_par", "_handle"]; - _par params ["_object"]; + params ["_params", "_handle"]; + _params params ["_object"]; if (!alive _object) exitWith { [_handle] call CBA_fnc_removePerFrameHandler; }; private _arr = GVAR(dev_trackLines) getOrDefault [(getObjectID _object), -1]; - if (typeName _arr isEqualTo "SCALAR") exitWith { + if (_arr isEqualType 0) exitWith { [_handle] call CBA_fnc_removePerFrameHandler; }; diff --git a/addons/frag/functions/fnc_initBlackList.sqf b/addons/frag/functions/fnc_initBlackList.sqf index f95cd09ec52..12c510857b7 100644 --- a/addons/frag/functions/fnc_initBlackList.sqf +++ b/addons/frag/functions/fnc_initBlackList.sqf @@ -30,11 +30,10 @@ if (count _convArray == 0 ) exitWith { // Add CBA setting blacklist to blacklist and log errors private _errors = 0; -private _items = count _convArray; -for "_i" from 0 to _items - 1 do { - private _ammo = _convArray#_i; - if (typeName _ammo isNotEqualTo "STRING") then { - INFO_1("Improper ammo string at index %1", _i); +forEach { + private _ammo = _x; + if (!(_ammo isEqualType "")) then { + INFO_1("Improper ammo string at index %1", _forEachIndex); INC(_errors); continue; }; @@ -46,6 +45,6 @@ for "_i" from 0 to _items - 1 do { }; GVAR(shouldFragCache) set [_convArray#_i, false]; -}; +} forEach ; -INFO_2("Initialized blacklist. Total items found: %1, number of items failed: %2", _items, _errors); +INFO_2("Initialized blacklist. Total items found: %1, number of items failed: %2", count _convArray, _errors); From dd7fc86295d85b7be8978a64c85210c99f375ab6 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 17:40:31 -0600 Subject: [PATCH 119/282] fixed comment to properly state variable purpose --- addons/frag/functions/fnc_dev_debugAmmo.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index 14c5891a018..db093f66c92 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -7,7 +7,7 @@ * * Arguments: * 0: Log ammo types that wouldn't normally frag - * 1: Only export ammo classes of classes referenced in cfgAmmo + * 1: Only export ammo classes of classes referenced in cfgMagazines * and their submunitions. * 2: Force a CSV format on debug print * From 6fc950a5f18ea098aad237065df45e1c01d92240 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 17:53:12 -0600 Subject: [PATCH 120/282] Comments fixed --- addons/frag/functions/fnc_getFragInfo.sqf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/frag/functions/fnc_getFragInfo.sqf b/addons/frag/functions/fnc_getFragInfo.sqf index b76e6e9ed87..47d724da34f 100644 --- a/addons/frag/functions/fnc_getFragInfo.sqf +++ b/addons/frag/functions/fnc_getFragInfo.sqf @@ -72,8 +72,8 @@ if (_warn) then { /********************** _ammoInfo format *************************//* * 0: _fragRange - search range for fragments, calculated with - * a 0.5% chance to hit as the minimum - * 1: _fragVel - gurney equation calculated velocity + * the minimum chance to hit as defined + * 1: _fragVelocity - gurney equation calculated velocity * 2: _fragTypes - array of fragment types * 3: _fragCount - modified frag count used under assumptions * of spherical fragmentation From 6e209ba4f0de113e86fee92cb226ffc7dc289478 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 17:54:22 -0600 Subject: [PATCH 121/282] slight performance increase using forEach loops Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_dev_clearTraces.sqf | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/addons/frag/functions/fnc_dev_clearTraces.sqf b/addons/frag/functions/fnc_dev_clearTraces.sqf index e8ebfb2b143..21a350b8c93 100644 --- a/addons/frag/functions/fnc_dev_clearTraces.sqf +++ b/addons/frag/functions/fnc_dev_clearTraces.sqf @@ -14,9 +14,10 @@ * * Public: No */ -for "_i" from 0 to count GVAR(dev_eventSpheres) - 1 do { - deleteVehicle (GVAR(dev_eventSpheres)#_i); -}; + +{ + deleteVehicle _x; +} forEach GVAR(dev_eventSpheres); GVAR(dev_eventSpheres) = []; GVAR(dev_trackLines) = createHashMap; From 4ef116643d9a1f09910db6077b99118b315a5b05 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 18:10:30 -0600 Subject: [PATCH 122/282] Small optimization to optimize config lookup quick testing shows a whole 600ns increase in Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_dev_fragCalcDump.sqf | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf index ef92cd9c77e..988df479e65 100644 --- a/addons/frag/functions/fnc_dev_fragCalcDump.sqf +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -40,8 +40,9 @@ diag_log text "//****************** fragCalcDump Beg ******************//"; private _fragInfo = [_ammo] call FUNC(getFragInfo); _fragInfo params ["_fragRange", "_fragMaxVelocity", "", "_modifiedFragCount"]; private _fragCount = 4 * pi* _modifiedFragCount; - private _indirectHitRange = getNumber (configFile >> "cfgAmmo" >> _ammo >> "indirectHitRange"); - private _indirectHit = getNumber (configFile >> "cfgAmmo" >> _ammo >> "indirectHit"); + private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; + private _indirectHitRange = getNumber (_ammoConfig >> "indirectHitRange"); + private _indirectHit = getNumber (_ammoConfig >> "indirectHit"); private _fragPowerSpeedRange = [0.5, 1] vectorMultiply _fragMaxVelocity; diag_log text format ["Ammo type: %1 | Should frag: %2", _ammo, _shouldFrag]; From 902af64d7efb65b494c2bb68c58d3bb83d7f88fd Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 18:16:06 -0600 Subject: [PATCH 123/282] avoid mismatch sides when debugging frags with unconcious or captive shooters Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_dev_fired.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_dev_fired.sqf b/addons/frag/functions/fnc_dev_fired.sqf index aa5e59a33a1..cc67b89f587 100644 --- a/addons/frag/functions/fnc_dev_fired.sqf +++ b/addons/frag/functions/fnc_dev_fired.sqf @@ -16,4 +16,4 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); -[_projectile, true, ((side _unit) getFriend (side ACE_player)) >= 0.6] call FUNC(dev_addRound); +[_projectile, true, [side group _unit, side group ACE_player] call BIS_fnc_sideIsFriendly] call FUNC(dev_addRound); From bd33ab0e913a9f6b8603a96e31aa30297b097b83 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 18:16:40 -0600 Subject: [PATCH 124/282] removed return of sphere object, not required or useful. --- addons/frag/functions/fnc_dev_sphereDraw.sqf | 2 -- 1 file changed, 2 deletions(-) diff --git a/addons/frag/functions/fnc_dev_sphereDraw.sqf b/addons/frag/functions/fnc_dev_sphereDraw.sqf index 5eb8e30b00c..fe895dbcc47 100644 --- a/addons/frag/functions/fnc_dev_sphereDraw.sqf +++ b/addons/frag/functions/fnc_dev_sphereDraw.sqf @@ -44,5 +44,3 @@ private _colorString = "#(argb,8,8,3)color" + _color; private _sphere = createVehicle ["Sign_Sphere25cm_F", ASLtoATL _posASL, [], 0, "CAN_COLLIDE"]; _sphere setObjectTextureGlobal [0, _colorString]; GVAR(dev_eventSpheres) pushBack _sphere; - -_sphere; From f7137916020425472393d7d8a04f53da054afe5f Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 18:35:26 -0600 Subject: [PATCH 125/282] fixed a loop that got caught in the merge crossfire --- addons/frag/functions/fnc_initBlackList.sqf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/frag/functions/fnc_initBlackList.sqf b/addons/frag/functions/fnc_initBlackList.sqf index 12c510857b7..78b8ecb19a6 100644 --- a/addons/frag/functions/fnc_initBlackList.sqf +++ b/addons/frag/functions/fnc_initBlackList.sqf @@ -30,7 +30,7 @@ if (count _convArray == 0 ) exitWith { // Add CBA setting blacklist to blacklist and log errors private _errors = 0; -forEach { +{ private _ammo = _x; if (!(_ammo isEqualType "")) then { INFO_1("Improper ammo string at index %1", _forEachIndex); @@ -44,7 +44,7 @@ forEach { continue; }; - GVAR(shouldFragCache) set [_convArray#_i, false]; -} forEach ; + GVAR(shouldFragCache) set [_ammo, false]; +} forEach _convArray; -INFO_2("Initialized blacklist. Total items found: %1, number of items failed: %2", count _convArray, _errors); +INFO_2("Initialized blacklist. Total items found: %1, number of items failed: %2",count _convArray,_errors); From a8e268cdff6afe7061fb76ee36b187f635a2d677 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 18:40:03 -0600 Subject: [PATCH 126/282] Optimized approach to classifying blacklist type Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_addBlackList.sqf | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/addons/frag/functions/fnc_addBlackList.sqf b/addons/frag/functions/fnc_addBlackList.sqf index ecb6af71e2d..1c54f7c0a94 100644 --- a/addons/frag/functions/fnc_addBlackList.sqf +++ b/addons/frag/functions/fnc_addBlackList.sqf @@ -18,12 +18,9 @@ params ["_projectile"]; TRACE_1("addBlackList",_round); -switch (typeName _projectile) do { - case "OBJECT": { - GVAR(shouldFragCache) set [typeOf _projectile, false]; - }; - case "STRING": { - GVAR(shouldFragCache) set [_projectile, false]; - }; - default { }; + +if (_projectile isEqualType objNull) then { + _projectile = typeOf _projectile; }; + +GVAR(shouldFragCache) set [_projectile, false]; From c4a93c775d2345ff4770cab069f542804aa0033e Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 18:44:15 -0600 Subject: [PATCH 127/282] Implemented changes discussed here https://github.com/acemod/ACE3/pull/9728#discussion_r1452726904 --- addons/frag/functions/fnc_dev_sphereDraw.sqf | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/addons/frag/functions/fnc_dev_sphereDraw.sqf b/addons/frag/functions/fnc_dev_sphereDraw.sqf index fe895dbcc47..73d71b12915 100644 --- a/addons/frag/functions/fnc_dev_sphereDraw.sqf +++ b/addons/frag/functions/fnc_dev_sphereDraw.sqf @@ -28,15 +28,15 @@ if (count _posASL < 3) then { }; if (_color select [0,1] != "(") then { - switch (toLowerANSI _color) do { - case "blue": { _color = "(0,0,0.8,0.5)"; }; - case "black": { _color = "(1,1,1,0.5)"; }; - case "white": { _color = "(0,0,0,0.5)"; }; - case "red": { _color = "(0.8,0,0,0.5)"; }; - case "green": { _color = "(0,0.8,0,0.5)"; }; - case "yellow": { _color = "(0.8,0.8,0,0.5)"; }; - case "orange": { _color = "(0.8,0.518,0,0.5)"; }; - default { _color = "(0.8,0.8,0,0.5)";}; + _color = switch (toLowerANSI _color) do { + case "blue": {"(0,0,0.8,0.5)"}; + case "black": {"(1,1,1,0.5)"}; + case "white": {"(0,0,0,0.5)"}; + case "red": {"(0.8,0,0,0.5)"}; + case "green": {"(0,0.8,0,0.5)"}; + case "yellow": {"(0.8,0.8,0,0.5)"}; + case "orange": {"(0.8,0.518,0,0.5)"}; + default {"(0.8,0.8,0,0.5)"}; }; }; private _colorString = "#(argb,8,8,3)color" + _color; From b2666fceecd36ebb5d2329287e7f62d59be624fd Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 18:47:06 -0600 Subject: [PATCH 128/282] Config lookup optimization mentioned by johnb432 here: https://github.com/acemod/ACE3/pull/9728#discussion_r1452726505 --- addons/frag/functions/fnc_dev_debugAmmo.sqf | 9 ++-- addons/frag/functions/fnc_getFragInfo.sqf | 44 ++++++++++++++----- addons/frag/functions/fnc_getMaterialInfo.sqf | 7 +-- addons/frag/functions/fnc_getSpallInfo.sqf | 7 +-- addons/frag/functions/fnc_initBlackList.sqf | 2 +- addons/frag/functions/fnc_shouldFrag.sqf | 11 ++--- addons/frag/functions/fnc_shouldSpall.sqf | 7 +-- 7 files changed, 56 insertions(+), 31 deletions(-) diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index db093f66c92..fd7b0b30d32 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -39,9 +39,10 @@ if (_onlyShotAmmoTypes) then { ]; if (_ammo isEqualTo "" || {_ammo in _allAmmoConfigs}) exitWith {}; _allAmmoConfigs pushBack _ammo; - private _subMunit = toLowerANSI getText (configFile >> "cfgAmmo" >> _ammo >> "submunitionAmmo"); + private _ammoConfig = configFile >> "cfgAmmo" >> _ammo; + private _subMunit = toLowerANSI getText (_ammoConfig >> "submunitionAmmo"); if (_subMunit isNotEqualTo "") then { - _subMunit = getArray (configFile >> "cfgAmmo" >> _ammo >> "submunitionAmmo"); + _subMunit = getArray (_ammoConfig >> "submunitionAmmo"); for "_i" from 0 to count _subMunit - 1 do { if (_i mod 2 == 0) then { [toLowerANSI (_subMunit#_i)] call _configSearchFunc; @@ -57,7 +58,7 @@ if (_onlyShotAmmoTypes) then { [toLowerANSI getText (_x >> "ammo")] call _configSearchFunc; } forEach _allMagazineConfigs; } else { - _allAmmoConfigs = configProperties [configFile >> "cfgAmmo", "isClass _x && !('ace_frag' in configName _x)", true] apply {configName _x}; + _allAmmoConfigs = configProperties [configFile >> "CfgAmmo", "isClass _x && !('ace_frag' in configName _x)", true] apply {configName _x}; }; private _processedCfgAmmos = []; @@ -67,7 +68,7 @@ private _printCount = 0; if (_ammo != "" && {!(_ammo in _processedCfgAmmos)}) then { _processedCfgAmmos pushBack _ammo; - private _ammoConfig = (configFile >> "cfgAmmo" >> _ammo); + private _ammoConfig = (configFile >> "CfgAmmo" >> _ammo); private _shoulFrag = [_ammo] call FUNC(shouldFrag); if (_shoulFrag || _logAll) then { diff --git a/addons/frag/functions/fnc_getFragInfo.sqf b/addons/frag/functions/fnc_getFragInfo.sqf index 47d724da34f..f5a0fce58b8 100644 --- a/addons/frag/functions/fnc_getFragInfo.sqf +++ b/addons/frag/functions/fnc_getFragInfo.sqf @@ -27,10 +27,11 @@ private _ammoInfo = GVAR(fragInfoCache) get _ammo; if (!isNil "_ammoInfo") exitWith {_ammoInfo}; +private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; private _fragTypes = []; private _warn = false; -if (isArray (configFile >> "cfgAmmo" >> _ammo >> QGVAR(CLASSES))) then { - _fragTypes = getArray (configFile >> "cfgAmmo" >> _ammo >> QGVAR(CLASSES)); +if (isArray (_ammoConfig >> QGVAR(CLASSES))) then { + _fragTypes = getArray (_ammoConfig >> QGVAR(CLASSES)); } else { _warn = true; }; @@ -55,16 +56,35 @@ if (isArray (configFile >> "cfgAmmo" >> _ammo >> QGVAR(CLASSES))) then { * or 0.8 * _gurneyConstant * sqrt (_chargeMass /(_metalMass + _chargeMass * _geometryCoefficient)); (slightly faster to compute) */ -private _chargeMass = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(CHARGE)); -if (_chargeMass == 0) then {_chargeMass = 1; _warn = true;}; -private _metalMass = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(METAL)); -if (_metalMass == 0) then {_metalMass = 2; _warn = true;}; -private _geometryCoefficient = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(GURNEY_K)); -if (_geometryCoefficient == 0) then {_geometryCoefficient = 0.8; _warn = true;}; -private _gurneyConstant = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(GURNEY_C)); -if (_gurneyConstant == 0) then {_gurneyConstant = 2440; _warn = true;}; -private _fragCount = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(fragCount)); -if (_fragCount == 0) then {_fragCount = 400; _warn = true;}; +private _chargeMass = getNumber (_ammoConfig >> QGVAR(CHARGE)); +if (_chargeMass == 0) then { + _chargeMass = 1; + _warn = true; +}; + +private _metalMass = getNumber (_ammoConfig >> QGVAR(METAL)); +if (_metalMass == 0) then { + _metalMass = 2; + _warn = true; +}; + +private _geometryCoefficient = getNumber (_ammoConfig >> QGVAR(GURNEY_K)); +if (_geometryCoefficient == 0) then { + _geometryCoefficient = 0.8; + _warn = true; +}; + +private _gurneyConstant = getNumber (_ammoConfig >> QGVAR(GURNEY_C)); +if (_gurneyConstant == 0) then { + _gurneyConstant = 2440; + _warn = true; +}; + +private _fragCount = getNumber (_ammoConfig >> QGVAR(fragCount)); +if (_fragCount == 0) then { + _fragCount = 400; + _warn = true; +}; if (_warn) then { INFO_1("Ammo class %1 lacks proper explosive properties definitions for frag!",_ammo); diff --git a/addons/frag/functions/fnc_getMaterialInfo.sqf b/addons/frag/functions/fnc_getMaterialInfo.sqf index 54d01cc103d..2ca46ac8d81 100644 --- a/addons/frag/functions/fnc_getMaterialInfo.sqf +++ b/addons/frag/functions/fnc_getMaterialInfo.sqf @@ -28,10 +28,11 @@ if (!isNil "_material") exitWith { _material }; // Use 'soundEnviron' or 'soundHit' to extract approx material -if (isClass (configFile >> "CfgSurfaces" >> _surfType)) then { - _material = getText (configFile >> "CfgSurfaces" >> _surfType >> "soundEnviron"); +private _surfaceConfig = configFile >> "CfgSurfaces" >> _surfType; +if (isClass _surfaceConfig) then { + _material = getText (_surfaceConfig >> "soundEnviron"); if (_material isEqualTo "" || {_material isEqualTo "empty"}) then { - _material = getText (configFile >> "CfgSurfaces" >> _surfType >> "soundhit"); + _material = getText (_surfaceConfig >> "soundhit"); }; } else { // Messy way when a surface isn't added to cfgSurfaces private _surfFileText = toLowerANSI preprocessFile _surfType; diff --git a/addons/frag/functions/fnc_getSpallInfo.sqf b/addons/frag/functions/fnc_getSpallInfo.sqf index 7126803933d..a8751351fe0 100644 --- a/addons/frag/functions/fnc_getSpallInfo.sqf +++ b/addons/frag/functions/fnc_getSpallInfo.sqf @@ -25,9 +25,10 @@ private _ammoInfo = GVAR(spallInfoCache) get _ammo; if (!isNil "_ammoInfo") exitWith {_ammoInfo}; -private _caliber = getNumber (configFile >> "CfgAmmo" >> _ammo >> "caliber"); -private _explosive = 1 min getNumber (configFile >> "CfgAmmo" >> _ammo >> "explosive"); -private _indirectHit = getNumber (configFile >> "CfgAmmo" >> _ammo >> "indirectHitRange"); +private _ammoConfig = (configFile >> "CfgAmmo" >> _ammo); +private _caliber = getNumber (_ammoConfig >> "caliber"); +private _explosive = 1 min getNumber (_ammoConfig >> "explosive"); +private _indirectHit = getNumber (_ammoConfig >> "indirectHitRange"); private _ammoInfo = [_caliber, _explosive, _indirectHit]; GVAR(spallInfoCache) set [_ammo, _ammoInfo]; diff --git a/addons/frag/functions/fnc_initBlackList.sqf b/addons/frag/functions/fnc_initBlackList.sqf index 78b8ecb19a6..3802130de1d 100644 --- a/addons/frag/functions/fnc_initBlackList.sqf +++ b/addons/frag/functions/fnc_initBlackList.sqf @@ -24,7 +24,7 @@ if (!ADDON) then { // could improve text parsing of CBA setting string private _convArray = parseSimpleArray GVAR(blackList); -if (count _convArray == 0 ) exitWith { +if (_convArray isEqualTo []) exitWith { TRACE_1("Empty blacklist", _convArray); }; diff --git a/addons/frag/functions/fnc_shouldFrag.sqf b/addons/frag/functions/fnc_shouldFrag.sqf index d957781f10a..f9e032d3014 100644 --- a/addons/frag/functions/fnc_shouldFrag.sqf +++ b/addons/frag/functions/fnc_shouldFrag.sqf @@ -24,11 +24,12 @@ if (!isNil "_shouldFrag") exitWith {_shouldFrag}; _shouldFrag = true; -private _skip = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(skip)); -private _force = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(force)); -private _explosive = getNumber (configFile >> "cfgAmmo" >> _ammo >> "explosive"); -private _indirectHit = getNumber (configFile >> "cfgAmmo" >> _ammo >> "indirectHit"); -private _indirectRange = getNumber (configFile >> "cfgAmmo" >> _ammo >> "indirectHitRange"); +private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; +private _skip = getNumber (_ammoConfig >> QGVAR(skip)); +private _force = getNumber (_ammoConfig >> QGVAR(force)); +private _explosive = getNumber (_ammoConfig >> "explosive"); +private _indirectHit = getNumber (_ammoConfig >> "indirectHit"); +private _indirectRange = getNumber (_ammoConfig >> "indirectHitRange"); if (_skip == 1 || (_force == 0 && {_explosive < 0.5 || {_indirectHit < 3 || {_indirectRange < 5 && _indirectHit < _indirectRange}}})) then { diff --git a/addons/frag/functions/fnc_shouldSpall.sqf b/addons/frag/functions/fnc_shouldSpall.sqf index 1ece3ba0c8a..0265aa305af 100644 --- a/addons/frag/functions/fnc_shouldSpall.sqf +++ b/addons/frag/functions/fnc_shouldSpall.sqf @@ -22,9 +22,10 @@ private _shouldSpall = GVAR(shouldSpallCache) get _ammo; if (!isNil "_shouldSpall") exitWith {_shouldSpall}; -private _caliber = getNumber (configFile >> "CfgAmmo" >> _ammo >> "caliber"); -private _explosive = getNumber (configFile >> "CfgAmmo" >> _ammo >> "explosive"); -private _indirectHit = getNumber (configFile >> "CfgAmmo" >> _ammo >> "indirectHitRange"); +private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; +private _caliber = getNumber (_ammoConfig >> "caliber"); +private _explosive = getNumber (_ammoConfig >> "explosive"); +private _indirectHit = getNumber (_ammoConfig >> "indirectHitRange"); _shouldSpall = _caliber * GVAR(spallIntensity) >= 2.5 || (_explosive >= 0.5 && _explosive * _indirectHit * GVAR(spallIntensity) >= 4); From b7807044bf668cd9ec1b66a4ad43839233b1d506 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 18:47:21 -0600 Subject: [PATCH 129/282] white space/formatting changes --- addons/frag/functions/fnc_dev_fragCalcDump.sqf | 4 +++- addons/frag/functions/fnc_doFragTargeted.sqf | 12 ++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf index 988df479e65..14cc43354d4 100644 --- a/addons/frag/functions/fnc_dev_fragCalcDump.sqf +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -32,7 +32,9 @@ diag_log text "//****************** fragCalcDump Beg ******************//"; { // Begin _allAmmoConfigs forEach private _ammo = toLowerANSI configName _x; - if (_ammo == "" || {_ammo in _processedCfgAmmos} ) then { continue }; + if (_ammo == "" || {_ammo in _processedCfgAmmos} ) then { + continue + }; private _shouldFrag = [_ammo] call FUNC(shouldFrag); diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index c6a2cbf95ee..60723d2ed95 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -69,7 +69,9 @@ TRACE_3("Targets found",_posASL,_fragRange,count _objects); private _fragArcs = createHashMap; private _totalFragCount = 0; { // Begin of forEach iterating on _objects - if (!alive _x) then {continue}; + if (!alive _x) then { + continue; + }; private _target = _x; #ifdef DEBUG_MODE_DRAWFRAG @@ -90,7 +92,9 @@ private _totalFragCount = 0; private _boxParams = boundingBoxReal [_target, "FireGeometry"]; _boxParams params ["_pointA", "_pointB"]; private _dims = _pointB vectorDiff _pointA; - if (_dims#0 * _dims#1 * _dims#2 <= 0.5) then {continue}; + if (_dims#0 * _dims#1 * _dims#2 <= 0.5) then { + continue; + }; _crossSectionArea = _dims#1 * _dims#2; _height = _dims#2; }; @@ -109,7 +113,7 @@ private _totalFragCount = 0; }; if (_fragCount == 0) then { TRACE_2("fragments",_fragChance,_fragCount); - continue + continue; }; // handle limiting fragments per degree arc @@ -166,7 +170,7 @@ private _totalFragCount = 0; _totalFragCount = _totalFragCount + _fragCount; if (_totalFragCount >= _maxFrags) then { TRACE_2("maxFrags", _totalFragCount, _maxFrags); - break + break; }; } forEach _objects; From 85b566a176334f568ebe4fcc3e0e4ec28106c4a0 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 19:06:32 -0600 Subject: [PATCH 130/282] removed old parameter changed in https://github.com/acemod/ACE3/pull/9728/commits/f28d5d23720f64928d5879431dc3bb75f76224bf --- addons/frag/functions/fnc_dev_trackObj.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index ea3aa3146fd..723fadd2e9b 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -35,7 +35,7 @@ private _colorArray = switch (toLowerANSI _color) do { case "white": {[0, 0, 0, 1]}; default {[0, 0.8, 0.8, 1]}; }; -GVAR(dev_trackLines) set [getObjectID _object, [1, [getposATL _object], _colorArray]]; +GVAR(dev_trackLines) set [getObjectID _object, [[getposATL _object], _colorArray]]; // event handler to track round and cleanup when round is "dead" [ From 67ede7649468ab6edda16a2b9ccfc6e2cda56883 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 19:57:31 -0600 Subject: [PATCH 131/282] compacted text a bit --- addons/frag/XEH_postInit.sqf | 1 - addons/frag/XEH_preInit.sqf | 3 --- addons/frag/functions/fnc_addBlackList.sqf | 1 - addons/frag/functions/fnc_dev_fragCalcDump.sqf | 2 -- addons/frag/functions/fnc_dev_switchUnitHandle.sqf | 1 - addons/frag/functions/fnc_doFragTargeted.sqf | 6 +----- addons/frag/functions/fnc_doSpall.sqf | 2 -- addons/frag/functions/fnc_initRound.sqf | 2 -- addons/frag/initSettings.inc.sqf | 1 - 9 files changed, 1 insertion(+), 18 deletions(-) diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index f431919de6b..b6afbf66ed4 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -24,7 +24,6 @@ } ] call CBA_fnc_addEventHandler; - #ifdef LOG_FRAG_INFO [true, true, 30] call FUNC(dev_debugAmmo); #endif diff --git a/addons/frag/XEH_preInit.sqf b/addons/frag/XEH_preInit.sqf index abfa7262713..99bb1e830be 100644 --- a/addons/frag/XEH_preInit.sqf +++ b/addons/frag/XEH_preInit.sqf @@ -6,7 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; - GVAR(spallMaterialCache) = createHashMap; GVAR(spallInfoCache) = createHashMap; GVAR(shouldSpallCache) = createHashMap; @@ -16,7 +15,6 @@ GVAR(shouldFragCache) = createHashMap; GVAR(fragInfoCache) = createHashMap; GVAR(lastFragTime) = -2; - #include "initSettings.inc.sqf" #ifdef DEBUG_MODE_DRAW @@ -28,5 +26,4 @@ GVAR(dev_drawPFEH) = -1; #include "initSettingsDebug.inc.sqf" #endif - ADDON = true; diff --git a/addons/frag/functions/fnc_addBlackList.sqf b/addons/frag/functions/fnc_addBlackList.sqf index 1c54f7c0a94..86ac77de0f8 100644 --- a/addons/frag/functions/fnc_addBlackList.sqf +++ b/addons/frag/functions/fnc_addBlackList.sqf @@ -18,7 +18,6 @@ params ["_projectile"]; TRACE_1("addBlackList",_round); - if (_projectile isEqualType objNull) then { _projectile = typeOf _projectile; }; diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf index 14cc43354d4..dbfc87f7939 100644 --- a/addons/frag/functions/fnc_dev_fragCalcDump.sqf +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -22,7 +22,6 @@ params [ ["_logAll", false, [false]] ]; - private _allAmmoConfigs = configProperties [configFile >> "cfgAmmo", "isClass _x && !('ace_frag' in configName _x)", true]; private _processedCfgAmmos = []; @@ -36,7 +35,6 @@ diag_log text "//****************** fragCalcDump Beg ******************//"; continue }; - private _shouldFrag = [_ammo] call FUNC(shouldFrag); if (_nSkip || _logAll) then { private _fragInfo = [_ammo] call FUNC(getFragInfo); diff --git a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf index d2aed63c45f..efd321e1973 100644 --- a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf +++ b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf @@ -27,7 +27,6 @@ if (!local _currentUnit) exitWith { ] call CBA_fnc_waitUntilAndExecute; }; - private _actionID = missionNamespace getVariable [QGVAR(dev_clearTraceAction), -1]; if (_actionID > -1 && {!isNull _lastUnit}) then { _lastUnit removeAction _actionID; diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index 60723d2ed95..bc415923bc3 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -49,7 +49,6 @@ if (_objects isEqualTo []) exitWith { 0; }; - // grab crews and add them in so that targets stay approx. sorted by distance { private _crew = crew _x; @@ -74,7 +73,7 @@ private _totalFragCount = 0; }; private _target = _x; - #ifdef DEBUG_MODE_DRAWFRAG + #ifdef DEBUG_MODE_DRAW [_target, false] call FUNC(dev_trackHitBox); #endif @@ -99,9 +98,6 @@ private _totalFragCount = 0; _height = _dims#2; }; - - - private _distance = _target distance _posASL; // calculate chance to be hit by a fragment diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index 64c040b3bab..152533bfd5e 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -61,12 +61,10 @@ private _velocityChange = vectorMagnitude _lastVelocity - vectorMagnitude _vel; private _spallPower = (ACE_FRAG_ROUND_COEF * _caliber * sqrt _velocityChange + _explosive * _indirectHit) * GVAR(spallIntensity); TRACE_3("found speed",_velocityChange,_caliber,_spallPower); - if (_spallPower < 2) exitWith { TRACE_1("lowImpulse",_ammo); }; - private _lastVelocityUnit = vectorNormalized _lastVelocity; private _deltaStep = _lastVelocityUnit vectorMultiply 0.05; diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index 4c4f41f19ea..cfbeb21d218 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -19,7 +19,6 @@ params [ ["_projectile", objNull, [objNull]] ]; - private _ammo = typeOf _projectile; if (_ammo isEqualTo "" || {isNull _projectile}) exitWith { TRACE_2("bad ammo or projectile",_ammo,_projectile); @@ -45,7 +44,6 @@ if (_shouldFrag && GVAR(enabled)) then { ]; }; - private _shouldSpall = _ammo call FUNC(shouldSpall); if (GVAR(spallEnabled) && {_shouldSpall}) then { _projectile addEventHandler [ diff --git a/addons/frag/initSettings.inc.sqf b/addons/frag/initSettings.inc.sqf index 0e14fe4daf0..65812ec89ef 100644 --- a/addons/frag/initSettings.inc.sqf +++ b/addons/frag/initSettings.inc.sqf @@ -16,7 +16,6 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; 1 ] call CBA_fnc_addSetting; - [ QGVAR(reflectionsEnabled), "CHECKBOX", [LSTRING(EnableReflections), LSTRING(EnableReflections_Desc)], From 572f9093f7c5b54130860b89b31aae44efccf77a Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 15 Jan 2024 19:57:52 -0600 Subject: [PATCH 132/282] formatting whitespace --- addons/frag/functions/fnc_dev_trackHitBox.sqf | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/addons/frag/functions/fnc_dev_trackHitBox.sqf b/addons/frag/functions/fnc_dev_trackHitBox.sqf index d23776070b3..79a5db05c7e 100644 --- a/addons/frag/functions/fnc_dev_trackHitBox.sqf +++ b/addons/frag/functions/fnc_dev_trackHitBox.sqf @@ -1,7 +1,8 @@ #include "..\script_component.hpp" /* * Author: Lambda.Tiger - * Add a hit box outline to an object + * Add a hit box outline to an object, outdated for unit hits as they + * use hit-point locations * * Arguments: * 0: Object to draw the hit box of : @@ -19,6 +20,7 @@ params [ ["_object", objNull, [objNull]], ["_addSphere", true, [true]] ]; +TRACE_2("Adding hitbox",_object,_addSphere); if (isNull _object) exitWith {}; @@ -33,7 +35,7 @@ if (_object isKindOf "CAManBase") then { } else { _box = boundingBoxReal [_object, "FireGeometry"]; }; -_box params ["_lowP","_upP"]; +_box params ["_lowP", "_upP"]; // adjust with stance switch (stance _object) do { From 7aa17aa91bda47da06a1a9f50efb162ea160bc87 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 16 Jan 2024 15:38:47 -0600 Subject: [PATCH 133/282] Grammatical erros --- addons/frag/script_component.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index 800a9552089..d35293e34cd 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -29,7 +29,7 @@ #define ACE_FRAG_ROUND_COEF 0.02828427 // half of gravity approx 9.81/2 #define ACE_FRAG_HALF_GRAVITY_APPROX 4.905 -// stop searching at 0.5% chance to hit +// Lowest chance to hit of 0.5% #define ACE_FRAG_MIN_FRAG_HIT_CHANCE 0.005 #define ACE_FRAG_MIN_GROUND_OFFSET 0.25 #define ACE_FRAG_LOW_FRAG_COEFF 4 From 8dd76d1ba6c6658f0476b4ac76bcb6e2915d35c7 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 16 Jan 2024 15:39:16 -0600 Subject: [PATCH 134/282] Changes as discussed here https://github.com/acemod/ACE3/pull/9728#discussion_r1453104308 --- addons/frag/functions/fnc_findReflections.sqf | 4 ++-- addons/frag/functions/fnc_initBlackList.sqf | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/frag/functions/fnc_findReflections.sqf b/addons/frag/functions/fnc_findReflections.sqf index b0ae161597d..a028a2f70b3 100644 --- a/addons/frag/functions/fnc_findReflections.sqf +++ b/addons/frag/functions/fnc_findReflections.sqf @@ -65,7 +65,7 @@ if (_zIndex < 5) then { while {count _nlos != count _excludes && {_c < (count _nlos)}} do { scopeName "mainSearch"; { - if (!(_forEachIndex in _excludes)) then { + if !(_forEachIndex in _excludes) then { private _index = _buckets pushBack [_x, [_x]]; _excludes pushBack _forEachIndex; _bucketPos = _x; @@ -74,7 +74,7 @@ if (_zIndex < 5) then { }; } forEach _nlos; { - if (!(_forEachIndex in _excludes)) then { + if !(_forEachIndex in _excludes) then { _testPos = _x; if (_testPos vectorDistanceSqr _bucketPos <= 30) then { _bucketList pushBack _x; diff --git a/addons/frag/functions/fnc_initBlackList.sqf b/addons/frag/functions/fnc_initBlackList.sqf index 3802130de1d..605ef1d180e 100644 --- a/addons/frag/functions/fnc_initBlackList.sqf +++ b/addons/frag/functions/fnc_initBlackList.sqf @@ -32,7 +32,7 @@ if (_convArray isEqualTo []) exitWith { private _errors = 0; { private _ammo = _x; - if (!(_ammo isEqualType "")) then { + if !(_ammo isEqualType "") then { INFO_1("Improper ammo string at index %1", _forEachIndex); INC(_errors); continue; From 6dacd38101502e65375f4fb76a05245750d35208 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 16 Jan 2024 15:40:51 -0600 Subject: [PATCH 135/282] Few quick optimizations of == to isEqualTo --- addons/frag/functions/fnc_dev_debugAmmo.sqf | 2 +- addons/frag/functions/fnc_dev_fragCalcDump.sqf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index fd7b0b30d32..f178bb0052c 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -65,7 +65,7 @@ private _processedCfgAmmos = []; private _printCount = 0; { // Begin forEach to check each ammo type private _ammo = _x; - if (_ammo != "" && {!(_ammo in _processedCfgAmmos)}) then { + if (_ammo isNotEqualTo "" && {!(_ammo in _processedCfgAmmos)}) then { _processedCfgAmmos pushBack _ammo; private _ammoConfig = (configFile >> "CfgAmmo" >> _ammo); diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf index dbfc87f7939..7850b8d602e 100644 --- a/addons/frag/functions/fnc_dev_fragCalcDump.sqf +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -31,7 +31,7 @@ diag_log text "//****************** fragCalcDump Beg ******************//"; { // Begin _allAmmoConfigs forEach private _ammo = toLowerANSI configName _x; - if (_ammo == "" || {_ammo in _processedCfgAmmos} ) then { + if (_ammo isEqualTo "" || {_ammo in _processedCfgAmmos} ) then { continue }; From 9178611a160a76e8a5d43fcf536e6499c9841867 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 16 Jan 2024 15:41:10 -0600 Subject: [PATCH 136/282] Debug updated to be easier to control --- addons/frag/functions/fnc_dev_drawTrace.sqf | 1 + addons/frag/functions/fnc_dev_switchUnitHandle.sqf | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/addons/frag/functions/fnc_dev_drawTrace.sqf b/addons/frag/functions/fnc_dev_drawTrace.sqf index 94ea9ad75d6..f39a6cdd0e8 100644 --- a/addons/frag/functions/fnc_dev_drawTrace.sqf +++ b/addons/frag/functions/fnc_dev_drawTrace.sqf @@ -14,6 +14,7 @@ * * Public: No */ +if (!GVAR(debugOptions)) exitWith {}; { _y params ["_posArray", "_color"]; diff --git a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf index efd321e1973..c290c762c42 100644 --- a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf +++ b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf @@ -15,7 +15,8 @@ * * Public: No */ -params ["_lastUnit", "_currentUnit"]; +TRACE_1("switchUnit",_this); +params ["_currentUnit", "_lastUnit"]; if (isNull _currentUnit || {_lastUnit isEqualTo _currentUnit}) exitWith {}; if (!local _currentUnit) exitWith { @@ -34,7 +35,9 @@ if (_actionID > -1 && {!isNull _lastUnit}) then { _actionID = _currentUnit addAction [ "Reset Lines", - FUNC(dev_clearTraces), + { + remoteExecCall [QFUNC(dev_clearTraces), 2]; + }, nil, 1.5, true, @@ -44,4 +47,4 @@ _actionID = _currentUnit addAction [ 8 ]; -missionNamespace getVariable [QGVAR(dev_clearTraceAction), _actionID]; +missionNamespace setVariable [QGVAR(dev_clearTraceAction), _actionID]; From 769bb29342257a3fdfea1108945843a966f9e803 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 16 Jan 2024 15:43:14 -0600 Subject: [PATCH 137/282] Changed how spall hold off is calculated to avoid repeated unneeded computations --- addons/frag/XEH_preInit.sqf | 2 +- addons/frag/functions/fnc_doSpall.sqf | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/addons/frag/XEH_preInit.sqf b/addons/frag/XEH_preInit.sqf index 99bb1e830be..8b91a18d180 100644 --- a/addons/frag/XEH_preInit.sqf +++ b/addons/frag/XEH_preInit.sqf @@ -9,7 +9,7 @@ PREP_RECOMPILE_END; GVAR(spallMaterialCache) = createHashMap; GVAR(spallInfoCache) = createHashMap; GVAR(shouldSpallCache) = createHashMap; -GVAR(lastSpallTime) = -2; +GVAR(nextSpallAllowTime) = -2; GVAR(shouldFragCache) = createHashMap; GVAR(fragInfoCache) = createHashMap; diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index 152533bfd5e..4a069c51179 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -28,11 +28,11 @@ params [ ["_vectorUp", [0,0,1]] ]; -if (CBA_missionTime - GVAR(lastSpallTime) < ACE_FRAG_SPALL_HOLDOFF || +if (CBA_missionTime < GVAR(nextSpallAllowTime)|| _lastPosASL isEqualTo [0,0,0] || - {isNull _objectHit || {_objectHit isKindOf "man" || - {_ammo isEqualTo ""}}}) exitWith { - TRACE_4("time/invldHit",CBA_missionTime,GVAR(lastSpallTime),_objectHit,_lastPosASL); + {_ammo isEqualTo "" || {!isNull _objectHit && + {objectHit isKindOf "man"}}}) exitWith { + TRACE_4("time/invldHit",CBA_missionTime,GVAR(nextSpallAllowTime),_objectHit,_lastPosASL); }; private _material = [_surfaceType] call FUNC(getMaterialInfo); @@ -90,20 +90,20 @@ if (120 > acos ( _lastVelocityUnit vectorDotProduct _surfaceNorm)) then { private _insideObject = true; for "_i" from 2 to 21 do { - private _nPos = _spallPosASL vectorAdd _deltaStep; - if (!lineIntersects [_spallPosASL, _nPos]) then { - _spallPosASL = _nPos vectorAdd (_deltaStep vectorMultiply 2); + private _nextPos = _spallPosASL vectorAdd _deltaStep; + if (!lineIntersects [_spallPosASL, _nextPos]) then { + _spallPosASL = _nextPos vectorAdd (_deltaStep vectorMultiply 2); _insideObject = false; break }; - _spallPosASL = _nPos; + _spallPosASL = _nextPos; }; if (_insideObject) exitWith { TRACE_3("insideObj",_lastPosASL,_spallPosASL,alive _projectile); }; // Passed all exitWiths -GVAR(lastSpallTime) = CBA_missionTime; +GVAR(nextSpallAllowTime) = CBA_missionTime + ACE_FRAG_SPALL_HOLDOFF; #ifdef DEBUG_MODE_DRAW if GVAR(dbgSphere) then { From 63cba6b006d0038924801fe81f8b6db416f0549f Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 16 Jan 2024 15:49:20 -0600 Subject: [PATCH 138/282] clarified a hold off variable --- addons/frag/functions/fnc_doFrag.sqf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 16fdbeadc0e..ecd7db40de2 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -28,12 +28,12 @@ params [ ["_shotParents", [objNull, objNull], [[]]] ]; -// Check for vehicle hold-off timeout +// Don't let a single object cause all fragmentation events _shotParents params ["_shotParentVic"]; -if (_shotParentVic getVariable [QGVAR(nextFragTime), -1] > CBA_missionTime) exitWith { +if (_shotParentVic getVariable [QGVAR(obj_nextFragTime), -1] > CBA_missionTime) exitWith { TRACE_1("vehicleTimeExit",_shotParentVic); }; -_shotParentVic setVariable [QGVAR(nextFragTime), CBA_missionTime + ACE_FRAG_HOLDOFF_VEHICLE]; +_shotParentVic setVariable [QGVAR(obj_nextFragTime), CBA_missionTime + ACE_FRAG_HOLDOFF_VEHICLE]; // Check normal round timeout and adjust _max frags private _timeSinceLastFrag = CBA_missionTime - GVAR(lastFragTime); From 4be8c821cb0df66918979827730bc4d6073395ba Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 16 Jan 2024 22:47:42 -0600 Subject: [PATCH 139/282] Better approach to ACE_FRAG_RM_EH macro --- addons/frag/CfgAmmo.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index a8db2b0b6fb..45842a425fd 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -3,7 +3,7 @@ #define BASE_DRAG_HD (BASE_DRAG * HD_MULT) #define ACE_FRAG_RM_EH class EventHandlers: EventHandlers {\ class ADDON {\ - init = "";\ + delete init;\ };\ } #define ACE_FRAG_ADD_EH_BASE class EventHandlers {\ From 4727386c07aa3cce34966e5bf2a090ac49248259 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 17:47:07 -0600 Subject: [PATCH 140/282] Git rid of superfulous stringtable entries Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/stringtable.xml | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/addons/frag/stringtable.xml b/addons/frag/stringtable.xml index 1eac8bcfe8f..6724dbdf233 100644 --- a/addons/frag/stringtable.xml +++ b/addons/frag/stringtable.xml @@ -220,38 +220,6 @@ 设定在每一帧数内,系统最大可追踪的破片粒子数量。此设定可有效帮助系统减低计算压力。 設定在每一幀數內,系統最大可追蹤的碎片/剝落粒子數量。此設定可有效幫助系統減低計算壓力 - - (SP only) Frag/Spall Debug Tracing - (Solo SP) Seguimiento de depuración de Fragmentación/Astillamiento - (Tylko SP) Wizualny debug odł./odpr. - (Pouze SP) Debug sledování Frag/Úlomků - (nur SP) Splitter-/Explosions-Debug-Verfolgung - (Somente SP) Depuração de fragmentação e estilhaços traçantes - (SP uniquement) Fragmentation/éclat debug - (Csak SP) Repesz/Pattogzás debug követés - (Только для одиночной игры) Отслеживаение/отладка осколков - (Solo SP) Debug Tracciamento Frag/Spall - (SP のみ) 破片/剥離のデバッグ用表示 - (싱글플레이 전용) 탄환파편/파편 디버그 추적화 - (仅单人)追踪显示破片粒子 - (僅在單人模式) 碎片/剝落除錯追蹤 - - - (SP only) Requires a mission/editor restart. Enables visual tracing of fragmentation and spalling rounds in SP game mode only. - (Solo SP) Requiere un reinicio misión/editor. Permite el seguimiento visual de la fragmentación y astillamientos de los proyectiles en modo SP. - (Tylko SP) Wymaga restartu misji/edytora. Aktywuje wizualne śledzenie odłamków oraz odprysków w trybie gry Single Player. - (nur SP) Splitter-/Explosions-Debugging - (Pouze SP) Vyžaduje restart mise/editoru. Aktivuje vizuální stopování fragmentace a úlomů pouze v režimu jednoho hráče. - (Somente SP) Requer um reinício de missão / editor. Habilita o rastreamento visual de projéteis de fragmentação e estilhaçamento apenas no modo de jogo SP. - (SP seulement) Requiert un redémarrage de mission ou de l'éditeur. Active les traceurs visuels de fragmentation et d'éclats en mode solo seulement. - (Csak SP) Küldetés/Editor újraindítás szükséges. Engedélyezi a repeszek és pattogzó lövedékek vizuális nyomkövetését, csak egyjátékos módok alatt. - (Только для одиночной игры) Требует перезапуска миссии/редактора. Включает визуальные следы от осколков и обломков в режиме одиночной игры. - (Solo SP) Richiede un restart editor/missione. Abilita il tracciamento visivo di schegge da frammentazione/spalling in modalità Giocatore Singolo. - (SP のみ) ミッションとエディタの再起動が必要です。有効化すると、シングルプレイでのみ破片と剥離の飛翔体が見えるようになります。 - (仅单人)激活后,只有在单人模式下才可观察到破片粒子的移动轨迹。 - (僅在單人模式) 讓你在單人模式下可觀察到碎片/剝落粒子的移動軌跡 - (SP 전용) 임무 / 편집자가 다시 시작해야합니다. SP 게임 모드에서만 파편화 및 탄환파편의 시각적 추적을 가능하게 합니다. - (SP only) Frag/Spall Debug Tracing (Solo SP) Seguimiento de depuración de Fragmentación/Astillamiento From 16e699e38723f981ed1f47aea8fbbdf47b7050e0 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 18:03:44 -0600 Subject: [PATCH 141/282] unneeded parens Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_dev_trackHitBox.sqf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/frag/functions/fnc_dev_trackHitBox.sqf b/addons/frag/functions/fnc_dev_trackHitBox.sqf index 79a5db05c7e..e6f9114e612 100644 --- a/addons/frag/functions/fnc_dev_trackHitBox.sqf +++ b/addons/frag/functions/fnc_dev_trackHitBox.sqf @@ -39,9 +39,9 @@ _box params ["_lowP", "_upP"]; // adjust with stance switch (stance _object) do { - case ("STAND"): {_upP set [2, 1.9];}; - case ("CROUCH"): {_upP set [2, 1.3];}; - case ("PRONE"): {_upP set [2, 0.8];}; + case "STAND": {_upP set [2, 1.9];}; + case "CROUCH": {_upP set [2, 1.3];}; + case "PRONE": {_upP set [2, 0.8];}; }; private _centerPoint = ASLToAGL getPosASL _object; From cdf1b4d6eb27c79d2bb9cc85cd7be555603f8c52 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 18:04:38 -0600 Subject: [PATCH 142/282] Clarified arguments Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_dev_fired.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_dev_fired.sqf b/addons/frag/functions/fnc_dev_fired.sqf index cc67b89f587..90024715997 100644 --- a/addons/frag/functions/fnc_dev_fired.sqf +++ b/addons/frag/functions/fnc_dev_fired.sqf @@ -4,7 +4,7 @@ * Add fired rounds to dev track. * * Arguments: - * None. Parameters inherited from EFUNC(common,firedEH) + * Parameters inherited from EFUNC(common,firedEH) * * Return Value: * None From 1b03ef7d52ce297d2de4de110342910bd58246a7 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 18:05:26 -0600 Subject: [PATCH 143/282] getposATL to getPosATL Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_dev_trackObj.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index 723fadd2e9b..d33fbb27965 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -35,7 +35,7 @@ private _colorArray = switch (toLowerANSI _color) do { case "white": {[0, 0, 0, 1]}; default {[0, 0.8, 0.8, 1]}; }; -GVAR(dev_trackLines) set [getObjectID _object, [[getposATL _object], _colorArray]]; +GVAR(dev_trackLines) set [getObjectID _object, [[getPosATL _object], _colorArray]]; // event handler to track round and cleanup when round is "dead" [ From 0958d6a33b293b7da8ac4dbcee4dd8b6683f08e2 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 18:07:11 -0600 Subject: [PATCH 144/282] Update addons/frag/functions/fnc_dev_addRound.sqf Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_dev_addRound.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_dev_addRound.sqf b/addons/frag/functions/fnc_dev_addRound.sqf index 67ac2c8318e..f29f692cf45 100644 --- a/addons/frag/functions/fnc_dev_addRound.sqf +++ b/addons/frag/functions/fnc_dev_addRound.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: Lambda.Tiger - * This function adds a round to be traced + * This function adds a round to be traced. * * Arguments: * 0: Projectile From 16128721e0330acc33df303a053150d3c07c9376 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 18:20:47 -0600 Subject: [PATCH 145/282] Function header changes Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_dev_fragCalcDump.sqf | 5 ++--- addons/frag/functions/fnc_dev_sphereDraw.sqf | 2 +- addons/frag/functions/fnc_dev_trackHitBox.sqf | 4 ++-- addons/frag/functions/fnc_doFrag.sqf | 6 +++--- addons/frag/functions/fnc_doFragRandom.sqf | 2 +- addons/frag/functions/fnc_doFragTargeted.sqf | 10 +++++----- addons/frag/functions/fnc_initBlackList.sqf | 2 +- addons/frag/functions/fnc_initMaterialCache.sqf | 6 +++--- addons/frag/functions/fnc_initRound.sqf | 4 ++-- addons/frag/functions/fnc_shouldFrag.sqf | 6 +++--- addons/frag/functions/fnc_shouldSpall.sqf | 3 +-- 11 files changed, 24 insertions(+), 26 deletions(-) diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf index 7850b8d602e..8214ffac3bc 100644 --- a/addons/frag/functions/fnc_dev_fragCalcDump.sqf +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -3,11 +3,10 @@ * Author: Lambda.Tiger, based on fnc_dev_debugAmmo by "ACE-Team" * Dumps all ammo types to see if there's any reason to spawn fragments * given hit power and distance. Good for grasping the values used in - * shouldFrag to cull non-fragmenting rounds + * shouldFrag to cull non-fragmenting rounds. * * Arguments: - * 0: Display rounds that will never frag (power < 5). - * Default value false + * 0: Display rounds that will never frag (power < 5) (default: false) * * Return Value: * None diff --git a/addons/frag/functions/fnc_dev_sphereDraw.sqf b/addons/frag/functions/fnc_dev_sphereDraw.sqf index 73d71b12915..c99dbcb138b 100644 --- a/addons/frag/functions/fnc_dev_sphereDraw.sqf +++ b/addons/frag/functions/fnc_dev_sphereDraw.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: Lambda.Tiger - * Add a colored sphere at a specified point + * Add a colored sphere at a specified point. * * Arguments: * 0: ASL position to add sphere diff --git a/addons/frag/functions/fnc_dev_trackHitBox.sqf b/addons/frag/functions/fnc_dev_trackHitBox.sqf index e6f9114e612..49d7638e0d8 100644 --- a/addons/frag/functions/fnc_dev_trackHitBox.sqf +++ b/addons/frag/functions/fnc_dev_trackHitBox.sqf @@ -2,10 +2,10 @@ /* * Author: Lambda.Tiger * Add a hit box outline to an object, outdated for unit hits as they - * use hit-point locations + * use hit-point locations. * * Arguments: - * 0: Object to draw the hit box of : + * 0: Object to draw the hit box of * 1: Add sphere at object origin * * Return Value: diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index ecd7db40de2..3ade288f5a6 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -5,10 +5,10 @@ * as handling some of the performance optimizations. * * Arguments: - * 0: projectile that's fragmenting + * 0: Projectile that's fragmenting * 1: ASL position of projectile - * 2: velocity of projectile - * 3: projectile cfgAmmo classname + * 2: Velocity of projectile + * 3: Projectile cfgAmmo classname * 4: getShotParents of projectile at EH * * Return Value: diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index 698b720ce68..a28f6212d96 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -2,7 +2,7 @@ /* * Author: Jaynus, NouberNou, Lambda.Tiger * This function creates fragments randomly spreading out from an explosion to - * a maximum of 15 + * a maximum of 15. * * Arguments: * 0: Position of fragmenting projectile ASL diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index bc415923bc3..8257b4fd210 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -2,19 +2,19 @@ /* * Author: Jaynus, NouberNou, Lambda.Tiger * This function creates fragments targeted at specific entities, up to - * a configured maximum + * a configured maximum. * * Arguments: * 0: Position of fragmenting projectile ASL * 1: Velocity of the fragmenting projectile - * 2: Maximum range of fragments to calculate - * 3: Maximum number of fragments to produce + * 2: Maximum range of fragments to calculate + * 3: Maximum number of fragments to produce * 4: Types of fragments - * 5: A modified parameter used to calculate whether a fragment hits + * 5: A modified parameter used to calculate whether a fragment hits * 6: Shot parent * * Return Value: - * Number of fragments created + * Number of fragments created * * Example: * [getPosASL _proj, velocity _proj, 50, 50, [], 1, [player, player]] call ace_frag_fnc_doFragTargeted; diff --git a/addons/frag/functions/fnc_initBlackList.sqf b/addons/frag/functions/fnc_initBlackList.sqf index 605ef1d180e..ece32b20da4 100644 --- a/addons/frag/functions/fnc_initBlackList.sqf +++ b/addons/frag/functions/fnc_initBlackList.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: Lambda.Tiger - * Adds setting defined blacklisted rounds to blacklist + * Adds setting defined blacklisted rounds to blacklist. * * Arguments: * None diff --git a/addons/frag/functions/fnc_initMaterialCache.sqf b/addons/frag/functions/fnc_initMaterialCache.sqf index cde98f9fa1a..809221e40f1 100644 --- a/addons/frag/functions/fnc_initMaterialCache.sqf +++ b/addons/frag/functions/fnc_initMaterialCache.sqf @@ -2,13 +2,13 @@ /* * Author: Lambda.Tiger * For performance, we load a bunch of vanilla materials preemptively into - * the spall material cache + * the spall material cache. * * Arguments: - * none + * None * * Return Value: - * none + * None * * Example: * call initMaterialCache; diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index cfbeb21d218..eed7d3d6f45 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -1,10 +1,10 @@ #include "..\script_component.hpp" /* * Author: Lambda.Tiger - * This function adds rounds using their config init EH + * This function adds rounds using their config init EH. * Arguments: - * 0: _projectile - The object created + * 0: Projectile - The object created * * Return Value: * None diff --git a/addons/frag/functions/fnc_shouldFrag.sqf b/addons/frag/functions/fnc_shouldFrag.sqf index f9e032d3014..103f7aac755 100644 --- a/addons/frag/functions/fnc_shouldFrag.sqf +++ b/addons/frag/functions/fnc_shouldFrag.sqf @@ -2,13 +2,13 @@ /* * Author: Lambda.Tiger * This function checks whether an ammunition type should cause fragmentation - * and whether any submunitions exist + * and whether any submunitions exist. * * Arguments: - * 0: _ammo - cfgAmmo type of ammo to check + * 0: Type of ammo to check * * Return Value: - * _shouldFrag Should the specific round fragment + * Should the specific round fragment * * Example: * ["B_556x45_Ball"] call ace_frag_fnc_shouldFrag; diff --git a/addons/frag/functions/fnc_shouldSpall.sqf b/addons/frag/functions/fnc_shouldSpall.sqf index 0265aa305af..1ee1ed8f53a 100644 --- a/addons/frag/functions/fnc_shouldSpall.sqf +++ b/addons/frag/functions/fnc_shouldSpall.sqf @@ -1,8 +1,7 @@ #include "..\script_component.hpp" /* * Author: Lambda.Tiger - * This function checks whether an ammunition type should cause spalling - * + * This function checks whether an ammunition type should cause spalling. * * Arguments: * 0: _ammo - cfgAmmo type of ammo to check From 3cc300a04daaf06056971d208388db79d8d6f5f2 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 18:23:12 -0600 Subject: [PATCH 146/282] another great isNotEqualTo opportunity Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_doFragRandom.sqf | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index a28f6212d96..6ffaa663b0b 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -37,8 +37,7 @@ private _hMode = switch (true) do { default {"_mid"}; }; -private _type = if (count _fragType > 0 && - {"ace_frag_tiny" isEqualTo (_fragType#0)}) then { +private _type = if (_fragType isNotEqualTo [] && {"ace_frag_tiny" isEqualTo (_fragType#0)}) then { QGVAR(def_tiny_) } else { QGVAR(def_small_) From b6891b729d7d48b68c64c06d84364400b6c468a2 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 18:24:54 -0600 Subject: [PATCH 147/282] formatting changes Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_initBlackList.sqf | 3 --- addons/frag/functions/fnc_shouldSpall.sqf | 2 +- addons/frag/initSettings.inc.sqf | 7 ++++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/addons/frag/functions/fnc_initBlackList.sqf b/addons/frag/functions/fnc_initBlackList.sqf index ece32b20da4..91b5a1b59ec 100644 --- a/addons/frag/functions/fnc_initBlackList.sqf +++ b/addons/frag/functions/fnc_initBlackList.sqf @@ -17,9 +17,6 @@ TRACE_1("Beginning blacklist init", GVAR(blackList)); -if (!ADDON) then { - [FUNC(initBlackList), [], 1] call CBA_fnc_waitAndExecute; -}; // could improve text parsing of CBA setting string private _convArray = parseSimpleArray GVAR(blackList); diff --git a/addons/frag/functions/fnc_shouldSpall.sqf b/addons/frag/functions/fnc_shouldSpall.sqf index 1ee1ed8f53a..953a0b6a915 100644 --- a/addons/frag/functions/fnc_shouldSpall.sqf +++ b/addons/frag/functions/fnc_shouldSpall.sqf @@ -4,7 +4,7 @@ * This function checks whether an ammunition type should cause spalling. * * Arguments: - * 0: _ammo - cfgAmmo type of ammo to check + * 0: Type of ammo to check * * Return Value: * Whether the round type would spall when hitting an object diff --git a/addons/frag/initSettings.inc.sqf b/addons/frag/initSettings.inc.sqf index 65812ec89ef..25a2fc55c09 100644 --- a/addons/frag/initSettings.inc.sqf +++ b/addons/frag/initSettings.inc.sqf @@ -25,8 +25,9 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; ] call CBA_fnc_addSetting; [ - QGVAR(fragSimComplexity), "LIST", - [LSTRING(FragMode), LSTRING(FragMode_Desc)], + QGVAR(fragSimComplexity), + "LIST", + [LSTRING(FragMode), LSTRING(FragMode_Desc)], [_category, LSTRING(Frag)], [[2, 1, 0], [LSTRING(FragMode_Opt2),LSTRING(FragMode_Opt1),LSTRING(FragMode_Opt0)], 2], 1 @@ -46,7 +47,7 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; [_category, LSTRING(Frag)], QUOTE(['B_556x45_Ball']), 1, - nil, + {}, true ] call CBA_fnc_addSetting; From e5f62c71d2a518e15ffabe5ccb0c8f86a5f4e722 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 18:34:08 -0600 Subject: [PATCH 148/282] unneeded parens Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_getSpallInfo.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_getSpallInfo.sqf b/addons/frag/functions/fnc_getSpallInfo.sqf index a8751351fe0..5167a1c3c86 100644 --- a/addons/frag/functions/fnc_getSpallInfo.sqf +++ b/addons/frag/functions/fnc_getSpallInfo.sqf @@ -25,7 +25,7 @@ private _ammoInfo = GVAR(spallInfoCache) get _ammo; if (!isNil "_ammoInfo") exitWith {_ammoInfo}; -private _ammoConfig = (configFile >> "CfgAmmo" >> _ammo); +private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; private _caliber = getNumber (_ammoConfig >> "caliber"); private _explosive = 1 min getNumber (_ammoConfig >> "explosive"); private _indirectHit = getNumber (_ammoConfig >> "indirectHitRange"); From c0c423bb83deca46f253eae8d78d96f18e64c68f Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 18:52:55 -0600 Subject: [PATCH 149/282] Declared _ammoInfo twice --- addons/frag/functions/fnc_getSpallInfo.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_getSpallInfo.sqf b/addons/frag/functions/fnc_getSpallInfo.sqf index 5167a1c3c86..70d131712c5 100644 --- a/addons/frag/functions/fnc_getSpallInfo.sqf +++ b/addons/frag/functions/fnc_getSpallInfo.sqf @@ -29,7 +29,7 @@ private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; private _caliber = getNumber (_ammoConfig >> "caliber"); private _explosive = 1 min getNumber (_ammoConfig >> "explosive"); private _indirectHit = getNumber (_ammoConfig >> "indirectHitRange"); -private _ammoInfo = [_caliber, _explosive, _indirectHit]; +_ammoInfo = [_caliber, _explosive, _indirectHit]; GVAR(spallInfoCache) set [_ammo, _ammoInfo]; From 51603619e6de80aeb5a04afdac7e6d09004bf102 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 18:53:45 -0600 Subject: [PATCH 150/282] optimized around checking if systems are active and moved debug arguments to an ifdef --- addons/frag/functions/fnc_initRound.sqf | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index eed7d3d6f45..fd3f196fe5a 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -14,18 +14,20 @@ * * Public: No */ - TRACE_1("ACE_Frag rndInit",_this); + +TRACE_1("ACE_Frag rndInit",_this); params [ ["_projectile", objNull, [objNull]] ]; +if !(isServer) exitWith {}; + private _ammo = typeOf _projectile; if (_ammo isEqualTo "" || {isNull _projectile}) exitWith { TRACE_2("bad ammo or projectile",_ammo,_projectile); }; -private _shouldFrag = _ammo call FUNC(shouldFrag); -if (_shouldFrag && GVAR(enabled)) then { +if (GVAR(enabled) && {_ammo call FUNC(shouldFrag)}) then { _projectile addEventHandler [ "Explode", { @@ -44,8 +46,7 @@ if (_shouldFrag && GVAR(enabled)) then { ]; }; -private _shouldSpall = _ammo call FUNC(shouldSpall); -if (GVAR(spallEnabled) && {_shouldSpall}) then { +if (GVAR(spallEnabled) && {_ammo call FUNC(shouldSpall)}) then { _projectile addEventHandler [ "HitPart", { @@ -72,4 +73,8 @@ if (GVAR(debugOptions) && (_shouldFrag || _shouldSpall)) then { [_projectile, "red", true] call FUNC(dev_trackObj); }; #endif +#ifdef DEBUG_MODE_FULL +private _shouldSpall = _ammo call FUNC(shouldSpall); +private _shouldFrag = _ammo call FUNC(shouldFrag) +#endif TRACE_2("initExit",_shouldFrag,_shouldSpall); From 73d00646071d554ccd1907fce6076f5ff8c6e803 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 18:54:13 -0600 Subject: [PATCH 151/282] Removed white space from removing an if statement in a previous commit --- addons/frag/functions/fnc_initBlackList.sqf | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/frag/functions/fnc_initBlackList.sqf b/addons/frag/functions/fnc_initBlackList.sqf index 91b5a1b59ec..ceac8ed4bd3 100644 --- a/addons/frag/functions/fnc_initBlackList.sqf +++ b/addons/frag/functions/fnc_initBlackList.sqf @@ -17,7 +17,6 @@ TRACE_1("Beginning blacklist init", GVAR(blackList)); - // could improve text parsing of CBA setting string private _convArray = parseSimpleArray GVAR(blackList); From ea15eeaee946c41533ce3108fd042667d14db603 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 19:03:19 -0600 Subject: [PATCH 152/282] Removed superfulous parenthese Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_dev_addRound.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_dev_addRound.sqf b/addons/frag/functions/fnc_dev_addRound.sqf index f29f692cf45..ef68a2a352a 100644 --- a/addons/frag/functions/fnc_dev_addRound.sqf +++ b/addons/frag/functions/fnc_dev_addRound.sqf @@ -38,7 +38,7 @@ if (_isSidePlayer) then { if (!alive _projectile) exitWith { [_handle] call CBA_fnc_removePerFrameHandler; }; - private _projectileArray = GVAR(dev_trackLines) getOrDefault [(getObjectID _projectile), -1]; + private _projectileArray = GVAR(dev_trackLines) getOrDefault [getObjectID _projectile, -1]; if (_projectileArray isEqualType 0) exitWith {}; (_projectileArray#0) pushBack getPosATL _projectile; }, From a1c498d33812713d32ef36d082cff9f6eb4fab8a Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 19:40:12 -0600 Subject: [PATCH 153/282] clarified function description and removed unneeded comments --- addons/frag/functions/fnc_dev_addRound.sqf | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/addons/frag/functions/fnc_dev_addRound.sqf b/addons/frag/functions/fnc_dev_addRound.sqf index f29f692cf45..7888b9bc80a 100644 --- a/addons/frag/functions/fnc_dev_addRound.sqf +++ b/addons/frag/functions/fnc_dev_addRound.sqf @@ -1,12 +1,16 @@ #include "..\script_component.hpp" /* * Author: Lambda.Tiger - * This function adds a round to be traced. + * This function initialize projectile tracking of a round so that it's path + * can be drawn in debug mode. It may optionally include hit / explode / + * deflected event handlers that spawn color coded spheres on each event, + * green / red / blue, respectively. * * Arguments: - * 0: Projectile - * 1: Add projectile event handlers - * 2: Is the round blue + * 0: Projectile to be tracked. + * 1: Add projectile hit/explode/defelceted event handlers. + * 2: Is the round fired by a unit on the same side as the player + * true results in blue traces, false in red. * * Return Value: * None @@ -16,19 +20,19 @@ * * Public: No */ + params [ "_projectile", ["_addProjectileEventHandlers", true, [true]], ["_isSidePlayer", true, [true]] ]; -// track round on each frame -// Create entry in position array from hashmap if (_isSidePlayer) then { GVAR(dev_trackLines) set [getObjectID _projectile, [[getposATL _projectile], [0, 0, 1, 1]]]; } else { GVAR(dev_trackLines) set [getObjectID _projectile, [[getposATL _projectile], [1, 0, 0, 1]]]; }; + // event handler to track round and cleanup when round is "dead" [ { @@ -48,7 +52,6 @@ if (_isSidePlayer) then { if (!_addProjectileEventHandlers) exitWith {}; -// Add hitPart eventHandler _projectile addEventHandler [ "HitPart", { @@ -61,7 +64,6 @@ _projectile addEventHandler [ } ]; -// Add explode event handler _projectile addEventHandler [ "Explode", { @@ -74,7 +76,6 @@ _projectile addEventHandler [ } ]; -// Add deflected eventHandler _projectile addEventHandler [ "Deflected", { From 0321b783859621bddb728823220f522f0ce76baf Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 19:41:07 -0600 Subject: [PATCH 154/282] Moved "isServer" check to initRound function --- addons/frag/CfgAmmo.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index 45842a425fd..d3d800cccba 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -1,6 +1,7 @@ #define BASE_DRAG -0.01 #define HD_MULT 5 #define BASE_DRAG_HD (BASE_DRAG * HD_MULT) +#define ACE_FRAG_INIT_CODE _this call FUNC(initRound) #define ACE_FRAG_RM_EH class EventHandlers: EventHandlers {\ class ADDON {\ delete init;\ @@ -8,12 +9,12 @@ } #define ACE_FRAG_ADD_EH_BASE class EventHandlers {\ class ADDON {\ - init = QUOTE(if (isServer) then {_this call FUNC(initRound);};);\ + init = QUOTE(ACE_FRAG_INIT_CODE);\ };\ } #define ACE_FRAG_ADD_EH class EventHandlers: EventHandlers {\ class ADDON {\ - init = QUOTE(if (isServer) then {_this call FUNC(initRound);};);\ + init = QUOTE(ACE_FRAG_INIT_CODE);\ };\ } From 3f84a45deebdcc95c27145109476b116a34f9a29 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 20:44:28 -0600 Subject: [PATCH 155/282] https://github.com/acemod/ACE3/pull/9728#discussion_r1454832701 --- addons/frag/functions/fnc_addBlackList.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_addBlackList.sqf b/addons/frag/functions/fnc_addBlackList.sqf index 86ac77de0f8..4d07eacdff8 100644 --- a/addons/frag/functions/fnc_addBlackList.sqf +++ b/addons/frag/functions/fnc_addBlackList.sqf @@ -4,7 +4,7 @@ * Adds a round type to the blacklist (will be ignored). * * Arguments: - * 0: Projectile or classname + * 0: Projectile or * * Return Value: * None From da1d184009f16930171d2c26996ef3a80e41a478 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 20:46:15 -0600 Subject: [PATCH 156/282] changed params statement, function header, and propigated doFrag argument changes --- addons/frag/functions/fnc_initRound.sqf | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index fd3f196fe5a..2a04deae149 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -1,10 +1,11 @@ #include "..\script_component.hpp" /* * Author: Lambda.Tiger - * This function adds rounds using their config init EH. - + * This function adds projectile explode and hitPart event handlers and is + * intended to be called from an projectile config init event handler. + * * Arguments: - * 0: Projectile - The object created + * 0: The projectile to be initialized * * Return Value: * None @@ -16,9 +17,7 @@ */ TRACE_1("ACE_Frag rndInit",_this); -params [ - ["_projectile", objNull, [objNull]] -]; +params ["_projectile"]; if !(isServer) exitWith {}; @@ -31,13 +30,13 @@ if (GVAR(enabled) && {_ammo call FUNC(shouldFrag)}) then { _projectile addEventHandler [ "Explode", { - params ["_proj", "_posASL"]; + params ["_proj", "_posASL", "_velocity"]; private _shotParents = getShotParents _proj; private _ammo = typeOf _proj; // wait for frag damage to kill units before spawning fragments [ FUNC(doFrag), - _this + [_ammo, _shotParents] + [_posASL, _velocity, _ammo, _shotParents] ] call CBA_fnc_execNextFrame; if (GVAR(reflectionsEnabled)) then { [_posASL, _ammo] call FUNC(doReflections); @@ -73,8 +72,4 @@ if (GVAR(debugOptions) && (_shouldFrag || _shouldSpall)) then { [_projectile, "red", true] call FUNC(dev_trackObj); }; #endif -#ifdef DEBUG_MODE_FULL -private _shouldSpall = _ammo call FUNC(shouldSpall); -private _shouldFrag = _ammo call FUNC(shouldFrag) -#endif -TRACE_2("initExit",_shouldFrag,_shouldSpall); +TRACE_1("initExit",_ammo); From 183d9f0ac69a1bb8f5a85552f2db7976610db3fd Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 20:48:27 -0600 Subject: [PATCH 157/282] capitization from cfg to Cfg in config lookups --- addons/frag/functions/fnc_dev_fragCalcDump.sqf | 8 +++----- addons/frag/functions/fnc_getMaterialInfo.sqf | 4 ++-- addons/frag/functions/fnc_initBlackList.sqf | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf index 8214ffac3bc..58429f33f07 100644 --- a/addons/frag/functions/fnc_dev_fragCalcDump.sqf +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -6,7 +6,7 @@ * shouldFrag to cull non-fragmenting rounds. * * Arguments: - * 0: Display rounds that will never frag (power < 5) (default: false) + * 0: Display rounds that will never frag (power < 5). (default: false) * * Return Value: * None @@ -17,11 +17,9 @@ * Public: No */ -params [ - ["_logAll", false, [false]] -]; +params [["_logAll", false, [false]]]; -private _allAmmoConfigs = configProperties [configFile >> "cfgAmmo", "isClass _x && !('ace_frag' in configName _x)", true]; +private _allAmmoConfigs = configProperties [configFile >> "CfgAmmo", "isClass _x && !('ace_frag' in configName _x)", true]; private _processedCfgAmmos = []; private _nPrinted = 0; diff --git a/addons/frag/functions/fnc_getMaterialInfo.sqf b/addons/frag/functions/fnc_getMaterialInfo.sqf index 2ca46ac8d81..e38144b6e62 100644 --- a/addons/frag/functions/fnc_getMaterialInfo.sqf +++ b/addons/frag/functions/fnc_getMaterialInfo.sqf @@ -8,7 +8,7 @@ * on the surface hit. * * Arguments: - * 0: surfacetype - either a cfgSurfaces path .bisurf filepath + * 0: surfacetype - either a CfgSurfaces path .bisurf filepath * * Return Value: * _material - Material categories as expanded on in line 44 below @@ -34,7 +34,7 @@ if (isClass _surfaceConfig) then { if (_material isEqualTo "" || {_material isEqualTo "empty"}) then { _material = getText (_surfaceConfig >> "soundhit"); }; -} else { // Messy way when a surface isn't added to cfgSurfaces +} else { // Messy way when a surface isn't added to CfgSurfaces private _surfFileText = toLowerANSI preprocessFile _surfType; _surfFileText = _surfFileText regexReplace ["[^a-z0-9]", ""]; private _idx = ACE_FRAG_SOUNDENVIRON_STR_LEN + (_surfFileText find "soundenviron"); diff --git a/addons/frag/functions/fnc_initBlackList.sqf b/addons/frag/functions/fnc_initBlackList.sqf index ceac8ed4bd3..5dee461e168 100644 --- a/addons/frag/functions/fnc_initBlackList.sqf +++ b/addons/frag/functions/fnc_initBlackList.sqf @@ -34,7 +34,7 @@ private _errors = 0; continue; }; - if (!isClass (configFile >> "cfgAmmo" >> _ammo)) then { + if (!isClass (configFile >> "CfgAmmo" >> _ammo)) then { INFO_1("Ammo class: %1 does not exist", str _ammo); INC(_errors); continue; From df884dc4bc6fb6e46c1c122a94b2087d3d18a2fb Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 20:50:20 -0600 Subject: [PATCH 158/282] changed default arguments, check isKindOf to "CAManBase" --- addons/frag/functions/fnc_dev_addRound.sqf | 4 ++-- addons/frag/functions/fnc_doFrag.sqf | 20 ++++++++-------- addons/frag/functions/fnc_doFragRandom.sqf | 24 ++++++++++---------- addons/frag/functions/fnc_doFragTargeted.sqf | 18 +++++++-------- addons/frag/functions/fnc_doSpall.sqf | 19 ++++++++-------- 5 files changed, 42 insertions(+), 43 deletions(-) diff --git a/addons/frag/functions/fnc_dev_addRound.sqf b/addons/frag/functions/fnc_dev_addRound.sqf index cdc21164ab0..64d78e2759d 100644 --- a/addons/frag/functions/fnc_dev_addRound.sqf +++ b/addons/frag/functions/fnc_dev_addRound.sqf @@ -23,8 +23,8 @@ params [ "_projectile", - ["_addProjectileEventHandlers", true, [true]], - ["_isSidePlayer", true, [true]] + ["_addProjectileEventHandlers", true], + ["_isSidePlayer", true] ]; if (_isSidePlayer) then { diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 3ade288f5a6..7a42b23ce85 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -5,11 +5,10 @@ * as handling some of the performance optimizations. * * Arguments: - * 0: Projectile that's fragmenting - * 1: ASL position of projectile - * 2: Velocity of projectile - * 3: Projectile cfgAmmo classname - * 4: getShotParents of projectile at EH + * 0: ASL position of projectile. + * 1: Velocity of projectile + * 2: Projectile CfgAmmo classname + * 3: getShotParents of projectile at EH * * Return Value: * None @@ -21,11 +20,10 @@ */ TRACE_1("begin doFrag",_this); params [ - "", - ["_posASL", [0, 0, 0], [[]], [3]], - ["_velocity", [0, 0, 0] , [[]], [3]], - ["_ammo", "", [""]], - ["_shotParents", [objNull, objNull], [[]]] + "_posASL", + "_velocity", + "_ammo", + "_shotParents" ]; // Don't let a single object cause all fragmentation events @@ -37,7 +35,7 @@ _shotParentVic setVariable [QGVAR(obj_nextFragTime), CBA_missionTime + ACE_FRAG_ // Check normal round timeout and adjust _max frags private _timeSinceLastFrag = CBA_missionTime - GVAR(lastFragTime); -if (_ammo isEqualTo "" || {_posASL isEqualTo [0, 0, 0] || _timeSinceLastFrag < ACE_FRAG_HOLDOFF}) exitWith { +if (_timeSinceLastFrag < ACE_FRAG_HOLDOFF || {_posASL isEqualTo [0, 0, 0] || _ammo isEqualTo ""}) exitWith { TRACE_3("timeExit",_timeSinceLastFrag,CBA_missionTime,GVAR(lastFragTime)); }; private _maxFragCount = round linearConversion [0.1, 1.5, _timeSinceLastFrag, ACE_FRAG_COUNT_MIN, ACE_FRAG_COUNT_MAX, true]; diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index 6ffaa663b0b..20964cf8626 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -5,12 +5,12 @@ * a maximum of 15. * * Arguments: - * 0: Position of fragmenting projectile ASL - * 1: Velocity of the fragmenting projectile - * 2: Height (AGL) of the fragmenting projectile - * 3: Type of fragments to generate - * 4: Remaining fragment budget - * 5: Shot parents + * 0: Position of fragmenting projectile ASL. + * 1: Velocity of the fragmenting projectile. + * 2: Height (AGL) of the fragmenting projectile. + * 3: Type of fragments to generate. + * 4: Remaining fragment budget. + * 5: Shot parents. * * Return Value: * None @@ -22,15 +22,15 @@ */ params [ "_posASL", - ["_fragVelocity", [0,0,0]], - ["_heightAGL", 2, [123]], - ["_fragType", [], [[]]], - ["_maxFragCount", 10, [123]], - ["_shotParents", [objNull, objNull], [[]], [2]] + "_fragVelocity", + "_heightAGL", + "_fragType", + "_maxFragCount", + "_shotParents", ]; TRACE_6("doFragRandom",_posASL,_fragVelocity,_heightAGL,_fragType,_maxFragCount,_shotParents); -// See cfgAmmoFragSpawner for different frag types +// See CfgAmmoFragSpawner for different frag types private _hMode = switch (true) do { case (_heightAGL > 10): {"_top"}; case (_heightAGL > 5): {"_hi"}; diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index 8257b4fd210..4d9d9e15a97 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -24,12 +24,12 @@ params [ "_posASL", - ["_fragVelocity", 800, [123]], - ["_fragRange", 50, [123]], - ["_maxFrags", 20, [123]], - ["_fragTypes", [], [[]]], - ["_modFragCount", 1, [123]], - ["_shotParents", [objNull, objNull], [[]], [2]] + "_fragVelocity", + "_fragRange", + "_maxFrags", + "_fragTypes", + "_modFragCount", + "_shotParents", ]; TRACE_5("fnc_doFragTargeted",_posASL,_fragRange,_maxFrags,_fragTypes,_modFragCount); @@ -52,7 +52,7 @@ if (_objects isEqualTo []) exitWith { // grab crews and add them in so that targets stay approx. sorted by distance { private _crew = crew _x; - if (count _crew > 1) then { + if (_crew isNotEqualTo []) then { private _arr = [_x]; { _arr pushBackUnique _x; @@ -83,8 +83,8 @@ private _totalFragCount = 0; private _isPerson = _target isKindOf "CAManBase"; if (_isPerson) then { switch (stance _target) do { - case ("STAND"): {_height = 1.9; _crossSectionArea = 1.5;}; - case ("CROUCH"): {_height = 1.2; _crossSectionArea = 1;}; + case "STAND": {_height = 1.9; _crossSectionArea = 1.5;}; + case "CROUCH": {_height = 1.2; _crossSectionArea = 1;}; default {_crossSectionArea = 0.75;}; }; } else { diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index 4a069c51179..15b8b8c6147 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -15,23 +15,24 @@ * * Public: No */ + TRACE_1("doSpall",_this); params [ "_projectile", - ["_objectHit", objNull], - ["_lastPosASL", [0, 0, 0]], - ["_lastVelocity", [0, 0, 0]], - ["_surfaceNorm", [0, 0, 0]], - ["_surfaceType", ""], - ["_ammo", "", [""]], - ["_shotParents", [objNull, objNull], [[]]], - ["_vectorUp", [0,0,1]] + "_objectHit", + "_lastPosASL", + "_lastVelocity", + "_surfaceNorm", + "_surfaceType", + "_ammo", + "_shotParents", + "_vectorUp", ]; if (CBA_missionTime < GVAR(nextSpallAllowTime)|| _lastPosASL isEqualTo [0,0,0] || {_ammo isEqualTo "" || {!isNull _objectHit && - {objectHit isKindOf "man"}}}) exitWith { + {objectHit isKindOf "CAManBase"}}}) exitWith { TRACE_4("time/invldHit",CBA_missionTime,GVAR(nextSpallAllowTime),_objectHit,_lastPosASL); }; From 8b45d0aa1770cab493853d823a171bfb85b445f8 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 20:51:34 -0600 Subject: [PATCH 159/282] Updated function headers --- addons/frag/functions/fnc_dev_clearTraces.sqf | 2 +- addons/frag/functions/fnc_dev_trackHitBox.sqf | 5 +++-- addons/frag/functions/fnc_getFragInfo.sqf | 11 +++++------ addons/frag/functions/fnc_getSpallInfo.sqf | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/addons/frag/functions/fnc_dev_clearTraces.sqf b/addons/frag/functions/fnc_dev_clearTraces.sqf index 21a350b8c93..07cec693d58 100644 --- a/addons/frag/functions/fnc_dev_clearTraces.sqf +++ b/addons/frag/functions/fnc_dev_clearTraces.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: Lambda.Tiger - * Clears all dev spheres and traces + * Clears all dev spheres and traces. * * Arguments: * None diff --git a/addons/frag/functions/fnc_dev_trackHitBox.sqf b/addons/frag/functions/fnc_dev_trackHitBox.sqf index 49d7638e0d8..534bd0944ec 100644 --- a/addons/frag/functions/fnc_dev_trackHitBox.sqf +++ b/addons/frag/functions/fnc_dev_trackHitBox.sqf @@ -5,8 +5,8 @@ * use hit-point locations. * * Arguments: - * 0: Object to draw the hit box of - * 1: Add sphere at object origin + * 0: Object that should have it's hit box drawn. + * 1: Add sphere at object origin. (Default: true) * * Return Value: * None @@ -16,6 +16,7 @@ * * Public: No */ + params [ ["_object", objNull, [objNull]], ["_addSphere", true, [true]] diff --git a/addons/frag/functions/fnc_getFragInfo.sqf b/addons/frag/functions/fnc_getFragInfo.sqf index f5a0fce58b8..d695435f36d 100644 --- a/addons/frag/functions/fnc_getFragInfo.sqf +++ b/addons/frag/functions/fnc_getFragInfo.sqf @@ -5,15 +5,14 @@ * ammo type. * * Arguments: - * 0: _ammo - cfgAmmo type of ammo to check + * 0: _ammo - CfgAmmo type of ammo to check. * * Return Value: * _ammoInfo - * 0: _fragRange - search range for fragments - * 1: _fragVel - gurney equation calculated velocity - * 2: _fragTypes - array of fragment types - * 3: _fragCount - modified frag count used under assumptions -* of spherical fragmentation + * 0: _fragRange - search range for fragments. + * 1: _fragVel - gurney equation calculated velocity. + * 2: _fragTypes - array of fragment types. + * 3: _fragCount - modified frag count used under assumptions of spherical fragmentation. * * Example: * ["B_556x45_Ball"] call ace_frag_fnc_getFragInfo; diff --git a/addons/frag/functions/fnc_getSpallInfo.sqf b/addons/frag/functions/fnc_getSpallInfo.sqf index 70d131712c5..4c76a0b909c 100644 --- a/addons/frag/functions/fnc_getSpallInfo.sqf +++ b/addons/frag/functions/fnc_getSpallInfo.sqf @@ -5,13 +5,13 @@ * ammo type. * * Arguments: - * 0: _ammo - cfgAmmo type of ammo to check + * 0: _ammo - CfgAmmo type of ammo to check * * Return Value: * _ammoInfo - * 0: _caliber - search range for fragments - * 1: _explosive - whether the round is explosive or not - * 2: _indirectHitRange - Indirect hit damage + * 0: _caliber - search range for fragments + * 1: _explosive - whether the round is explosive or not + * 2: _indirectHitRange - Indirect hit damage * * Example: * ["B_556x45_Ball"] call ace_frag_fnc_getSpallInfo; From 9bcf2b76502c506c7da1d151f0f3525e22f8cc43 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 20:51:59 -0600 Subject: [PATCH 160/282] white space and define placement changes --- addons/frag/functions/fnc_dev_debugAmmo.sqf | 29 ++++++++++--------- addons/frag/functions/fnc_dev_drawTrace.sqf | 5 ++-- addons/frag/functions/fnc_dev_fired.sqf | 2 ++ .../functions/fnc_dev_switchUnitHandle.sqf | 1 + addons/frag/functions/fnc_dev_trackObj.sqf | 1 + 5 files changed, 22 insertions(+), 16 deletions(-) diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index f178bb0052c..7bfb4fed12f 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -3,13 +3,13 @@ /* * Author: ACE-Team, Lambda.Tiger * This function will dump every ammo config that would generate ace_frag - * fragments that could be fired from a weapon + * fragments that could be fired from a weapon. * * Arguments: - * 0: Log ammo types that wouldn't normally frag - * 1: Only export ammo classes of classes referenced in cfgMagazines - * and their submunitions. - * 2: Force a CSV format on debug print + * 0: Log ammo types that wouldn't normally frag. (Default: false) + * 1: Only export ammo classes of classes referenced in CfgMagazines and their + * submunitions. (Default: false) + * 2: Force a CSV format on debug print. (Default: false) * * Return Value: * None @@ -19,6 +19,7 @@ * * Public: No */ + params [ ["_logAll", false, [false]], ["_onlyShotAmmoTypes", false, [false]], @@ -39,20 +40,20 @@ if (_onlyShotAmmoTypes) then { ]; if (_ammo isEqualTo "" || {_ammo in _allAmmoConfigs}) exitWith {}; _allAmmoConfigs pushBack _ammo; - private _ammoConfig = configFile >> "cfgAmmo" >> _ammo; - private _subMunit = toLowerANSI getText (_ammoConfig >> "submunitionAmmo"); - if (_subMunit isNotEqualTo "") then { - _subMunit = getArray (_ammoConfig >> "submunitionAmmo"); - for "_i" from 0 to count _subMunit - 1 do { + private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; + private _subMunition = toLowerANSI getText (_ammoConfig >> "submunitionAmmo"); + if (_subMunition isNotEqualTo "") then { + _subMunition = getArray (_ammoConfig >> "submunitionAmmo"); + for "_i" from 0 to count _subMunition - 1 do { if (_i mod 2 == 0) then { - [toLowerANSI (_subMunit#_i)] call _configSearchFunc; + [toLowerANSI (_subMunition#_i)] call _configSearchFunc; }; }; } else { - [toLowerANSI _subMunit] call _configSearchFunc; + [toLowerANSI _subMunition] call _configSearchFunc; }; }; - private _allMagazineConfigs = configProperties [configFile >> "cfgMagazines", "isClass _x", true]; + private _allMagazineConfigs = configProperties [configFile >> "CfgMagazines", "isClass _x", true]; { [toLowerANSI getText (_x >> "ammo")] call _configSearchFunc; @@ -68,7 +69,7 @@ private _printCount = 0; if (_ammo isNotEqualTo "" && {!(_ammo in _processedCfgAmmos)}) then { _processedCfgAmmos pushBack _ammo; - private _ammoConfig = (configFile >> "CfgAmmo" >> _ammo); + private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; private _shoulFrag = [_ammo] call FUNC(shouldFrag); if (_shoulFrag || _logAll) then { diff --git a/addons/frag/functions/fnc_dev_drawTrace.sqf b/addons/frag/functions/fnc_dev_drawTrace.sqf index f39a6cdd0e8..7c4cb40189d 100644 --- a/addons/frag/functions/fnc_dev_drawTrace.sqf +++ b/addons/frag/functions/fnc_dev_drawTrace.sqf @@ -1,8 +1,7 @@ #include "..\script_component.hpp" -#define HITBOX_DRAW_PATH [[3, 2, 1, 5, 6, 7, 3, 0, 4, 5], [0, 1], [2, 6], [7, 4]] /* * Author: Lambda.Tiger - * Per frame function to draw all dev traces + * Per frame function to draw all dev traces. * * Arguments: * none @@ -14,6 +13,8 @@ * * Public: No */ + +#define HITBOX_DRAW_PATH [[3, 2, 1, 5, 6, 7, 3, 0, 4, 5], [0, 1], [2, 6], [7, 4]] if (!GVAR(debugOptions)) exitWith {}; { diff --git a/addons/frag/functions/fnc_dev_fired.sqf b/addons/frag/functions/fnc_dev_fired.sqf index 90024715997..4ed25573fef 100644 --- a/addons/frag/functions/fnc_dev_fired.sqf +++ b/addons/frag/functions/fnc_dev_fired.sqf @@ -14,6 +14,8 @@ * * Public: No */ + //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); + [_projectile, true, [side group _unit, side group ACE_player] call BIS_fnc_sideIsFriendly] call FUNC(dev_addRound); diff --git a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf index c290c762c42..16f7ab55309 100644 --- a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf +++ b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf @@ -15,6 +15,7 @@ * * Public: No */ + TRACE_1("switchUnit",_this); params ["_currentUnit", "_lastUnit"]; diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index d33fbb27965..3e820c81256 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -16,6 +16,7 @@ * * Public: No */ + params [ "_object", ["_color", "blue", ["blue"]], From 35592fa0af1cf0cd5879d4395f2cd1a29e31379f Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 20:52:25 -0600 Subject: [PATCH 161/282] removed 2 argument option and removed some defaults --- addons/frag/functions/fnc_dev_sphereDraw.sqf | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/addons/frag/functions/fnc_dev_sphereDraw.sqf b/addons/frag/functions/fnc_dev_sphereDraw.sqf index c99dbcb138b..31cebab110f 100644 --- a/addons/frag/functions/fnc_dev_sphereDraw.sqf +++ b/addons/frag/functions/fnc_dev_sphereDraw.sqf @@ -4,8 +4,8 @@ * Add a colored sphere at a specified point. * * Arguments: - * 0: ASL position to add sphere - * 1: Color of sphere + * 0: ASL position to add sphere. + * 1: Color of sphere. (Default: Blue) * * Return Value: * None @@ -15,18 +15,12 @@ * * Public: No */ + params [ - ["_posASL", [0, 0, 0], [[]], [2,3]], - ["_color", "(1,0,0,0.5)", [""]] + "_posASL", + ["_color", "blue", [""]] ]; -if (count _posASL < 3) then { - _posASL pushBack 0; - _posASL = ASLtoATL _posASL; - _posASL set [2, 0]; - _posASL = ATLtoASL _posASL; -}; - if (_color select [0,1] != "(") then { _color = switch (toLowerANSI _color) do { case "blue": {"(0,0,0.8,0.5)"}; From 63d67df7bfd8dcaedb54ce97a5550a21d1aadc14 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 21:11:38 -0600 Subject: [PATCH 162/282] removed spurious commas --- addons/frag/functions/fnc_doFragRandom.sqf | 2 +- addons/frag/functions/fnc_doFragTargeted.sqf | 2 +- addons/frag/functions/fnc_doSpall.sqf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index 20964cf8626..47384fe14d8 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -26,7 +26,7 @@ params [ "_heightAGL", "_fragType", "_maxFragCount", - "_shotParents", + "_shotParents" ]; TRACE_6("doFragRandom",_posASL,_fragVelocity,_heightAGL,_fragType,_maxFragCount,_shotParents); diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index 4d9d9e15a97..9532b908f89 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -29,7 +29,7 @@ params [ "_maxFrags", "_fragTypes", "_modFragCount", - "_shotParents", + "_shotParents" ]; TRACE_5("fnc_doFragTargeted",_posASL,_fragRange,_maxFrags,_fragTypes,_modFragCount); diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index 15b8b8c6147..4f86f801af6 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -26,7 +26,7 @@ params [ "_surfaceType", "_ammo", "_shotParents", - "_vectorUp", + "_vectorUp" ]; if (CBA_missionTime < GVAR(nextSpallAllowTime)|| From c921b1f9b40b7ea24559d293bf7022301bc60a0b Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 21:28:07 -0600 Subject: [PATCH 163/282] removed unused debug GVAR --- addons/frag/XEH_preInit.sqf | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/frag/XEH_preInit.sqf b/addons/frag/XEH_preInit.sqf index 8b91a18d180..daf20e0f628 100644 --- a/addons/frag/XEH_preInit.sqf +++ b/addons/frag/XEH_preInit.sqf @@ -20,7 +20,6 @@ GVAR(lastFragTime) = -2; #ifdef DEBUG_MODE_DRAW GVAR(dev_trackLines) = createHashMap; GVAR(dev_hitBoxes) = createHashMap; -GVAR(dev_failedToDelete) = 0; GVAR(dev_eventSpheres) = []; GVAR(dev_drawPFEH) = -1; #include "initSettingsDebug.inc.sqf" From 13834d7f17bebc2e40cfdc9e192436dffa9d7c4f Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 21:28:53 -0600 Subject: [PATCH 164/282] Switched debug clear traces from addAction to ACE self interact --- addons/frag/XEH_PREP.hpp | 1 - addons/frag/XEH_postInit.sqf | 26 ++++++++-- .../functions/fnc_dev_switchUnitHandle.sqf | 51 ------------------- 3 files changed, 22 insertions(+), 56 deletions(-) delete mode 100644 addons/frag/functions/fnc_dev_switchUnitHandle.sqf diff --git a/addons/frag/XEH_PREP.hpp b/addons/frag/XEH_PREP.hpp index f87756ea137..5402c89e23c 100644 --- a/addons/frag/XEH_PREP.hpp +++ b/addons/frag/XEH_PREP.hpp @@ -8,7 +8,6 @@ PREP(dev_fragCalcDump); PREP(dev_trackHitBox); PREP(dev_trackObj); PREP(dev_sphereDraw); -PREP(dev_switchUnitHandle); PREP(doExplosions); PREP(doFrag); PREP(doFragRandom); diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index b6afbf66ed4..6209f17e0e6 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -15,10 +15,28 @@ 0 ] call CBA_fnc_addPerFrameHandler; [ - "unit", - LINKFUNC(dev_switchUnitHandle), - true - ] call CBA_fnc_addPlayerEventHandler; + "ace_interact_menu_newControllableObject", + { + params ["_type"]; + + private _action = [ + QGVAR(debugReset), + "Reset ACE Frag traces", + "", + { + remoteExecCall [QFUNC(dev_clearTraces), 2]; + }, + {true} + ] call EFUNC(interact_menu,createAction); + [ + _type, + 1, + ["ACE_SelfActions"], + _action, + true + ] call ace_interact_menu_fnc_addActionToClass; + } + ] call CBA_fnc_addEventHandler; }; #endif } diff --git a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf b/addons/frag/functions/fnc_dev_switchUnitHandle.sqf deleted file mode 100644 index 16f7ab55309..00000000000 --- a/addons/frag/functions/fnc_dev_switchUnitHandle.sqf +++ /dev/null @@ -1,51 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: Lambda.Tiger - * Handle for debug actions when switching units - * - * Arguments: - * 0: Last unit - * 1: Current unit - * - * Return Value: - * None - * - * Example: - * [unit0, player] call ace_frag_fnc_dev_switchUnitHandle; - * - * Public: No - */ - -TRACE_1("switchUnit",_this); -params ["_currentUnit", "_lastUnit"]; - -if (isNull _currentUnit || {_lastUnit isEqualTo _currentUnit}) exitWith {}; -if (!local _currentUnit) exitWith { - [ - {local _currentUnit}, - FUNC(dev_switchUnitHandle), - _this, - 5 - ] call CBA_fnc_waitUntilAndExecute; -}; - -private _actionID = missionNamespace getVariable [QGVAR(dev_clearTraceAction), -1]; -if (_actionID > -1 && {!isNull _lastUnit}) then { - _lastUnit removeAction _actionID; -}; - -_actionID = _currentUnit addAction [ - "Reset Lines", - { - remoteExecCall [QFUNC(dev_clearTraces), 2]; - }, - nil, - 1.5, - true, - false, - "", - "true", - 8 -]; - -missionNamespace setVariable [QGVAR(dev_clearTraceAction), _actionID]; From 85df838aab597a95894b9b63833ec32dc78aaa2f Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 21:39:54 -0600 Subject: [PATCH 165/282] variable names weren't verbose enough --- addons/frag/functions/fnc_initRound.sqf | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index 2a04deae149..51c4920533d 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -11,7 +11,7 @@ * None * * Example: - * [_proj] call ace_frag_fnc_initRound; + * [_projectile] call ace_frag_fnc_initRound; * * Public: No */ @@ -30,9 +30,9 @@ if (GVAR(enabled) && {_ammo call FUNC(shouldFrag)}) then { _projectile addEventHandler [ "Explode", { - params ["_proj", "_posASL", "_velocity"]; - private _shotParents = getShotParents _proj; - private _ammo = typeOf _proj; + params ["_projectile", "_posASL", "_velocity"]; + private _shotParents = getShotParents _projectile; + private _ammo = typeOf _projectile; // wait for frag damage to kill units before spawning fragments [ FUNC(doFrag), @@ -49,20 +49,20 @@ if (GVAR(spallEnabled) && {_ammo call FUNC(shouldSpall)}) then { _projectile addEventHandler [ "HitPart", { - params ["_proj", "_hitObj", "", - "_posASL", "_vel", "_sNorm", "", + params ["_projectile", "_hitObject", "", + "_posASL", "_velocity", "_surfNorm", "", "", "_surfType" ]; - private _shotPrnt = getShotParents _proj; - private _ammo = typeOf _proj; - private _vUp = vectorUp _proj; + private _shotParent = getShotParents _projectile; + private _ammo = typeOf _projectile; + private _vectorUp = vectorUp _projectile; /* * Wait a round to see what happens to the round, may result in * multiple hits / slowdowns getting shunted to the first hit */ [ FUNC(doSpall), - [_proj, _hitObj, _posASL, _vel, _sNorm, _surfType, _ammo, _shotPrnt, _vUp] + [_projectile, _hitObject, _posASL, _velocity, _surfNorm, _surfType, _ammo, _shotParent, _vectorUp] ] call CBA_fnc_execNextFrame; } ]; From f7417377e5921c73c66686241af490af5555887d Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 21:52:47 -0600 Subject: [PATCH 166/282] Mactched format https://github.com/acemod/ACE3/pull/9728#discussion_r1454926681 --- addons/frag/initSettings.inc.sqf | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/addons/frag/initSettings.inc.sqf b/addons/frag/initSettings.inc.sqf index 25a2fc55c09..6feb0c4dc9b 100644 --- a/addons/frag/initSettings.inc.sqf +++ b/addons/frag/initSettings.inc.sqf @@ -1,7 +1,8 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; [ - QGVAR(enabled), "CHECKBOX", + QGVAR(enabled), + "CHECKBOX", [LSTRING(EnableFrag), LSTRING(EnableFrag_Desc)], [_category, LSTRING(Frag)], true, @@ -9,7 +10,8 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; ] call CBA_fnc_addSetting; [ - QGVAR(spallEnabled), "CHECKBOX", + QGVAR(spallEnabled), + "CHECKBOX", [LSTRING(EnableSpall), LSTRING(EnableSpall_Desc)], [_category, LSTRING(Spall)], false, @@ -17,7 +19,8 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; ] call CBA_fnc_addSetting; [ - QGVAR(reflectionsEnabled), "CHECKBOX", + QGVAR(reflectionsEnabled), + "CHECKBOX", [LSTRING(EnableReflections), LSTRING(EnableReflections_Desc)], [_category, LSTRING(Reflections)], false, @@ -34,7 +37,8 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; ] call CBA_fnc_addSetting; [ - QGVAR(atLeastOne), "CHECKBOX", + QGVAR(atLeastOne), + "CHECKBOX", [LSTRING(MinFrag), LSTRING(MinFrag_Desc)], [_category, LSTRING(Frag)], false, @@ -42,7 +46,8 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; ] call CBA_fnc_addSetting; [ - QGVAR(blackList), "EDITBOX", + QGVAR(blackList), + "EDITBOX", [LSTRING(DefBlackList), LSTRING(DefBlackList_Desc)], [_category, LSTRING(Frag)], QUOTE(['B_556x45_Ball']), @@ -52,7 +57,8 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; ] call CBA_fnc_addSetting; [ - QGVAR(spallIntensity), "SLIDER", + QGVAR(spallIntensity), + "SLIDER", [LSTRING(SpallIntensity), LSTRING(SpallIntensity_Desc)], [_category, LSTRING(Spall)], [0.1, 2, 1, 1], From a4f2ad45d8a95973fbbc65a1d38f9f2dc57b44f6 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 21:53:20 -0600 Subject: [PATCH 167/282] Updated debug settings --- addons/frag/initSettingsDebug.inc.sqf | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/addons/frag/initSettingsDebug.inc.sqf b/addons/frag/initSettingsDebug.inc.sqf index e775a6d9e60..4f2e0dce962 100644 --- a/addons/frag/initSettingsDebug.inc.sqf +++ b/addons/frag/initSettingsDebug.inc.sqf @@ -1,14 +1,16 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; [ - QGVAR(debugOptions), "CHECKBOX", + QGVAR(debugOptions), + "CHECKBOX", [LSTRING(EnableDebugTrace), LSTRING(EnableDebugTrace_Desc)], [_category, LSTRING(Debug)], true ] call CBA_fnc_addSetting; [ - QGVAR(dbgSphere), "CHECKBOX", + QGVAR(dbgSphere), + "CHECKBOX", [LSTRING(HitSphereEnable), LSTRING(HitSphereEnable_Desc)], [_category, LSTRING(Debug)], false, @@ -18,7 +20,8 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; ] call CBA_fnc_addSetting; [ - QGVAR(drawHitBox),"CHECKBOX", + QGVAR(drawHitBox), + "CHECKBOX", [LSTRING(DrawHitBox), LSTRING(DrawHitBox_Desc)], [_category, LSTRING(Debug)], true From 59bf6e3b9112698d51d4f56e5efaf0b206769361 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jan 2024 23:13:31 -0600 Subject: [PATCH 168/282] Shot parent possible fix #1 --- addons/frag/XEH_postInit.sqf | 6 ++++++ addons/frag/functions/fnc_initRound.sqf | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index 6209f17e0e6..5e2ac8aac02 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -6,6 +6,12 @@ if (isServer) then { call FUNC(initBlackList); call FUNC(initMaterialCache); + [ + QEGVAR(common,setShotParents), + { + (_this#0) setVariable [QGVAR(shotParent), [_this#1, _this#2]]; + } + ] call CBA_fnc_addEventHandler; }; #ifdef DEBUG_MODE_DRAW diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index 51c4920533d..b37333cd64d 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -31,7 +31,7 @@ if (GVAR(enabled) && {_ammo call FUNC(shouldFrag)}) then { "Explode", { params ["_projectile", "_posASL", "_velocity"]; - private _shotParents = getShotParents _projectile; + private _shotParents = _projectile getVariable [QGVAR(shotParent), getShotParents _projectile]; private _ammo = typeOf _projectile; // wait for frag damage to kill units before spawning fragments [ From 722e86a2008bc18ea2082cb75cb7e15a889c6445 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 18 Jan 2024 02:54:19 -0600 Subject: [PATCH 169/282] Removed extra text from CfgAmmoFragParameters --- addons/frag/CfgAmmoFragParameters.hpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/addons/frag/CfgAmmoFragParameters.hpp b/addons/frag/CfgAmmoFragParameters.hpp index 11285095955..8eee5e1dc7a 100644 --- a/addons/frag/CfgAmmoFragParameters.hpp +++ b/addons/frag/CfgAmmoFragParameters.hpp @@ -6,11 +6,6 @@ class B_20mm: BulletBase { // Used in Weisel/AWC Nyx, which makes it a Rheinmetall Mk 20 Rh-202 // http://www.navweaps.com/Weapons/WNGER_20mm-65_mk20.php // total mass of 134g probably not enough to do anything - /*GVAR(fragCount) = 20; - GVAR(metal) = ; - GVAR(charge) = ; - GVAR(gurney_c) = ; - GVAR(gurney_k) = "1/2";*/ GVAR(skip) = 1; }; class B_30mm_HE: B_19mm_HE { From 4ebbc289483f874bfd26dfa7657913ea6a073c1f Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 18 Jan 2024 02:59:08 -0600 Subject: [PATCH 170/282] Makes sure spall power square root is positive and also we don't produce fragments when for some reason the round accelerates. --- addons/frag/functions/fnc_doSpall.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index 4f86f801af6..d2ac3e019a1 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -52,7 +52,7 @@ private _vel = if (alive _projectile) then { [0, 0, 0]; }; -private _velocityChange = vectorMagnitude _lastVelocity - vectorMagnitude _vel; +private _velocityChange = 0 max (vectorMagnitude _lastVelocity - vectorMagnitude _vel); /* * This is all fudge factor since real spalling is too complex for calculation. * There are two terms. The first is from round impact, taking a quasi scale From 8b3826a78cd55d2bb06e6854394c6d2a67a2fe02 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 18 Jan 2024 15:10:31 -0600 Subject: [PATCH 171/282] white space for clarity Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_dev_clearTraces.sqf | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/frag/functions/fnc_dev_clearTraces.sqf b/addons/frag/functions/fnc_dev_clearTraces.sqf index 07cec693d58..d0579493310 100644 --- a/addons/frag/functions/fnc_dev_clearTraces.sqf +++ b/addons/frag/functions/fnc_dev_clearTraces.sqf @@ -18,6 +18,7 @@ { deleteVehicle _x; } forEach GVAR(dev_eventSpheres); + GVAR(dev_eventSpheres) = []; GVAR(dev_trackLines) = createHashMap; From 78a15b1d5c02ae3297db71777aa0ee1c48da14d7 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 18 Jan 2024 15:13:36 -0600 Subject: [PATCH 172/282] Optimize dev_hitbox deleting Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_dev_drawTrace.sqf | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/addons/frag/functions/fnc_dev_drawTrace.sqf b/addons/frag/functions/fnc_dev_drawTrace.sqf index 7c4cb40189d..b8de5d6790c 100644 --- a/addons/frag/functions/fnc_dev_drawTrace.sqf +++ b/addons/frag/functions/fnc_dev_drawTrace.sqf @@ -27,11 +27,10 @@ if (!GVAR(debugOptions)) exitWith {}; } forEach GVAR(dev_trackLines); if (GVAR(drawHitBox)) then { - private _deleteArr = []; { _y params ["_object", "_boxPoints", "_color"]; if (!alive _object) then { - _deleteArr pushBack _x; + GVAR(dev_hitBoxes) deleteAt _x; continue; }; @@ -40,10 +39,5 @@ if (GVAR(drawHitBox)) then { drawLine3D [_object modelToWorld (_boxPoints#(_x#_i)), _object modelToWorld (_boxPoints#(_x#(_i-1))), _color]; }; } forEach HITBOX_DRAW_PATH; - } forEach GVAR(dev_hitBoxes); - - { - GVAR(dev_hitBoxes) deleteAt _x; - } forEach _deleteArr; }; From 5f1cf0b4b620917d17b280807136cab69bf4ff12 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 18 Jan 2024 16:00:15 -0600 Subject: [PATCH 173/282] saving people from their own bad testing setup --- addons/frag/XEH_postInit.sqf | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index 6209f17e0e6..ed94bac6d97 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -9,6 +9,9 @@ }; #ifdef DEBUG_MODE_DRAW + if (isServer) then { + [QGVAR(dev_clearTraces),LINKFUNC(dev_clearTraces)] call CBA_fnc_addEventHandler; + }; if (hasInterface) then { GVAR(dev_drawPFEH) = [ LINKFUNC(dev_drawTrace), @@ -24,7 +27,7 @@ "Reset ACE Frag traces", "", { - remoteExecCall [QFUNC(dev_clearTraces), 2]; + [QGVAR(dev_clearTraces), []] call CBA_fnc_serverEvent; }, {true} ] call EFUNC(interact_menu,createAction); From f3788afc89d45441fd487d0a929a40ca685de478 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 18 Jan 2024 16:00:42 -0600 Subject: [PATCH 174/282] Since the functions always exist, I guess these variables should too --- addons/frag/XEH_preInit.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/XEH_preInit.sqf b/addons/frag/XEH_preInit.sqf index daf20e0f628..edaf0777b98 100644 --- a/addons/frag/XEH_preInit.sqf +++ b/addons/frag/XEH_preInit.sqf @@ -17,11 +17,11 @@ GVAR(lastFragTime) = -2; #include "initSettings.inc.sqf" -#ifdef DEBUG_MODE_DRAW GVAR(dev_trackLines) = createHashMap; GVAR(dev_hitBoxes) = createHashMap; GVAR(dev_eventSpheres) = []; GVAR(dev_drawPFEH) = -1; +#ifdef DEBUG_MODE_DRAW #include "initSettingsDebug.inc.sqf" #endif From a3efede64f6d23027161462de8b8596fe544d022 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 18 Jan 2024 16:01:11 -0600 Subject: [PATCH 175/282] Fixe bad search function --- addons/frag/functions/fnc_dev_debugAmmo.sqf | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index 7bfb4fed12f..c680d51017e 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -40,17 +40,19 @@ if (_onlyShotAmmoTypes) then { ]; if (_ammo isEqualTo "" || {_ammo in _allAmmoConfigs}) exitWith {}; _allAmmoConfigs pushBack _ammo; - private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; - private _subMunition = toLowerANSI getText (_ammoConfig >> "submunitionAmmo"); - if (_subMunition isNotEqualTo "") then { - _subMunition = getArray (_ammoConfig >> "submunitionAmmo"); + private _submunitionConfig = configFile >> "CfgAmmo" >> _ammo >> "submunitionAmmo"; + if (isArray _submunitionConfig) then { + private _subMunition = getArray _submunitionConfig; for "_i" from 0 to count _subMunition - 1 do { if (_i mod 2 == 0) then { [toLowerANSI (_subMunition#_i)] call _configSearchFunc; }; }; } else { - [toLowerANSI _subMunition] call _configSearchFunc; + private _subMunition = getText _submunitionConfig; + if (_subMunition isNotEqualTo "") then { + [toLowerANSI _subMunition] call _configSearchFunc; + }; }; }; private _allMagazineConfigs = configProperties [configFile >> "CfgMagazines", "isClass _x", true]; @@ -66,7 +68,7 @@ private _processedCfgAmmos = []; private _printCount = 0; { // Begin forEach to check each ammo type private _ammo = _x; - if (_ammo isNotEqualTo "" && {!(_ammo in _processedCfgAmmos)}) then { + if (_ammo isNotEqualTo "") then { _processedCfgAmmos pushBack _ammo; private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; From 863692625dd7fefc80051ffcbdbc6b3e9eb67ce0 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 18 Jan 2024 18:21:39 -0600 Subject: [PATCH 176/282] optimization, see https://github.com/acemod/ACE3/pull/9728#discussion_r1458112339 --- addons/frag/functions/fnc_doFragTargeted.sqf | 22 ++++++++------------ 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index 9532b908f89..09336623d7d 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -50,24 +50,20 @@ if (_objects isEqualTo []) exitWith { }; // grab crews and add them in so that targets stay approx. sorted by distance +private _targets = []; { - private _crew = crew _x; - if (_crew isNotEqualTo []) then { - private _arr = [_x]; - { - _arr pushBackUnique _x; - } forEach _crew; - - _objects set [_forEachIndex, _arr]; - }; + private _crew = crew _x; + _crew pushBackUnique _x; + _targets append _crew; + } forEach _objects; -_objects = flatten _objects; -TRACE_3("Targets found",_posASL,_fragRange,count _objects); + +TRACE_3("Targets found",_posASL,_fragRange,count _targets); // limit number of fragments per direction (2D) to 10 using _fragArcs private _fragArcs = createHashMap; private _totalFragCount = 0; -{ // Begin of forEach iterating on _objects +{ // Begin of forEach iterating on _targets if (!alive _x) then { continue; }; @@ -168,7 +164,7 @@ private _totalFragCount = 0; TRACE_2("maxFrags", _totalFragCount, _maxFrags); break; }; -} forEach _objects; +} forEach _targets; #ifdef DEBUG_MODE_FULL systemChat ("fragCount cnt: " + str _totalFragCount); From 00dc4193ad666bcfde69411d619b479a75445c0f Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 18 Jan 2024 18:22:17 -0600 Subject: [PATCH 177/282] changed SPG-9 Fragments --- addons/frag/CfgAmmoFragParameters.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/CfgAmmoFragParameters.hpp b/addons/frag/CfgAmmoFragParameters.hpp index 8eee5e1dc7a..906c51a1e91 100644 --- a/addons/frag/CfgAmmoFragParameters.hpp +++ b/addons/frag/CfgAmmoFragParameters.hpp @@ -396,7 +396,7 @@ class M_SPG9_HE: M_SPG9_HEAT { GVAR(charge) = 655; GVAR(gurney_c) = 2800; GVAR(gurney_k) = "1/2"; - GVAR(classes)[] = {QGVAR(small), QGVAR(tiny), QGVAR(small), QGVAR(medium_HD)}; + GVAR(classes)[] = {QGVAR(small), QGVAR(tiny), QGVAR(medium), QGVAR(medium)}; }; From 2d9828de915e0ef803ddf2b874fb759946c6d915 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 18 Jan 2024 19:16:39 -0600 Subject: [PATCH 178/282] removed unneeded toLower --- addons/frag/functions/fnc_dev_fragCalcDump.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf index 58429f33f07..148fed8b66c 100644 --- a/addons/frag/functions/fnc_dev_fragCalcDump.sqf +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -26,7 +26,7 @@ private _nPrinted = 0; diag_log text "//****************** fragCalcDump Beg ******************//"; { // Begin _allAmmoConfigs forEach - private _ammo = toLowerANSI configName _x; + private _ammo = configName _x; if (_ammo isEqualTo "" || {_ammo in _processedCfgAmmos} ) then { continue From 2e6186c09bfc1c25aafe69bbba31ae90a2e4f9ea Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Fri, 19 Jan 2024 13:32:22 -0600 Subject: [PATCH 179/282] Changed case output to match config --- addons/frag/functions/fnc_dev_debugAmmo.sqf | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index c680d51017e..35eb2eed70b 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -40,25 +40,27 @@ if (_onlyShotAmmoTypes) then { ]; if (_ammo isEqualTo "" || {_ammo in _allAmmoConfigs}) exitWith {}; _allAmmoConfigs pushBack _ammo; - private _submunitionConfig = configFile >> "CfgAmmo" >> _ammo >> "submunitionAmmo"; + private _cfgAmmoRoot = configFile >> "CfgAmmo"; + private _submunitionConfig = _cfgAmmoRoot >> _ammo >> "submunitionAmmo"; if (isArray _submunitionConfig) then { private _subMunition = getArray _submunitionConfig; for "_i" from 0 to count _subMunition - 1 do { if (_i mod 2 == 0) then { - [toLowerANSI (_subMunition#_i)] call _configSearchFunc; + [configName (_cfgAmmoRoot >> (_subMunition#_i))] call _configSearchFunc; }; }; } else { private _subMunition = getText _submunitionConfig; if (_subMunition isNotEqualTo "") then { - [toLowerANSI _subMunition] call _configSearchFunc; + [configName (_cfgAmmoRoot >> _subMunition)] call _configSearchFunc; }; }; }; private _allMagazineConfigs = configProperties [configFile >> "CfgMagazines", "isClass _x", true]; - + private _cfgAmmoCfgPath = configFile >> "CfgAmmo"; { - [toLowerANSI getText (_x >> "ammo")] call _configSearchFunc; + private _magAmmo = getText (_x >> "ammo"); + [configName (_cfgAmmoCfgPath >> _magAmmo)] call _configSearchFunc; } forEach _allMagazineConfigs; } else { _allAmmoConfigs = configProperties [configFile >> "CfgAmmo", "isClass _x && !('ace_frag' in configName _x)", true] apply {configName _x}; From 35400620c7e7b35b495403028e49d95c2fa097bc Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sun, 21 Jan 2024 17:08:48 -0600 Subject: [PATCH 180/282] Increased relative chance to hit torso/pelvis when fragemnt should hit. --- addons/frag/script_component.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index d35293e34cd..0b12094c373 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -23,8 +23,7 @@ #define ACE_FRAG_SPALL_HOLDOFF 0.25 #define ACE_FRAG_COUNT_MIN 5 #define ACE_FRAG_COUNT_MAX 50 -#define ACE_FRAG_HITPOINTS ["spine1","spine2","spine3","head","leftarm","leftarmroll","leftforearm","rightarm","rightarmroll","rightforearm","pelvis","leftupleg","leftuplegroll","leftlegroll","leftfoot","rightupleg","rightuplegroll","rightleg","rightlegroll","rightfoot"] -#define ACE_FRAG_HITPOINTS_WEIGHTS +#define ACE_FRAG_HITPOINTS ["spine1", "spine1", "spine1", "spine2", "spine2", "spine2", "spine3", "spine3", "spine3", "pelvis", "pelvis", "pelvis", "head", "leftarm", "leftarmroll", "leftforearm", "rightarm", "rightarmroll", "rightforearm", "leftupleg", "leftuplegroll", "leftlegroll", "leftfoot", "rightupleg", "rightuplegroll", "rightleg", "rightlegroll", "rightfoot", "neck"] // sqrt(2)/50 #define ACE_FRAG_ROUND_COEF 0.02828427 // half of gravity approx 9.81/2 From fd6b9bcee1ecfb62e121f1c9a34539aa48d90ed3 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sun, 21 Jan 2024 17:08:59 -0600 Subject: [PATCH 181/282] Removed double space --- addons/frag/functions/fnc_doFragTargeted.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index 09336623d7d..e6e4b1888d1 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -52,7 +52,7 @@ if (_objects isEqualTo []) exitWith { // grab crews and add them in so that targets stay approx. sorted by distance private _targets = []; { - private _crew = crew _x; + private _crew = crew _x; _crew pushBackUnique _x; _targets append _crew; From 07f055e16dd5e4adc122d167aa103feb111c523c Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 8 Feb 2024 17:10:04 -0600 Subject: [PATCH 182/282] updated some round types --- addons/frag/CfgAmmoFragParameters.hpp | 51 ++++++++++++++++++++------- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/addons/frag/CfgAmmoFragParameters.hpp b/addons/frag/CfgAmmoFragParameters.hpp index 906c51a1e91..0890acdf11f 100644 --- a/addons/frag/CfgAmmoFragParameters.hpp +++ b/addons/frag/CfgAmmoFragParameters.hpp @@ -29,8 +29,7 @@ class B_30mm_MP: B_30mm_HE { GVAR(gurney_c) = 2600; GVAR(gurney_k) = "1/2"; }; -class Gatling_30mm_HE_Plane_CAS_01_F; -class Cannon_30mm_HE_Plane_CAS_02_F: Gatling_30mm_HE_Plane_CAS_01_F { +class Gatling_30mm_HE_Plane_CAS_01_F: BulletBase { GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(tiny), QGVAR(small)}; GVAR(fragCount) = 100; @@ -39,6 +38,7 @@ class Cannon_30mm_HE_Plane_CAS_02_F: Gatling_30mm_HE_Plane_CAS_01_F { GVAR(gurney_c) = 2600; // guessed GVAR(gurney_k) = "1/2"; }; + class B_40mm_GPR: B_30mm_HE { // Based on noted 40mm Autocannons, base ROF, and ammo names, looks to be a CTAS40, specifically GPR-PD-T // https://www.cta-international.com/ammunition/ @@ -146,9 +146,6 @@ class Mo_cluster_Bomb_03_F: Mo_cluster_Bomb_01_F { // idk, @lambda.tiger on the // ~~~~ Grenades: class Grenade; -class ACE_FlashlightProxy_White: Grenade { - GVAR(skip) = 1; -}; class GrenadeHand: Grenade { ACE_FRAG_ADD_EH_BASE; GVAR(skip) = 0; @@ -175,19 +172,27 @@ class SmokeShell: GrenadeHand { class G_40mm_HE: GrenadeBase { class EventHandlers: EventHandlers {}; // Source: http://www.inetres.com/gp/military/infantry/grenade/40mm_ammo.html#M441 - GVAR(skip) = 1; + GVAR(skip) = 0; GVAR(force) = 0; - GVAR(classes)[] = {QGVAR(small)}; - GVAR(fragCount) = 800; // guess based on probability hit of 1% + GVAR(classes)[] = {QGVAR(small), QGVAR(tiny), QGVAR(small)}; + GVAR(fragCount) = 600; // guess based on probability hit of 1% GVAR(metal) = 200; GVAR(charge) = 32; GVAR(gurney_c) = 2700; GVAR(gurney_k) = "3/5"; // interior fragmenter/charge is a sphere }; +class G_20mm_HE: G_40mm_HE { + GVAR(classes)[] = {QGVAR(tiny)}; + GVAR(fragCount) = 200; // Halved size & dimensions from 40mm HE + GVAR(metal) = 50; + GVAR(charge) = 8; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "3/5"; // interior fragmenter/charge is a sphere +}; class G_40mm_HEDP: G_40mm_HE { class EventHandlers: EventHandlers {}; // Source: http://www.inetres.com/gp/military/infantry/grenade/40mm_ammo.html#M433 - GVAR(classes)[] = {QGVAR(small_HD)}; + GVAR(classes)[] = {QGVAR(tiny), QGVAR(small), QGVAR(small_HD)}; GVAR(fragCount) = 270; // seems to have greater framentation ability, but lower range per source GVAR(metal) = 200; GVAR(charge) = 45; @@ -456,13 +461,22 @@ class M_AT: M_PG_AT { // DAR (Hydra 70) M151 warhead class Missile_AGM_02_F: MissileBase { // Source: http://fas.org/man/dod-101/sys/smart/agm-65.htm GVAR(skip) = 0; - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 1600; // guesstimate / provides ~112 m frag range (1% chance to hit) + GVAR(fragCount) = 1600; + GVAR(metal) = 56250; + GVAR(charge) = 39000; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/2"; +}; +class Missile_AGM_01_F: Missile_AGM_02_F { // Kh-25MTP + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(fragCount) = 1600; GVAR(metal) = 56250; GVAR(charge) = 39000; GVAR(gurney_c) = 2700; GVAR(gurney_k) = "1/2"; + }; class Rocket_04_HE_F: MissileBase { // Shrieker (Hydra 70) GVAR(skip) = 0; @@ -473,10 +487,19 @@ class Rocket_04_HE_F: MissileBase { // Shrieker (Hydra 70) GVAR(gurney_c) = 2700; GVAR(gurney_k) = "1/2"; }; +class Rocket_03_HE_F: Rocket_04_HE_F { // S-8D makes the most sense + GVAR(fragCount) = 600; // Thermobaric rounds usually have fewer fragments + GVAR(metal) = 1300; + GVAR(charge) = 2500; + GVAR(gurney_c) = 2300; +}; +class Rocket_04_AP_F: Rocket_04_HE_F { + GVAR(skip) = 1; +}; class M_Scalpel_AT: MissileBase { // 9K121 Vikhr GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 800; // guesstimate based on frag jacket, provides ~80 m frag range (1% chance to hit) + GVAR(fragCount) = 800; // guesstimate, provides ~80 m frag range (1% chance to hit) GVAR(metal) = 10000; GVAR(charge) = 3000; GVAR(gurney_c) = 2700; @@ -664,6 +687,10 @@ class ammo_Penetrator_Base: ShellBase { }; // ~~~~ Special +class IRStrobeBase: GrenadeCore { + GVAR(skip) = 1; +}; + class Default; class Laserbeam: Default { GVAR(skip) = 1; From f63b4088eb923374f07eaf1c72d0a7e92a64c67a Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 8 Feb 2024 17:11:36 -0600 Subject: [PATCH 183/282] Added commented 2.18 commands and updated script component --- addons/frag/functions/fnc_doFrag.sqf | 8 ++++---- addons/frag/functions/fnc_doFragRandom.sqf | 6 +----- addons/frag/functions/fnc_doSpall.sqf | 2 +- addons/frag/script_component.hpp | 22 +++++++++++++++++----- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 7a42b23ce85..0915111b98a 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -38,13 +38,13 @@ private _timeSinceLastFrag = CBA_missionTime - GVAR(lastFragTime); if (_timeSinceLastFrag < ACE_FRAG_HOLDOFF || {_posASL isEqualTo [0, 0, 0] || _ammo isEqualTo ""}) exitWith { TRACE_3("timeExit",_timeSinceLastFrag,CBA_missionTime,GVAR(lastFragTime)); }; -private _maxFragCount = round linearConversion [0.1, 1.5, _timeSinceLastFrag, ACE_FRAG_COUNT_MIN, ACE_FRAG_COUNT_MAX, true]; +private _maxFragCount = round linearConversion [ACE_FRAG_COUNT_MIN_TIME, ACE_FRAG_COUNT_MAX_TIME, _timeSinceLastFrag, ACE_FRAG_COUNT_MIN, ACE_FRAG_COUNT_MAX, true]; TRACE_3("willFrag",_timeSinceLastFrag,CBA_missionTime,_maxFragCount); private _ammoArr = [_ammo] call FUNC(getFragInfo); _ammoArr params ["_fragRange", "_fragVel", "_fragTypes", "_modFragCount"]; // For low frag rounds limit the # of frags created -if (_modFragCount < 10) then { +if (_modFragCount < ACE_FRAG_LOW_FRAG_MOD_COUNT) then { _maxFragCount = _modFragCount * ACE_FRAG_LOW_FRAG_COEFF; GVAR(lastFragTime) = CBA_missionTime - ACE_FRAG_LOW_FRAG_HOLDOFF_REDUCTION; } else { @@ -53,10 +53,10 @@ if (_modFragCount < 10) then { // Offset for ground clearance private _heightATL = (ASLToATL _posASL)#2; if (_heightATL < ACE_FRAG_MIN_GROUND_OFFSET) then { - _posASL = _posASL vectorAdd [0, 0, ACE_FRAG_MIN_GROUND_OFFSET]; + _posASL = _posASL vectorAdd [0, 0, ACE_FRAG_MIN_GROUND_OFFSET - (0 min _heightATL)]; }; -TRACE_3("fnc_doFragTargeted IF", _fragRange, _timeSinceLastFrag, GVAR(fragSimComplexity)); +TRACE_3("fnc_doFragTargeted IF",_fragRange,_timeSinceLastFrag,GVAR(fragSimComplexity)); if (GVAR(fragSimComplexity) != 1 && _fragRange > 3) then { _maxFragCount = _maxFragCount - ([_posASL, _fragVel, _fragRange, _maxFragCount, _fragTypes, _modFragCount, _shotParents] call FUNC(doFragTargeted)); }; diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index 47384fe14d8..6e6f8ecf51c 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -37,11 +37,7 @@ private _hMode = switch (true) do { default {"_mid"}; }; -private _type = if (_fragType isNotEqualTo [] && {"ace_frag_tiny" isEqualTo (_fragType#0)}) then { - QGVAR(def_tiny_) -} else { - QGVAR(def_small_) -}; +private _type = [QGVAR(def_small_), QGVAR(def_tiny_)] select (_fragType isNotEqualTo [] && {"ace_frag_tiny" isEqualTo (_fragType#0)}); _maxFragCount = switch (true) do { case (_maxFragCount <= 5): {"5"}; diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index d2ac3e019a1..d4ef2526516 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -129,7 +129,7 @@ private _spallSpawner = createVehicle [ "CAN_COLLIDE" ]; _spallSpawner setVectorDirandUp [_lastVelocityUnit, _vectorUp]; -_spallSpawner setVelocity (_lastVelocityUnit vectorMultiply (_velocityChange/ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF)); +_spallSpawner setVelocity (_lastVelocityUnit vectorMultiply (_velocityChange * ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF)); _spallSpawner setShotParents _shotParents; #ifdef DEBUG_MODE_FULL diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index 0b12094c373..d32af33ede1 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -3,7 +3,7 @@ #include "\z\ace\addons\main\script_mod.hpp" // #define LOG_FRAG_INFO -// #define DEBUG_MODE_FULL +#define DEBUG_MODE_FULL // #define DEBUG_MODE_DRAW // #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS @@ -18,19 +18,31 @@ #include "\z\ace\addons\main\script_macros.hpp" +// Mimimum hold-off time between frag events globally or per vehicle #define ACE_FRAG_HOLDOFF 0.25 #define ACE_FRAG_HOLDOFF_VEHICLE 1 -#define ACE_FRAG_SPALL_HOLDOFF 0.25 +// Scaling for the min/max # of fragments since last frag event +#define ACE_FRAG_COUNT_MIN_TIME 0.1 #define ACE_FRAG_COUNT_MIN 5 +#define ACE_FRAG_COUNT_MAX_TIME 1 #define ACE_FRAG_COUNT_MAX 50 +// Default hitpoint targets #define ACE_FRAG_HITPOINTS ["spine1", "spine1", "spine1", "spine2", "spine2", "spine2", "spine3", "spine3", "spine3", "pelvis", "pelvis", "pelvis", "head", "leftarm", "leftarmroll", "leftforearm", "rightarm", "rightarmroll", "rightforearm", "leftupleg", "leftuplegroll", "leftlegroll", "leftfoot", "rightupleg", "rightuplegroll", "rightleg", "rightlegroll", "rightfoot", "neck"] -// sqrt(2)/50 -#define ACE_FRAG_ROUND_COEF 0.02828427 // half of gravity approx 9.81/2 #define ACE_FRAG_HALF_GRAVITY_APPROX 4.905 // Lowest chance to hit of 0.5% #define ACE_FRAG_MIN_FRAG_HIT_CHANCE 0.005 #define ACE_FRAG_MIN_GROUND_OFFSET 0.25 +// Make frag hold-off time shortger for low frag +// value of 150/4/pi ~= 11.93662 +#define ACE_FRAG_LOW_FRAG_MOD_COUNT 11.93662 #define ACE_FRAG_LOW_FRAG_COEFF 4 #define ACE_FRAG_LOW_FRAG_HOLDOFF_REDUCTION 4 -#define ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF 2 +// Max frag distance - correlates to a a fragCount of 20k & hit chance of 0.5% +#define ACE_FRAG_MAX_FRAG_RANGE 565 + +// Spall values +#define ACE_FRAG_SPALL_HOLDOFF 0.25 +#define ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF 0.5 +// sqrt(2)/50 +#define ACE_FRAG_ROUND_COEF 0.02828427 \ No newline at end of file From 60543a5f5944e78b2166eed4025cc3cafe5436b0 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 8 Feb 2024 17:11:57 -0600 Subject: [PATCH 184/282] added print incomplete only option to fnc_debugAmmo --- addons/frag/functions/fnc_dev_debugAmmo.sqf | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index 35eb2eed70b..80fa3687dbc 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -7,9 +7,10 @@ * * Arguments: * 0: Log ammo types that wouldn't normally frag. (Default: false) - * 1: Only export ammo classes of classes referenced in CfgMagazines and their + * 1: Only print ammo without ACE_frag entries, inherited or otherwise. (Default: true) + * 2: Only export ammo classes of classes referenced in CfgMagazines and their * submunitions. (Default: false) - * 2: Force a CSV format on debug print. (Default: false) + * 3: Force a CSV format on debug print. (Default: false) * * Return Value: * None @@ -22,13 +23,14 @@ params [ ["_logAll", false, [false]], + ["_printOnlyIncomplete", true, [true]], ["_onlyShotAmmoTypes", false, [false]], ["_csvFormat", false, [false]] ]; diag_log text format ["~~~~~~~~~~~~~Start [%1]~~~~~~~~~~~~~", _this]; if (_csvFormat) then { - diag_log text format ["ammo,gurney_c,gurney_m,gurney_k,gurney_gC,fragTypes,fragCount,Inheritance"]; + diag_log text format ["ammo,gurney_c,gurney_m,gurney_k,gurney_gC,skip,fragCount,Inheritance"]; }; // Gather all configs, either those that could be created from firing or all classes @@ -79,6 +81,7 @@ private _printCount = 0; if (_shoulFrag || _logAll) then { private _warn = false; + private _skip = getNumber (_ammoConfig >> QGVAR(skip)); private _fragTypes = getArray (_ammoConfig >> QGVAR(CLASSES)); if (_fragTypes isEqualTo []) then {_warn = true;}; private _c = getNumber(_ammoConfig >> QGVAR(CHARGE)); @@ -92,13 +95,13 @@ private _printCount = 0; private _fragCount = getNumber (_ammoConfig >> QGVAR(fragCount)); if (_fragCount == 0) then {_fragCount = 200; _warn = true;}; - if (_warn) then { + if (!_printOnlyIncomplete || {_warn && _skip isNotEqualTo 0}) then { INC(_printCount); if (_csvFormat) then { - diag_log text format ["%7,%1,%2,%3,%4,%5,%6,%8", _c, _m, _k, _gC, _fragTypes, _fragCount, _ammo, [_ammoConfig, true] call BIS_fnc_returnParents]; + diag_log text format ["%7,%1,%2,%3,%4,%5,%6,%8", _c, _m, _k, _gC, _skip, _fragCount, _ammo, [_ammoConfig, true] call BIS_fnc_returnParents]; } else { diag_log text format ["Ammo [%1] MISSING frag configs:", _ammo]; - diag_log text format [" _c=%1,_m=%2,_k=%3,_gC=%4,_fragTypes=%5,_fragCount=%6", _c, _m, _k, _gC, _fragTypes, _fragCount]; + diag_log text format ["_c=%1,_m=%2,_k=%3,_gC=%4,_skip=%5,_fragCount=%6,_fragTypes=%7", _c, _m, _k, _gC, _skip, _fragCount, _fragTypes]; }; }; }; From 2ad2564a1e4f58668c1485a6f9d4321f20c98c20 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 8 Feb 2024 17:12:11 -0600 Subject: [PATCH 185/282] removed all spaces from macros --- addons/frag/functions/fnc_dev_fired.sqf | 2 +- addons/frag/functions/fnc_doFragTargeted.sqf | 5 ++++- addons/frag/functions/fnc_getFragInfo.sqf | 2 +- addons/frag/functions/fnc_initBlackList.sqf | 8 ++++---- addons/frag/functions/fnc_shouldFrag.sqf | 2 +- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/addons/frag/functions/fnc_dev_fired.sqf b/addons/frag/functions/fnc_dev_fired.sqf index 4ed25573fef..432228a1733 100644 --- a/addons/frag/functions/fnc_dev_fired.sqf +++ b/addons/frag/functions/fnc_dev_fired.sqf @@ -16,6 +16,6 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); [_projectile, true, [side group _unit, side group ACE_player] call BIS_fnc_sideIsFriendly] call FUNC(dev_addRound); diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index e6e4b1888d1..c4da0816869 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -43,6 +43,9 @@ if (_fragTypes isEqualTo []) then { ]; }; +// Post 2.18 change - uncomment line 47, remove line 49, 56-62, 70-72, and change lines 64 & 170 from _targetse to _objects +// private _objects = [ASLToAGL _posASL, _fragRange, _fragRange, 0, false, _fragRange ] nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], false, true, true]; + private _objects = (ASLToATL _posASL) nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], _fragRange]; if (_objects isEqualTo []) exitWith { TRACE_2("No nearby targets",_posASL,_fragRange); @@ -161,7 +164,7 @@ private _totalFragCount = 0; _totalFragCount = _totalFragCount + _fragCount; if (_totalFragCount >= _maxFrags) then { - TRACE_2("maxFrags", _totalFragCount, _maxFrags); + TRACE_2("maxFrags",_totalFragCount,_maxFrags); break; }; } forEach _targets; diff --git a/addons/frag/functions/fnc_getFragInfo.sqf b/addons/frag/functions/fnc_getFragInfo.sqf index d695435f36d..d38f38765e0 100644 --- a/addons/frag/functions/fnc_getFragInfo.sqf +++ b/addons/frag/functions/fnc_getFragInfo.sqf @@ -98,7 +98,7 @@ if (_warn) then { * of spherical fragmentation */ _ammoInfo = [ - sqrt (_fragCount / (4 * pi * ACE_FRAG_MIN_FRAG_HIT_CHANCE)), + ACE_FRAG_MAX_FRAG_RANGE max sqrt (_fragCount / (4 * pi * ACE_FRAG_MIN_FRAG_HIT_CHANCE)), 0.8 * _gurneyConstant * sqrt (_chargeMass / (_metalMass + _chargeMass * _geometryCoefficient)), _fragTypes, _fragCount / 4 / pi diff --git a/addons/frag/functions/fnc_initBlackList.sqf b/addons/frag/functions/fnc_initBlackList.sqf index 5dee461e168..a8263c08e85 100644 --- a/addons/frag/functions/fnc_initBlackList.sqf +++ b/addons/frag/functions/fnc_initBlackList.sqf @@ -15,13 +15,13 @@ * Public: No */ -TRACE_1("Beginning blacklist init", GVAR(blackList)); +TRACE_1("Beginning blacklist init",GVAR(blackList)); // could improve text parsing of CBA setting string private _convArray = parseSimpleArray GVAR(blackList); if (_convArray isEqualTo []) exitWith { - TRACE_1("Empty blacklist", _convArray); + TRACE_1("Empty blacklist",_convArray); }; // Add CBA setting blacklist to blacklist and log errors @@ -29,13 +29,13 @@ private _errors = 0; { private _ammo = _x; if !(_ammo isEqualType "") then { - INFO_1("Improper ammo string at index %1", _forEachIndex); + INFO_1("Improper ammo string at index %1",_forEachIndex); INC(_errors); continue; }; if (!isClass (configFile >> "CfgAmmo" >> _ammo)) then { - INFO_1("Ammo class: %1 does not exist", str _ammo); + INFO_1("Ammo class: %1 does not exist",str _ammo); INC(_errors); continue; }; diff --git a/addons/frag/functions/fnc_shouldFrag.sqf b/addons/frag/functions/fnc_shouldFrag.sqf index 103f7aac755..3af9de5463b 100644 --- a/addons/frag/functions/fnc_shouldFrag.sqf +++ b/addons/frag/functions/fnc_shouldFrag.sqf @@ -33,7 +33,7 @@ private _indirectRange = getNumber (_ammoConfig >> "indirectHitRange"); if (_skip == 1 || (_force == 0 && {_explosive < 0.5 || {_indirectHit < 3 || {_indirectRange < 5 && _indirectHit < _indirectRange}}})) then { - TRACE_5("No frag",_ammo,_skip, _explosive, _indirectRange, _indirectHit); + TRACE_5("No frag",_ammo,_skip,_explosive,_indirectRange,_indirectHit); _shouldFrag = false; }; From a4c88ec713df0303cd8b0142465dc053fc2b3d70 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 8 Feb 2024 17:23:33 -0600 Subject: [PATCH 186/282] removd unneeded define --- addons/frag/functions/fnc_dev_debugAmmo.sqf | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index 80fa3687dbc..32c11c01645 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -1,4 +1,3 @@ -#define DEBUG_MODE_FULL #include "..\script_component.hpp" /* * Author: ACE-Team, Lambda.Tiger From 665707bbdaf32c1024057c739e0aa7b4e1dd1150 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 8 Feb 2024 17:29:03 -0600 Subject: [PATCH 187/282] a Brett (HEMTT) suggested change I miss --- addons/frag/functions/fnc_doFragTargeted.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index c4da0816869..44092ff59ce 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -104,7 +104,7 @@ private _totalFragCount = 0; private _fragCount = if (_fragChance > 1) then { 3 min (floor _fragChance); } else { - [0, 1] select (GVAR(atLeastOne) || {random 1 < _fragChance}); + parseNumber (GVAR(atLeastOne) || {random 1 < _fragChance}); }; if (_fragCount == 0) then { TRACE_2("fragments",_fragChance,_fragCount); From 1da1c6880317c0e981ff68e54f50ef47eed3b2d4 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 14 Feb 2024 16:50:09 -0600 Subject: [PATCH 188/282] Apply suggestions from code review Small formatting changes and small errors Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_dev_addRound.sqf | 6 +++--- addons/frag/functions/fnc_dev_debugAmmo.sqf | 12 ++++++------ addons/frag/functions/fnc_dev_fired.sqf | 2 +- addons/frag/functions/fnc_dev_fragCalcDump.sqf | 8 ++++---- addons/frag/functions/fnc_dev_sphereDraw.sqf | 2 +- addons/frag/functions/fnc_dev_trackHitBox.sqf | 4 ++-- addons/frag/functions/fnc_dev_trackObj.sqf | 15 ++++++++------- addons/frag/functions/fnc_doFrag.sqf | 2 +- addons/frag/functions/fnc_doFragTargeted.sqf | 8 ++++---- addons/frag/functions/fnc_doSpall.sqf | 8 ++++---- addons/frag/functions/fnc_getFragInfo.sqf | 4 ++-- addons/frag/functions/fnc_getMaterialInfo.sqf | 2 +- addons/frag/functions/fnc_initRound.sqf | 2 +- addons/frag/script_component.hpp | 2 +- 14 files changed, 39 insertions(+), 38 deletions(-) diff --git a/addons/frag/functions/fnc_dev_addRound.sqf b/addons/frag/functions/fnc_dev_addRound.sqf index 64d78e2759d..498f6ffad59 100644 --- a/addons/frag/functions/fnc_dev_addRound.sqf +++ b/addons/frag/functions/fnc_dev_addRound.sqf @@ -13,7 +13,7 @@ * true results in blue traces, false in red. * * Return Value: - * None + * Nothing Useful * * Example: * [_projectile, false, false] call ace_frag_dev_addRound; @@ -28,9 +28,9 @@ params [ ]; if (_isSidePlayer) then { - GVAR(dev_trackLines) set [getObjectID _projectile, [[getposATL _projectile], [0, 0, 1, 1]]]; + GVAR(dev_trackLines) set [getObjectID _projectile, [[getPosATL _projectile], [0, 0, 1, 1]]]; } else { - GVAR(dev_trackLines) set [getObjectID _projectile, [[getposATL _projectile], [1, 0, 0, 1]]]; + GVAR(dev_trackLines) set [getObjectID _projectile, [[getPosATL _projectile], [1, 0, 0, 1]]]; }; // event handler to track round and cleanup when round is "dead" diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index 32c11c01645..682301714ef 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -81,20 +81,20 @@ private _printCount = 0; private _warn = false; private _skip = getNumber (_ammoConfig >> QGVAR(skip)); - private _fragTypes = getArray (_ammoConfig >> QGVAR(CLASSES)); + private _fragTypes = getArray (_ammoConfig >> QGVAR(classes)); if (_fragTypes isEqualTo []) then {_warn = true;}; - private _c = getNumber(_ammoConfig >> QGVAR(CHARGE)); + private _c = getNumber (_ammoConfig >> QGVAR(charge)); if (_c == 0) then {_warn = true;}; - private _m = getNumber(_ammoConfig >> QGVAR(METAL)); + private _m = getNumber (_ammoConfig >> QGVAR(metal)); if (_m == 0) then {_warn = true;}; - private _k = getNumber(_ammoConfig >> QGVAR(GURNEY_K)); + private _k = getNumber (_ammoConfig >> QGVAR(gurney_k)); if (_k == 0) then {_warn = true;}; - private _gC = getNumber(_ammoConfig >> QGVAR(GURNEY_C)); + private _gC = getNumber (_ammoConfig >> QGVAR(gurney_c)); if (_gC == 0) then {_warn = true;}; private _fragCount = getNumber (_ammoConfig >> QGVAR(fragCount)); if (_fragCount == 0) then {_fragCount = 200; _warn = true;}; - if (!_printOnlyIncomplete || {_warn && _skip isNotEqualTo 0}) then { + if (!_printOnlyIncomplete || {_warn && _skip != 0}) then { INC(_printCount); if (_csvFormat) then { diag_log text format ["%7,%1,%2,%3,%4,%5,%6,%8", _c, _m, _k, _gC, _skip, _fragCount, _ammo, [_ammoConfig, true] call BIS_fnc_returnParents]; diff --git a/addons/frag/functions/fnc_dev_fired.sqf b/addons/frag/functions/fnc_dev_fired.sqf index 432228a1733..113fb997dff 100644 --- a/addons/frag/functions/fnc_dev_fired.sqf +++ b/addons/frag/functions/fnc_dev_fired.sqf @@ -7,7 +7,7 @@ * Parameters inherited from EFUNC(common,firedEH) * * Return Value: - * None + * Nothing Useful * * Example: * [clientFiredBIS-XEH] call ace_frag_fnc_fired diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf index 148fed8b66c..ded15a6d1cb 100644 --- a/addons/frag/functions/fnc_dev_fragCalcDump.sqf +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -12,7 +12,7 @@ * None * * Example: - * [false, 10] call ace_frag_fnc_fragoCalcDump + * false call ace_frag_fnc_dev_fragCalcDump * * Public: No */ @@ -28,15 +28,15 @@ diag_log text "//****************** fragCalcDump Beg ******************//"; { // Begin _allAmmoConfigs forEach private _ammo = configName _x; - if (_ammo isEqualTo "" || {_ammo in _processedCfgAmmos} ) then { + if (_ammo isEqualTo "" || {_ammo in _processedCfgAmmos}) then { continue }; private _shouldFrag = [_ammo] call FUNC(shouldFrag); - if (_nSkip || _logAll) then { + if (_shouldFrag || _logAll) then { private _fragInfo = [_ammo] call FUNC(getFragInfo); _fragInfo params ["_fragRange", "_fragMaxVelocity", "", "_modifiedFragCount"]; - private _fragCount = 4 * pi* _modifiedFragCount; + private _fragCount = 4 * pi * _modifiedFragCount; private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; private _indirectHitRange = getNumber (_ammoConfig >> "indirectHitRange"); private _indirectHit = getNumber (_ammoConfig >> "indirectHit"); diff --git a/addons/frag/functions/fnc_dev_sphereDraw.sqf b/addons/frag/functions/fnc_dev_sphereDraw.sqf index 31cebab110f..9a8408ff4c5 100644 --- a/addons/frag/functions/fnc_dev_sphereDraw.sqf +++ b/addons/frag/functions/fnc_dev_sphereDraw.sqf @@ -11,7 +11,7 @@ * None * * Example: - * [unit0, player] call ace_frag_fnc_dev_switchUnitHandle; + * [getPosASL player, "blue"] call ace_frag_fnc_dev_sphereDraw; * * Public: No */ diff --git a/addons/frag/functions/fnc_dev_trackHitBox.sqf b/addons/frag/functions/fnc_dev_trackHitBox.sqf index 534bd0944ec..58fa9b60de3 100644 --- a/addons/frag/functions/fnc_dev_trackHitBox.sqf +++ b/addons/frag/functions/fnc_dev_trackHitBox.sqf @@ -48,7 +48,7 @@ private _centerPoint = ASLToAGL getPosASL _object; if (GVAR(dbgSphere) && {_addSphere && {isNull objectParent _object}}) then { private _centerSphere = [getPosASL _object, "yellow"] call FUNC(dev_sphereDraw); - _centerSphere disableCollisionWith vehicle _object; + _centerSphere disableCollisionWith _object; _centerSphere attachTo [_object, _object worldToModel _centerPoint]; }; @@ -66,7 +66,7 @@ private _points = [ [_p7#0, _p1#1, _p7#2] ]; -_color = switch (side _object) do { +private _color = switch (side _object) do { case east: {[1, 0, 0, 1]}; case resistance: {[0, 1, 0, 1]}; default {[0, 0, 1, 1]}; diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index 3e820c81256..d3cbf03c578 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: Lambda.Tiger - * This function adds an object to have it's course tracked (every frame). + * This function adds an object to have its course tracked (every frame). * * Arguments: * 0: Object to draw track OBJECT> @@ -42,21 +42,22 @@ GVAR(dev_trackLines) set [getObjectID _object, [[getPosATL _object], _colorArray [ { if (isGamePaused) exitWith {}; - params ["_params", "_handle"]; - _params params ["_object"]; + params ["_object", "_handle"]; + if (!alive _object) exitWith { [_handle] call CBA_fnc_removePerFrameHandler; }; - private _arr = GVAR(dev_trackLines) getOrDefault [(getObjectID _object), -1]; + + private objectArray = GVAR(dev_trackLines) get (getObjectID _object); - if (_arr isEqualType 0) exitWith { + if (isNil "_objectArray") exitWith { [_handle] call CBA_fnc_removePerFrameHandler; }; - (_arr#0) pushBack getPosATL _object; + (objectArray#0) pushBack getPosATL _object; }, 0, - [_object] + _object ] call CBA_fnc_addPerFrameHandler; // Projectile event handlers that add spheres and points for more accurate round tracking diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 0915111b98a..5b59967b154 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -14,7 +14,7 @@ * None * * Example: - * [_projectile, getPosASL _projectile, velocity _projectile, typeOf _projectile, getShotParents _projectile] call ace_frag_fnc_doFrag; + * [getPosASL _projectile, velocity _projectile, typeOf _projectile, getShotParents _projectile] call ace_frag_fnc_doFrag; * * Public: No */ diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index 44092ff59ce..5c96df56922 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -49,7 +49,7 @@ if (_fragTypes isEqualTo []) then { private _objects = (ASLToATL _posASL) nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], _fragRange]; if (_objects isEqualTo []) exitWith { TRACE_2("No nearby targets",_posASL,_fragRange); - 0; + 0 }; // grab crews and add them in so that targets stay approx. sorted by distance @@ -126,12 +126,12 @@ private _totalFragCount = 0; // target pos for fragment to hit private _targetPos = (velocity _target vectorMultiply _timeOfFlight) vectorAdd [0, 0, ACE_FRAG_HALF_GRAVITY_APPROX * _timeOfFlight ^ 2]; - if _isPerson then { + _targetPos = if (_isPerson) then { private _hitPoint = selectRandom ACE_FRAG_HITPOINTS; private _hitPointPos = _target selectionPosition [_hitPoint, "HitPoints", "AveragePoint"]; - _targetPos = _target modelToWorldWorld _hitPointPos vectorAdd _targetPos; + _target modelToWorldWorld _hitPointPos vectorAdd _targetPos; } else { - _targetPos = _targetPos vectorAdd getPosASL _target vectorAdd [ + _targetPos vectorAdd getPosASL _target vectorAdd [ -0.5 + random 1, -0.5 + random 1, (0.1 + random 0.4) * _height diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index d4ef2526516..4793b2d013b 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -33,11 +33,11 @@ if (CBA_missionTime < GVAR(nextSpallAllowTime)|| _lastPosASL isEqualTo [0,0,0] || {_ammo isEqualTo "" || {!isNull _objectHit && {objectHit isKindOf "CAManBase"}}}) exitWith { - TRACE_4("time/invldHit",CBA_missionTime,GVAR(nextSpallAllowTime),_objectHit,_lastPosASL); + TRACE_4("time/invalidHit",CBA_missionTime,GVAR(nextSpallAllowTime),_objectHit,_lastPosASL); }; private _material = [_surfaceType] call FUNC(getMaterialInfo); -if (_material isEqualTo "ground") then { +if (_material == "ground") then { #ifdef DEBUG_MODE_FULL systemChat "ground spall"; #endif @@ -49,7 +49,7 @@ private _vel = if (alive _projectile) then { _explosive = 0; // didn't explode since it's alive a frame later velocity _projectile } else { - [0, 0, 0]; + [0, 0, 0] }; private _velocityChange = 0 max (vectorMagnitude _lastVelocity - vectorMagnitude _vel); @@ -85,7 +85,7 @@ if GVAR(dbgSphere) then { * impacts. 120 degrees due to 90 degree offset with _lastVelocityUnit into object. */ private _spallPosASL = _lastPosASL vectorAdd _deltaStep; -if (120 > acos ( _lastVelocityUnit vectorDotProduct _surfaceNorm)) then { +if (120 > acos (_lastVelocityUnit vectorDotProduct _surfaceNorm)) then { _spallPosASL = _spallPosASL vectorAdd (_deltaStep vectorMultiply 5); }; private _insideObject = true; diff --git a/addons/frag/functions/fnc_getFragInfo.sqf b/addons/frag/functions/fnc_getFragInfo.sqf index d38f38765e0..8d5470064b1 100644 --- a/addons/frag/functions/fnc_getFragInfo.sqf +++ b/addons/frag/functions/fnc_getFragInfo.sqf @@ -29,8 +29,8 @@ if (!isNil "_ammoInfo") exitWith {_ammoInfo}; private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; private _fragTypes = []; private _warn = false; -if (isArray (_ammoConfig >> QGVAR(CLASSES))) then { - _fragTypes = getArray (_ammoConfig >> QGVAR(CLASSES)); +if (isArray (_ammoConfig >> QGVAR(classes))) then { + _fragTypes = getArray (_ammoConfig >> QGVAR(classes)); } else { _warn = true; }; diff --git a/addons/frag/functions/fnc_getMaterialInfo.sqf b/addons/frag/functions/fnc_getMaterialInfo.sqf index e38144b6e62..a7940d016c3 100644 --- a/addons/frag/functions/fnc_getMaterialInfo.sqf +++ b/addons/frag/functions/fnc_getMaterialInfo.sqf @@ -31,7 +31,7 @@ if (!isNil "_material") exitWith { private _surfaceConfig = configFile >> "CfgSurfaces" >> _surfType; if (isClass _surfaceConfig) then { _material = getText (_surfaceConfig >> "soundEnviron"); - if (_material isEqualTo "" || {_material isEqualTo "empty"}) then { + if (_material == "" || {_material == "empty"}) then { _material = getText (_surfaceConfig >> "soundhit"); }; } else { // Messy way when a surface isn't added to CfgSurfaces diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index b37333cd64d..4d785e2e5fc 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -68,7 +68,7 @@ if (GVAR(spallEnabled) && {_ammo call FUNC(shouldSpall)}) then { ]; }; #ifdef DEBUG_MODE_DRAW -if (GVAR(debugOptions) && (_shouldFrag || _shouldSpall)) then { +if (GVAR(debugOptions) && {_ammo call FUNC(shouldFrag) || {_ammo call FUNC(shouldSpall)}}) then { [_projectile, "red", true] call FUNC(dev_trackObj); }; #endif diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index d32af33ede1..92591eda690 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -3,7 +3,7 @@ #include "\z\ace\addons\main\script_mod.hpp" // #define LOG_FRAG_INFO -#define DEBUG_MODE_FULL +// #define DEBUG_MODE_FULL // #define DEBUG_MODE_DRAW // #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS From fa241cacb5d26e0832c479e29d90aa5da8cf4244 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 14 Feb 2024 17:14:43 -0600 Subject: [PATCH 189/282] Removed doublespace Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_doFrag.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 5b59967b154..a835f080278 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -53,7 +53,7 @@ if (_modFragCount < ACE_FRAG_LOW_FRAG_MOD_COUNT) then { // Offset for ground clearance private _heightATL = (ASLToATL _posASL)#2; if (_heightATL < ACE_FRAG_MIN_GROUND_OFFSET) then { - _posASL = _posASL vectorAdd [0, 0, ACE_FRAG_MIN_GROUND_OFFSET - (0 min _heightATL)]; + _posASL = _posASL vectorAdd [0, 0, ACE_FRAG_MIN_GROUND_OFFSET - (0 min _heightATL)]; }; TRACE_3("fnc_doFragTargeted IF",_fragRange,_timeSinceLastFrag,GVAR(fragSimComplexity)); From 61029ba723d79be2b41123c7246b1f5c8e6f988f Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 14 Feb 2024 17:56:05 -0600 Subject: [PATCH 190/282] Update addons/frag/functions/fnc_dev_addRound.sqf If the round isn't in the hashmap anymore, we have to stop the PFH. Brought code up to same standard as used in FUNC(dev_trackObj). - johnb432 Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_dev_addRound.sqf | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/addons/frag/functions/fnc_dev_addRound.sqf b/addons/frag/functions/fnc_dev_addRound.sqf index 498f6ffad59..a1cc372bb71 100644 --- a/addons/frag/functions/fnc_dev_addRound.sqf +++ b/addons/frag/functions/fnc_dev_addRound.sqf @@ -37,17 +37,22 @@ if (_isSidePlayer) then { [ { if (isGamePaused) exitWith {}; - params ["_params", "_handle"]; - _params params ["_projectile"]; + params ["_projectile", "_handle"]; + if (!alive _projectile) exitWith { [_handle] call CBA_fnc_removePerFrameHandler; }; - private _projectileArray = GVAR(dev_trackLines) getOrDefault [getObjectID _projectile, -1]; - if (_projectileArray isEqualType 0) exitWith {}; + + private _projectileArray = GVAR(dev_trackLines) get (getObjectID _projectile); + + if (isNil "_projectileArray") exitWith { + [_handle] call CBA_fnc_removePerFrameHandler; + }; + (_projectileArray#0) pushBack getPosATL _projectile; }, 0, - [_projectile] + _projectile ] call CBA_fnc_addPerFrameHandler; if (!_addProjectileEventHandlers) exitWith {}; From 4d9f61eeaf30f8641cc0466d6d63b9f868787393 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 14 Feb 2024 18:50:01 -0600 Subject: [PATCH 191/282] Update addons/frag/functions/fnc_dev_drawTrace.sqf Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_dev_drawTrace.sqf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_dev_drawTrace.sqf b/addons/frag/functions/fnc_dev_drawTrace.sqf index b8de5d6790c..3bae4b085ad 100644 --- a/addons/frag/functions/fnc_dev_drawTrace.sqf +++ b/addons/frag/functions/fnc_dev_drawTrace.sqf @@ -4,12 +4,13 @@ * Per frame function to draw all dev traces. * * Arguments: - * none + * None * * Return Value: * None * * Example: + * call ace_frag_fnc_dev_drawTrace; * * Public: No */ From ae116e2577479bba7e3047613b8892b1e14b414b Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 14 Feb 2024 19:55:26 -0600 Subject: [PATCH 192/282] variable name changes --- addons/frag/functions/fnc_dev_debugAmmo.sqf | 18 +++++++++--------- addons/frag/functions/fnc_getFragInfo.sqf | 16 ++++++++-------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index 682301714ef..2c00d98e5de 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -79,25 +79,25 @@ private _printCount = 0; if (_shoulFrag || _logAll) then { - private _warn = false; + private _print = false; private _skip = getNumber (_ammoConfig >> QGVAR(skip)); private _fragTypes = getArray (_ammoConfig >> QGVAR(classes)); - if (_fragTypes isEqualTo []) then {_warn = true;}; + if (_fragTypes isEqualTo []) then {_print = true;}; private _c = getNumber (_ammoConfig >> QGVAR(charge)); - if (_c == 0) then {_warn = true;}; + if (_c == 0) then {_print = true;}; private _m = getNumber (_ammoConfig >> QGVAR(metal)); - if (_m == 0) then {_warn = true;}; + if (_m == 0) then {_print = true;}; private _k = getNumber (_ammoConfig >> QGVAR(gurney_k)); - if (_k == 0) then {_warn = true;}; + if (_k == 0) then {_print = true;}; private _gC = getNumber (_ammoConfig >> QGVAR(gurney_c)); - if (_gC == 0) then {_warn = true;}; + if (_gC == 0) then {_print = true;}; private _fragCount = getNumber (_ammoConfig >> QGVAR(fragCount)); - if (_fragCount == 0) then {_fragCount = 200; _warn = true;}; + if (_fragCount == 0) then {_fragCount = 200; _print = true;}; - if (!_printOnlyIncomplete || {_warn && _skip != 0}) then { + if (!_printOnlyIncomplete || {_print && _skip != 0}) then { INC(_printCount); if (_csvFormat) then { - diag_log text format ["%7,%1,%2,%3,%4,%5,%6,%8", _c, _m, _k, _gC, _skip, _fragCount, _ammo, [_ammoConfig, true] call BIS_fnc_returnParents]; + diag_log text format ["%7,%1,%2,%3,%4,%5,%6,%9,%8", _c, _m, _k, _gC, _skip, _fragCount, _ammo, [_ammoConfig, true] call BIS_fnc_returnParents, _shouldFrag]; } else { diag_log text format ["Ammo [%1] MISSING frag configs:", _ammo]; diag_log text format ["_c=%1,_m=%2,_k=%3,_gC=%4,_skip=%5,_fragCount=%6,_fragTypes=%7", _c, _m, _k, _gC, _skip, _fragCount, _fragTypes]; diff --git a/addons/frag/functions/fnc_getFragInfo.sqf b/addons/frag/functions/fnc_getFragInfo.sqf index 8d5470064b1..3caa5ef918d 100644 --- a/addons/frag/functions/fnc_getFragInfo.sqf +++ b/addons/frag/functions/fnc_getFragInfo.sqf @@ -28,11 +28,11 @@ if (!isNil "_ammoInfo") exitWith {_ammoInfo}; private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; private _fragTypes = []; -private _warn = false; +private _notify = false; if (isArray (_ammoConfig >> QGVAR(classes))) then { _fragTypes = getArray (_ammoConfig >> QGVAR(classes)); } else { - _warn = true; + _notify = true; }; /************ Gurney equation notes *****************//* @@ -58,34 +58,34 @@ if (isArray (_ammoConfig >> QGVAR(classes))) then { private _chargeMass = getNumber (_ammoConfig >> QGVAR(CHARGE)); if (_chargeMass == 0) then { _chargeMass = 1; - _warn = true; + _notify = true; }; private _metalMass = getNumber (_ammoConfig >> QGVAR(METAL)); if (_metalMass == 0) then { _metalMass = 2; - _warn = true; + _notify = true; }; private _geometryCoefficient = getNumber (_ammoConfig >> QGVAR(GURNEY_K)); if (_geometryCoefficient == 0) then { _geometryCoefficient = 0.8; - _warn = true; + _notify = true; }; private _gurneyConstant = getNumber (_ammoConfig >> QGVAR(GURNEY_C)); if (_gurneyConstant == 0) then { _gurneyConstant = 2440; - _warn = true; + _notify = true; }; private _fragCount = getNumber (_ammoConfig >> QGVAR(fragCount)); if (_fragCount == 0) then { _fragCount = 400; - _warn = true; + _notify = true; }; -if (_warn) then { +if (_notify) then { INFO_1("Ammo class %1 lacks proper explosive properties definitions for frag!",_ammo); }; From a976b28c69bec2fea4f2de01027d4868a5a0cc6d Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 14 Feb 2024 19:57:49 -0600 Subject: [PATCH 193/282] magic number clean up and white space --- addons/frag/functions/fnc_dev_trackObj.sqf | 4 ++-- addons/frag/functions/fnc_doFragTargeted.sqf | 20 ++++++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index d3cbf03c578..dc695fbfead 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -18,7 +18,7 @@ */ params [ - "_object", + ["_object", objNull, [objNull]], ["_color", "blue", ["blue"]], ["_isProj", false, [false]] ]; @@ -47,7 +47,7 @@ GVAR(dev_trackLines) set [getObjectID _object, [[getPosATL _object], _colorArray if (!alive _object) exitWith { [_handle] call CBA_fnc_removePerFrameHandler; }; - + private objectArray = GVAR(dev_trackLines) get (getObjectID _object); if (isNil "_objectArray") exitWith { diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index 5c96df56922..f914b644912 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -21,6 +21,9 @@ * * Public: No */ +#define ACE_FRAG_DEFAULT_HEIGHT 0.5 +#define ACE_FRAG_DEFAULT_CROSS_AREA 0.75 +#define ACE_FRAG_MIN_TARGET_AREA 0.5 params [ "_posASL", @@ -77,20 +80,25 @@ private _totalFragCount = 0; #endif // Estimate volume and height of target - private _height = 0.5; - private _crossSectionArea = 1; + private _height = ACE_FRAG_DEFAULT_HEIGHT; + private _crossSectionArea = ACE_FRAG_DEFAULT_CROSS_AREA; private _isPerson = _target isKindOf "CAManBase"; if (_isPerson) then { switch (stance _target) do { - case "STAND": {_height = 1.9; _crossSectionArea = 1.5;}; - case "CROUCH": {_height = 1.2; _crossSectionArea = 1;}; - default {_crossSectionArea = 0.75;}; + case "STAND": { + _height = 1.9; + _crossSectionArea = 1.5; + }; + case "CROUCH": { + _height = 1.2; + _crossSectionArea = 1; + }; }; } else { private _boxParams = boundingBoxReal [_target, "FireGeometry"]; _boxParams params ["_pointA", "_pointB"]; private _dims = _pointB vectorDiff _pointA; - if (_dims#0 * _dims#1 * _dims#2 <= 0.5) then { + if (_dims#0 * _dims#1 * _dims#2 <= ACE_FRAG_MIN_TARGET_AREA) then { continue; }; _crossSectionArea = _dims#1 * _dims#2; From 4ef23df3b3730b6d2c2d5c43eeb5b1e02fda2918 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 14 Feb 2024 20:07:19 -0600 Subject: [PATCH 194/282] white space, function headers and variable names --- addons/frag/functions/fnc_doSpall.sqf | 14 +++++++------- addons/frag/functions/fnc_shouldFrag.sqf | 11 +++++++---- addons/frag/script_component.hpp | 2 +- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index 4793b2d013b..f352e253d30 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -66,8 +66,8 @@ if (_spallPower < 2) exitWith { TRACE_1("lowImpulse",_ammo); }; -private _lastVelocityUnit = vectorNormalized _lastVelocity; -private _deltaStep = _lastVelocityUnit vectorMultiply 0.05; +private _lastVelocityNorm = vectorNormalized _lastVelocity; +private _deltaStep = _lastVelocityNorm vectorMultiply 0.05; if (terrainIntersectASL [_lastPosASL vectorAdd _deltaStep, _lastPosASL]) exitWith { TRACE_2("terrainIntersect",_lastPosASL,_deltaStep); @@ -75,17 +75,17 @@ if (terrainIntersectASL [_lastPosASL vectorAdd _deltaStep, _lastPosASL]) exitWit #ifdef DEBUG_MODE_DRAW if GVAR(dbgSphere) then { - [_lastPosASL vectorAdd _lastVelocityUnit, "orange"] call FUNC(dev_sphereDraw); + [_lastPosASL vectorAdd _lastVelocityNorm, "orange"] call FUNC(dev_sphereDraw); [_lastPosASL, "yellow"] call FUNC(dev_sphereDraw); }; #endif /* * Improve performance of finding otherside of object on shallow angle - * impacts. 120 degrees due to 90 degree offset with _lastVelocityUnit into object. + * impacts. 120 degrees due to 90 degree offset with _lastVelocityNorm into object. */ private _spallPosASL = _lastPosASL vectorAdd _deltaStep; -if (120 > acos (_lastVelocityUnit vectorDotProduct _surfaceNorm)) then { +if (120 > acos (_lastVelocityNorm vectorDotProduct _surfaceNorm)) then { _spallPosASL = _spallPosASL vectorAdd (_deltaStep vectorMultiply 5); }; private _insideObject = true; @@ -128,8 +128,8 @@ private _spallSpawner = createVehicle [ 0, "CAN_COLLIDE" ]; -_spallSpawner setVectorDirandUp [_lastVelocityUnit, _vectorUp]; -_spallSpawner setVelocity (_lastVelocityUnit vectorMultiply (_velocityChange * ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF)); +_spallSpawner setVectorDirandUp [_lastVelocityNorm, _vectorUp]; +_spallSpawner setVelocity (_lastVelocityNorm vectorMultiply (_velocityChange * ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF)); _spallSpawner setShotParents _shotParents; #ifdef DEBUG_MODE_FULL diff --git a/addons/frag/functions/fnc_shouldFrag.sqf b/addons/frag/functions/fnc_shouldFrag.sqf index 3af9de5463b..0ce6509b49f 100644 --- a/addons/frag/functions/fnc_shouldFrag.sqf +++ b/addons/frag/functions/fnc_shouldFrag.sqf @@ -1,8 +1,7 @@ #include "..\script_component.hpp" /* * Author: Lambda.Tiger - * This function checks whether an ammunition type should cause fragmentation - * and whether any submunitions exist. + * This function checks whether an ammunition type should create fragments. * * Arguments: * 0: Type of ammo to check @@ -31,8 +30,12 @@ private _explosive = getNumber (_ammoConfig >> "explosive"); private _indirectHit = getNumber (_ammoConfig >> "indirectHit"); private _indirectRange = getNumber (_ammoConfig >> "indirectHitRange"); -if (_skip == 1 || (_force == 0 && {_explosive < 0.5 || {_indirectHit < 3 - || {_indirectRange < 5 && _indirectHit < _indirectRange}}})) then { +if (_skip == 1 || + (_force == 0 && + {_explosive < 0.5 || + {_indirectHit < 3 || + {_indirectRange < 5 && + _indirectHit < _indirectRange}}})) then { TRACE_5("No frag",_ammo,_skip,_explosive,_indirectRange,_indirectHit); _shouldFrag = false; }; diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index 92591eda690..2f3f9068dc4 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -45,4 +45,4 @@ #define ACE_FRAG_SPALL_HOLDOFF 0.25 #define ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF 0.5 // sqrt(2)/50 -#define ACE_FRAG_ROUND_COEF 0.02828427 \ No newline at end of file +#define ACE_FRAG_ROUND_COEF 0.02828427 From bc2a6bb9d9cc9a74fabe6ecde2984380bbdf504b Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 14 Feb 2024 20:15:38 -0600 Subject: [PATCH 195/282] small Should spall optimization Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_shouldSpall.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_shouldSpall.sqf b/addons/frag/functions/fnc_shouldSpall.sqf index 953a0b6a915..1846bd99c76 100644 --- a/addons/frag/functions/fnc_shouldSpall.sqf +++ b/addons/frag/functions/fnc_shouldSpall.sqf @@ -26,7 +26,7 @@ private _caliber = getNumber (_ammoConfig >> "caliber"); private _explosive = getNumber (_ammoConfig >> "explosive"); private _indirectHit = getNumber (_ammoConfig >> "indirectHitRange"); -_shouldSpall = _caliber * GVAR(spallIntensity) >= 2.5 || (_explosive >= 0.5 && _explosive * _indirectHit * GVAR(spallIntensity) >= 4); +_shouldSpall = _caliber * GVAR(spallIntensity) >= 2.5 || (_explosive >= 0.5 && {_explosive * _indirectHit * GVAR(spallIntensity) >= 4}); GVAR(shouldSpallCache) set [_ammo, _shouldSpall]; From 668d222a3f5b2f42654e432b9f90bf1ec4989853 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 15 Feb 2024 18:13:06 -0600 Subject: [PATCH 196/282] Removed blacklist functions and settings --- addons/frag/XEH_PREP.hpp | 2 - addons/frag/functions/fnc_addBlackList.sqf | 25 ----------- addons/frag/functions/fnc_initBlackList.sqf | 46 --------------------- addons/frag/initSettings.inc.sqf | 11 ----- 4 files changed, 84 deletions(-) delete mode 100644 addons/frag/functions/fnc_addBlackList.sqf delete mode 100644 addons/frag/functions/fnc_initBlackList.sqf diff --git a/addons/frag/XEH_PREP.hpp b/addons/frag/XEH_PREP.hpp index 5402c89e23c..845f59a38e9 100644 --- a/addons/frag/XEH_PREP.hpp +++ b/addons/frag/XEH_PREP.hpp @@ -1,4 +1,3 @@ -PREP(addBlackList); PREP(dev_addRound); PREP(dev_clearTraces); PREP(dev_debugAmmo); @@ -18,7 +17,6 @@ PREP(findReflections); PREP(getMaterialInfo); PREP(getSpallInfo); PREP(getFragInfo); -PREP(initBlackList); PREP(initMaterialCache); PREP(initRound); PREP(shouldFrag); diff --git a/addons/frag/functions/fnc_addBlackList.sqf b/addons/frag/functions/fnc_addBlackList.sqf deleted file mode 100644 index 4d07eacdff8..00000000000 --- a/addons/frag/functions/fnc_addBlackList.sqf +++ /dev/null @@ -1,25 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: Jaynus, NouberNou, Lambda.Tiger - * Adds a round type to the blacklist (will be ignored). - * - * Arguments: - * 0: Projectile or - * - * Return Value: - * None - * - * Example: - * [projectile] call ace_frag_fnc_addBlackList - * - * Public: No - */ - -params ["_projectile"]; -TRACE_1("addBlackList",_round); - -if (_projectile isEqualType objNull) then { - _projectile = typeOf _projectile; -}; - -GVAR(shouldFragCache) set [_projectile, false]; diff --git a/addons/frag/functions/fnc_initBlackList.sqf b/addons/frag/functions/fnc_initBlackList.sqf deleted file mode 100644 index a8263c08e85..00000000000 --- a/addons/frag/functions/fnc_initBlackList.sqf +++ /dev/null @@ -1,46 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: Lambda.Tiger - * Adds setting defined blacklisted rounds to blacklist. - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_frag_fnc_addBlackList - * - * Public: No - */ - -TRACE_1("Beginning blacklist init",GVAR(blackList)); - -// could improve text parsing of CBA setting string -private _convArray = parseSimpleArray GVAR(blackList); - -if (_convArray isEqualTo []) exitWith { - TRACE_1("Empty blacklist",_convArray); -}; - -// Add CBA setting blacklist to blacklist and log errors -private _errors = 0; -{ - private _ammo = _x; - if !(_ammo isEqualType "") then { - INFO_1("Improper ammo string at index %1",_forEachIndex); - INC(_errors); - continue; - }; - - if (!isClass (configFile >> "CfgAmmo" >> _ammo)) then { - INFO_1("Ammo class: %1 does not exist",str _ammo); - INC(_errors); - continue; - }; - - GVAR(shouldFragCache) set [_ammo, false]; -} forEach _convArray; - -INFO_2("Initialized blacklist. Total items found: %1, number of items failed: %2",count _convArray,_errors); diff --git a/addons/frag/initSettings.inc.sqf b/addons/frag/initSettings.inc.sqf index 6feb0c4dc9b..9cadb4463ed 100644 --- a/addons/frag/initSettings.inc.sqf +++ b/addons/frag/initSettings.inc.sqf @@ -45,17 +45,6 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; 1 ] call CBA_fnc_addSetting; -[ - QGVAR(blackList), - "EDITBOX", - [LSTRING(DefBlackList), LSTRING(DefBlackList_Desc)], - [_category, LSTRING(Frag)], - QUOTE(['B_556x45_Ball']), - 1, - {}, - true -] call CBA_fnc_addSetting; - [ QGVAR(spallIntensity), "SLIDER", From c09c2a170caa91abece8202e3fe9339e6edca367 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 15 Feb 2024 20:59:58 -0600 Subject: [PATCH 197/282] reformatted function headers, removed value type checking, and changed lazy eval. --- addons/frag/functions/fnc_dev_addRound.sqf | 19 +++++++++---------- addons/frag/functions/fnc_dev_debugAmmo.sqf | 8 ++++---- addons/frag/functions/fnc_dev_fired.sqf | 4 +++- .../frag/functions/fnc_dev_fragCalcDump.sqf | 7 +++---- addons/frag/functions/fnc_dev_sphereDraw.sqf | 13 ++++++------- addons/frag/functions/fnc_dev_trackHitBox.sqf | 19 +++++++++---------- addons/frag/functions/fnc_dev_trackObj.sqf | 15 ++++++++------- 7 files changed, 42 insertions(+), 43 deletions(-) diff --git a/addons/frag/functions/fnc_dev_addRound.sqf b/addons/frag/functions/fnc_dev_addRound.sqf index a1cc372bb71..5995b36670f 100644 --- a/addons/frag/functions/fnc_dev_addRound.sqf +++ b/addons/frag/functions/fnc_dev_addRound.sqf @@ -7,10 +7,9 @@ * green / red / blue, respectively. * * Arguments: - * 0: Projectile to be tracked. - * 1: Add projectile hit/explode/defelceted event handlers. - * 2: Is the round fired by a unit on the same side as the player - * true results in blue traces, false in red. + * 0: Projectile to be tracked + * 1: Add projectile hit/explode/defelceted event handlers (default: true) + * 2: Should the round track be blue. True results in blue traces, false in red (default: true) * * Return Value: * Nothing Useful @@ -24,10 +23,10 @@ params [ "_projectile", ["_addProjectileEventHandlers", true], - ["_isSidePlayer", true] + ["_isTraceBlue", true] ]; -if (_isSidePlayer) then { +if (_isTraceBlue) then { GVAR(dev_trackLines) set [getObjectID _projectile, [[getPosATL _projectile], [0, 0, 1, 1]]]; } else { GVAR(dev_trackLines) set [getObjectID _projectile, [[getPosATL _projectile], [1, 0, 0, 1]]]; @@ -38,17 +37,17 @@ if (_isSidePlayer) then { { if (isGamePaused) exitWith {}; params ["_projectile", "_handle"]; - + if (!alive _projectile) exitWith { [_handle] call CBA_fnc_removePerFrameHandler; }; - + private _projectileArray = GVAR(dev_trackLines) get (getObjectID _projectile); - + if (isNil "_projectileArray") exitWith { [_handle] call CBA_fnc_removePerFrameHandler; }; - + (_projectileArray#0) pushBack getPosATL _projectile; }, 0, diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index 2c00d98e5de..7ade5df72b7 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -5,11 +5,11 @@ * fragments that could be fired from a weapon. * * Arguments: - * 0: Log ammo types that wouldn't normally frag. (Default: false) - * 1: Only print ammo without ACE_frag entries, inherited or otherwise. (Default: true) + * 0: Log ammo types that wouldn't normally frag (default: false) + * 1: Only print ammo without ACE_frag entries, inherited or otherwise (default: true) * 2: Only export ammo classes of classes referenced in CfgMagazines and their - * submunitions. (Default: false) - * 3: Force a CSV format on debug print. (Default: false) + * submunitions (default: false) + * 3: Force a CSV format on debug print. (default: false) * * Return Value: * None diff --git a/addons/frag/functions/fnc_dev_fired.sqf b/addons/frag/functions/fnc_dev_fired.sqf index 113fb997dff..9dbd039f460 100644 --- a/addons/frag/functions/fnc_dev_fired.sqf +++ b/addons/frag/functions/fnc_dev_fired.sqf @@ -18,4 +18,6 @@ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); -[_projectile, true, [side group _unit, side group ACE_player] call BIS_fnc_sideIsFriendly] call FUNC(dev_addRound); +if (GVAR(debugOptions) && {_ammo call FUNC(shouldFrag) || {_ammo call FUNC(shouldSpall)}}) then { + [_projectile, true, [side group _unit, side group ACE_player] call BIS_fnc_sideIsFriendly] call FUNC(dev_addRound); +}; diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf index ded15a6d1cb..937cf2ddb66 100644 --- a/addons/frag/functions/fnc_dev_fragCalcDump.sqf +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -1,12 +1,11 @@ #include "..\script_component.hpp" /* * Author: Lambda.Tiger, based on fnc_dev_debugAmmo by "ACE-Team" - * Dumps all ammo types to see if there's any reason to spawn fragments - * given hit power and distance. Good for grasping the values used in - * shouldFrag to cull non-fragmenting rounds. + * Dumps all ammo types to see if there's any reason to spawn fragments given hit power and distance. + * Good for grasping the values used in shouldFrag to cull non-fragmenting rounds. * * Arguments: - * 0: Display rounds that will never frag (power < 5). (default: false) + * 0: Display rounds that will never frag (default: false) * * Return Value: * None diff --git a/addons/frag/functions/fnc_dev_sphereDraw.sqf b/addons/frag/functions/fnc_dev_sphereDraw.sqf index 9a8408ff4c5..cf9ca7335c0 100644 --- a/addons/frag/functions/fnc_dev_sphereDraw.sqf +++ b/addons/frag/functions/fnc_dev_sphereDraw.sqf @@ -4,22 +4,21 @@ * Add a colored sphere at a specified point. * * Arguments: - * 0: ASL position to add sphere. - * 1: Color of sphere. (Default: Blue) + * 0: Position (posASL) to add sphere + * 1: Color of sphere (default: "blue") * * Return Value: * None * * Example: - * [getPosASL player, "blue"] call ace_frag_fnc_dev_sphereDraw; + * [getPosASL player, "red"] call ace_frag_fnc_dev_sphereDraw; * * Public: No */ -params [ - "_posASL", - ["_color", "blue", [""]] -]; +params ["_posASL", ["_color", "blue"]]; + +if (!isServer) exitWith {}; if (_color select [0,1] != "(") then { _color = switch (toLowerANSI _color) do { diff --git a/addons/frag/functions/fnc_dev_trackHitBox.sqf b/addons/frag/functions/fnc_dev_trackHitBox.sqf index 58fa9b60de3..85ef03e4a85 100644 --- a/addons/frag/functions/fnc_dev_trackHitBox.sqf +++ b/addons/frag/functions/fnc_dev_trackHitBox.sqf @@ -1,12 +1,11 @@ #include "..\script_component.hpp" /* * Author: Lambda.Tiger - * Add a hit box outline to an object, outdated for unit hits as they - * use hit-point locations. + * Add a hit box outline to an object. * * Arguments: - * 0: Object that should have it's hit box drawn. - * 1: Add sphere at object origin. (Default: true) + * 0: Object that should have it's hit box drawn (default: objNull) + * 1: Add sphere at object origin (default: true) * * Return Value: * None @@ -18,8 +17,8 @@ */ params [ - ["_object", objNull, [objNull]], - ["_addSphere", true, [true]] + ["_object", objNull], + ["_addSphere", true] ]; TRACE_2("Adding hitbox",_object,_addSphere); @@ -46,7 +45,7 @@ switch (stance _object) do { }; private _centerPoint = ASLToAGL getPosASL _object; -if (GVAR(dbgSphere) && {_addSphere && {isNull objectParent _object}}) then { +if (GVAR(dbgSphere) && _addSphere && {isNull objectParent _object}) then { private _centerSphere = [getPosASL _object, "yellow"] call FUNC(dev_sphereDraw); _centerSphere disableCollisionWith _object; _centerSphere attachTo [_object, _object worldToModel _centerPoint]; @@ -67,9 +66,9 @@ private _points = [ ]; private _color = switch (side _object) do { - case east: {[1, 0, 0, 1]}; - case resistance: {[0, 1, 0, 1]}; - default {[0, 0, 1, 1]}; + case east: {[0.8, 0, 0, 1]}; + case resistance: {[0, 0.8, 0, 1]}; + default {[0, 0, 0.8, 1]}; }; GVAR(dev_hitBoxes) set [getObjectID _object, [_object, _points, _color]]; diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index dc695fbfead..df9f48fb49a 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -4,9 +4,9 @@ * This function adds an object to have its course tracked (every frame). * * Arguments: - * 0: Object to draw track OBJECT> - * 1: Color of trace - * 2: Whether the object is a projectile or whether to add projectile EHs + * 0: Object to draw track OBJECT> (default: "objNull") + * 1: Color of trace (default: "blue") + * 2: Whether the object is a projectile or whether to add projectile EHs (default: false) * * Return Value: * None @@ -18,12 +18,13 @@ */ params [ - ["_object", objNull, [objNull]], - ["_color", "blue", ["blue"]], - ["_isProj", false, [false]] + ["_object", objNull], + ["_color", "blue"], + ["_isProj", false] ]; TRACE_3("devDraw",_object,_color,_isProj); + // pick color and add it to the array private _colorArray = switch (toLowerANSI _color) do { case "purple": {[0.8, 0, 0.8, 1]}; @@ -41,7 +42,7 @@ GVAR(dev_trackLines) set [getObjectID _object, [[getPosATL _object], _colorArray // event handler to track round and cleanup when round is "dead" [ { - if (isGamePaused) exitWith {}; + if (isGamePaused || setAccTime == 0) exitWith {}; params ["_object", "_handle"]; if (!alive _object) exitWith { From 656fa9f7f70ec31f803255c320a00eb056e8cc62 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 15 Feb 2024 21:01:02 -0600 Subject: [PATCH 198/282] fixed missing underscore in change from review --- addons/frag/functions/fnc_dev_trackObj.sqf | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index df9f48fb49a..4c73809dfe1 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -24,7 +24,6 @@ params [ ]; TRACE_3("devDraw",_object,_color,_isProj); - // pick color and add it to the array private _colorArray = switch (toLowerANSI _color) do { case "purple": {[0.8, 0, 0.8, 1]}; @@ -49,7 +48,7 @@ GVAR(dev_trackLines) set [getObjectID _object, [[getPosATL _object], _colorArray [_handle] call CBA_fnc_removePerFrameHandler; }; - private objectArray = GVAR(dev_trackLines) get (getObjectID _object); + private _objectArray = GVAR(dev_trackLines) get (getObjectID _object); if (isNil "_objectArray") exitWith { [_handle] call CBA_fnc_removePerFrameHandler; From 78a27ff0252daa72e9f0cf7a43ff1328f3adc3ae Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 15 Feb 2024 21:03:12 -0600 Subject: [PATCH 199/282] function header, lazy eval, and params list simplifications --- addons/frag/functions/fnc_dev_trackObj.sqf | 2 +- addons/frag/functions/fnc_doFrag.sqf | 14 +++----- addons/frag/functions/fnc_doFragRandom.sqf | 24 +++++-------- addons/frag/functions/fnc_doFragTargeted.sqf | 13 ++----- addons/frag/functions/fnc_doSpall.sqf | 36 ++++++++----------- addons/frag/functions/fnc_getMaterialInfo.sqf | 13 ++++--- addons/frag/functions/fnc_getSpallInfo.sqf | 11 +++--- .../frag/functions/fnc_initMaterialCache.sqf | 5 ++- addons/frag/functions/fnc_initRound.sqf | 9 ++--- addons/frag/functions/fnc_shouldSpall.sqf | 2 +- 10 files changed, 46 insertions(+), 83 deletions(-) diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index 4c73809dfe1..fae711e26d5 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -41,7 +41,7 @@ GVAR(dev_trackLines) set [getObjectID _object, [[getPosATL _object], _colorArray // event handler to track round and cleanup when round is "dead" [ { - if (isGamePaused || setAccTime == 0) exitWith {}; + if (isGamePaused || accTime == 0) exitWith {}; params ["_object", "_handle"]; if (!alive _object) exitWith { diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index a835f080278..27c92d16821 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -1,11 +1,10 @@ #include "..\script_component.hpp" /* * Author: Jaynus, NouberNou, Lambda.Tiger - * This function handles creating both random and targeted fragments as well - * as handling some of the performance optimizations. + * This function handles creating both random and targeted fragments as well as handling some of the performance optimizations. * * Arguments: - * 0: ASL position of projectile. + * 0: Position (posASL) of projectile * 1: Velocity of projectile * 2: Projectile CfgAmmo classname * 3: getShotParents of projectile at EH @@ -19,12 +18,7 @@ * Public: No */ TRACE_1("begin doFrag",_this); -params [ - "_posASL", - "_velocity", - "_ammo", - "_shotParents" -]; +params ["_posASL", "_velocity", "_ammo", "_shotParents"]; // Don't let a single object cause all fragmentation events _shotParents params ["_shotParentVic"]; @@ -35,7 +29,7 @@ _shotParentVic setVariable [QGVAR(obj_nextFragTime), CBA_missionTime + ACE_FRAG_ // Check normal round timeout and adjust _max frags private _timeSinceLastFrag = CBA_missionTime - GVAR(lastFragTime); -if (_timeSinceLastFrag < ACE_FRAG_HOLDOFF || {_posASL isEqualTo [0, 0, 0] || _ammo isEqualTo ""}) exitWith { +if (_timeSinceLastFrag < ACE_FRAG_HOLDOFF || {_posASL isEqualTo [0, 0, 0]} || {_ammo isEqualTo ""}) exitWith { TRACE_3("timeExit",_timeSinceLastFrag,CBA_missionTime,GVAR(lastFragTime)); }; private _maxFragCount = round linearConversion [ACE_FRAG_COUNT_MIN_TIME, ACE_FRAG_COUNT_MAX_TIME, _timeSinceLastFrag, ACE_FRAG_COUNT_MIN, ACE_FRAG_COUNT_MAX, true]; diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index 6e6f8ecf51c..5101e414d02 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -1,16 +1,15 @@ #include "..\script_component.hpp" /* * Author: Jaynus, NouberNou, Lambda.Tiger - * This function creates fragments randomly spreading out from an explosion to - * a maximum of 15. + * This function creates fragments randomly spreading out from an explosion to a maximum of 15. * * Arguments: - * 0: Position of fragmenting projectile ASL. - * 1: Velocity of the fragmenting projectile. - * 2: Height (AGL) of the fragmenting projectile. - * 3: Type of fragments to generate. - * 4: Remaining fragment budget. - * 5: Shot parents. + * 0: Position (posASL) of fragmenting projectile + * 1: Velocity of the fragmenting projectile + * 2: Height (AGL) of the fragmenting projectile + * 3: Type of fragments to generate + * 4: Remaining fragment budget + * 5: Shot parents * * Return Value: * None @@ -20,14 +19,7 @@ * * Public: No */ -params [ - "_posASL", - "_fragVelocity", - "_heightAGL", - "_fragType", - "_maxFragCount", - "_shotParents" -]; +params ["_posASL", "_fragVelocity", "_heightAGL", "_fragType", "_maxFragCount", "_shotParents"]; TRACE_6("doFragRandom",_posASL,_fragVelocity,_heightAGL,_fragType,_maxFragCount,_shotParents); // See CfgAmmoFragSpawner for different frag types diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index f914b644912..d49025541e8 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -1,8 +1,7 @@ #include "..\script_component.hpp" /* * Author: Jaynus, NouberNou, Lambda.Tiger - * This function creates fragments targeted at specific entities, up to - * a configured maximum. + * This function creates fragments targeted at specific entities, up to _maxFrags. * * Arguments: * 0: Position of fragmenting projectile ASL @@ -25,15 +24,7 @@ #define ACE_FRAG_DEFAULT_CROSS_AREA 0.75 #define ACE_FRAG_MIN_TARGET_AREA 0.5 -params [ - "_posASL", - "_fragVelocity", - "_fragRange", - "_maxFrags", - "_fragTypes", - "_modFragCount", - "_shotParents" -]; +params [ "_posASL", "_fragVelocity", "_fragRange", "_maxFrags", "_fragTypes", "_modFragCount", "_shotParents"]; TRACE_5("fnc_doFragTargeted",_posASL,_fragRange,_maxFrags,_fragTypes,_modFragCount); if (_fragTypes isEqualTo []) then { diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index f352e253d30..4bcb58ecab0 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: Jaynus, NouberNou, Lambda.Tiger, - * This function creates spalling if the hit slowed the speed down enough. + * This function creates spalling if the hit slowed the projectile speed down enough. * * Arguments: * Arguments are the same as BI's "HitPart" EH: @@ -15,24 +15,16 @@ * * Public: No */ +#define GLUE(g1,g2) g1##g2 TRACE_1("doSpall",_this); -params [ - "_projectile", - "_objectHit", - "_lastPosASL", - "_lastVelocity", - "_surfaceNorm", - "_surfaceType", - "_ammo", - "_shotParents", - "_vectorUp" -]; +params ["_projectile", "_objectHit", "_lastPosASL", "_lastVelocity", "_surfaceNorm", "_surfaceType", "_ammo", "_shotParents", "_vectorUp"]; -if (CBA_missionTime < GVAR(nextSpallAllowTime)|| - _lastPosASL isEqualTo [0,0,0] || - {_ammo isEqualTo "" || {!isNull _objectHit && - {objectHit isKindOf "CAManBase"}}}) exitWith { +if (CBA_missionTime < GVAR(nextSpallAllowTime) || + {isNull _objectHit} || + {_lastPosASL isEqualTo [0,0,0]} || + {_ammo isEqualTo ""} || + {_objectHit isKindOf "CAManBase"}) exitWith { TRACE_4("time/invalidHit",CBA_missionTime,GVAR(nextSpallAllowTime),_objectHit,_lastPosASL); }; @@ -114,15 +106,15 @@ if GVAR(dbgSphere) then { private _spawnSize = switch (true) do { - case (_spallPower < 3): { "_spall_tiny" }; - case (_spallPower < 5): { "_spall_small" }; - case (_spallPower < 8): { "_spall_medium" }; - case (_spallPower < 12): { "_spall_large" }; - default { "_spall_huge" }; + case (_spallPower < 3): {"_spall_tiny"}; + case (_spallPower < 5): {"_spall_small"}; + case (_spallPower < 8): {"_spall_medium"}; + case (_spallPower < 12): {"_spall_large"} ; + default {"_spall_huge"}; }; private _spallSpawner = createVehicle [ - "ace_frag_" + _material + _spawnSize, + QUOTE(GLUE(ADDON,_)) + _material + _spawnSize, ASLToATL _spallPosASL, [], 0, diff --git a/addons/frag/functions/fnc_getMaterialInfo.sqf b/addons/frag/functions/fnc_getMaterialInfo.sqf index a7940d016c3..7b3435b16a4 100644 --- a/addons/frag/functions/fnc_getMaterialInfo.sqf +++ b/addons/frag/functions/fnc_getMaterialInfo.sqf @@ -1,23 +1,22 @@ #include "..\script_component.hpp" -#define ACE_FRAG_SOUNDENVIRON_STR_LEN 12 -#define ACE_FRAG_SOUNDGIT_STR_LEN 8 -#define ACE_FRAG_MATERIAL_SEARCH_LEN 10 /* * Author: Lambda.Tiger - * This function returns a classification of material type based - * on the surface hit. + * This function returns a classification of material type based on the surface hit. * * Arguments: - * 0: surfacetype - either a CfgSurfaces path .bisurf filepath + * 0: Surface type given as either a CfgSurfaces path or .bisurf filepath, same format as "HitPart" projectile parameter * * Return Value: - * _material - Material categories as expanded on in line 44 below + * Material categories as expanded on in line 44 below * * Example: * [_surfaceType] call ace_frag_fnc_getFragInfo; * * Public: No */ +#define ACE_FRAG_SOUNDENVIRON_STR_LEN 12 +#define ACE_FRAG_SOUNDGIT_STR_LEN 8 +#define ACE_FRAG_MATERIAL_SEARCH_LEN 10 params ["_surfType"]; diff --git a/addons/frag/functions/fnc_getSpallInfo.sqf b/addons/frag/functions/fnc_getSpallInfo.sqf index 4c76a0b909c..da1347a135a 100644 --- a/addons/frag/functions/fnc_getSpallInfo.sqf +++ b/addons/frag/functions/fnc_getSpallInfo.sqf @@ -1,17 +1,16 @@ #include "..\script_component.hpp" /* * Author: Lambda.Tiger - * This function returns spalling parameters for a specific - * ammo type. + * This function returns spalling parameters for a specific ammo type. * * Arguments: - * 0: _ammo - CfgAmmo type of ammo to check + * 0: Ammo classname * * Return Value: * _ammoInfo - * 0: _caliber - search range for fragments - * 1: _explosive - whether the round is explosive or not - * 2: _indirectHitRange - Indirect hit damage + * 0: Caliber + * 1: What part of the hit damage is from ballistic vs explosive energy (1 for all explosive) + * 2: Indirect hit damage * * Example: * ["B_556x45_Ball"] call ace_frag_fnc_getSpallInfo; diff --git a/addons/frag/functions/fnc_initMaterialCache.sqf b/addons/frag/functions/fnc_initMaterialCache.sqf index 809221e40f1..b125d0119c6 100644 --- a/addons/frag/functions/fnc_initMaterialCache.sqf +++ b/addons/frag/functions/fnc_initMaterialCache.sqf @@ -1,8 +1,7 @@ #include "..\script_component.hpp" /* * Author: Lambda.Tiger - * For performance, we load a bunch of vanilla materials preemptively into - * the spall material cache. + * For performance, we load a bunch of vanilla materials preemptively into the spall material cache. * * Arguments: * None @@ -11,7 +10,7 @@ * None * * Example: - * call initMaterialCache; + * call ace_frag_fnc_initMaterialCache; * * Public: No */ diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index 4d785e2e5fc..18dbb400ef0 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -19,7 +19,7 @@ TRACE_1("ACE_Frag rndInit",_this); params ["_projectile"]; -if !(isServer) exitWith {}; +if (!isServer) exitWith {}; private _ammo = typeOf _projectile; if (_ammo isEqualTo "" || {isNull _projectile}) exitWith { @@ -49,15 +49,12 @@ if (GVAR(spallEnabled) && {_ammo call FUNC(shouldSpall)}) then { _projectile addEventHandler [ "HitPart", { - params ["_projectile", "_hitObject", "", - "_posASL", "_velocity", "_surfNorm", "", - "", "_surfType" - ]; + params ["_projectile", "_hitObject", "", "_posASL", "_velocity", "_surfNorm", "", "", "_surfType"]; private _shotParent = getShotParents _projectile; private _ammo = typeOf _projectile; private _vectorUp = vectorUp _projectile; /* - * Wait a round to see what happens to the round, may result in + * Wait a frame to see what happens to the round, may result in * multiple hits / slowdowns getting shunted to the first hit */ [ diff --git a/addons/frag/functions/fnc_shouldSpall.sqf b/addons/frag/functions/fnc_shouldSpall.sqf index 1846bd99c76..c545c886763 100644 --- a/addons/frag/functions/fnc_shouldSpall.sqf +++ b/addons/frag/functions/fnc_shouldSpall.sqf @@ -4,7 +4,7 @@ * This function checks whether an ammunition type should cause spalling. * * Arguments: - * 0: Type of ammo to check + * 0: Ammo classname * * Return Value: * Whether the round type would spall when hitting an object From dfdea2d9c7f6ae252a0c909334790e261683db93 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 15 Feb 2024 21:03:29 -0600 Subject: [PATCH 200/282] function header and variable name readability --- addons/frag/functions/fnc_getFragInfo.sqf | 39 +++++++++++------------ 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/addons/frag/functions/fnc_getFragInfo.sqf b/addons/frag/functions/fnc_getFragInfo.sqf index 3caa5ef918d..0d69de5d177 100644 --- a/addons/frag/functions/fnc_getFragInfo.sqf +++ b/addons/frag/functions/fnc_getFragInfo.sqf @@ -1,18 +1,17 @@ #include "..\script_component.hpp" /* * Author: Jaynus, NouberNou, Lambda.Tiger - * This function returns fragmentation parameters for a specific - * ammo type. + * This function returns fragmentation parameters for a specific ammo type. * * Arguments: - * 0: _ammo - CfgAmmo type of ammo to check. + * 0: Ammo classname * * Return Value: * _ammoInfo - * 0: _fragRange - search range for fragments. - * 1: _fragVel - gurney equation calculated velocity. - * 2: _fragTypes - array of fragment types. - * 3: _fragCount - modified frag count used under assumptions of spherical fragmentation. + * 0: Search range for fragments in meters + * 1: Gurney equation calculated speed + * 2: Array of fragment types + * 3: Modified frag count under assumptions of spherical fragmentation * * Example: * ["B_556x45_Ball"] call ace_frag_fnc_getFragInfo; @@ -28,18 +27,18 @@ if (!isNil "_ammoInfo") exitWith {_ammoInfo}; private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; private _fragTypes = []; -private _notify = false; +private _notifyMissingEntries = false; if (isArray (_ammoConfig >> QGVAR(classes))) then { _fragTypes = getArray (_ammoConfig >> QGVAR(classes)); } else { - _notify = true; + _notifyMissingEntries = true; }; /************ Gurney equation notes *****************//* * see https://en.wikipedia.org/wiki/Gurney_equations * - * GURNEY_K is the geometry constant added to _metalMass/_chargeMass - * GURNEY_C = sqrt(2E) + * gurney_k is the geometry constant added to _metalMass/_chargeMass + * gurney_c = sqrt(2E) * * _chargeMass = 185; - grams of comp-b * _metalMass = 210; - grams of metal are accelerated by explosion @@ -58,44 +57,42 @@ if (isArray (_ammoConfig >> QGVAR(classes))) then { private _chargeMass = getNumber (_ammoConfig >> QGVAR(CHARGE)); if (_chargeMass == 0) then { _chargeMass = 1; - _notify = true; + _notifyMissingEntries = true; }; private _metalMass = getNumber (_ammoConfig >> QGVAR(METAL)); if (_metalMass == 0) then { _metalMass = 2; - _notify = true; + _notifyMissingEntries = true; }; private _geometryCoefficient = getNumber (_ammoConfig >> QGVAR(GURNEY_K)); if (_geometryCoefficient == 0) then { _geometryCoefficient = 0.8; - _notify = true; + _notifyMissingEntries = true; }; private _gurneyConstant = getNumber (_ammoConfig >> QGVAR(GURNEY_C)); if (_gurneyConstant == 0) then { _gurneyConstant = 2440; - _notify = true; + _notifyMissingEntries = true; }; private _fragCount = getNumber (_ammoConfig >> QGVAR(fragCount)); if (_fragCount == 0) then { _fragCount = 400; - _notify = true; + _notifyMissingEntries = true; }; -if (_notify) then { +if (_notifyMissingEntries) then { INFO_1("Ammo class %1 lacks proper explosive properties definitions for frag!",_ammo); }; /********************** _ammoInfo format *************************//* - * 0: _fragRange - search range for fragments, calculated with - * the minimum chance to hit as defined + * 0: _fragRange - search range for fragments, calculated with the minimum chance to hit as defined * 1: _fragVelocity - gurney equation calculated velocity * 2: _fragTypes - array of fragment types - * 3: _fragCount - modified frag count used under assumptions - * of spherical fragmentation + * 3: _fragCount - modified frag count used under assumptions of spherical fragmentation */ _ammoInfo = [ ACE_FRAG_MAX_FRAG_RANGE max sqrt (_fragCount / (4 * pi * ACE_FRAG_MIN_FRAG_HIT_CHANCE)), From 6cbfe15c4cf956fac904215e300e193ff363f00a Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 15 Feb 2024 21:04:05 -0600 Subject: [PATCH 201/282] changed defaults to make them more clear they're just a default value --- addons/frag/XEH_preInit.sqf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/frag/XEH_preInit.sqf b/addons/frag/XEH_preInit.sqf index edaf0777b98..8120192a440 100644 --- a/addons/frag/XEH_preInit.sqf +++ b/addons/frag/XEH_preInit.sqf @@ -9,11 +9,11 @@ PREP_RECOMPILE_END; GVAR(spallMaterialCache) = createHashMap; GVAR(spallInfoCache) = createHashMap; GVAR(shouldSpallCache) = createHashMap; -GVAR(nextSpallAllowTime) = -2; +GVAR(nextSpallAllowTime) = -1; GVAR(shouldFragCache) = createHashMap; GVAR(fragInfoCache) = createHashMap; -GVAR(lastFragTime) = -2; +GVAR(lastFragTime) = -1; #include "initSettings.inc.sqf" From 21e7b3d10790297cb03ab21c8908f3ea120f8fb1 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 15 Feb 2024 21:04:46 -0600 Subject: [PATCH 202/282] Updated wiki to be clearer in a few areas, and add some other information I've found working on this --- docs/wiki/framework/frag-framework.md | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/docs/wiki/framework/frag-framework.md b/docs/wiki/framework/frag-framework.md index b8916549eae..e4e14b84786 100644 --- a/docs/wiki/framework/frag-framework.md +++ b/docs/wiki/framework/frag-framework.md @@ -9,7 +9,7 @@ mod: ace version: major: 3 minor: 16 - patch: 0 + patch: 4 --- ## 1. Overview @@ -39,11 +39,13 @@ class CfgAmmo { }; ``` -### 1.1 Metal amount +### 1.1 Fragment count `ace_frag_fragCount` -Number of fragments that would be fragmented. This number may be found online or inferred from similar munitions. This affects the to be hit by a fragment and maximum range a fragment may hit a unit. +Maximum number of fragments that the real munition would create. Frag count affects the chance to be hit by a fragment and maximum range a fragment may hit a unit. Frag count may be found online, inferred from similar munitions, or derived based on desired hit distance. For a desired distance, the frag count ($$N_{frag}$$) is given by, +$$N_{frag} = 4\pi\cdot P_{hit,min}\cdot distance_{max}^2 = 0.02\pi\cdot distance_{max}^2$$ +where $$P_{hit,min}$$ is the configured minimum considered chance to hit of 0.5%. Therefore, when calculating frag count for a frag grenade with a wounding radius of 15 meters, calculating for a distancce of 80 meter may be desired instead. Dimensionless value, count of number of fragments. @@ -53,21 +55,21 @@ Dimensionless value, count of number of fragments. Amount of metal being fragmented. Generally taken as the entire weight of the warhead, though in some cases you might want to only include the fragmentation jacket or body. -Dimensionless value, as long as same unit as `ace_frag_charge` (for example `kg/kg` or `g/g` or `lbs/lbs`). +As long as the units match `ace_frag_charge`, the total mass of fragmenting metal given in any unit of mass (i.e., both use `kg`, `g`, or `lbs`). ### 1.3 Explosives filler amount `ace_frag_charge` -Amount of explosive filler in the warhead. `ace_frag_metal` and `ace_frag_charge` are dimensionless values, as long as they are both in the same unit (for example kg/kg g/g lbs/lbs). +Mass of explosive filler in the warhead. This may include any detonation/igntion charges, but usually such charges are relatively small. -Dimensionless value, as long as same unit as `ace_frag_metal` (for example `kg/kg` or `g/g` or `lbs/lbs`). +As long as the units match `ace_frag_metal`, the total mass of explosive filler given in any unit of mass (i.e., both use `kg`, `g`, or `lbs`). ### 1.4 Gurney velocity constant `ace_frag_gurney_c` -Gurney constant for explosive force. You can find a list of common explosive types below. If you can not find it here, or want more accurate numbers, just google the type of explosive and Gurney constant and you can find substantial information. This is **not** the detonation velocity of the explosive, do not confuse them! +Gurney constant for explosive force. You can find a list of common explosive types below. If you can not find it here, or want more accurate numbers, just google the type of explosive and Gurney constant and you can find substantial information. This is **not** the detonation velocityof the explosive, do not confuse them†! Type | Speed --------------- | -------- @@ -86,6 +88,8 @@ Tetryl | 2500 m/s TNT | 2440 m/s Tritonal | 2320 m/s +†A rule of thumb from literature is that the Gurney constant is given as 0.338 times the detonation velocity. + ### 1.5 Gurney shape factor `ace_frag_gurney_k` @@ -119,7 +123,7 @@ There are different types of fragmentation fragments to choose from, and they ca | ACE_frag_huge | ACE_frag_huge_HD -The tinier the piece of fragmentation the shorter the distance of travel. The `_HD` variants are all even higher drag versions. Grenades generally should use the `_HD` variants. Experimentation here is important. +Tinier fragments do less damage, and generally correlate to lower mass fragments. The `_HD` variants are all higher drag versions. Higher drag version are useful for fragments that are irregular or would not fly very far. Experimentation here is important. ### 1.7 Ignore fragmentation @@ -131,4 +135,4 @@ Setting this to `1` will skip fragmentation for ammo of this type. This is usefu `ace_frag_force` -Settings this to `1` will force the fragmentation system to use frag on this ammo, ignoring internal qualifications based on hit values. +Settings this to `1` will force the fragmentation for this ammo type, ignoring internal hit value based qualifications. From 4913887e36f7002ed2af1170044017e024c72b41 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 15 Feb 2024 21:05:08 -0600 Subject: [PATCH 203/282] added MP debug compatability --- addons/frag/XEH_postInit.sqf | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index 9e3a13de1f8..7be2fa31e7f 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -15,14 +15,18 @@ }; #ifdef DEBUG_MODE_DRAW - if (isServer) then { - [QGVAR(dev_clearTraces),LINKFUNC(dev_clearTraces)] call CBA_fnc_addEventHandler; + [QGVAR(dev_clearTraces),LINKFUNC(dev_clearTraces)] call CBA_fnc_addEventHandler; + + if (!isServer && hasInterface) then { + ["ace_firedPlayer", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerNonLocal", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; + ["ace_firedNonPlayer", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerVehicle", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerVehicleNonLocal", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; + ["ace_firedNonPlayerVehicle", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; }; if (hasInterface) then { - GVAR(dev_drawPFEH) = [ - LINKFUNC(dev_drawTrace), - 0 - ] call CBA_fnc_addPerFrameHandler; + GVAR(dev_drawPFEH) = [LINKFUNC(dev_drawTrace), 0] call CBA_fnc_addPerFrameHandler; [ "ace_interact_menu_newControllableObject", { @@ -33,7 +37,8 @@ "Reset ACE Frag traces", "", { - [QGVAR(dev_clearTraces), []] call CBA_fnc_serverEvent; + [QGVAR(dev_clearTraces), []] call CBA_fnc_remoteEvent; + call FUNC(dev_clearTraces); }, {true} ] call EFUNC(interact_menu,createAction); From 66c566b772c9ff7f7a66a77e86f909b0fcab9f67 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 15 Feb 2024 21:05:31 -0600 Subject: [PATCH 204/282] Possible shouldFrag legibility improvement --- addons/frag/functions/fnc_shouldFrag.sqf | 32 ++++++++++++++---------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/addons/frag/functions/fnc_shouldFrag.sqf b/addons/frag/functions/fnc_shouldFrag.sqf index 0ce6509b49f..d9ed570ffdd 100644 --- a/addons/frag/functions/fnc_shouldFrag.sqf +++ b/addons/frag/functions/fnc_shouldFrag.sqf @@ -4,7 +4,7 @@ * This function checks whether an ammunition type should create fragments. * * Arguments: - * 0: Type of ammo to check + * 0: Ammo classname * * Return Value: * Should the specific round fragment @@ -25,19 +25,25 @@ _shouldFrag = true; private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; private _skip = getNumber (_ammoConfig >> QGVAR(skip)); -private _force = getNumber (_ammoConfig >> QGVAR(force)); -private _explosive = getNumber (_ammoConfig >> "explosive"); -private _indirectHit = getNumber (_ammoConfig >> "indirectHit"); -private _indirectRange = getNumber (_ammoConfig >> "indirectHitRange"); - -if (_skip == 1 || - (_force == 0 && - {_explosive < 0.5 || - {_indirectHit < 3 || - {_indirectRange < 5 && - _indirectHit < _indirectRange}}})) then { - TRACE_5("No frag",_ammo,_skip,_explosive,_indirectRange,_indirectHit); +if (_skip == 1) then { _shouldFrag = false; + TRACE_1("No frag: skip",_skip); +}; + +private _force = getNumber (_ammoConfig >> QGVAR(force)); +if (_shouldFrag && _force == 0) then { + private _explosive = getNumber (_ammoConfig >> "explosive"); + if (_explosive < 0.4) exitWith { + _shouldFrag = false; + TRACE_3("No frag: _explosive",_skip,_force,_explosive); + }; + private _indirectHit = getNumber (_ammoConfig >> "indirectHit"); + private _indirectRange = getNumber (_ammoConfig >> "indirectHitRange"); + if (_indirectHit < 3 || + {_indirectRange < 5 && _indirectHit < _indirectRange}) then { + _shouldFrag = false; + TRACE_5("No frag",_ammo,_skip,_explosive,_indirectRange,_indirectHit); + }; }; GVAR(shouldFragCache) set [_ammo, _shouldFrag]; From a8778a622646fe70fe3f27db51a3f5c6fa1577c4 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 15 Feb 2024 21:14:03 -0600 Subject: [PATCH 205/282] added changes to stringtable --- addons/frag/stringtable.xml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/addons/frag/stringtable.xml b/addons/frag/stringtable.xml index 6724dbdf233..ab3d2034ecc 100644 --- a/addons/frag/stringtable.xml +++ b/addons/frag/stringtable.xml @@ -221,32 +221,32 @@ 設定在每一幀數內,系統最大可追蹤的碎片/剝落粒子數量。此設定可有效幫助系統減低計算壓力 - (SP only) Frag/Spall Debug Tracing - (Solo SP) Seguimiento de depuración de Fragmentación/Astillamiento + Frag/Spall Debug Tracing + Seguimiento de depuración de Fragmentación/Astillamiento (Tylko SP) Wizualny debug odł./odpr. (Pouze SP) Debug sledování Frag/Úlomků - (nur SP) Splitter-/Explosions-Debug-Verfolgung + Splitter-/Explosions-Debug-Verfolgung (Somente SP) Depuração de fragmentação e estilhaços traçantes - (SP uniquement) Fragmentation/éclat debug + Fragmentation/éclat debug (Csak SP) Repesz/Pattogzás debug követés (Только для одиночной игры) Отслеживаение/отладка осколков - (Solo SP) Debug Tracciamento Frag/Spall + Debug Tracciamento Frag/Spall (SP のみ) 破片/剥離のデバッグ用表示 (싱글플레이 전용) 탄환파편/파편 디버그 추적화 (仅单人)追踪显示破片粒子 (僅在單人模式) 碎片/剝落除錯追蹤 - (SP only) Requires a mission/editor restart. Enables visual tracing of fragmentation and spalling rounds in SP game mode only. - (Solo SP) Requiere un reinicio misión/editor. Permite el seguimiento visual de la fragmentación y astillamientos de los proyectiles en modo SP. + Requires a mission/editor restart. Enables visual tracing of fragmentation and spalling rounds. + Requiere un reinicio misión/editor. Permite el seguimiento visual de la fragmentación y astillamientos de los proyectiles. (Tylko SP) Wymaga restartu misji/edytora. Aktywuje wizualne śledzenie odłamków oraz odprysków w trybie gry Single Player. - (nur SP) Splitter-/Explosions-Debugging + Splitter-/Explosions-Debugging (Pouze SP) Vyžaduje restart mise/editoru. Aktivuje vizuální stopování fragmentace a úlomů pouze v režimu jednoho hráče. (Somente SP) Requer um reinício de missão / editor. Habilita o rastreamento visual de projéteis de fragmentação e estilhaçamento apenas no modo de jogo SP. - (SP seulement) Requiert un redémarrage de mission ou de l'éditeur. Active les traceurs visuels de fragmentation et d'éclats en mode solo seulement. + Requiert un redémarrage de mission ou de l'éditeur. Active les traceurs visuels de fragmentation et d'éclats. (Csak SP) Küldetés/Editor újraindítás szükséges. Engedélyezi a repeszek és pattogzó lövedékek vizuális nyomkövetését, csak egyjátékos módok alatt. (Только для одиночной игры) Требует перезапуска миссии/редактора. Включает визуальные следы от осколков и обломков в режиме одиночной игры. - (Solo SP) Richiede un restart editor/missione. Abilita il tracciamento visivo di schegge da frammentazione/spalling in modalità Giocatore Singolo. + Richiede un restart editor/missione. Abilita il tracciamento visivo di schegge da frammentazione/spalling. (SP のみ) ミッションとエディタの再起動が必要です。有効化すると、シングルプレイでのみ破片と剥離の飛翔体が見えるようになります。 (仅单人)激活后,只有在单人模式下才可观察到破片粒子的移动轨迹。 (僅在單人模式) 讓你在單人模式下可觀察到碎片/剝落粒子的移動軌跡 From f4dc05283b4a19533040add7b3c2f4fe0a10f36a Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 15 Feb 2024 21:59:07 -0600 Subject: [PATCH 206/282] Grammar sweep on the wiki, and added some clarifications to config values --- docs/wiki/framework/frag-framework.md | 34 +++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/wiki/framework/frag-framework.md b/docs/wiki/framework/frag-framework.md index e4e14b84786..1905a7996e6 100644 --- a/docs/wiki/framework/frag-framework.md +++ b/docs/wiki/framework/frag-framework.md @@ -14,7 +14,7 @@ version: ## 1. Overview -The fragmentation system in ACE3 is a significant improvement over the fragmentation system in ACE2. Previously the system relied on fuzzy math from the values of `indirectHit` and `indirectHitRange` in `CfgAmmo` to calculate roughly the velocity and range of fragmentation. This had some serious drawbacks, especially in the case of smaller explosives such as hand grenades and 40mm grenades where casualty production was lower than desired. +The fragmentation system in ACE3 is a significant improvement over the fragmentation system in ACE2. Previously the system relied on fuzzy math from the values of `indirectHit` and `indirectHitRange` in `CfgAmmo` to calculate roughly the velocity and range of fragmentation. This had some serious drawbacks, especially in the case of smaller explosives such as hand grenades and 40mm grenades where lethality was lower than desired. In ACE3 the system has moved away from what "feels" right to actual explosive engineering equations, primarily the [Gurney equations](http://en.wikipedia.org/wiki/Gurney_equations). This allows us to get close to the actual fragmentation velocities that would be produced by an explosive configuration similar to type of ammo we are simulating. @@ -39,37 +39,37 @@ class CfgAmmo { }; ``` -### 1.1 Fragment count +### 2.1 Fragment count `ace_frag_fragCount` -Maximum number of fragments that the real munition would create. Frag count affects the chance to be hit by a fragment and maximum range a fragment may hit a unit. Frag count may be found online, inferred from similar munitions, or derived based on desired hit distance. For a desired distance, the frag count ($$N_{frag}$$) is given by, +The maximum number of fragments that the real munition would create. Frag count affects the chance of being hit by a fragment and the maximum range in which a fragment may hit a unit. Frag count may be found online, inferred from similar munitions, or derived based on desired hit distance. For a desired distance, the frag count ($$N_{frag}$$) is given by, $$N_{frag} = 4\pi\cdot P_{hit,min}\cdot distance_{max}^2 = 0.02\pi\cdot distance_{max}^2$$ -where $$P_{hit,min}$$ is the configured minimum considered chance to hit of 0.5%. Therefore, when calculating frag count for a frag grenade with a wounding radius of 15 meters, calculating for a distancce of 80 meter may be desired instead. +where $$P_{hit,min}$$ is 0.5%, the minimum chance to hit that is considered when generating fragments. Therefore, calculating the frag count for a frag grenade with a wounding radius of 15 meters, calculating for a distance of 80 meters may be desired instead. Dimensionless value, count of number of fragments. -### 1.2 Metal amount +### 2.2 Metal amount `ace_frag_metal` -Amount of metal being fragmented. Generally taken as the entire weight of the warhead, though in some cases you might want to only include the fragmentation jacket or body. +The amount of metal being fragmented. Generally taken as the entire weight of the warhead, though in some cases you might want to only include the fragmentation jacket or body. As long as the units match `ace_frag_charge`, the total mass of fragmenting metal given in any unit of mass (i.e., both use `kg`, `g`, or `lbs`). -### 1.3 Explosives filler amount +### 2.3 Explosives filler amount `ace_frag_charge` -Mass of explosive filler in the warhead. This may include any detonation/igntion charges, but usually such charges are relatively small. +The mass of explosive filler in the warhead. This may include any detonation/igntion charges, but usually such charges are relatively small. As long as the units match `ace_frag_metal`, the total mass of explosive filler given in any unit of mass (i.e., both use `kg`, `g`, or `lbs`). -### 1.4 Gurney velocity constant +### 2.4 Gurney velocity constant `ace_frag_gurney_c` -Gurney constant for explosive force. You can find a list of common explosive types below. If you can not find it here, or want more accurate numbers, just google the type of explosive and Gurney constant and you can find substantial information. This is **not** the detonation velocityof the explosive, do not confuse them†! +The Gurney constant for explosive force. You can find a list of common explosive types below. If you can not find it here, or want more accurate numbers, just google the type of explosive and Gurney constant and you can find substantial information. This is **not** the detonation velocityof the explosive, do not confuse them†! Type | Speed --------------- | -------- @@ -90,11 +90,11 @@ Tritonal | 2320 m/s †A rule of thumb from literature is that the Gurney constant is given as 0.338 times the detonation velocity. -### 1.5 Gurney shape factor +### 2.5 Gurney shape factor `ace_frag_gurney_k` -Shape factor for the explosive configuration. You should choose it based on the general configuration of explosives/metal in the warhead. Most grenades for example are a sphere. Artillery and aircraft bombs are a cylinder. Mines generally a flat plate. Below is a list of the three common shapes and their factors. +The shape factor for the explosive configuration. You should choose it based on the general configuration of explosives/metal in the warhead. Most grenades for example are a sphere. Artillery and aircraft bombs are a cylinder. Mines generally a flat plate. Below is a list of the three common shapes and their factors. Shape | Factor -------- | ------ @@ -104,7 +104,7 @@ Plate | 3/5 There are other configurations but these are the most common. If you are interested in others check out the wikipedia link given above. Most of these will not correctly function in ACE3 though due to additional variables for the equation. -### 1.6 Fragments type +### 2.6 Fragments type `ace_frag_classes[]` @@ -125,14 +125,14 @@ There are different types of fragmentation fragments to choose from, and they ca Tinier fragments do less damage, and generally correlate to lower mass fragments. The `_HD` variants are all higher drag versions. Higher drag version are useful for fragments that are irregular or would not fly very far. Experimentation here is important. -### 1.7 Ignore fragmentation +### 2.7 Ignore fragmentation `ace_frag_skip` -Setting this to `1` will skip fragmentation for ammo of this type. This is useful for things that might cause high network load, such as FFAR rockets, or possibly even 40mm grenades from AGLs. Experimentation under network conditions is required. +When `1`, the ammunition type will not produce fragments. `ace_frag_skip` does not stop submunitions of the ammo type from producing fragments. `ace_frag_skip` may be helpful for ammunition types that might cause high network load or for explosives that do not produce fragments. Experimentation under network conditions may be required. `ace_frag_skip` takes a higher priority than `ace_frag_force`. -### 1.8 Force fragmentation +### 2.8 Force fragmentation `ace_frag_force` -Settings this to `1` will force the fragmentation for this ammo type, ignoring internal hit value based qualifications. +When `1`, the ammunition type will fragment, ignoring internal hit value-based qualifications. `ace_frag_force` takes a lower priority than `ace_frag_skip`. From 7248496e62a31d68d4064253762a26161264427d Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Fri, 16 Feb 2024 16:40:27 -0600 Subject: [PATCH 207/282] optimized dev_trackHitbox and made variables more explicit --- addons/frag/functions/fnc_dev_trackHitBox.sqf | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/addons/frag/functions/fnc_dev_trackHitBox.sqf b/addons/frag/functions/fnc_dev_trackHitBox.sqf index 85ef03e4a85..7f9d5aeba87 100644 --- a/addons/frag/functions/fnc_dev_trackHitBox.sqf +++ b/addons/frag/functions/fnc_dev_trackHitBox.sqf @@ -25,23 +25,23 @@ TRACE_2("Adding hitbox",_object,_addSphere); if (isNull _object) exitWith {}; // Grab the right hitBox -private _box = []; +private _boundingBox = []; if (_object isKindOf "CAManBase") then { if (isNull objectParent _object) then { - _box = 0 boundingBox _object; + _boundingBox = 0 boundingBox _object; } else { - _box = boundingBoxReal [_object, "Geometry"]; + _boundingBox = boundingBoxReal [_object, "Geometry"]; }; } else { - _box = boundingBoxReal [_object, "FireGeometry"]; + _boundingBox = boundingBoxReal [_object, "FireGeometry"]; }; -_box params ["_lowP", "_upP"]; +_boundingBox params ["_lowerPoint", "_upperPoint"]; // adjust with stance switch (stance _object) do { - case "STAND": {_upP set [2, 1.9];}; - case "CROUCH": {_upP set [2, 1.3];}; - case "PRONE": {_upP set [2, 0.8];}; + case "STAND": {_upperPoint set [2, 1.9];}; + case "CROUCH": {_upperPoint set [2, 1.3];}; + case "PRONE": {_upperPoint set [2, 0.8];}; }; private _centerPoint = ASLToAGL getPosASL _object; @@ -52,17 +52,19 @@ if (GVAR(dbgSphere) && _addSphere && {isNull objectParent _object}) then { }; // create an optimized outline -private _p1 = _upP; -private _p7 = _lowP; +_upperPoint params ["_x1","_y1","_z1"]; +_lowerPoint params ["_x2","_y2","_z2"]; +private _p1 = _upperPoint; +private _p7 = _lowerPoint; private _points = [ - _upP, - [_p1#0, _p7#1, _p1#2], - [_p7#0, _p7#1, _p1#2], - [_p7#0, _p1#1, _p1#2], - [_p1#0, _p1#1, _p7#2], - [_p1#0, _p7#1, _p7#2], - _lowP, - [_p7#0, _p1#1, _p7#2] + _upperPoint, + [_x1, _y2, _z1], + [_x2, _y2, _z1], + [_x2, _y1, _z1], + [_x1, _y1, _z2], + [_x1, _y2, _z2], + _lowerPoint, + [_x2, _y1, _z2] ]; private _color = switch (side _object) do { From 4728a56394a038cdad4b5df103702611a5f597e0 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Fri, 16 Feb 2024 16:54:53 -0600 Subject: [PATCH 208/282] Cleaned up documentation and documentation --- addons/frag/stringtable.xml | 6 ------ docs/wiki/framework/frag-framework.md | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/addons/frag/stringtable.xml b/addons/frag/stringtable.xml index ab3d2034ecc..8470a36600d 100644 --- a/addons/frag/stringtable.xml +++ b/addons/frag/stringtable.xml @@ -144,12 +144,6 @@ For each unit a fragment could be shot towards, create it. This setting has no effect when "Random fragmentation" is selected. - - BlackListed Ammo Classnames - - - Comma seperated cfgAmmo classnames to always skip. Loaded at mission start. - Spalling Intensity diff --git a/docs/wiki/framework/frag-framework.md b/docs/wiki/framework/frag-framework.md index 1905a7996e6..e38798beab3 100644 --- a/docs/wiki/framework/frag-framework.md +++ b/docs/wiki/framework/frag-framework.md @@ -69,7 +69,7 @@ As long as the units match `ace_frag_metal`, the total mass of explosive filler `ace_frag_gurney_c` -The Gurney constant for explosive force. You can find a list of common explosive types below. If you can not find it here, or want more accurate numbers, just google the type of explosive and Gurney constant and you can find substantial information. This is **not** the detonation velocityof the explosive, do not confuse them†! +The Gurney constant for explosive force. You can find a list of common explosive types below. If you can not find it here, or want more accurate numbers, just google the type of explosive and Gurney constant and you can find substantial information. This is **not** the detonation velocity of the explosive, do not confuse them†! Type | Speed --------------- | -------- From 008328c7b0938de00acfaf63e9a82f1027dd8b2e Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Fri, 16 Feb 2024 16:56:13 -0600 Subject: [PATCH 209/282] reorganized postInit CBA_settingInitialized EH --- addons/frag/XEH_postInit.sqf | 55 ++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index 7be2fa31e7f..2e5b1b22b2e 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -15,9 +15,10 @@ }; #ifdef DEBUG_MODE_DRAW - [QGVAR(dev_clearTraces),LINKFUNC(dev_clearTraces)] call CBA_fnc_addEventHandler; + [QGVAR(dev_clearTraces), LINKFUNC(dev_clearTraces)] call CBA_fnc_addEventHandler; - if (!isServer && hasInterface) then { + if (!hasInterface) exitWith {}; + if (!isServer) then { ["ace_firedPlayer", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; ["ace_firedPlayerNonLocal", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; ["ace_firedNonPlayer", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; @@ -25,33 +26,31 @@ ["ace_firedPlayerVehicleNonLocal", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; ["ace_firedNonPlayerVehicle", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; }; - if (hasInterface) then { - GVAR(dev_drawPFEH) = [LINKFUNC(dev_drawTrace), 0] call CBA_fnc_addPerFrameHandler; - [ - "ace_interact_menu_newControllableObject", - { - params ["_type"]; + GVAR(dev_drawPFEH) = [LINKFUNC(dev_drawTrace), 0] call CBA_fnc_addPerFrameHandler; + [ + "ace_interact_menu_newControllableObject", + { + params ["_type"]; - private _action = [ - QGVAR(debugReset), - "Reset ACE Frag traces", - "", - { - [QGVAR(dev_clearTraces), []] call CBA_fnc_remoteEvent; - call FUNC(dev_clearTraces); - }, - {true} - ] call EFUNC(interact_menu,createAction); - [ - _type, - 1, - ["ACE_SelfActions"], - _action, - true - ] call ace_interact_menu_fnc_addActionToClass; - } - ] call CBA_fnc_addEventHandler; - }; + private _action = [ + QGVAR(debugReset), + "Reset ACE Frag traces", + "", + { + [QGVAR(dev_clearTraces), []] call CBA_fnc_remoteEvent; + call FUNC(dev_clearTraces); + }, + {true} + ] call EFUNC(interact_menu,createAction); + [ + _type, + 1, + ["ACE_SelfActions"], + _action, + true + ] call ace_interact_menu_fnc_addActionToClass; + } + ] call CBA_fnc_addEventHandler; #endif } ] call CBA_fnc_addEventHandler; From dd65fc8f382a84594666da32eb6a989b46e2598d Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 17 Feb 2024 13:03:09 -0600 Subject: [PATCH 210/282] missing underscore in fnc_dev_trackObj Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_dev_trackObj.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index fae711e26d5..880a0d19eb9 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -54,7 +54,7 @@ GVAR(dev_trackLines) set [getObjectID _object, [[getPosATL _object], _colorArray [_handle] call CBA_fnc_removePerFrameHandler; }; - (objectArray#0) pushBack getPosATL _object; + (_objectArray#0) pushBack getPosATL _object; }, 0, _object From c3470de53480c1397fd1cdf41d70936d467a6371 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 17 Feb 2024 13:04:19 -0600 Subject: [PATCH 211/282] stopped adding unneeded extra points Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> --- addons/frag/functions/fnc_dev_addRound.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_dev_addRound.sqf b/addons/frag/functions/fnc_dev_addRound.sqf index 5995b36670f..3105aeb4025 100644 --- a/addons/frag/functions/fnc_dev_addRound.sqf +++ b/addons/frag/functions/fnc_dev_addRound.sqf @@ -35,7 +35,7 @@ if (_isTraceBlue) then { // event handler to track round and cleanup when round is "dead" [ { - if (isGamePaused) exitWith {}; + if (isGamePaused || accTime == 0) exitWith {}; params ["_projectile", "_handle"]; if (!alive _projectile) exitWith { From b98aae7866434aed682ed4690d2402b0adeb4ad9 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 17 Feb 2024 13:12:33 -0600 Subject: [PATCH 212/282] cleaned un-updated stringtable entries --- addons/frag/functions/fnc_doSpall.sqf | 1 - addons/frag/stringtable.xml | 36 --------------------------- 2 files changed, 37 deletions(-) diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index 4bcb58ecab0..980fb19f333 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -21,7 +21,6 @@ TRACE_1("doSpall",_this); params ["_projectile", "_objectHit", "_lastPosASL", "_lastVelocity", "_surfaceNorm", "_surfaceType", "_ammo", "_shotParents", "_vectorUp"]; if (CBA_missionTime < GVAR(nextSpallAllowTime) || - {isNull _objectHit} || {_lastPosASL isEqualTo [0,0,0]} || {_ammo isEqualTo ""} || {_objectHit isKindOf "CAManBase"}) exitWith { diff --git a/addons/frag/stringtable.xml b/addons/frag/stringtable.xml index 8470a36600d..a84dfb65bae 100644 --- a/addons/frag/stringtable.xml +++ b/addons/frag/stringtable.xml @@ -200,51 +200,15 @@ The number of spall track calculations to perform in any given frame. This helps spread the FPS impact of tracking spall rounds across multiple frames, limiting its impact even further. - Ilość obliczeń wykonywanych przez symulację odprysków w danej klatce. Ta opcja pomaga rozprzestrzenić obliczenia odprysków na więcej klatek, zmniejszając spadek FPS jeszcze bardziej. Gibt die Anzahl der Explosionverfolgungsberechnungen an, die gleichzeitig ausgeführt werden. Das kann dabei helfen den FPS-Einfluss abzuschwächen, wenn Teile über mehrere Frames hinweg verfolgt werden. - El número de cálculos de esquirlas que se hará en cualquier cuadro. Esto ayuda a dispersar el impacto en FPS del seguimiento de esquirlas de balas a través de múltiples cuadros, lo que limita aún más su impacto. - Počet úlomků v daném snímku. Toto pomáhá rozšířit FPS dopad sledovaného úlomku napříč více snímky, omezuje jeho vliv ještě více. - O número de cálculos por estilhaço rastreado para executar em qualquer quadro. Isso ajuda a distribuir o impacto no FPS do rastreamento de estilhaço em vários quadros, o que limita o seu impacto ainda mais. - Le nombre de calculs de suivi à effectuer pour chaque image. Cela aide à répartir l'impact des calculs sur plusieurs images, limitant ainsi encore davantage l'impact sur les FPS. - A lepattogzási útvonalak számításának darabjai képkockánként. Ez eloszlatja az FPS-megszakadást több képkockára, ezzel csökkentve a súlyosságát. - Число обрабатываемых осколков за кадр. Это позволяет распределить нагрузку по отслеживанию осколков между несколькими кадрами, чтобы предотвратить падение FPS. - Il numero di calcoli per tracciamento di spalling ad ogni frame. Questo aiuta a distribuire l'impatto del tracciamento dello spalling su più frame, riducendolo ulteriormente. - 与えられたフレームごとに追跡する剥離飛翔体の数を決定します。FPS に影響をあたえないよう、剥離飛翔体を複数のフレームで追跡し、分散させています。 - 가능한 프레임마다 파편을 추적 및 계산합니다. 여러 프레임에 걸쳐 파편난 발사체를 추적하여 FPS에 도움을 줍니다. 이를 제한함으로써 더욱 큰 효과를 볼 수 있습니다. - 设定在每一帧数内,系统最大可追踪的破片粒子数量。此设定可有效帮助系统减低计算压力。 - 設定在每一幀數內,系統最大可追蹤的碎片/剝落粒子數量。此設定可有效幫助系統減低計算壓力 Frag/Spall Debug Tracing - Seguimiento de depuración de Fragmentación/Astillamiento - (Tylko SP) Wizualny debug odł./odpr. - (Pouze SP) Debug sledování Frag/Úlomků Splitter-/Explosions-Debug-Verfolgung - (Somente SP) Depuração de fragmentação e estilhaços traçantes - Fragmentation/éclat debug - (Csak SP) Repesz/Pattogzás debug követés - (Только для одиночной игры) Отслеживаение/отладка осколков - Debug Tracciamento Frag/Spall - (SP のみ) 破片/剥離のデバッグ用表示 - (싱글플레이 전용) 탄환파편/파편 디버그 추적화 - (仅单人)追踪显示破片粒子 - (僅在單人模式) 碎片/剝落除錯追蹤 Requires a mission/editor restart. Enables visual tracing of fragmentation and spalling rounds. - Requiere un reinicio misión/editor. Permite el seguimiento visual de la fragmentación y astillamientos de los proyectiles. - (Tylko SP) Wymaga restartu misji/edytora. Aktywuje wizualne śledzenie odłamków oraz odprysków w trybie gry Single Player. Splitter-/Explosions-Debugging - (Pouze SP) Vyžaduje restart mise/editoru. Aktivuje vizuální stopování fragmentace a úlomů pouze v režimu jednoho hráče. - (Somente SP) Requer um reinício de missão / editor. Habilita o rastreamento visual de projéteis de fragmentação e estilhaçamento apenas no modo de jogo SP. - Requiert un redémarrage de mission ou de l'éditeur. Active les traceurs visuels de fragmentation et d'éclats. - (Csak SP) Küldetés/Editor újraindítás szükséges. Engedélyezi a repeszek és pattogzó lövedékek vizuális nyomkövetését, csak egyjátékos módok alatt. - (Только для одиночной игры) Требует перезапуска миссии/редактора. Включает визуальные следы от осколков и обломков в режиме одиночной игры. - Richiede un restart editor/missione. Abilita il tracciamento visivo di schegge da frammentazione/spalling. - (SP のみ) ミッションとエディタの再起動が必要です。有効化すると、シングルプレイでのみ破片と剥離の飛翔体が見えるようになります。 - (仅单人)激活后,只有在单人模式下才可观察到破片粒子的移动轨迹。 - (僅在單人模式) 讓你在單人模式下可觀察到碎片/剝落粒子的移動軌跡 - (SP 전용) 임무 / 편집자가 다시 시작해야합니다. SP 게임 모드에서만 파편화 및 탄환파편의 시각적 추적을 가능하게 합니다. Draw Event Spheres From 05dedff99da6a5a126c9036fd7b782e0bcfbad67 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 20 Feb 2024 20:32:05 -0600 Subject: [PATCH 213/282] reworked some function headers and deleted whitespace in doFragTargeted --- addons/frag/functions/fnc_dev_drawTrace.sqf | 2 +- addons/frag/functions/fnc_doFragTargeted.sqf | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/addons/frag/functions/fnc_dev_drawTrace.sqf b/addons/frag/functions/fnc_dev_drawTrace.sqf index 3bae4b085ad..18a0e866098 100644 --- a/addons/frag/functions/fnc_dev_drawTrace.sqf +++ b/addons/frag/functions/fnc_dev_drawTrace.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: Lambda.Tiger - * Per frame function to draw all dev traces. + * This function draws all development traces and is intended to be called on each frame. * * Arguments: * None diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index d49025541e8..676922727d0 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -37,7 +37,7 @@ if (_fragTypes isEqualTo []) then { ]; }; -// Post 2.18 change - uncomment line 47, remove line 49, 56-62, 70-72, and change lines 64 & 170 from _targetse to _objects +// Post 2.18 change - uncomment line 41, remove line 43, 50-55, 63-65, and change lines 57 & 168 from _targetse to _objects // private _objects = [ASLToAGL _posASL, _fragRange, _fragRange, 0, false, _fragRange ] nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], false, true, true]; private _objects = (ASLToATL _posASL) nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], _fragRange]; @@ -52,7 +52,6 @@ private _targets = []; private _crew = crew _x; _crew pushBackUnique _x; _targets append _crew; - } forEach _objects; TRACE_3("Targets found",_posASL,_fragRange,count _targets); From fc745e49abaf51aa3878cfa45525af4934db19fc Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Fri, 1 Mar 2024 19:14:07 +0100 Subject: [PATCH 214/282] Removed outdated code --- addons/frag/XEH_postInit.sqf | 4 ---- 1 file changed, 4 deletions(-) diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index 2e5b1b22b2e..9bd5544813f 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -4,7 +4,6 @@ "CBA_settingsInitialized", { if (isServer) then { - call FUNC(initBlackList); call FUNC(initMaterialCache); [ QEGVAR(common,setShotParents), @@ -15,8 +14,6 @@ }; #ifdef DEBUG_MODE_DRAW - [QGVAR(dev_clearTraces), LINKFUNC(dev_clearTraces)] call CBA_fnc_addEventHandler; - if (!hasInterface) exitWith {}; if (!isServer) then { ["ace_firedPlayer", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; @@ -37,7 +34,6 @@ "Reset ACE Frag traces", "", { - [QGVAR(dev_clearTraces), []] call CBA_fnc_remoteEvent; call FUNC(dev_clearTraces); }, {true} From 279f2e05525d986b08129a192c1053d4c3515982 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Fri, 1 Mar 2024 19:51:21 +0100 Subject: [PATCH 215/282] Formatting and header fixes --- addons/frag/functions/fnc_dev_trackObj.sqf | 2 +- addons/frag/functions/fnc_doFrag.sqf | 1 + addons/frag/functions/fnc_doFragRandom.sqf | 1 + addons/frag/functions/fnc_doSpall.sqf | 1 + addons/frag/functions/fnc_getFragInfo.sqf | 8 ++++---- addons/frag/functions/fnc_getMaterialInfo.sqf | 3 ++- addons/frag/initSettings.inc.sqf | 2 +- addons/frag/initSettingsDebug.inc.sqf | 2 +- 8 files changed, 12 insertions(+), 8 deletions(-) diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index 880a0d19eb9..d690637814a 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -4,7 +4,7 @@ * This function adds an object to have its course tracked (every frame). * * Arguments: - * 0: Object to draw track OBJECT> (default: "objNull") + * 0: Object to draw track (default: objNull) * 1: Color of trace (default: "blue") * 2: Whether the object is a projectile or whether to add projectile EHs (default: false) * diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 27c92d16821..8d0840fa08d 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -17,6 +17,7 @@ * * Public: No */ + TRACE_1("begin doFrag",_this); params ["_posASL", "_velocity", "_ammo", "_shotParents"]; diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index 5101e414d02..fa7e63bbe1a 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -19,6 +19,7 @@ * * Public: No */ + params ["_posASL", "_fragVelocity", "_heightAGL", "_fragType", "_maxFragCount", "_shotParents"]; TRACE_6("doFragRandom",_posASL,_fragVelocity,_heightAGL,_fragType,_maxFragCount,_shotParents); diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index 980fb19f333..04f636773f5 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -15,6 +15,7 @@ * * Public: No */ + #define GLUE(g1,g2) g1##g2 TRACE_1("doSpall",_this); diff --git a/addons/frag/functions/fnc_getFragInfo.sqf b/addons/frag/functions/fnc_getFragInfo.sqf index 0d69de5d177..c8bbdd5d86a 100644 --- a/addons/frag/functions/fnc_getFragInfo.sqf +++ b/addons/frag/functions/fnc_getFragInfo.sqf @@ -54,25 +54,25 @@ if (isArray (_ammoConfig >> QGVAR(classes))) then { * or 0.8 * _gurneyConstant * sqrt (_chargeMass /(_metalMass + _chargeMass * _geometryCoefficient)); (slightly faster to compute) */ -private _chargeMass = getNumber (_ammoConfig >> QGVAR(CHARGE)); +private _chargeMass = getNumber (_ammoConfig >> QGVAR(charge)); if (_chargeMass == 0) then { _chargeMass = 1; _notifyMissingEntries = true; }; -private _metalMass = getNumber (_ammoConfig >> QGVAR(METAL)); +private _metalMass = getNumber (_ammoConfig >> QGVAR(metal)); if (_metalMass == 0) then { _metalMass = 2; _notifyMissingEntries = true; }; -private _geometryCoefficient = getNumber (_ammoConfig >> QGVAR(GURNEY_K)); +private _geometryCoefficient = getNumber (_ammoConfig >> QGVAR(gurney_k)); if (_geometryCoefficient == 0) then { _geometryCoefficient = 0.8; _notifyMissingEntries = true; }; -private _gurneyConstant = getNumber (_ammoConfig >> QGVAR(GURNEY_C)); +private _gurneyConstant = getNumber (_ammoConfig >> QGVAR(gurney_c)); if (_gurneyConstant == 0) then { _gurneyConstant = 2440; _notifyMissingEntries = true; diff --git a/addons/frag/functions/fnc_getMaterialInfo.sqf b/addons/frag/functions/fnc_getMaterialInfo.sqf index 7b3435b16a4..75a004843b2 100644 --- a/addons/frag/functions/fnc_getMaterialInfo.sqf +++ b/addons/frag/functions/fnc_getMaterialInfo.sqf @@ -10,10 +10,11 @@ * Material categories as expanded on in line 44 below * * Example: - * [_surfaceType] call ace_frag_fnc_getFragInfo; + * [_surfaceType] call ace_frag_fnc_getMaterialInfo; * * Public: No */ + #define ACE_FRAG_SOUNDENVIRON_STR_LEN 12 #define ACE_FRAG_SOUNDGIT_STR_LEN 8 #define ACE_FRAG_MATERIAL_SEARCH_LEN 10 diff --git a/addons/frag/initSettings.inc.sqf b/addons/frag/initSettings.inc.sqf index 9cadb4463ed..73cc70e6b47 100644 --- a/addons/frag/initSettings.inc.sqf +++ b/addons/frag/initSettings.inc.sqf @@ -1,4 +1,4 @@ -private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; +private _category = format ["ACE %1", LLSTRING(Module_DisplayName)]; [ QGVAR(enabled), diff --git a/addons/frag/initSettingsDebug.inc.sqf b/addons/frag/initSettingsDebug.inc.sqf index 4f2e0dce962..c2ab266569c 100644 --- a/addons/frag/initSettingsDebug.inc.sqf +++ b/addons/frag/initSettingsDebug.inc.sqf @@ -1,4 +1,4 @@ -private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; +private _category = format ["ACE %1", LLSTRING(Module_DisplayName)]; [ QGVAR(debugOptions), From 480d2df446f864b9724a38ddb1012fbe48df6566 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Fri, 1 Mar 2024 19:51:51 +0100 Subject: [PATCH 216/282] Ignore curators and spectators --- addons/frag/functions/fnc_doFragTargeted.sqf | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index 676922727d0..ffaa59e9631 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -20,6 +20,7 @@ * * Public: No */ + #define ACE_FRAG_DEFAULT_HEIGHT 0.5 #define ACE_FRAG_DEFAULT_CROSS_AREA 0.75 #define ACE_FRAG_MIN_TARGET_AREA 0.5 @@ -37,10 +38,10 @@ if (_fragTypes isEqualTo []) then { ]; }; -// Post 2.18 change - uncomment line 41, remove line 43, 50-55, 63-65, and change lines 57 & 168 from _targetse to _objects -// private _objects = [ASLToAGL _posASL, _fragRange, _fragRange, 0, false, _fragRange ] nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], false, true, true]; +// Post 2.18 change - uncomment line 41, remove line 43, 50-55, 64-66, and change lines 57 & 169 from _targets to _objects +// private _objects = [ASLToAGL _posASL, _fragRange, _fragRange, 0, false, _fragRange] nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], false, true, true]; -private _objects = (ASLToATL _posASL) nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], _fragRange]; +private _objects = (ASLToAGL _posASL) nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], _fragRange]; if (_objects isEqualTo []) exitWith { TRACE_2("No nearby targets",_posASL,_fragRange); 0 @@ -60,7 +61,8 @@ TRACE_3("Targets found",_posASL,_fragRange,count _targets); private _fragArcs = createHashMap; private _totalFragCount = 0; { // Begin of forEach iterating on _targets - if (!alive _x) then { + // Ignore dead units, curators and spectators + if (!alive _x || {getNumber ((configOf _x) >> "isPlayableLogic") == 1}) then { continue; }; private _target = _x; From d6c21e0cc44ffd83f2e82358e8bbe5fb7025089f Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sat, 2 Mar 2024 14:54:19 +0100 Subject: [PATCH 217/282] Made clear traces global again, added interaction condition --- addons/frag/XEH_postInit.sqf | 6 ++++-- addons/frag/initSettingsDebug.inc.sqf | 5 +---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index 9bd5544813f..49e0888509a 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -14,6 +14,8 @@ }; #ifdef DEBUG_MODE_DRAW + [QGVAR(dev_clearTraces), LINKFUNC(dev_clearTraces)] call CBA_fnc_addEventHandler; + if (!hasInterface) exitWith {}; if (!isServer) then { ["ace_firedPlayer", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; @@ -34,9 +36,9 @@ "Reset ACE Frag traces", "", { - call FUNC(dev_clearTraces); + [QGVAR(dev_clearTraces), []] call CBA_fnc_globalEvent; }, - {true} + {GVAR(dev_trackLines) isNotEqualTo createHashMap} ] call EFUNC(interact_menu,createAction); [ _type, diff --git a/addons/frag/initSettingsDebug.inc.sqf b/addons/frag/initSettingsDebug.inc.sqf index c2ab266569c..a1528a446cf 100644 --- a/addons/frag/initSettingsDebug.inc.sqf +++ b/addons/frag/initSettingsDebug.inc.sqf @@ -13,10 +13,7 @@ private _category = format ["ACE %1", LLSTRING(Module_DisplayName)]; "CHECKBOX", [LSTRING(HitSphereEnable), LSTRING(HitSphereEnable_Desc)], [_category, LSTRING(Debug)], - false, - 0, - {}, - true + false ] call CBA_fnc_addSetting; [ From d6a37f3fdeb6dffa372b2c1d8f7ff4e0bc380d95 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sat, 2 Mar 2024 16:36:43 +0100 Subject: [PATCH 218/282] Change stringtable entries --- addons/frag/XEH_postInit.sqf | 2 +- addons/frag/functions/fnc_doFragTargeted.sqf | 1 - addons/frag/stringtable.xml | 8 ++++---- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index 49e0888509a..21ba57c9fba 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -46,7 +46,7 @@ ["ACE_SelfActions"], _action, true - ] call ace_interact_menu_fnc_addActionToClass; + ] call EFUNC(interact_menu,addActionToClass); } ] call CBA_fnc_addEventHandler; #endif diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index ffaa59e9631..dab13782fb3 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -40,7 +40,6 @@ if (_fragTypes isEqualTo []) then { // Post 2.18 change - uncomment line 41, remove line 43, 50-55, 64-66, and change lines 57 & 169 from _targets to _objects // private _objects = [ASLToAGL _posASL, _fragRange, _fragRange, 0, false, _fragRange] nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], false, true, true]; - private _objects = (ASLToAGL _posASL) nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], _fragRange]; if (_objects isEqualTo []) exitWith { TRACE_2("No nearby targets",_posASL,_fragRange); diff --git a/addons/frag/stringtable.xml b/addons/frag/stringtable.xml index a84dfb65bae..a60e70222e3 100644 --- a/addons/frag/stringtable.xml +++ b/addons/frag/stringtable.xml @@ -127,7 +127,7 @@ Simulation Mode - Create a combination of random and/or unit targeted fragments + Sets the fragmentation simulation mode, which can be targeted, random or both. Unit targeted fragmentation @@ -142,13 +142,13 @@ Disable Fragment Misses - For each unit a fragment could be shot towards, create it. This setting has no effect when "Random fragmentation" is selected. + Create a fragment for each unit that a fragment could be shot towards. This setting has no effect when "Random fragmentation" is selected. Spalling Intensity - Modifier to increase or decrease the number and intensity of spalling events. Increasing this value may cause performance degredation + Modifier to increase or decrease the number and intensity of spalling events. Increasing this value may cause performance degradation. Maximum Projectiles Tracked @@ -220,7 +220,7 @@ Draw Hitboxes - Draw hitboxes on objects added using ace_frag_fnc_dev_trackHitBox. + Draw hitboxes on objects that were hit. From e3395c5a2073831708f5cb65bee9648baab1f35e Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 2 Mar 2024 17:22:32 -0600 Subject: [PATCH 219/282] Removed unused stringtable entries & fixed hitbox description --- addons/frag/stringtable.xml | 56 ++----------------------------------- 1 file changed, 2 insertions(+), 54 deletions(-) diff --git a/addons/frag/stringtable.xml b/addons/frag/stringtable.xml index a60e70222e3..28c5627c541 100644 --- a/addons/frag/stringtable.xml +++ b/addons/frag/stringtable.xml @@ -150,64 +150,12 @@ Modifier to increase or decrease the number and intensity of spalling events. Increasing this value may cause performance degradation. - - Maximum Projectiles Tracked - Máximos proyectiles rastreados - Maks. liczba śledzonych pocisków - Maximalzahl der verfolgten Projektile - Maximální počet sledovaných projektilů - Máximo de projéteis rastreados - Nombre maximum de projectiles suivis - Maximum követett repeszek - Макс. количество отслеживаемых снарядов - Numero massimo di Proiettili Tracciati - 飛翔体最大追跡数 - 최대 발사체 추적수 - 最大破片粒子追踪数量 - 最大碎片/剝落粒子追蹤數量 - - - This setting controls the maximum amount of projectiles the fragmentation and spalling system will track at any given time. If more projectiles are fired, they will not be tracked. Lower this setting if you do not want FPS drops at high-count projectile scenarios ( >200 rounds in the air at once) - Este ajuste controla la cantidad máxima de proyectiles del sistema de fragmentación y astillamiento de los que se hará un seguimiento en cualquier momento dado. Si se disparan más proyectiles, no serán rastreados. Baja esta opción si no deseas una bajada de FPS en escenarios con muchos proyectiles (>200 proyectiles en el aire a la vez) - To ustawienie kontroluje maksymalną ilość pocisków, jakie fragmentacja i odpryski symulują w danym momencie. Jeżeli więcej pocisków będzie wystrzelonych, wtedy nie będą one śledzone. Zmniejsz tą opcję jeżeli nie chcesz odczuwać spadków FPS podczas ciężkiej wymiany ognia (więcej niż 200 pocisków w powietrzu na raz). - Diese Einstellung steuert die maximale Anzahl an Projektilen, die das Splitter- und Explosionssystem gleichzeitig verfolgen wird. Wenn mehr Projektile abgefeuert werden, werden sie nicht verfolgt werden. Diese Einstellung zu verringern, kann FPS-Einbrüche bei Szenarien mit vielen Projektilen verhindern (>200 Objekte gleichzeitig in der Luft) - Toto nastavení kontroluje maximální množství projektilů z fragmentace a úlomků, která jsou sledována v dané době. Pokud je vystřeleno více projektilů, tak nebudou sledovány. Snižte toto nastavení pokud si nepřejete propady FPS v situacích, kde je velké množství projektilů ( >200 nábojů najednou ve vzduchu) - Esta definição controla a quantidade máxima de projéteis que o sistema de fragmentação e estilhaçamento irá acompanhar em qualquer momento. Se mais projéteis são disparados, eles não serão rastreados. Diminua essa configuração se você não quiser que o FPS caia em cenários com alta contagem de projéteis (> 200 projéteis no ar ao mesmo tempo) - Ce paramètre contrôle le nombre maximum de projectiles et d'éclats résultant de la fragmentation, que le système peut suivre à chaque instant.\nSi plus de projectiles sont générés, ils ne seront pas pris en compte. Baissez ce réglage si vous ne voulez pas de chute de FPS en cas de nombre important de projectiles (>200 éclats en même temps). - Ez a beállítás szabályozza a repeszeződés és pattogzás által kilőtt objektumok követett számát. Ha több ez a szám, ezek az objektumok nem lesznek követve. Csökkentsd ezt a beállítást, ha nem akarsz lassulásokat magas-törmelékmennyiségű helyzetekben (200+ repesz a levegőben egyszerre) - Эта настройка контролирует максимальное количество снарядов, которок отслеживает система осколков и обломков в каждый момент времени. Снаряды, выстреленные сверх этого числа, отслеживаться не будут. Уменьшите это значение, если вы не хотите падения FPS при большом количестве снарядов в одной перестрелке (> 200 одновременно летящих снарядов) - Questo parametro controlla il numero massimo di proiettili che la frammentazione e il sistema di spalling tracciano in ogni momento. Se vengono sparati ulteriori proiettili, non verranno tracciati. Abbassa questo parametro se non vuoi cali di FPS in scenari con molti proiettili (>200 proiettili in aria contemporaneamente) - この設定では、断片化および剥離システムが常に追跡する飛翔体の最大量を制御します。 さらに多くの飛翔体が発射された場合、それらは追跡されません。 弾数が多いシナリオでFPSを低下させたくない場合は、この設定を下げてください。 (一度に200発以上が空中に発射されます) - 이 설정은 탄환파편 및 파편 시스템으로 인해 생긴 발사체의 수를 결정합니다. 만약 더 많은 발사체가 나올 경우 정해진 수 이외에는 추적하지 않습니다. 이 설정을 낮춤으로써 파편이 많은 시나리오를 실행할때 더욱 원활히 진행할 수 있습니다 (한 번에 200개 이하) - 设定在指定时间内,系统最大可追踪的破片粒子数量。如有更多的碎片在这之后产生,这些粒子将不会被追踪。如果你想要维持好的帧数,此设定勿调的过高。( >一次200颗粒子) - 設定在指定時間內,系統最大可追蹤的碎片/剝落粒子數量。如有更多的碎片在這之後產生,這些粒子將不會被追蹤。如果你想要維持好的幀數,此設定勿調的過高。( >一次200顆粒子) - - - Maximum Projectiles Per Frame - Máximos proyectiles por cuadro - Maximale Anzahl an Projektilen pro Frame - Maks. liczba pocisków na klatkę - Maximální počet projektilů za jeden snímek - Projéteis máximos por quadro - Nombre maximal de projectiles par image - Maximum repesz/képkocka - Макс. количество снарядов за кадр - Numero massimo di proiettili per Frame - フレームごとの飛翔体最大数 - 프레임 당 최대 발사체 수 - 每帧最大破片粒子数量 - 每一幀數(FPS)最大碎片/剝落粒子數量 - - - The number of spall track calculations to perform in any given frame. This helps spread the FPS impact of tracking spall rounds across multiple frames, limiting its impact even further. - Gibt die Anzahl der Explosionverfolgungsberechnungen an, die gleichzeitig ausgeführt werden. Das kann dabei helfen den FPS-Einfluss abzuschwächen, wenn Teile über mehrere Frames hinweg verfolgt werden. - Frag/Spall Debug Tracing Splitter-/Explosions-Debug-Verfolgung - Requires a mission/editor restart. Enables visual tracing of fragmentation and spalling rounds. + Enables visual tracing of fragmentation and spalling rounds. Splitter-/Explosions-Debugging @@ -220,7 +168,7 @@ Draw Hitboxes - Draw hitboxes on objects that were hit. + Draw hitboxes on objects that were targeted. From f57ac9432587c57bef77f4b749056d62ca910f84 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 2 Mar 2024 17:59:45 -0600 Subject: [PATCH 220/282] Small coding standard changes (missing semicolons on non-return values, extra parenthesis) --- addons/frag/functions/fnc_dev_drawTrace.sqf | 2 +- addons/frag/functions/fnc_dev_fragCalcDump.sqf | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/frag/functions/fnc_dev_drawTrace.sqf b/addons/frag/functions/fnc_dev_drawTrace.sqf index 18a0e866098..63b05bc8ba5 100644 --- a/addons/frag/functions/fnc_dev_drawTrace.sqf +++ b/addons/frag/functions/fnc_dev_drawTrace.sqf @@ -20,7 +20,7 @@ if (!GVAR(debugOptions)) exitWith {}; { _y params ["_posArray", "_color"]; - if (count (_posArray) > 1) then { + if (count _posArray > 1) then { for "_j" from 1 to count _posArray - 1 do { drawLine3D [_posArray#(_j-1), _posArray#_j, _color]; }; diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf index 937cf2ddb66..acd98574636 100644 --- a/addons/frag/functions/fnc_dev_fragCalcDump.sqf +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -21,14 +21,14 @@ params [["_logAll", false, [false]]]; private _allAmmoConfigs = configProperties [configFile >> "CfgAmmo", "isClass _x && !('ace_frag' in configName _x)", true]; private _processedCfgAmmos = []; -private _nPrinted = 0; +private _numberPrinted = 0; diag_log text "//****************** fragCalcDump Beg ******************//"; { // Begin _allAmmoConfigs forEach private _ammo = configName _x; if (_ammo isEqualTo "" || {_ammo in _processedCfgAmmos}) then { - continue + continue; }; private _shouldFrag = [_ammo] call FUNC(shouldFrag); @@ -48,11 +48,11 @@ diag_log text "//****************** fragCalcDump Beg ******************//"; diag_log text format [" Frag range: %1", _fragRange]; diag_log text format [" Frag speed range: %1", _fragPowerSpeedRange]; diag_log text format [" Number frags: %1", _fragCount]; - INC(_nPrinted); + INC(_numberPrinted); }; _processedCfgAmmos pushBack _ammo; } forEach _allAmmoConfigs; diag_log text "//****************** fragCalcDump End ******************//"; -diag_log text format ["//********************** printed %1 *********************//", _nPrinted]; +diag_log text format ["//********************** printed %1 *********************//", _numberPrinted]; From 8a2f40c360e4ab0be874fb0c6e27fc38ac42ecb6 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 2 Mar 2024 18:00:11 -0600 Subject: [PATCH 221/282] Changed sphere size and added return based on usage in dev_trackHitBox --- addons/frag/functions/fnc_dev_sphereDraw.sqf | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/frag/functions/fnc_dev_sphereDraw.sqf b/addons/frag/functions/fnc_dev_sphereDraw.sqf index cf9ca7335c0..8c3137b647d 100644 --- a/addons/frag/functions/fnc_dev_sphereDraw.sqf +++ b/addons/frag/functions/fnc_dev_sphereDraw.sqf @@ -8,7 +8,7 @@ * 1: Color of sphere (default: "blue") * * Return Value: - * None + * The created sphere object * * Example: * [getPosASL player, "red"] call ace_frag_fnc_dev_sphereDraw; @@ -34,6 +34,7 @@ if (_color select [0,1] != "(") then { }; private _colorString = "#(argb,8,8,3)color" + _color; -private _sphere = createVehicle ["Sign_Sphere25cm_F", ASLtoATL _posASL, [], 0, "CAN_COLLIDE"]; +private _sphere = createVehicle ["Sign_Sphere10cm_F", ASLtoATL _posASL, [], 0, "CAN_COLLIDE"]; _sphere setObjectTextureGlobal [0, _colorString]; GVAR(dev_eventSpheres) pushBack _sphere; +_sphere From 3cb07e832342fc8cce5f3833084f34e4e8d0e13d Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 2 Mar 2024 18:08:03 -0600 Subject: [PATCH 222/282] removed "_lo" random fragment entries as they are unused --- addons/frag/CfgAmmoFragSpawner.hpp | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/addons/frag/CfgAmmoFragSpawner.hpp b/addons/frag/CfgAmmoFragSpawner.hpp index 867766f72c4..99c8012511c 100644 --- a/addons/frag/CfgAmmoFragSpawner.hpp +++ b/addons/frag/CfgAmmoFragSpawner.hpp @@ -19,9 +19,6 @@ class GVAR(spawnbase): B_65x39_Caseless { class GVAR(def_10): GVAR(spawnbase) { submunitionConeType[] = {"random", 10}; }; -class GVAR(def_10_lo): GVAR(def_10) { - submunitionConeAngle = 85; -}; class GVAR(def_10_mid): GVAR(def_10) { submunitionConeAngle = 85; triggerSpeedCoef[] = {-1.5, 1.5}; @@ -40,9 +37,6 @@ class GVAR(def_10_top): GVAR(def_10) { class GVAR(def_15): GVAR(spawnbase) { submunitionConeType[] = {"random", 15}; }; -class GVAR(def_15_lo): GVAR(def_15) { - submunitionConeAngle = 85; -}; class GVAR(def_15_mid): GVAR(def_15) { submunitionConeAngle = 85; triggerSpeedCoef[] = {-1.5, 1.5}; @@ -62,9 +56,6 @@ class GVAR(def_15_top): GVAR(def_15) { class GVAR(def_5): GVAR(spawnbase) { submunitionConeType[] = {"random", 5}; }; -class GVAR(def_5_lo): GVAR(def_5) { - submunitionConeAngle = 85; -}; class GVAR(def_5_mid): GVAR(def_5) { submunitionConeAngle = 85; triggerSpeedCoef[] = {-1.5, 1.5}; @@ -85,9 +76,6 @@ class GVAR(def_tiny_15): GVAR(spawnbase) { submunitionConeType[] = {"random", 15}; submunitionAmmo = QGVAR(tiny); }; -class GVAR(def_tiny_15_lo): GVAR(def_tiny_15) { - submunitionConeAngle = 85; -}; class GVAR(def_tiny_15_mid): GVAR(def_tiny_15) { submunitionConeAngle = 85; triggerSpeedCoef[] = {-1.5, 1.5}; @@ -108,9 +96,6 @@ class GVAR(def_tiny_10): GVAR(spawnbase) { submunitionConeType[] = {"random", 10}; submunitionAmmo = QGVAR(tiny); }; -class GVAR(def_tiny_10_lo): GVAR(def_tiny_10) { - submunitionConeAngle = 85; -}; class GVAR(def_tiny_10_mid): GVAR(def_tiny_10) { submunitionConeAngle = 85; triggerSpeedCoef[] = {-1.5, 1.5}; @@ -131,9 +116,6 @@ class GVAR(def_tiny_5): GVAR(spawnbase) { submunitionConeType[] = {"random", 5}; submunitionAmmo = QGVAR(tiny); }; -class GVAR(def_tiny_5_lo): GVAR(def_tiny_5) { - submunitionConeAngle = 85; -}; class GVAR(def_tiny_5_mid): GVAR(def_tiny_5) { submunitionConeAngle = 85; triggerSpeedCoef[] = {-1.5, 1.5}; @@ -154,9 +136,6 @@ class GVAR(def_small_15): GVAR(spawnbase) { submunitionConeType[] = {"random", 15}; submunitionAmmo = QGVAR(small); }; -class GVAR(def_small_15_lo): GVAR(def_small_15) { - submunitionConeAngle = 815; -}; class GVAR(def_small_15_mid): GVAR(def_small_15) { submunitionConeAngle = 815; triggerSpeedCoef[] = {-1.15, 1.15}; @@ -177,9 +156,6 @@ class GVAR(def_small_10): GVAR(spawnbase) { submunitionConeType[] = {"random", 10}; submunitionAmmo = QGVAR(small); }; -class GVAR(def_small_10_lo): GVAR(def_small_10) { - submunitionConeAngle = 810; -}; class GVAR(def_small_10_mid): GVAR(def_small_10) { submunitionConeAngle = 810; triggerSpeedCoef[] = {-1.10, 1.10}; @@ -199,9 +175,6 @@ class GVAR(def_small_5): GVAR(spawnbase) { submunitionConeType[] = {"random", 5}; submunitionAmmo = QGVAR(small); }; -class GVAR(def_small_5_lo): GVAR(def_small_5) { - submunitionConeAngle = 85; -}; class GVAR(def_small_5_mid): GVAR(def_small_5) { submunitionConeAngle = 85; triggerSpeedCoef[] = {-1.5, 1.5}; From 3e52ce29812b715f4f808b9310533995ab294399 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 2 Mar 2024 19:17:38 -0600 Subject: [PATCH 223/282] doFragRandom was always being called and spawning at least 5 fragments even when the fragment budget of 50 was reached. Fixed variable name (AGL instead of ATL). --- addons/frag/functions/fnc_doFrag.sqf | 4 ++-- addons/frag/functions/fnc_doFragRandom.sqf | 11 ++++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 8d0840fa08d..cf919851863 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -17,7 +17,7 @@ * * Public: No */ - +#define ACE_FRAG_MIN_FRAG_BUDGET_FOR_RANDOM 3 TRACE_1("begin doFrag",_this); params ["_posASL", "_velocity", "_ammo", "_shotParents"]; @@ -56,6 +56,6 @@ if (GVAR(fragSimComplexity) != 1 && _fragRange > 3) then { _maxFragCount = _maxFragCount - ([_posASL, _fragVel, _fragRange, _maxFragCount, _fragTypes, _modFragCount, _shotParents] call FUNC(doFragTargeted)); }; -if (GVAR(fragSimComplexity) > 0) then { +if (GVAR(fragSimComplexity) > 0 && _maxFragCount >= ACE_FRAG_MIN_FRAG_BUDGET_FOR_RANDOM) then { [_posASL, _velocity, _heightATL, _fragTypes, _maxFragCount, _shotParents] call FUNC(doFragRandom); }; diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index fa7e63bbe1a..f276c8edced 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -1,7 +1,8 @@ #include "..\script_component.hpp" /* * Author: Jaynus, NouberNou, Lambda.Tiger - * This function creates fragments randomly spreading out from an explosion to a maximum of 15. + * This function creates fragments randomly spreading out from an explosion. + * This function will spawn 5, 10, or 15 fragments depending on the * * Arguments: * 0: Position (posASL) of fragmenting projectile @@ -20,13 +21,13 @@ * Public: No */ -params ["_posASL", "_fragVelocity", "_heightAGL", "_fragType", "_maxFragCount", "_shotParents"]; -TRACE_6("doFragRandom",_posASL,_fragVelocity,_heightAGL,_fragType,_maxFragCount,_shotParents); +params ["_posASL", "_fragVelocity", "_heightATL", "_fragType", "_maxFragCount", "_shotParents"]; +TRACE_6("doFragRandom",_posASL,_fragVelocity,_heightATL,_fragType,_maxFragCount,_shotParents); // See CfgAmmoFragSpawner for different frag types private _hMode = switch (true) do { - case (_heightAGL > 10): {"_top"}; - case (_heightAGL > 5): {"_hi"}; + case (_heightATL > 10): {"_top"}; + case (_heightATL > 5): {"_hi"}; default {"_mid"}; }; From 5915d0ee641f270253f0d105115238220f703807 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 2 Mar 2024 19:21:51 -0600 Subject: [PATCH 224/282] removed unnceassary "disableCollisionWith" --- addons/frag/functions/fnc_dev_trackHitBox.sqf | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/frag/functions/fnc_dev_trackHitBox.sqf b/addons/frag/functions/fnc_dev_trackHitBox.sqf index 7f9d5aeba87..b3f8f7a1536 100644 --- a/addons/frag/functions/fnc_dev_trackHitBox.sqf +++ b/addons/frag/functions/fnc_dev_trackHitBox.sqf @@ -47,7 +47,6 @@ private _centerPoint = ASLToAGL getPosASL _object; if (GVAR(dbgSphere) && _addSphere && {isNull objectParent _object}) then { private _centerSphere = [getPosASL _object, "yellow"] call FUNC(dev_sphereDraw); - _centerSphere disableCollisionWith _object; _centerSphere attachTo [_object, _object worldToModel _centerPoint]; }; From 4c905fed420c67485638a615ba9152ffe57c8471 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 2 Mar 2024 22:28:41 -0600 Subject: [PATCH 225/282] Clarified trace statements and corrected format and spelling --- addons/frag/functions/fnc_doFragRandom.sqf | 2 +- addons/frag/functions/fnc_doFragTargeted.sqf | 16 +++++++++------- addons/frag/functions/fnc_getMaterialInfo.sqf | 8 +++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index f276c8edced..1d3b3f51624 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -46,7 +46,7 @@ _fragSpawner setVelocity _fragVelocity; _fragSpawner setShotParents _shotParents; #ifdef DEBUG_MODE_FULL -systemChat ("fragging, id: " + getObjectID _proj); +systemChat ("frag random objectID: " + getObjectID _proj); #endif #ifdef DEBUG_MODE_DRAW _fragSpawner addEventHandler [ diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index dab13782fb3..6630f460abe 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -38,8 +38,8 @@ if (_fragTypes isEqualTo []) then { ]; }; -// Post 2.18 change - uncomment line 41, remove line 43, 50-55, 64-66, and change lines 57 & 169 from _targets to _objects -// private _objects = [ASLToAGL _posASL, _fragRange, _fragRange, 0, false, _fragRange] nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], false, true, true]; +// Post 2.18 change - uncomment line 41, and remove lines 43, 50-55, 64-66 +// private _targets = [ASLToAGL _posASL, _fragRange, _fragRange, 0, false, _fragRange] nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], false, true, true]; private _objects = (ASLToAGL _posASL) nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], _fragRange]; if (_objects isEqualTo []) exitWith { TRACE_2("No nearby targets",_posASL,_fragRange); @@ -56,12 +56,14 @@ private _targets = []; TRACE_3("Targets found",_posASL,_fragRange,count _targets); -// limit number of fragments per direction (2D) to 10 using _fragArcs +// limit number of fragments per direction (2D) to _fragsPerFragArc using _fragArcs private _fragArcs = createHashMap; +private _fragsPerFragArc = _modFragCount * ACE_FRAG_FRAGS_PER_ARC_CONSTANT; private _totalFragCount = 0; { // Begin of forEach iterating on _targets // Ignore dead units, curators and spectators if (!alive _x || {getNumber ((configOf _x) >> "isPlayableLogic") == 1}) then { + TRACE_1("dead or logic",_x); continue; }; private _target = _x; @@ -106,14 +108,14 @@ private _totalFragCount = 0; parseNumber (GVAR(atLeastOne) || {random 1 < _fragChance}); }; if (_fragCount == 0) then { - TRACE_2("fragments",_fragChance,_fragCount); + TRACE_2("no fragments",_fragChance,_fragCount); continue; }; // handle limiting fragments per degree arc private _dir = floor (_posASL getDir _target); private _fragPerArc = _fragArcs getOrDefault [_dir, 0]; - if (_fragPerArc > 10) then { + if (_fragPerArc > _fragsPerFragArc) then { continue; } else { _fragArcs set [_dir, _fragPerArc + _fragCount]; @@ -169,7 +171,7 @@ private _totalFragCount = 0; } forEach _targets; #ifdef DEBUG_MODE_FULL -systemChat ("fragCount cnt: " + str _totalFragCount); -TRACE_1("fragCount",_totalFragCount); +systemChat ("targeted frag count: " + str _totalFragCount); +TRACE_1("targeted frag count",_totalFragCount); #endif _totalFragCount diff --git a/addons/frag/functions/fnc_getMaterialInfo.sqf b/addons/frag/functions/fnc_getMaterialInfo.sqf index 75a004843b2..f2910ed0d33 100644 --- a/addons/frag/functions/fnc_getMaterialInfo.sqf +++ b/addons/frag/functions/fnc_getMaterialInfo.sqf @@ -16,7 +16,7 @@ */ #define ACE_FRAG_SOUNDENVIRON_STR_LEN 12 -#define ACE_FRAG_SOUNDGIT_STR_LEN 8 +#define ACE_FRAG_SOUNDHIT_STR_LEN 8 #define ACE_FRAG_MATERIAL_SEARCH_LEN 10 params ["_surfType"]; @@ -24,9 +24,7 @@ params ["_surfType"]; private _material = GVAR(spallMaterialCache) get _surfType; TRACE_2("materialCache",_surfType,_material); -if (!isNil "_material") exitWith { - _material -}; +if (!isNil "_material") exitWith {_material}; // Use 'soundEnviron' or 'soundHit' to extract approx material private _surfaceConfig = configFile >> "CfgSurfaces" >> _surfType; if (isClass _surfaceConfig) then { @@ -39,7 +37,7 @@ if (isClass _surfaceConfig) then { _surfFileText = _surfFileText regexReplace ["[^a-z0-9]", ""]; private _idx = ACE_FRAG_SOUNDENVIRON_STR_LEN + (_surfFileText find "soundenviron"); if (_surfFileText select [_idx, 5] isEqualTo "empty") then { - _idx = ACE_FRAG_SOUNDGIT_STR_LEN + (_surfFileText find "soundhit"); + _idx = ACE_FRAG_SOUNDHIT_STR_LEN + (_surfFileText find "soundhit"); }; _material = _surfFileText select [_idx, ACE_FRAG_MATERIAL_SEARCH_LEN]; }; From 9c6a919bb921804548052818bfdb1c9793dcaa3d Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 2 Mar 2024 22:29:41 -0600 Subject: [PATCH 226/282] Do spall exits for time 90% of the time (round hits multiple walls) and should exit on "hitting ground since no spalling is generated --- addons/frag/functions/fnc_doSpall.sqf | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index 04f636773f5..68d1336c2da 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -17,19 +17,19 @@ */ #define GLUE(g1,g2) g1##g2 - TRACE_1("doSpall",_this); +if (CBA_missionTime < GVAR(nextSpallAllowTime)) exitWith { + TRACE_2("time exit",CBA_missionTime,GVAR(nextSpallAllowTime)); +}; params ["_projectile", "_objectHit", "_lastPosASL", "_lastVelocity", "_surfaceNorm", "_surfaceType", "_ammo", "_shotParents", "_vectorUp"]; -if (CBA_missionTime < GVAR(nextSpallAllowTime) || - {_lastPosASL isEqualTo [0,0,0]} || - {_ammo isEqualTo ""} || +if (_ammo == "" || {_objectHit isKindOf "CAManBase"}) exitWith { - TRACE_4("time/invalidHit",CBA_missionTime,GVAR(nextSpallAllowTime),_objectHit,_lastPosASL); + TRACE_4("invalid round or hit",CBA_missionTime,GVAR(nextSpallAllowTime),_objectHit,_lastPosASL); }; private _material = [_surfaceType] call FUNC(getMaterialInfo); -if (_material == "ground") then { +if (_material == "ground") exitWith { #ifdef DEBUG_MODE_FULL systemChat "ground spall"; #endif @@ -44,15 +44,15 @@ private _vel = if (alive _projectile) then { [0, 0, 0] }; -private _velocityChange = 0 max (vectorMagnitude _lastVelocity - vectorMagnitude _vel); +private _speedChange = 0 max (vectorMagnitude _lastVelocity - vectorMagnitude _vel); /* * This is all fudge factor since real spalling is too complex for calculation. * There are two terms. The first is from round impact, taking a quasi scale * of sqrt(2)/50 * round caliber * srqt(change in speed). The second term is * explosive * indirect hit, for any explosive contribution */ -private _spallPower = (ACE_FRAG_ROUND_COEF * _caliber * sqrt _velocityChange + _explosive * _indirectHit) * GVAR(spallIntensity); -TRACE_3("found speed",_velocityChange,_caliber,_spallPower); +private _spallPower = (ACE_FRAG_SPALL_CALIBER_COEF * _caliber * sqrt _speedChange + _explosive * _indirectHit) * GVAR(spallIntensity); +TRACE_3("found speed",_speedChange,_caliber,_spallPower); if (_spallPower < 2) exitWith { TRACE_1("lowImpulse",_ammo); @@ -121,7 +121,7 @@ private _spallSpawner = createVehicle [ "CAN_COLLIDE" ]; _spallSpawner setVectorDirandUp [_lastVelocityNorm, _vectorUp]; -_spallSpawner setVelocity (_lastVelocityNorm vectorMultiply (_velocityChange * ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF)); +_spallSpawner setVelocityModelSpace [0, _speedChange * ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF, 0]; _spallSpawner setShotParents _shotParents; #ifdef DEBUG_MODE_FULL From fd2c59581a90c186c6e5dcee15dc4a730348b13e Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 2 Mar 2024 22:31:30 -0600 Subject: [PATCH 227/282] Fixed ordering in which frag hold off variables are set to not skip when unneeded --- addons/frag/functions/fnc_doFrag.sqf | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index cf919851863..252fedea4ea 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -22,22 +22,21 @@ TRACE_1("begin doFrag",_this); params ["_posASL", "_velocity", "_ammo", "_shotParents"]; // Don't let a single object cause all fragmentation events -_shotParents params ["_shotParentVic"]; -if (_shotParentVic getVariable [QGVAR(obj_nextFragTime), -1] > CBA_missionTime) exitWith { - TRACE_1("vehicleTimeExit",_shotParentVic); +_shotParents params ["_shotParentVehicles"]; +if (_shotParentVehicles getVariable [QGVAR(obj_nextFragTime), -1] > CBA_missionTime) exitWith { + TRACE_1("vehicleTimeExit",_shotParentVehicles); }; -_shotParentVic setVariable [QGVAR(obj_nextFragTime), CBA_missionTime + ACE_FRAG_HOLDOFF_VEHICLE]; // Check normal round timeout and adjust _max frags private _timeSinceLastFrag = CBA_missionTime - GVAR(lastFragTime); if (_timeSinceLastFrag < ACE_FRAG_HOLDOFF || {_posASL isEqualTo [0, 0, 0]} || {_ammo isEqualTo ""}) exitWith { TRACE_3("timeExit",_timeSinceLastFrag,CBA_missionTime,GVAR(lastFragTime)); }; -private _maxFragCount = round linearConversion [ACE_FRAG_COUNT_MIN_TIME, ACE_FRAG_COUNT_MAX_TIME, _timeSinceLastFrag, ACE_FRAG_COUNT_MIN, ACE_FRAG_COUNT_MAX, true]; TRACE_3("willFrag",_timeSinceLastFrag,CBA_missionTime,_maxFragCount); +_shotParentVehicles setVariable [QGVAR(obj_nextFragTime), CBA_missionTime + ACE_FRAG_HOLDOFF_VEHICLE]; +private _maxFragCount = round linearConversion [ACE_FRAG_COUNT_MIN_TIME, ACE_FRAG_COUNT_MAX_TIME, _timeSinceLastFrag, ACE_FRAG_COUNT_MIN, ACE_FRAG_COUNT_MAX, true]; -private _ammoArr = [_ammo] call FUNC(getFragInfo); -_ammoArr params ["_fragRange", "_fragVel", "_fragTypes", "_modFragCount"]; +[_ammo] call FUNC(getFragInfo) params ["_fragRange", "_fragVel", "_fragTypes", "_modFragCount"]; // For low frag rounds limit the # of frags created if (_modFragCount < ACE_FRAG_LOW_FRAG_MOD_COUNT) then { _maxFragCount = _modFragCount * ACE_FRAG_LOW_FRAG_COEFF; @@ -51,7 +50,7 @@ if (_heightATL < ACE_FRAG_MIN_GROUND_OFFSET) then { _posASL = _posASL vectorAdd [0, 0, ACE_FRAG_MIN_GROUND_OFFSET - (0 min _heightATL)]; }; -TRACE_3("fnc_doFragTargeted IF",_fragRange,_timeSinceLastFrag,GVAR(fragSimComplexity)); +TRACE_3("doFrag choices",_maxFragCount,_fragRange,GVAR(fragSimComplexity)); if (GVAR(fragSimComplexity) != 1 && _fragRange > 3) then { _maxFragCount = _maxFragCount - ([_posASL, _fragVel, _fragRange, _maxFragCount, _fragTypes, _modFragCount, _shotParents] call FUNC(doFragTargeted)); }; From 98caad5936b3af0f88fd8575cb8f44aead5881ee Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 2 Mar 2024 22:33:40 -0600 Subject: [PATCH 228/282] initRound ordering and fixed define names --- addons/frag/functions/fnc_initRound.sqf | 3 +-- addons/frag/script_component.hpp | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index 18dbb400ef0..0cab59f4f6d 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -17,9 +17,8 @@ */ TRACE_1("ACE_Frag rndInit",_this); -params ["_projectile"]; - if (!isServer) exitWith {}; +params ["_projectile"]; private _ammo = typeOf _projectile; if (_ammo isEqualTo "" || {isNull _projectile}) exitWith { diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index 2f3f9068dc4..0c860c76f89 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -40,9 +40,11 @@ #define ACE_FRAG_LOW_FRAG_HOLDOFF_REDUCTION 4 // Max frag distance - correlates to a a fragCount of 20k & hit chance of 0.5% #define ACE_FRAG_MAX_FRAG_RANGE 565 +// 4*pi/360 = 0.034906585 +#define ACE_FRAG_FRAGS_PER_ARC_CONSTANT 0.03491 // Spall values #define ACE_FRAG_SPALL_HOLDOFF 0.25 #define ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF 0.5 // sqrt(2)/50 -#define ACE_FRAG_ROUND_COEF 0.02828427 +#define ACE_FRAG_SPALL_CALIBER_COEF 0.02828427 From ff989176395d37a62771f997e229d3008d07e1c7 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 2 Mar 2024 22:46:55 -0600 Subject: [PATCH 229/282] Fixed function header --- addons/frag/functions/fnc_doFragRandom.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index 1d3b3f51624..a1735135216 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -2,7 +2,7 @@ /* * Author: Jaynus, NouberNou, Lambda.Tiger * This function creates fragments randomly spreading out from an explosion. - * This function will spawn 5, 10, or 15 fragments depending on the + * This function will spawn 5, 10, or 15 fragments. * * Arguments: * 0: Position (posASL) of fragmenting projectile From 4583a0dc9ca27dc52195ff490616a4dac8eca5a0 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 2 Mar 2024 23:55:32 -0600 Subject: [PATCH 230/282] reformatted comments and some v2.18 remakrs comments --- addons/frag/functions/fnc_doFrag.sqf | 8 ++++---- addons/frag/functions/fnc_doFragTargeted.sqf | 2 +- addons/frag/functions/fnc_initRound.sqf | 2 ++ 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 252fedea4ea..0b11b809cd9 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -22,9 +22,9 @@ TRACE_1("begin doFrag",_this); params ["_posASL", "_velocity", "_ammo", "_shotParents"]; // Don't let a single object cause all fragmentation events -_shotParents params ["_shotParentVehicles"]; -if (_shotParentVehicles getVariable [QGVAR(obj_nextFragTime), -1] > CBA_missionTime) exitWith { - TRACE_1("vehicleTimeExit",_shotParentVehicles); +_shotParents params ["_shotParentVehicle"]; +if (_shotParentVehicle getVariable [QGVAR(obj_nextFragTime), -1] > CBA_missionTime) exitWith { + TRACE_1("vehicleTimeExit",_shotParentVehicle); }; // Check normal round timeout and adjust _max frags @@ -33,7 +33,7 @@ if (_timeSinceLastFrag < ACE_FRAG_HOLDOFF || {_posASL isEqualTo [0, 0, 0]} || {_ TRACE_3("timeExit",_timeSinceLastFrag,CBA_missionTime,GVAR(lastFragTime)); }; TRACE_3("willFrag",_timeSinceLastFrag,CBA_missionTime,_maxFragCount); -_shotParentVehicles setVariable [QGVAR(obj_nextFragTime), CBA_missionTime + ACE_FRAG_HOLDOFF_VEHICLE]; +_shotParentVehicle setVariable [QGVAR(obj_nextFragTime), CBA_missionTime + ACE_FRAG_HOLDOFF_VEHICLE]; private _maxFragCount = round linearConversion [ACE_FRAG_COUNT_MIN_TIME, ACE_FRAG_COUNT_MAX_TIME, _timeSinceLastFrag, ACE_FRAG_COUNT_MIN, ACE_FRAG_COUNT_MAX, true]; [_ammo] call FUNC(getFragInfo) params ["_fragRange", "_fragVel", "_fragTypes", "_modFragCount"]; diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index 6630f460abe..3c2614cd27c 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -171,7 +171,7 @@ private _totalFragCount = 0; } forEach _targets; #ifdef DEBUG_MODE_FULL -systemChat ("targeted frag count: " + str _totalFragCount); +systemChat ("targeted frag count: " + str _totalFragCount); TRACE_1("targeted frag count",_totalFragCount); #endif _totalFragCount diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index 0cab59f4f6d..5d8bb2a1726 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -49,6 +49,8 @@ if (GVAR(spallEnabled) && {_ammo call FUNC(shouldSpall)}) then { "HitPart", { params ["_projectile", "_hitObject", "", "_posASL", "_velocity", "_surfNorm", "", "", "_surfType"]; + // starting v2.18 it may be faster to use the instigator parameter, the same as the second entry shotParents, to recreate _shotParent + // The "explode" EH does not get the same parameter private _shotParent = getShotParents _projectile; private _ammo = typeOf _projectile; private _vectorUp = vectorUp _projectile; From deecaf9249003bdf784f68219877330c48c501dc Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Mon, 4 Mar 2024 22:19:38 -0600 Subject: [PATCH 231/282] Removed unneeded ground offset --- addons/frag/functions/fnc_doFrag.sqf | 7 +------ addons/frag/functions/fnc_doFragRandom.sqf | 12 ++++++------ addons/frag/script_component.hpp | 1 - 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 0b11b809cd9..c068af3494b 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -44,11 +44,6 @@ if (_modFragCount < ACE_FRAG_LOW_FRAG_MOD_COUNT) then { } else { GVAR(lastFragTime) = CBA_missionTime; }; -// Offset for ground clearance -private _heightATL = (ASLToATL _posASL)#2; -if (_heightATL < ACE_FRAG_MIN_GROUND_OFFSET) then { - _posASL = _posASL vectorAdd [0, 0, ACE_FRAG_MIN_GROUND_OFFSET - (0 min _heightATL)]; -}; TRACE_3("doFrag choices",_maxFragCount,_fragRange,GVAR(fragSimComplexity)); if (GVAR(fragSimComplexity) != 1 && _fragRange > 3) then { @@ -56,5 +51,5 @@ if (GVAR(fragSimComplexity) != 1 && _fragRange > 3) then { }; if (GVAR(fragSimComplexity) > 0 && _maxFragCount >= ACE_FRAG_MIN_FRAG_BUDGET_FOR_RANDOM) then { - [_posASL, _velocity, _heightATL, _fragTypes, _maxFragCount, _shotParents] call FUNC(doFragRandom); + [_posASL, _velocity, _fragTypes, _maxFragCount, _shotParents] call FUNC(doFragRandom); }; diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index a1735135216..dd3d6b0b5e0 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -7,10 +7,9 @@ * Arguments: * 0: Position (posASL) of fragmenting projectile * 1: Velocity of the fragmenting projectile - * 2: Height (AGL) of the fragmenting projectile - * 3: Type of fragments to generate - * 4: Remaining fragment budget - * 5: Shot parents + * 2: Type of fragments to generate + * 3: Remaining fragment budget + * 4: Shot parents * * Return Value: * None @@ -21,10 +20,11 @@ * Public: No */ -params ["_posASL", "_fragVelocity", "_heightATL", "_fragType", "_maxFragCount", "_shotParents"]; -TRACE_6("doFragRandom",_posASL,_fragVelocity,_heightATL,_fragType,_maxFragCount,_shotParents); +params ["_posASL", "_fragVelocity", "_fragType", "_maxFragCount", "_shotParents"]; +TRACE_5("doFragRandom",_posASL,_fragVelocity,_fragType,_maxFragCount,_shotParents); // See CfgAmmoFragSpawner for different frag types +private _heightATL = (ASLToATL _posASL)#2; private _hMode = switch (true) do { case (_heightATL > 10): {"_top"}; case (_heightATL > 5): {"_hi"}; diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index 0c860c76f89..f394ad35a6f 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -32,7 +32,6 @@ #define ACE_FRAG_HALF_GRAVITY_APPROX 4.905 // Lowest chance to hit of 0.5% #define ACE_FRAG_MIN_FRAG_HIT_CHANCE 0.005 -#define ACE_FRAG_MIN_GROUND_OFFSET 0.25 // Make frag hold-off time shortger for low frag // value of 150/4/pi ~= 11.93662 #define ACE_FRAG_LOW_FRAG_MOD_COUNT 11.93662 From 9dd45e15ce7dd8d34b5811e65617e6668fbd31e8 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Wed, 13 Mar 2024 20:34:13 +0100 Subject: [PATCH 232/282] Expanded TRACE --- addons/frag/functions/fnc_doFrag.sqf | 4 +++- addons/frag/functions/fnc_doFragRandom.sqf | 2 +- addons/frag/functions/fnc_doSpall.sqf | 7 ++++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index c068af3494b..f4f81f3f1aa 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -17,9 +17,11 @@ * * Public: No */ + #define ACE_FRAG_MIN_FRAG_BUDGET_FOR_RANDOM 3 -TRACE_1("begin doFrag",_this); + params ["_posASL", "_velocity", "_ammo", "_shotParents"]; +TRACE_4("doFrag",_posASL,_velocity,_ammo,_shotParents); // Don't let a single object cause all fragmentation events _shotParents params ["_shotParentVehicle"]; diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index dd3d6b0b5e0..61328aa141e 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -31,7 +31,7 @@ private _hMode = switch (true) do { default {"_mid"}; }; -private _type = [QGVAR(def_small_), QGVAR(def_tiny_)] select (_fragType isNotEqualTo [] && {"ace_frag_tiny" isEqualTo (_fragType#0)}); +private _type = [QGVAR(def_small_), QGVAR(def_tiny_)] select (_fragType isNotEqualTo [] && {"ace_frag_tiny" == (_fragType#0)}); _maxFragCount = switch (true) do { case (_maxFragCount <= 5): {"5"}; diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index 68d1336c2da..35c6c58d71f 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -17,14 +17,15 @@ */ #define GLUE(g1,g2) g1##g2 -TRACE_1("doSpall",_this); + if (CBA_missionTime < GVAR(nextSpallAllowTime)) exitWith { TRACE_2("time exit",CBA_missionTime,GVAR(nextSpallAllowTime)); }; + params ["_projectile", "_objectHit", "_lastPosASL", "_lastVelocity", "_surfaceNorm", "_surfaceType", "_ammo", "_shotParents", "_vectorUp"]; +TRACE_9("doSpall",_projectile,_objectHit,_lastPosASL,_lastVelocity,_surfaceNorm,_surfaceType,_ammo,_shotParents,_vectorUp); -if (_ammo == "" || - {_objectHit isKindOf "CAManBase"}) exitWith { +if (_ammo == "" || {_objectHit isKindOf "CAManBase"}) exitWith { TRACE_4("invalid round or hit",CBA_missionTime,GVAR(nextSpallAllowTime),_objectHit,_lastPosASL); }; From ab51d8f8b03dedbe036edd1a21faab15d19cc8e2 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Wed, 13 Mar 2024 20:38:32 +0100 Subject: [PATCH 233/282] Fix typo --- addons/frag/functions/fnc_dev_debugAmmo.sqf | 4 ++-- addons/frag/functions/fnc_dev_drawTrace.sqf | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index 7ade5df72b7..2f781218989 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -75,9 +75,9 @@ private _printCount = 0; _processedCfgAmmos pushBack _ammo; private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; - private _shoulFrag = [_ammo] call FUNC(shouldFrag); + private _shouldFrag = [_ammo] call FUNC(shouldFrag); - if (_shoulFrag || _logAll) then { + if (_shouldFrag || _logAll) then { private _print = false; private _skip = getNumber (_ammoConfig >> QGVAR(skip)); diff --git a/addons/frag/functions/fnc_dev_drawTrace.sqf b/addons/frag/functions/fnc_dev_drawTrace.sqf index 63b05bc8ba5..970f88a7bc8 100644 --- a/addons/frag/functions/fnc_dev_drawTrace.sqf +++ b/addons/frag/functions/fnc_dev_drawTrace.sqf @@ -16,6 +16,7 @@ */ #define HITBOX_DRAW_PATH [[3, 2, 1, 5, 6, 7, 3, 0, 4, 5], [0, 1], [2, 6], [7, 4]] + if (!GVAR(debugOptions)) exitWith {}; { From 04a3ba8bb4341ac3a8f42bdf51c06307aaece7b6 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sun, 17 Mar 2024 13:41:09 +0100 Subject: [PATCH 234/282] Moved event to preInit --- addons/frag/XEH_postInit.sqf | 14 ++------------ addons/frag/XEH_preInit.sqf | 8 +++++++- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index 21ba57c9fba..1da47231540 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -1,19 +1,9 @@ #include "script_component.hpp" +#ifdef DEBUG_MODE_DRAW [ "CBA_settingsInitialized", { - if (isServer) then { - call FUNC(initMaterialCache); - [ - QEGVAR(common,setShotParents), - { - (_this#0) setVariable [QGVAR(shotParent), [_this#1, _this#2]]; - } - ] call CBA_fnc_addEventHandler; - }; - - #ifdef DEBUG_MODE_DRAW [QGVAR(dev_clearTraces), LINKFUNC(dev_clearTraces)] call CBA_fnc_addEventHandler; if (!hasInterface) exitWith {}; @@ -49,9 +39,9 @@ ] call EFUNC(interact_menu,addActionToClass); } ] call CBA_fnc_addEventHandler; - #endif } ] call CBA_fnc_addEventHandler; +#endif #ifdef LOG_FRAG_INFO [true, true, 30] call FUNC(dev_debugAmmo); diff --git a/addons/frag/XEH_preInit.sqf b/addons/frag/XEH_preInit.sqf index 8120192a440..68d608c87ff 100644 --- a/addons/frag/XEH_preInit.sqf +++ b/addons/frag/XEH_preInit.sqf @@ -6,7 +6,8 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -GVAR(spallMaterialCache) = createHashMap; +call FUNC(initMaterialCache); + GVAR(spallInfoCache) = createHashMap; GVAR(shouldSpallCache) = createHashMap; GVAR(nextSpallAllowTime) = -1; @@ -21,8 +22,13 @@ GVAR(dev_trackLines) = createHashMap; GVAR(dev_hitBoxes) = createHashMap; GVAR(dev_eventSpheres) = []; GVAR(dev_drawPFEH) = -1; + #ifdef DEBUG_MODE_DRAW #include "initSettingsDebug.inc.sqf" #endif +if (isServer) then { + [QEGVAR(common,setShotParents), {(_this#0) setVariable [QGVAR(shotParent), [_this#1, _this#2]]}] call CBA_fnc_addEventHandler; +}; + ADDON = true; From 786ce92274b03aa895d54bc3583a096bf01e9d31 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sun, 17 Mar 2024 17:23:16 -0500 Subject: [PATCH 235/282] Updated default fallback frag distance to be less extreme and changed fixed a magic number --- addons/frag/functions/fnc_getFragInfo.sqf | 6 +++--- addons/frag/script_component.hpp | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/addons/frag/functions/fnc_getFragInfo.sqf b/addons/frag/functions/fnc_getFragInfo.sqf index c8bbdd5d86a..2ffc1289d18 100644 --- a/addons/frag/functions/fnc_getFragInfo.sqf +++ b/addons/frag/functions/fnc_getFragInfo.sqf @@ -68,7 +68,7 @@ if (_metalMass == 0) then { private _geometryCoefficient = getNumber (_ammoConfig >> QGVAR(gurney_k)); if (_geometryCoefficient == 0) then { - _geometryCoefficient = 0.8; + _geometryCoefficient = 0.5; _notifyMissingEntries = true; }; @@ -80,7 +80,7 @@ if (_gurneyConstant == 0) then { private _fragCount = getNumber (_ammoConfig >> QGVAR(fragCount)); if (_fragCount == 0) then { - _fragCount = 400; + _fragCount = 250; _notifyMissingEntries = true; }; @@ -96,7 +96,7 @@ if (_notifyMissingEntries) then { */ _ammoInfo = [ ACE_FRAG_MAX_FRAG_RANGE max sqrt (_fragCount / (4 * pi * ACE_FRAG_MIN_FRAG_HIT_CHANCE)), - 0.8 * _gurneyConstant * sqrt (_chargeMass / (_metalMass + _chargeMass * _geometryCoefficient)), + ACE_FRAG_IMPERIC_VELOCITY_CONSTANT * _gurneyConstant * sqrt (_chargeMass / (_metalMass + _chargeMass * _geometryCoefficient)), _fragTypes, _fragCount / 4 / pi ]; diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index f394ad35a6f..ae3f36cc5e9 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -32,6 +32,7 @@ #define ACE_FRAG_HALF_GRAVITY_APPROX 4.905 // Lowest chance to hit of 0.5% #define ACE_FRAG_MIN_FRAG_HIT_CHANCE 0.005 +#define ACE_FRAG_IMPERIC_VELOCITY_CONSTANT 0.8 // Make frag hold-off time shortger for low frag // value of 150/4/pi ~= 11.93662 #define ACE_FRAG_LOW_FRAG_MOD_COUNT 11.93662 From eda865f377aee85305efb17b3fe11c926227a825 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 28 Mar 2024 19:05:41 -0500 Subject: [PATCH 236/282] Randomized random frag directions --- addons/frag/functions/fnc_doFragRandom.sqf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index 61328aa141e..81b1f494991 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -41,7 +41,8 @@ _maxFragCount = switch (true) do { // Spawn the fragment spawner private _fragSpawner = createVehicle [_type + _maxFragCount + _hMode, ASLToATL _posASL, [], 0, "CAN_COLLIDE"]; -_fragSpawner setVectorDirandUp [[0,0,1], [1,0,0]]; +private _randDir = random 360; +_fragSpawner setVectorDirandUp [[0,0,-1], [cos _randDir, sin _randDir,0]]; _fragSpawner setVelocity _fragVelocity; _fragSpawner setShotParents _shotParents; From 5bab127a5aac1396cdc3a9ab94b792d7002be596 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 28 Mar 2024 19:13:21 -0500 Subject: [PATCH 237/282] removed some magic numbers, and cached numbers from shouldSpall --- addons/frag/functions/fnc_doSpall.sqf | 10 +++++----- addons/frag/script_component.hpp | 5 +++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index 35c6c58d71f..7765a7cc500 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -55,7 +55,7 @@ private _speedChange = 0 max (vectorMagnitude _lastVelocity - vectorMagnitude _v private _spallPower = (ACE_FRAG_SPALL_CALIBER_COEF * _caliber * sqrt _speedChange + _explosive * _indirectHit) * GVAR(spallIntensity); TRACE_3("found speed",_speedChange,_caliber,_spallPower); -if (_spallPower < 2) exitWith { +if (_spallPower < ACE_FRAG_SPALL_POWER_MIN) exitWith { TRACE_1("lowImpulse",_ammo); }; @@ -107,10 +107,10 @@ if GVAR(dbgSphere) then { private _spawnSize = switch (true) do { - case (_spallPower < 3): {"_spall_tiny"}; - case (_spallPower < 5): {"_spall_small"}; - case (_spallPower < 8): {"_spall_medium"}; - case (_spallPower < 12): {"_spall_large"} ; + case (_spallPower < ACE_FRAG_SPALL_POWER_TINY_MAX): {"_spall_tiny"}; + case (_spallPower < ACE_FRAG_SPALL_POWER_SMALL_MAX): {"_spall_small"}; + case (_spallPower < ACE_FRAG_SPALL_POWER_MEDIUM_MAX): {"_spall_medium"}; + case (_spallPower < ACE_FRAG_SPALL_POWER_LARGE_MAX): {"_spall_large"}; default {"_spall_huge"}; }; diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index ae3f36cc5e9..e8d5ad32ca3 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -48,3 +48,8 @@ #define ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF 0.5 // sqrt(2)/50 #define ACE_FRAG_SPALL_CALIBER_COEF 0.02828427 +#define ACE_FRAG_SPALL_POWER_MIN 2 +#define ACE_FRAG_SPALL_POWER_TINY_MAX 5 +#define ACE_FRAG_SPALL_POWER_SMALL_MAX 8 +#define ACE_FRAG_SPALL_POWER_MEDIUM_MAX 11 +#define ACE_FRAG_SPALL_POWER_LARGE_MAX 15 \ No newline at end of file From ef39e78db986c5c2c8a95002469f48b662db9525 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 28 Mar 2024 19:17:13 -0500 Subject: [PATCH 238/282] removed magic numbers and cached values preemptively (normally spallInfoCache is called later, but we pull the right config parameters so we might as well store them) --- addons/frag/functions/fnc_shouldSpall.sqf | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/addons/frag/functions/fnc_shouldSpall.sqf b/addons/frag/functions/fnc_shouldSpall.sqf index c545c886763..002bc53e49f 100644 --- a/addons/frag/functions/fnc_shouldSpall.sqf +++ b/addons/frag/functions/fnc_shouldSpall.sqf @@ -23,10 +23,13 @@ if (!isNil "_shouldSpall") exitWith {_shouldSpall}; private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; private _caliber = getNumber (_ammoConfig >> "caliber"); -private _explosive = getNumber (_ammoConfig >> "explosive"); +private _explosive = 1 min getNumber (_ammoConfig >> "explosive"); private _indirectHit = getNumber (_ammoConfig >> "indirectHitRange"); -_shouldSpall = _caliber * GVAR(spallIntensity) >= 2.5 || (_explosive >= 0.5 && {_explosive * _indirectHit * GVAR(spallIntensity) >= 4}); +// We need get this for fnc_getSpallInfo, so might as well cache it since we have it +GVAR(spallInfoCache) set [_ammo, [_caliber, _explosive, _indirectHit]]; + +_shouldSpall = _caliber * GVAR(spallIntensity) >= 1.25 * ACE_FRAG_SPALL_POWER_MIN || (_explosive >= 0.5 && {_indirectHit * GVAR(spallIntensity) >= 2 * ACE_FRAG_SPALL_POWER_MIN}); GVAR(shouldSpallCache) set [_ammo, _shouldSpall]; From c487f7f511b03aa26973908fc9807d1ed91f2f84 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 28 Mar 2024 19:23:50 -0500 Subject: [PATCH 239/282] Unify example formatting Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com> --- addons/frag/functions/fnc_getMaterialInfo.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_getMaterialInfo.sqf b/addons/frag/functions/fnc_getMaterialInfo.sqf index f2910ed0d33..63a0fe0389a 100644 --- a/addons/frag/functions/fnc_getMaterialInfo.sqf +++ b/addons/frag/functions/fnc_getMaterialInfo.sqf @@ -10,7 +10,7 @@ * Material categories as expanded on in line 44 below * * Example: - * [_surfaceType] call ace_frag_fnc_getMaterialInfo; + * _surfaceType call ace_frag_fnc_getMaterialInfo * * Public: No */ From bd23b42863db8fb4d1d2b1f95bdff7dfde981b61 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 28 Mar 2024 19:33:56 -0500 Subject: [PATCH 240/282] cleaned up function examples --- addons/frag/functions/fnc_dev_addRound.sqf | 2 +- addons/frag/functions/fnc_dev_clearTraces.sqf | 2 +- addons/frag/functions/fnc_dev_sphereDraw.sqf | 2 +- addons/frag/functions/fnc_dev_trackHitBox.sqf | 2 +- addons/frag/functions/fnc_dev_trackObj.sqf | 2 +- addons/frag/functions/fnc_doFrag.sqf | 2 +- addons/frag/functions/fnc_doFragRandom.sqf | 2 +- addons/frag/functions/fnc_doFragTargeted.sqf | 2 +- addons/frag/functions/fnc_doSpall.sqf | 2 +- addons/frag/functions/fnc_getFragInfo.sqf | 2 +- addons/frag/functions/fnc_getMaterialInfo.sqf | 2 +- addons/frag/functions/fnc_getSpallInfo.sqf | 2 +- addons/frag/functions/fnc_initMaterialCache.sqf | 2 +- addons/frag/functions/fnc_initRound.sqf | 2 +- addons/frag/functions/fnc_shouldFrag.sqf | 2 +- addons/frag/functions/fnc_shouldSpall.sqf | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/addons/frag/functions/fnc_dev_addRound.sqf b/addons/frag/functions/fnc_dev_addRound.sqf index 3105aeb4025..bdb1526620f 100644 --- a/addons/frag/functions/fnc_dev_addRound.sqf +++ b/addons/frag/functions/fnc_dev_addRound.sqf @@ -15,7 +15,7 @@ * Nothing Useful * * Example: - * [_projectile, false, false] call ace_frag_dev_addRound; + * [_projectile, false, false] call ace_frag_dev_addRound * * Public: No */ diff --git a/addons/frag/functions/fnc_dev_clearTraces.sqf b/addons/frag/functions/fnc_dev_clearTraces.sqf index d0579493310..6e2b820bacb 100644 --- a/addons/frag/functions/fnc_dev_clearTraces.sqf +++ b/addons/frag/functions/fnc_dev_clearTraces.sqf @@ -10,7 +10,7 @@ * None * * Example: - * call ace_frag_fnc_dev_clearTraces; + * call ace_frag_fnc_dev_clearTraces * * Public: No */ diff --git a/addons/frag/functions/fnc_dev_sphereDraw.sqf b/addons/frag/functions/fnc_dev_sphereDraw.sqf index 8c3137b647d..270514f0a1a 100644 --- a/addons/frag/functions/fnc_dev_sphereDraw.sqf +++ b/addons/frag/functions/fnc_dev_sphereDraw.sqf @@ -11,7 +11,7 @@ * The created sphere object * * Example: - * [getPosASL player, "red"] call ace_frag_fnc_dev_sphereDraw; + * [getPosASL player, "red"] call ace_frag_fnc_dev_sphereDraw * * Public: No */ diff --git a/addons/frag/functions/fnc_dev_trackHitBox.sqf b/addons/frag/functions/fnc_dev_trackHitBox.sqf index b3f8f7a1536..327e45cf0d3 100644 --- a/addons/frag/functions/fnc_dev_trackHitBox.sqf +++ b/addons/frag/functions/fnc_dev_trackHitBox.sqf @@ -11,7 +11,7 @@ * None * * Example: - * [player] call ace_frag_fnc_dev_trackHitBox; + * player call ace_frag_fnc_dev_trackHitBox * * Public: No */ diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index d690637814a..439bd253af0 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -12,7 +12,7 @@ * None * * Example: - * [player] call ace_frag_fnc_dev_trackObj; + * player call ace_frag_fnc_dev_trackObj * * Public: No */ diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index f4f81f3f1aa..75f34c2edbd 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -13,7 +13,7 @@ * None * * Example: - * [getPosASL _projectile, velocity _projectile, typeOf _projectile, getShotParents _projectile] call ace_frag_fnc_doFrag; + * [getPosASL _projectile, velocity _projectile, typeOf _projectile, getShotParents _projectile] call ace_frag_fnc_doFrag * * Public: No */ diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index 81b1f494991..06c51e45345 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -15,7 +15,7 @@ * None * * Example: - * [getPosASL _proj, 800, 50, 50, [], 1, [player, player]] call ace_frag_fnc_doFragRandom; + * [getPosASL _projectile, 800, 50, 50, [], 1, [player, player]] call ace_frag_fnc_doFragRandom * * Public: No */ diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index 3c2614cd27c..dec759f9620 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -16,7 +16,7 @@ * Number of fragments created * * Example: - * [getPosASL _proj, velocity _proj, 50, 50, [], 1, [player, player]] call ace_frag_fnc_doFragTargeted; + * [getPosASL _projectile, velocity _projectile, 50, 50, [], 1, [player, player]] call ace_frag_fnc_doFragTargeted * * Public: No */ diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index 7765a7cc500..a0b09157781 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -11,7 +11,7 @@ * None * * Example: - * [BIS_HITPART_EH_ARGS] call ace_frag_fnc_doSpall; + * [BIS_HITPART_EH_ARGS] call ace_frag_fnc_doSpall * * Public: No */ diff --git a/addons/frag/functions/fnc_getFragInfo.sqf b/addons/frag/functions/fnc_getFragInfo.sqf index 2ffc1289d18..2fae0c71a3a 100644 --- a/addons/frag/functions/fnc_getFragInfo.sqf +++ b/addons/frag/functions/fnc_getFragInfo.sqf @@ -14,7 +14,7 @@ * 3: Modified frag count under assumptions of spherical fragmentation * * Example: - * ["B_556x45_Ball"] call ace_frag_fnc_getFragInfo; + * "B_556x45_Ball" call ace_frag_fnc_getFragInfo * * Public: No */ diff --git a/addons/frag/functions/fnc_getMaterialInfo.sqf b/addons/frag/functions/fnc_getMaterialInfo.sqf index 63a0fe0389a..199953b237b 100644 --- a/addons/frag/functions/fnc_getMaterialInfo.sqf +++ b/addons/frag/functions/fnc_getMaterialInfo.sqf @@ -10,7 +10,7 @@ * Material categories as expanded on in line 44 below * * Example: - * _surfaceType call ace_frag_fnc_getMaterialInfo + * "a3\data_f\penetration\concrete.bisurf" call ace_frag_fnc_getMaterialInfo * * Public: No */ diff --git a/addons/frag/functions/fnc_getSpallInfo.sqf b/addons/frag/functions/fnc_getSpallInfo.sqf index da1347a135a..c4ef3b4cd83 100644 --- a/addons/frag/functions/fnc_getSpallInfo.sqf +++ b/addons/frag/functions/fnc_getSpallInfo.sqf @@ -13,7 +13,7 @@ * 2: Indirect hit damage * * Example: - * ["B_556x45_Ball"] call ace_frag_fnc_getSpallInfo; + * "B_556x45_Ball" call ace_frag_fnc_getSpallInfo * * Public: No */ diff --git a/addons/frag/functions/fnc_initMaterialCache.sqf b/addons/frag/functions/fnc_initMaterialCache.sqf index b125d0119c6..fd7a84a72d0 100644 --- a/addons/frag/functions/fnc_initMaterialCache.sqf +++ b/addons/frag/functions/fnc_initMaterialCache.sqf @@ -10,7 +10,7 @@ * None * * Example: - * call ace_frag_fnc_initMaterialCache; + * call ace_frag_fnc_initMaterialCache * * Public: No */ diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index 5d8bb2a1726..22f5814470d 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -11,7 +11,7 @@ * None * * Example: - * [_projectile] call ace_frag_fnc_initRound; + * _projectile call ace_frag_fnc_initRound * * Public: No */ diff --git a/addons/frag/functions/fnc_shouldFrag.sqf b/addons/frag/functions/fnc_shouldFrag.sqf index d9ed570ffdd..8edcd5e1a97 100644 --- a/addons/frag/functions/fnc_shouldFrag.sqf +++ b/addons/frag/functions/fnc_shouldFrag.sqf @@ -10,7 +10,7 @@ * Should the specific round fragment * * Example: - * ["B_556x45_Ball"] call ace_frag_fnc_shouldFrag; + * "B_556x45_Ball" call ace_frag_fnc_shouldFrag * * Public: No */ diff --git a/addons/frag/functions/fnc_shouldSpall.sqf b/addons/frag/functions/fnc_shouldSpall.sqf index 002bc53e49f..096025c63f9 100644 --- a/addons/frag/functions/fnc_shouldSpall.sqf +++ b/addons/frag/functions/fnc_shouldSpall.sqf @@ -10,7 +10,7 @@ * Whether the round type would spall when hitting an object * * Example: - * ["B_556x45_Ball"] call ace_frag_fnc_shouldSpall; + * "B_556x45_Ball" call ace_frag_fnc_shouldSpall * * Public: No */ From a817e5e4d2595fc6e9f69fb1e8d92e84e692f18b Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 28 Mar 2024 19:59:49 -0500 Subject: [PATCH 241/282] removed excess square brackets --- addons/frag/functions/fnc_dev_addRound.sqf | 4 ++-- addons/frag/functions/fnc_dev_debugAmmo.sqf | 10 +++++----- addons/frag/functions/fnc_dev_fragCalcDump.sqf | 4 ++-- addons/frag/functions/fnc_dev_trackObj.sqf | 4 ++-- addons/frag/functions/fnc_doFrag.sqf | 2 +- addons/frag/functions/fnc_doSpall.sqf | 8 ++++---- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/addons/frag/functions/fnc_dev_addRound.sqf b/addons/frag/functions/fnc_dev_addRound.sqf index bdb1526620f..96b8d1e1aeb 100644 --- a/addons/frag/functions/fnc_dev_addRound.sqf +++ b/addons/frag/functions/fnc_dev_addRound.sqf @@ -39,13 +39,13 @@ if (_isTraceBlue) then { params ["_projectile", "_handle"]; if (!alive _projectile) exitWith { - [_handle] call CBA_fnc_removePerFrameHandler; + _handle call CBA_fnc_removePerFrameHandler; }; private _projectileArray = GVAR(dev_trackLines) get (getObjectID _projectile); if (isNil "_projectileArray") exitWith { - [_handle] call CBA_fnc_removePerFrameHandler; + _handle call CBA_fnc_removePerFrameHandler; }; (_projectileArray#0) pushBack getPosATL _projectile; diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index 2f781218989..7fc6b203881 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -35,7 +35,7 @@ if (_csvFormat) then { // Gather all configs, either those that could be created from firing or all classes private _allAmmoConfigs = []; if (_onlyShotAmmoTypes) then { - private _configSearchFunc = { + private _configSearchFunction = { params [ ["_ammo", "", [""]] ]; @@ -47,13 +47,13 @@ if (_onlyShotAmmoTypes) then { private _subMunition = getArray _submunitionConfig; for "_i" from 0 to count _subMunition - 1 do { if (_i mod 2 == 0) then { - [configName (_cfgAmmoRoot >> (_subMunition#_i))] call _configSearchFunc; + configName (_cfgAmmoRoot >> (_subMunition#_i)) call _configSearchFunction; }; }; } else { private _subMunition = getText _submunitionConfig; if (_subMunition isNotEqualTo "") then { - [configName (_cfgAmmoRoot >> _subMunition)] call _configSearchFunc; + configName (_cfgAmmoRoot >> _subMunition) call _configSearchFunction; }; }; }; @@ -61,7 +61,7 @@ if (_onlyShotAmmoTypes) then { private _cfgAmmoCfgPath = configFile >> "CfgAmmo"; { private _magAmmo = getText (_x >> "ammo"); - [configName (_cfgAmmoCfgPath >> _magAmmo)] call _configSearchFunc; + configName (_cfgAmmoCfgPath >> _magAmmo) call _configSearchFunction; } forEach _allMagazineConfigs; } else { _allAmmoConfigs = configProperties [configFile >> "CfgAmmo", "isClass _x && !('ace_frag' in configName _x)", true] apply {configName _x}; @@ -75,7 +75,7 @@ private _printCount = 0; _processedCfgAmmos pushBack _ammo; private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; - private _shouldFrag = [_ammo] call FUNC(shouldFrag); + private _shouldFrag = _ammo call FUNC(shouldFrag); if (_shouldFrag || _logAll) then { diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf index acd98574636..c72d096f781 100644 --- a/addons/frag/functions/fnc_dev_fragCalcDump.sqf +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -31,9 +31,9 @@ diag_log text "//****************** fragCalcDump Beg ******************//"; continue; }; - private _shouldFrag = [_ammo] call FUNC(shouldFrag); + private _shouldFrag = _ammo call FUNC(shouldFrag); if (_shouldFrag || _logAll) then { - private _fragInfo = [_ammo] call FUNC(getFragInfo); + private _fragInfo = _ammo call FUNC(getFragInfo); _fragInfo params ["_fragRange", "_fragMaxVelocity", "", "_modifiedFragCount"]; private _fragCount = 4 * pi * _modifiedFragCount; private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; diff --git a/addons/frag/functions/fnc_dev_trackObj.sqf b/addons/frag/functions/fnc_dev_trackObj.sqf index 439bd253af0..dca9cc49eaa 100644 --- a/addons/frag/functions/fnc_dev_trackObj.sqf +++ b/addons/frag/functions/fnc_dev_trackObj.sqf @@ -45,13 +45,13 @@ GVAR(dev_trackLines) set [getObjectID _object, [[getPosATL _object], _colorArray params ["_object", "_handle"]; if (!alive _object) exitWith { - [_handle] call CBA_fnc_removePerFrameHandler; + _handle call CBA_fnc_removePerFrameHandler; }; private _objectArray = GVAR(dev_trackLines) get (getObjectID _object); if (isNil "_objectArray") exitWith { - [_handle] call CBA_fnc_removePerFrameHandler; + _handle call CBA_fnc_removePerFrameHandler; }; (_objectArray#0) pushBack getPosATL _object; diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 75f34c2edbd..6037b06ae2d 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -38,7 +38,7 @@ TRACE_3("willFrag",_timeSinceLastFrag,CBA_missionTime,_maxFragCount); _shotParentVehicle setVariable [QGVAR(obj_nextFragTime), CBA_missionTime + ACE_FRAG_HOLDOFF_VEHICLE]; private _maxFragCount = round linearConversion [ACE_FRAG_COUNT_MIN_TIME, ACE_FRAG_COUNT_MAX_TIME, _timeSinceLastFrag, ACE_FRAG_COUNT_MIN, ACE_FRAG_COUNT_MAX, true]; -[_ammo] call FUNC(getFragInfo) params ["_fragRange", "_fragVel", "_fragTypes", "_modFragCount"]; +_ammo call FUNC(getFragInfo) params ["_fragRange", "_fragVel", "_fragTypes", "_modFragCount"]; // For low frag rounds limit the # of frags created if (_modFragCount < ACE_FRAG_LOW_FRAG_MOD_COUNT) then { _maxFragCount = _modFragCount * ACE_FRAG_LOW_FRAG_COEFF; diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index a0b09157781..589cb254e33 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -29,7 +29,7 @@ if (_ammo == "" || {_objectHit isKindOf "CAManBase"}) exitWith { TRACE_4("invalid round or hit",CBA_missionTime,GVAR(nextSpallAllowTime),_objectHit,_lastPosASL); }; -private _material = [_surfaceType] call FUNC(getMaterialInfo); +private _material = _surfaceType call FUNC(getMaterialInfo); if (_material == "ground") exitWith { #ifdef DEBUG_MODE_FULL systemChat "ground spall"; @@ -37,7 +37,7 @@ if (_material == "ground") exitWith { }; // Find spall speed / fragment info -[_ammo] call FUNC(getSpallInfo) params ["_caliber", "_explosive", "_indirectHit"]; +_ammo call FUNC(getSpallInfo) params ["_caliber", "_explosive", "_indirectHit"]; private _vel = if (alive _projectile) then { _explosive = 0; // didn't explode since it's alive a frame later velocity _projectile @@ -132,8 +132,8 @@ systemChat ("spd: " + str speed _spallSpawner + ", spawner: " + _fragSpawnType + _spallSpawner addEventHandler [ "SubmunitionCreated", { - params ["", "_subProj"]; - [_subProj] call FUNC(dev_addRound); + params ["", "_submunitionProjectile"]; + _submunitionProjectile call FUNC(dev_addRound); } ]; #endif From 08002058d23a93e635eeb7bbec3b4c57e7066549 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 28 Mar 2024 20:01:29 -0500 Subject: [PATCH 242/282] Final function example reformat --- addons/frag/functions/fnc_dev_drawTrace.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_dev_drawTrace.sqf b/addons/frag/functions/fnc_dev_drawTrace.sqf index 970f88a7bc8..525149b1c88 100644 --- a/addons/frag/functions/fnc_dev_drawTrace.sqf +++ b/addons/frag/functions/fnc_dev_drawTrace.sqf @@ -10,7 +10,7 @@ * None * * Example: - * call ace_frag_fnc_dev_drawTrace; + * call ace_frag_fnc_dev_drawTrace * * Public: No */ From 60d0af88b7a620109d48573d064eb1251516f3c8 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Fri, 29 Mar 2024 12:14:50 +0100 Subject: [PATCH 243/282] Update addons/frag/script_component.hpp --- addons/frag/script_component.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index e8d5ad32ca3..8c2a614d3ce 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -52,4 +52,4 @@ #define ACE_FRAG_SPALL_POWER_TINY_MAX 5 #define ACE_FRAG_SPALL_POWER_SMALL_MAX 8 #define ACE_FRAG_SPALL_POWER_MEDIUM_MAX 11 -#define ACE_FRAG_SPALL_POWER_LARGE_MAX 15 \ No newline at end of file +#define ACE_FRAG_SPALL_POWER_LARGE_MAX 15 From 6b828593eb9b200158cc598c7098851ff11f2c24 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Mon, 1 Apr 2024 15:31:00 +0200 Subject: [PATCH 244/282] Corrected docs --- docs/wiki/framework/frag-framework.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/wiki/framework/frag-framework.md b/docs/wiki/framework/frag-framework.md index e38798beab3..04b3f7e98f3 100644 --- a/docs/wiki/framework/frag-framework.md +++ b/docs/wiki/framework/frag-framework.md @@ -8,8 +8,8 @@ order: 7 mod: ace version: major: 3 - minor: 16 - patch: 4 + minor: 0 + patch: 0 --- ## 1. Overview @@ -61,7 +61,7 @@ As long as the units match `ace_frag_charge`, the total mass of fragmenting meta `ace_frag_charge` -The mass of explosive filler in the warhead. This may include any detonation/igntion charges, but usually such charges are relatively small. +The mass of explosive filler in the warhead. This may include any detonation/ignition charges, but usually such charges are relatively small. As long as the units match `ace_frag_metal`, the total mass of explosive filler given in any unit of mass (i.e., both use `kg`, `g`, or `lbs`). From e8283c30a0dece3937e7e6b414e5285b6e1e9655 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Mon, 1 Apr 2024 15:31:18 +0200 Subject: [PATCH 245/282] Use `getOrDefaultCall` --- addons/frag/functions/fnc_getSpallInfo.sqf | 19 +++++++------------ addons/frag/functions/fnc_shouldSpall.sqf | 20 ++++---------------- 2 files changed, 11 insertions(+), 28 deletions(-) diff --git a/addons/frag/functions/fnc_getSpallInfo.sqf b/addons/frag/functions/fnc_getSpallInfo.sqf index c4ef3b4cd83..bc988887054 100644 --- a/addons/frag/functions/fnc_getSpallInfo.sqf +++ b/addons/frag/functions/fnc_getSpallInfo.sqf @@ -20,16 +20,11 @@ params ["_ammo"]; -private _ammoInfo = GVAR(spallInfoCache) get _ammo; +GVAR(spallInfoCache) getOrDefaultCall [_ammo, { + private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; + private _caliber = getNumber (_ammoConfig >> "caliber"); + private _explosive = 1 min getNumber (_ammoConfig >> "explosive"); + private _indirectHit = getNumber (_ammoConfig >> "indirectHitRange"); -if (!isNil "_ammoInfo") exitWith {_ammoInfo}; - -private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; -private _caliber = getNumber (_ammoConfig >> "caliber"); -private _explosive = 1 min getNumber (_ammoConfig >> "explosive"); -private _indirectHit = getNumber (_ammoConfig >> "indirectHitRange"); -_ammoInfo = [_caliber, _explosive, _indirectHit]; - -GVAR(spallInfoCache) set [_ammo, _ammoInfo]; - -_ammoInfo + [_caliber, _explosive, _indirectHit] +}, true] diff --git a/addons/frag/functions/fnc_shouldSpall.sqf b/addons/frag/functions/fnc_shouldSpall.sqf index 096025c63f9..e3225c73c9d 100644 --- a/addons/frag/functions/fnc_shouldSpall.sqf +++ b/addons/frag/functions/fnc_shouldSpall.sqf @@ -17,20 +17,8 @@ params ["_ammo"]; -private _shouldSpall = GVAR(shouldSpallCache) get _ammo; +GVAR(shouldSpallCache) getOrDefaultCall [_ammo, { + (_ammo call FUNC(getSpallInfo)) params ["_caliber", "_explosive", "_indirectHit"]; -if (!isNil "_shouldSpall") exitWith {_shouldSpall}; - -private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; -private _caliber = getNumber (_ammoConfig >> "caliber"); -private _explosive = 1 min getNumber (_ammoConfig >> "explosive"); -private _indirectHit = getNumber (_ammoConfig >> "indirectHitRange"); - -// We need get this for fnc_getSpallInfo, so might as well cache it since we have it -GVAR(spallInfoCache) set [_ammo, [_caliber, _explosive, _indirectHit]]; - -_shouldSpall = _caliber * GVAR(spallIntensity) >= 1.25 * ACE_FRAG_SPALL_POWER_MIN || (_explosive >= 0.5 && {_indirectHit * GVAR(spallIntensity) >= 2 * ACE_FRAG_SPALL_POWER_MIN}); - -GVAR(shouldSpallCache) set [_ammo, _shouldSpall]; - -_shouldSpall + (_caliber * GVAR(spallIntensity) >= 1.25 * ACE_FRAG_SPALL_POWER_MIN) || {_explosive >= 0.5 && {_indirectHit * GVAR(spallIntensity) >= 2 * ACE_FRAG_SPALL_POWER_MIN}} +}, true] From 2206ef4ff19516c07e28561de1e6e03bb77a665a Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 13 Apr 2024 21:19:43 -0500 Subject: [PATCH 246/282] Removed unused classes, redefined using macros to minimize error and make review easier --- addons/frag/CfgAmmoFragSpawner.hpp | 544 +++-------------------------- 1 file changed, 58 insertions(+), 486 deletions(-) diff --git a/addons/frag/CfgAmmoFragSpawner.hpp b/addons/frag/CfgAmmoFragSpawner.hpp index 99c8012511c..6d5a4c86513 100644 --- a/addons/frag/CfgAmmoFragSpawner.hpp +++ b/addons/frag/CfgAmmoFragSpawner.hpp @@ -1,509 +1,81 @@ +#define TARGETED_SPAWNER_PROTOTYPE(size) class GVAR(DOUBLES(size,spawner_2_short)): GVAR(spawnbase_targeted) {\ + submunitionAmmo = QGVAR(size);\ +};\ +class GVAR(DOUBLES(size,spawner_2_mid)): GVAR(DOUBLES(size,spawner_2_short)) {\ + submunitionConeAngle = 2;\ +};\ +class GVAR(DOUBLES(size,spawner_2_far)): GVAR(DOUBLES(size,spawner_2_short)) {\ + submunitionConeAngle = 0.9;\ +};\ +class GVAR(DOUBLES(size,spawner_3_short)): GVAR(DOUBLES(size,spawner_2_short)) {\ + submunitionConeType[] = {"random", 3};\ +};\ +class GVAR(DOUBLES(size,spawner_3_mid)): GVAR(DOUBLES(size,spawner_3_short)) {\ + submunitionConeAngle = 2;\ +};\ +class GVAR(DOUBLES(size,spawner_3_far)): GVAR(DOUBLES(size,spawner_3_short)) {\ + submunitionConeAngle = 0.9;\ +} + +#define RANDOM_SPAWNER_PROTOTYPE(size,count) class GVAR(DOUBLES(TRIPLES(random,size,count),mid)): GVAR(spawnbase) {\ + submunitionConeType[] = {"random", count};\ + submunitionAmmo = QGVAR(size);\ + submunitionConeAngle = 85;\ + triggerSpeedCoef[] = {-1.5, 1.5};\ +};\ +class GVAR(DOUBLES(TRIPLES(random,size,count),high)): GVAR(spawnbase) {\ + submunitionConeType[] = {"random", count};\ + submunitionAmmo = QGVAR(size);\ + submunitionConeAngle = 80;\ + triggerSpeedCoef[] = {0.75, 1.5};\ +};\ +class GVAR(DOUBLES(TRIPLES(random,size,count),top)): GVAR(spawnbase) {\ + submunitionConeType[] = {"random", count};\ + submunitionAmmo = QGVAR(size);\ + submunitionConeAngle = 60;\ + triggerSpeedCoef[] = {0.75, 1.5};\ +} + class GVAR(spawnbase): B_65x39_Caseless { + ACE_FRAG_RM_EH; deleteParentWhenTriggered = 1; + explosionEffects = ""; submunitionConeType[] = {"random", 25}; submunitionAmmo[] = {QGVAR(tiny), 3, QGVAR(tiny_HD), 3, QGVAR(small), 4, QGVAR(small_HD), 4, QGVAR(medium_HD), 5}; submunitionDirectionType = "SubmunitionModelDirection"; submunitionConeAngleHorizontal = 15; submunitionConeAngle = 87; submunitionInitialOffset[] = {0,0,0}; - submunitionInitSpeed = 1000; + submunitionInitSpeed = 0; submunitionParentSpeedCoef = 1; triggerSpeedCoef[] = {0.75, 1.5}; triggerTime = 0; - ACE_FRAG_RM_EH; -}; - -/* - * Default frag, spawning 10 fragments - */ -class GVAR(def_10): GVAR(spawnbase) { - submunitionConeType[] = {"random", 10}; -}; -class GVAR(def_10_mid): GVAR(def_10) { - submunitionConeAngle = 85; - triggerSpeedCoef[] = {-1.5, 1.5}; -}; -class GVAR(def_10_hi): GVAR(def_10) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.5, -0.75}; -}; -class GVAR(def_10_top): GVAR(def_10) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.5, -0.75}; -}; -/* - * Default frag, spawning 15 fragments - */ -class GVAR(def_15): GVAR(spawnbase) { - submunitionConeType[] = {"random", 15}; -}; -class GVAR(def_15_mid): GVAR(def_15) { - submunitionConeAngle = 85; - triggerSpeedCoef[] = {-1.5, 1.5}; -}; -class GVAR(def_15_hi): GVAR(def_15) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.5, -0.75}; -}; -class GVAR(def_15_top): GVAR(def_15) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.5, -0.75}; -}; - -/* - * Default frag, spawning 5 fragments - */ -class GVAR(def_5): GVAR(spawnbase) { - submunitionConeType[] = {"random", 5}; -}; -class GVAR(def_5_mid): GVAR(def_5) { - submunitionConeAngle = 85; - triggerSpeedCoef[] = {-1.5, 1.5}; -}; -class GVAR(def_5_hi): GVAR(def_5) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.5, -0.75}; -}; -class GVAR(def_5_top): GVAR(def_5) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.5, -0.75}; -}; - -/* - * Default frag, spawning tiny fragments only - */ -class GVAR(def_tiny_15): GVAR(spawnbase) { - submunitionConeType[] = {"random", 15}; - submunitionAmmo = QGVAR(tiny); -}; -class GVAR(def_tiny_15_mid): GVAR(def_tiny_15) { - submunitionConeAngle = 85; - triggerSpeedCoef[] = {-1.5, 1.5}; -}; -class GVAR(def_tiny_15_hi): GVAR(def_tiny_15) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.5, -0.75}; -}; -class GVAR(def_tiny_15_top): GVAR(def_tiny_15) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.5, -0.75}; -}; - -/* - * Default frag, spawning 10 tiny fragments only - */ -class GVAR(def_tiny_10): GVAR(spawnbase) { - submunitionConeType[] = {"random", 10}; - submunitionAmmo = QGVAR(tiny); -}; -class GVAR(def_tiny_10_mid): GVAR(def_tiny_10) { - submunitionConeAngle = 85; - triggerSpeedCoef[] = {-1.5, 1.5}; -}; -class GVAR(def_tiny_10_hi): GVAR(def_tiny_10) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.5, -0.75}; -}; -class GVAR(def_tiny_10_top): GVAR(def_tiny_10) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.5, -0.75}; -}; - -/* - * Default frag, spawning 15 tiny fragments only - */ -class GVAR(def_tiny_5): GVAR(spawnbase) { - submunitionConeType[] = {"random", 5}; - submunitionAmmo = QGVAR(tiny); -}; -class GVAR(def_tiny_5_mid): GVAR(def_tiny_5) { - submunitionConeAngle = 85; - triggerSpeedCoef[] = {-1.5, 1.5}; -}; -class GVAR(def_tiny_5_hi): GVAR(def_tiny_5) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.5, -0.75}; -}; -class GVAR(def_tiny_5_top): GVAR(def_tiny_5) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.5, -0.75}; -}; - -/* - * Default frag, spawning 15 tiny fragments only - */ -class GVAR(def_small_15): GVAR(spawnbase) { - submunitionConeType[] = {"random", 15}; - submunitionAmmo = QGVAR(small); -}; -class GVAR(def_small_15_mid): GVAR(def_small_15) { - submunitionConeAngle = 815; - triggerSpeedCoef[] = {-1.15, 1.15}; -}; -class GVAR(def_small_15_hi): GVAR(def_small_15) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.15, -0.715}; -}; -class GVAR(def_small_15_top): GVAR(def_small_15) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.15, -0.715}; }; -/* - * Default frag, spawning 10 small fragments only - */ -class GVAR(def_small_10): GVAR(spawnbase) { - submunitionConeType[] = {"random", 10}; - submunitionAmmo = QGVAR(small); -}; -class GVAR(def_small_10_mid): GVAR(def_small_10) { - submunitionConeAngle = 810; - triggerSpeedCoef[] = {-1.10, 1.10}; -}; -class GVAR(def_small_10_hi): GVAR(def_small_10) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.10, -0.710}; -}; -class GVAR(def_small_10_top): GVAR(def_small_10) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.10, -0.710}; -}; -/* - * Default frag, spawning small fragments only - */ -class GVAR(def_small_5): GVAR(spawnbase) { - submunitionConeType[] = {"random", 5}; - submunitionAmmo = QGVAR(small); -}; -class GVAR(def_small_5_mid): GVAR(def_small_5) { - submunitionConeAngle = 85; - triggerSpeedCoef[] = {-1.5, 1.5}; -}; -class GVAR(def_small_5_hi): GVAR(def_small_5) { - submunitionConeAngle = 80; - triggerSpeedCoef[] = {-1.5, -0.75}; -}; -class GVAR(def_small_5_top): GVAR(def_small_5) { - submunitionConeAngle = 60; - triggerSpeedCoef[] = {-1.5, -0.75}; -}; + RANDOM_SPAWNER_PROTOTYPE(tiny,15); + RANDOM_SPAWNER_PROTOTYPE(tiny,10); + RANDOM_SPAWNER_PROTOTYPE(tiny,5); + RANDOM_SPAWNER_PROTOTYPE(small,15); + RANDOM_SPAWNER_PROTOTYPE(small,10); + RANDOM_SPAWNER_PROTOTYPE(small,5); /* * Targeted fragment spawner, for when multiple fragments are spawned (1-3) */ class GVAR(spawnbase_targeted): GVAR(spawnbase) { submunitionConeType[] = {"random", 2}; - submunitionConeAngle = 2; - submunitionInitSpeed = 0; - triggerSpeedCoef[] = {0.5, 1}; -}; - -class GVAR(tiny_spawner_2_short): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(tiny_spawner_2_mid): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(tiny_spawner_2_far): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(tiny_spawner_3_short): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; -}; -class GVAR(tiny_spawner_3_mid): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; -}; -class GVAR(tiny_spawner_3_far): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; -}; - -class GVAR(tiny_HD_spawner_2_short): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(tiny_HD_spawner_2_mid): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(tiny_HD_spawner_2_far): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(tiny_HD_spawner_3_short): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; -}; -class GVAR(tiny_HD_spawner_3_mid): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; -}; -class GVAR(tiny_HD_spawner_3_far): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(tiny_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; -}; - -class GVAR(small_spawner_2_short): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(small_spawner_2_mid): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(small_spawner_2_far): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(small_spawner_3_short): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; -}; -class GVAR(small_spawner_3_mid): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; -}; -class GVAR(small_spawner_3_far): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; -}; - -class GVAR(small_HD_spawner_2_short): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(small_HD_spawner_2_mid): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(small_HD_spawner_2_far): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(small_HD_spawner_3_short): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; -}; -class GVAR(small_HD_spawner_3_mid): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; -}; -class GVAR(small_HD_spawner_3_far): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(small_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; -}; - -class GVAR(medium_spawner_2_short): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(medium_spawner_2_mid): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(medium_spawner_2_far): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(medium_spawner_3_short): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; -}; -class GVAR(medium_spawner_3_mid): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; -}; -class GVAR(medium_spawner_3_far): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; -}; - -class GVAR(medium_HD_spawner_2_short): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(medium_HD_spawner_2_mid): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(medium_HD_spawner_2_far): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(medium_HD_spawner_3_short): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; -}; -class GVAR(medium_HD_spawner_3_mid): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; -}; -class GVAR(medium_HD_spawner_3_far): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(medium_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; -}; - -class GVAR(large_spawner_2_short): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(large_spawner_2_mid): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(large_spawner_2_far): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(large_spawner_3_short): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large); submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; -}; -class GVAR(large_spawner_3_mid): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; -}; -class GVAR(large_spawner_3_far): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; -}; - -class GVAR(large_HD_spawner_2_short): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(large_HD_spawner_2_mid): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(large_HD_spawner_2_far): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(large_HD_spawner_3_short): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; -}; -class GVAR(large_HD_spawner_3_mid): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; -}; -class GVAR(large_HD_spawner_3_far): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(large_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; + triggerSpeedCoef[] = {0.5, 1}; }; -class GVAR(huge_spawner_2_short): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(huge_spawner_2_mid): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(huge_spawner_2_far): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(huge_spawner_3_short): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; -}; -class GVAR(huge_spawner_3_mid): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; -}; -class GVAR(huge_spawner_3_far): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; -}; -class GVAR(huge_HD_spawner_2_short): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(huge_HD_spawner_2_mid): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(huge_HD_spawner_2_far): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 2}; -}; -class GVAR(huge_HD_spawner_3_short): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge_HD); - submunitionConeAngle = 4.5; - submunitionConeType[] = {"random", 3}; -}; -class GVAR(huge_HD_spawner_3_mid): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge_HD); - submunitionConeAngle = 2; - submunitionConeType[] = {"random", 3}; -}; -class GVAR(huge_HD_spawner_3_far): GVAR(spawnbase_targeted) { - submunitionAmmo = QGVAR(huge_HD); - submunitionConeAngle = 0.9; - submunitionConeType[] = {"random", 3}; -}; +TARGETED_SPAWNER_PROTOTYPE(tiny); +TARGETED_SPAWNER_PROTOTYPE(tiny_HD); +TARGETED_SPAWNER_PROTOTYPE(small); +TARGETED_SPAWNER_PROTOTYPE(small_HD); +TARGETED_SPAWNER_PROTOTYPE(medium); +TARGETED_SPAWNER_PROTOTYPE(medium_HD); +TARGETED_SPAWNER_PROTOTYPE(large); +TARGETED_SPAWNER_PROTOTYPE(large_HD); +TARGETED_SPAWNER_PROTOTYPE(huge); +TARGETED_SPAWNER_PROTOTYPE(huge_HD); From 25f14af67924776d94b8afb4a1b66d9fb435517f Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 13 Apr 2024 21:20:06 -0500 Subject: [PATCH 247/282] updated debugging output and fixed velocity error --- addons/frag/functions/fnc_doFragRandom.sqf | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index 06c51e45345..0e434830a39 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -27,11 +27,11 @@ TRACE_5("doFragRandom",_posASL,_fragVelocity,_fragType,_maxFragCount,_shotParent private _heightATL = (ASLToATL _posASL)#2; private _hMode = switch (true) do { case (_heightATL > 10): {"_top"}; - case (_heightATL > 5): {"_hi"}; + case (_heightATL > 4): {"_high"}; default {"_mid"}; }; -private _type = [QGVAR(def_small_), QGVAR(def_tiny_)] select (_fragType isNotEqualTo [] && {"ace_frag_tiny" == (_fragType#0)}); +private _type = [QGVAR(random_small_), QGVAR(random_tiny_)] select (_fragType isNotEqualTo [] && {"ace_frag_tiny" == (_fragType#0)}); _maxFragCount = switch (true) do { case (_maxFragCount <= 5): {"5"}; @@ -43,12 +43,10 @@ _maxFragCount = switch (true) do { private _fragSpawner = createVehicle [_type + _maxFragCount + _hMode, ASLToATL _posASL, [], 0, "CAN_COLLIDE"]; private _randDir = random 360; _fragSpawner setVectorDirandUp [[0,0,-1], [cos _randDir, sin _randDir,0]]; -_fragSpawner setVelocity _fragVelocity; +_fragSpawner setVelocity [0, 0, -0.5*_fragVelocity]; _fragSpawner setShotParents _shotParents; -#ifdef DEBUG_MODE_FULL -systemChat ("frag random objectID: " + getObjectID _proj); -#endif +TRACE_2("spawnedRandomFragmenter",typeOf _fragSpawner,getObjectID _fragSpawner); #ifdef DEBUG_MODE_DRAW _fragSpawner addEventHandler [ "SubmunitionCreated", From eb24c11e82a2b9124ac242b39ae93962d78fa9c5 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 13 Apr 2024 21:20:35 -0500 Subject: [PATCH 248/282] Reformatted for legibility and debug output --- addons/frag/CfgAmmoSpall.hpp | 2 +- addons/frag/functions/fnc_doFrag.sqf | 4 ++-- addons/frag/functions/fnc_doSpall.sqf | 4 +--- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/addons/frag/CfgAmmoSpall.hpp b/addons/frag/CfgAmmoSpall.hpp index a773cfc659c..ee9a253e0d9 100644 --- a/addons/frag/CfgAmmoSpall.hpp +++ b/addons/frag/CfgAmmoSpall.hpp @@ -1,4 +1,5 @@ class GVAR(spallBase): B_65x39_Caseless { + ACE_FRAG_RM_EH; submunitionAmmo[] = {QGVAR(small),4,QGVAR(medium),3,QGVAR(large),2,QGVAR(huge),1}; submunitionConeType[] = {"random", 20}; submunitionConeAngle = 40; @@ -9,7 +10,6 @@ class GVAR(spallBase): B_65x39_Caseless { triggerSpeedCoef[] = {0.75,1.25}; deleteParentWhenTriggered = 1; submunitionParentSpeedCoef = 1; - ACE_FRAG_RM_EH; }; diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 6037b06ae2d..d6bb56c18d3 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -38,7 +38,7 @@ TRACE_3("willFrag",_timeSinceLastFrag,CBA_missionTime,_maxFragCount); _shotParentVehicle setVariable [QGVAR(obj_nextFragTime), CBA_missionTime + ACE_FRAG_HOLDOFF_VEHICLE]; private _maxFragCount = round linearConversion [ACE_FRAG_COUNT_MIN_TIME, ACE_FRAG_COUNT_MAX_TIME, _timeSinceLastFrag, ACE_FRAG_COUNT_MIN, ACE_FRAG_COUNT_MAX, true]; -_ammo call FUNC(getFragInfo) params ["_fragRange", "_fragVel", "_fragTypes", "_modFragCount"]; +_ammo call FUNC(getFragInfo) params ["_fragRange", "_fragVelocity", "_fragTypes", "_modFragCount"]; // For low frag rounds limit the # of frags created if (_modFragCount < ACE_FRAG_LOW_FRAG_MOD_COUNT) then { _maxFragCount = _modFragCount * ACE_FRAG_LOW_FRAG_COEFF; @@ -49,7 +49,7 @@ if (_modFragCount < ACE_FRAG_LOW_FRAG_MOD_COUNT) then { TRACE_3("doFrag choices",_maxFragCount,_fragRange,GVAR(fragSimComplexity)); if (GVAR(fragSimComplexity) != 1 && _fragRange > 3) then { - _maxFragCount = _maxFragCount - ([_posASL, _fragVel, _fragRange, _maxFragCount, _fragTypes, _modFragCount, _shotParents] call FUNC(doFragTargeted)); + _maxFragCount = _maxFragCount - ([_posASL, _fragVelocity, _fragRange, _maxFragCount, _fragTypes, _modFragCount, _shotParents] call FUNC(doFragTargeted)); }; if (GVAR(fragSimComplexity) > 0 && _maxFragCount >= ACE_FRAG_MIN_FRAG_BUDGET_FOR_RANDOM) then { diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index 589cb254e33..a516648f0b1 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -31,9 +31,7 @@ if (_ammo == "" || {_objectHit isKindOf "CAManBase"}) exitWith { private _material = _surfaceType call FUNC(getMaterialInfo); if (_material == "ground") exitWith { - #ifdef DEBUG_MODE_FULL - systemChat "ground spall"; - #endif + TRACE_1("ground",_surfaceType); }; // Find spall speed / fragment info From 3c2a3c7ef21ac35d0fe4c95b8a94c2ab84d9a89b Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 13 Apr 2024 21:21:05 -0500 Subject: [PATCH 249/282] caught calc error while answer johnb's question --- addons/frag/functions/fnc_getFragInfo.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_getFragInfo.sqf b/addons/frag/functions/fnc_getFragInfo.sqf index 2fae0c71a3a..50af9cb5d68 100644 --- a/addons/frag/functions/fnc_getFragInfo.sqf +++ b/addons/frag/functions/fnc_getFragInfo.sqf @@ -95,7 +95,7 @@ if (_notifyMissingEntries) then { * 3: _fragCount - modified frag count used under assumptions of spherical fragmentation */ _ammoInfo = [ - ACE_FRAG_MAX_FRAG_RANGE max sqrt (_fragCount / (4 * pi * ACE_FRAG_MIN_FRAG_HIT_CHANCE)), + ACE_FRAG_MAX_FRAG_RANGE min sqrt (_fragCount / (4 * pi * ACE_FRAG_MIN_FRAG_HIT_CHANCE)), ACE_FRAG_IMPERIC_VELOCITY_CONSTANT * _gurneyConstant * sqrt (_chargeMass / (_metalMass + _chargeMass * _geometryCoefficient)), _fragTypes, _fragCount / 4 / pi From ce60bd35de39a0f8d66fb203e5477bdc00710d07 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 13 Apr 2024 21:22:31 -0500 Subject: [PATCH 250/282] Almost finished with compats and I had some changes to align vanilla as well --- addons/frag/CfgAmmoBaseEH.hpp | 1 + addons/frag/CfgAmmoFragParameters.hpp | 505 ++++++++++++++++++-------- 2 files changed, 349 insertions(+), 157 deletions(-) diff --git a/addons/frag/CfgAmmoBaseEH.hpp b/addons/frag/CfgAmmoBaseEH.hpp index b02b1b7c6fa..c28855d92b3 100644 --- a/addons/frag/CfgAmmoBaseEH.hpp +++ b/addons/frag/CfgAmmoBaseEH.hpp @@ -47,6 +47,7 @@ class ShotgunBase: ShotgunCore { class SubmunitionCore; class SubmunitionBase: SubmunitionCore { ACE_FRAG_ADD_EH_BASE; + GVAR(skip) = 1; }; class BoundingMineCore; diff --git a/addons/frag/CfgAmmoFragParameters.hpp b/addons/frag/CfgAmmoFragParameters.hpp index 0890acdf11f..e89b966c281 100644 --- a/addons/frag/CfgAmmoFragParameters.hpp +++ b/addons/frag/CfgAmmoFragParameters.hpp @@ -2,64 +2,112 @@ class B_19mm_HE: BulletBase { GVAR(skip) = 1; }; + class B_20mm: BulletBase { // Used in Weisel/AWC Nyx, which makes it a Rheinmetall Mk 20 Rh-202 - // http://www.navweaps.com/Weapons/WNGER_20mm-65_mk20.php - // total mass of 134g probably not enough to do anything + // Based on jane's ammunition handbook ~2002 (archive.org) + GVAR(skip) = 1; + GVAR(charge) = 6; + GVAR(metal) = 114; + GVAR(gurney_c) = 2830; + GVAR(gurney_k) = "1/2"; + GVAR(fragCount) = 100; + GVAR(classes)[] = {QGVAR(tiny)}; +}; + +class B_20mm_AP: BulletBase { GVAR(skip) = 1; }; + +class ammo_Gun20mmAABase: BulletBase { // 20x139mm + GVAR(skip) = 1; + GVAR(charge) = 6; + GVAR(metal) = 114; + GVAR(gurney_c) = 2830; + GVAR(gurney_k) = "1/2"; + GVAR(fragCount) = 100; + GVAR(classes)[] = {QGVAR(tiny)}; +}; + +class ammo_Gun30mmAABase: BulletBase { // 30x210mm HEI + GVAR(skip) = 0; + GVAR(charge) = 40; + GVAR(metal) = 410; + GVAR(gurney_k) = "1/2"; + GVAR(gurney_c) = 2901; + GVAR(fragCount) = 250; + GVAR(classes)[] = {QGVAR(tiny), QGVAR(tiny), QGVAR(small)}; + +}; + class B_30mm_HE: B_19mm_HE { // Used in Gorgon (Pandur II), assuming it's a L21A1 RARDEN, specifically HEI-T due to tracers // https://ordtech-industries.com/30x170-mm-ammunition-for-cannons-oerlikon-kcb-hispano-hs831l-l21-rarden/ GVAR(skip) = 0; - GVAR(classes)[] = {QGVAR(tiny), QGVAR(small)}; - GVAR(fragCount) = 100; - GVAR(metal) = 320; GVAR(charge) = 25; - GVAR(gurney_c) = 2547; // Hexal det. velocity / 3 + GVAR(metal) = 320; + GVAR(gurney_c) = 2552; GVAR(gurney_k) = "1/2"; + GVAR(fragCount) = 180; + GVAR(classes)[] = {QGVAR(tiny), QGVAR(tiny), QGVAR(small)}; }; class B_30mm_MP: B_30mm_HE { // Used in Mora (FV510 Warrior), assuming it's a Mk44 Bushmaster II, specifically HEI-T due to tracers // http://www.navweaps.com/Weapons/WNUS_30mm_BushmasterII.php - GVAR(classes)[] = {QGVAR(tiny), QGVAR(small)}; - GVAR(fragCount) = 100; // assumed based on https://www.youtube.com/watch?v=c5SsspD0MeU GVAR(metal) = 388; GVAR(charge) = 56; GVAR(gurney_c) = 2600; GVAR(gurney_k) = "1/2"; + GVAR(fragCount) = 180; // assumed based on https://www.youtube.com/watch?v=c5SsspD0MeU + GVAR(classes)[] = {QGVAR(tiny), QGVAR(tiny), QGVAR(small)}; }; + class Gatling_30mm_HE_Plane_CAS_01_F: BulletBase { GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(tiny), QGVAR(small)}; - GVAR(fragCount) = 100; + GVAR(fragCount) = 180; GVAR(metal) = 388; GVAR(charge) = 56; GVAR(gurney_c) = 2600; // guessed GVAR(gurney_k) = "1/2"; }; -class B_40mm_GPR: B_30mm_HE { - // Based on noted 40mm Autocannons, base ROF, and ammo names, looks to be a CTAS40, specifically GPR-PD-T - // https://www.cta-international.com/ammunition/ - // https://ndiastorage.blob.core.usgovcloudapi.net/ndia/2002/gun/leslie.pdf - GVAR(classes)[] = {QGVAR(tiny), QGVAR(small)}; - GVAR(fragCount) = 250; - GVAR(metal) = 750; - GVAR(charge) = 120; - GVAR(gurney_c) = 2700; // guessed + +class ammo_Gun35mmAABase: BulletBase { + // Gepard uses an Oerlikon GDF and the AA vehicles mimics it like it + // https://en.wikipedia.org/wiki/Oerlikon_GDF#Ammunition + // https://www.nammo.com/product/our-products/ammunition/medium-caliber-ammunition/35-mm-series/35-mm-x-228-hei-sd-and-hei-t-sd/ + GVAR(skip) = 0; + GVAR(charge) = 98; + GVAR(metal) = 400; GVAR(gurney_k) = "1/2"; + GVAR(gurney_c) = 2700; + GVAR(fragCount) = 300; + GVAR(classes)[] = {QGVAR(tiny), QGVAR(tiny), QGVAR(small)}; }; + class B_35mm_AA: BulletBase { // Gepard uses an Oerlikon GDF and the AA vehicles mimics it like it // https://en.wikipedia.org/wiki/Oerlikon_GDF#Ammunition // https://www.nammo.com/product/our-products/ammunition/medium-caliber-ammunition/35-mm-series/35-mm-x-228-hei-sd-and-hei-t-sd/ GVAR(skip) = 0; - GVAR(classes)[] = {QGVAR(tiny), QGVAR(tiny), QGVAR(small)}; - GVAR(fragCount) = 175; - GVAR(metal) = 400; GVAR(charge) = 98; + GVAR(metal) = 400; + GVAR(gurney_k) = "1/2"; GVAR(gurney_c) = 2700; + GVAR(fragCount) = 300; + GVAR(classes)[] = {QGVAR(tiny), QGVAR(tiny), QGVAR(small)}; +}; + +class B_40mm_GPR: B_30mm_HE { + // Based on noted 40mm Autocannons, base ROF, and ammo names, looks to be a CTAS40, specifically GPR-PD-T + // https://www.cta-international.com/ammunition/ + // https://ndiastorage.blob.core.usgovcloudapi.net/ndia/2002/gun/leslie.pdf + GVAR(classes)[] = {QGVAR(tiny), QGVAR(small)}; + GVAR(fragCount) = 250; + GVAR(metal) = 750; + GVAR(charge) = 120; + GVAR(gurney_c) = 2700; // guessed GVAR(gurney_k) = "1/2"; }; class UnderwaterMine_Range_Ammo: MineBase { @@ -69,40 +117,43 @@ class UnderwaterMine_Range_Ammo: MineBase { // ~~~~ Bombs: class Bo_GBU12_LGB: ammo_Bomb_LaserGuidedBase { - GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; - GVAR(fragCount) = 17500; - GVAR(metal) = 140000; + GVAR(skip) = 0; GVAR(charge) = 87000; + GVAR(metal) = 140000; GVAR(gurney_c) = 2320; - GVAR(gurney_k) = "3/5"; + GVAR(gurney_k) = "1/2"; + GVAR(fragCount) = 17500; + GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; }; class Bomb_03_F: ammo_Bomb_LaserGuidedBase { - GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; - GVAR(fragCount) = 17500; - GVAR(metal) = 150000; + GVAR(skip) = 0; GVAR(charge) = 100000; + GVAR(metal) = 150000; GVAR(gurney_c) = 2320; - GVAR(gurney_k) = "3/5"; + GVAR(gurney_k) = "1/2"; + GVAR(fragCount) = 17500; + GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; }; class Bomb_04_F: ammo_Bomb_LaserGuidedBase { - GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; - GVAR(fragCount) = 17500; - GVAR(metal) = 140000; + GVAR(skip) = 0; GVAR(charge) = 87000; + GVAR(metal) = 140000; GVAR(gurney_c) = 2320; - GVAR(gurney_k) = "3/5"; + GVAR(gurney_k) = "1/2"; + GVAR(fragCount) = 17500; + GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; }; -class ammo_Bomb_SmallDiameterBase: ammo_Bomb_LaserGuidedBase { +class BombCluster_01_Ammo_F: Bomb_04_F { GVAR(skip) = 1; }; -class ammo_Bomb_SDB: ammo_Bomb_SmallDiameterBase { +class ammo_Bomb_SmallDiameterBase: ammo_Bomb_LaserGuidedBase { GVAR(skip) = 0; - GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; - GVAR(fragCount) = 17500; - GVAR(metal) = 113000; - GVAR(charge) = 16000; + GVAR(charge) = 160; // kg + GVAR(metal) = 113; // kg GVAR(gurney_c) = 2830; - GVAR(gurney_k) = "3/5"; + GVAR(gurney_k) = "1/2"; + GVAR(fragCount) = 8000; + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium), QGVAR(large), QGVAR(large), QGVAR(huge), QGVAR(huge_HD)}; }; class BombCore; @@ -155,12 +206,18 @@ class GrenadeHand: Grenade { individual grenades. */ GVAR(classes)[] = {QGVAR(tiny)}; - GVAR(fragCount) = 1000; + GVAR(fragCount) = 800; GVAR(metal) = 210; // metal in grams GVAR(charge) = 185; // explosive in grams GVAR(gurney_c) = 2843; // Gurney velocity constant for explosive type. See: http://en.wikipedia.org/wiki/Gurney_equations GVAR(gurney_k) = "3/5"; // Gurney shape factor, in this case a sphere. See: http://en.wikipedia.org/wiki/Gurney_equations }; +class mini_Grenade: GrenadeHand { + GVAR(classes)[] = {QGVAR(tiny)}; + GVAR(fragCount) = 520; + GVAR(metal) = 104; + GVAR(charge) = 36; +}; class GrenadeHand_stone: GrenadeHand { ACE_FRAG_RM_EH; GVAR(skip) = 1; @@ -242,6 +299,10 @@ class APERSBoundingMine_Range_Ammo: MineBase { GVAR(gurney_k) = "3/5"; }; +class TrainingMine_Ammo: APERSMine_Range_Ammo { + GVAR(skip) = 1; +}; + class SLAMDirectionalMine_Wire_Ammo: DirectionalBombBase { ACE_FRAG_RM_EH; GVAR(skip) = 1; @@ -295,16 +356,24 @@ class IEDLandSmall_Remote_Ammo: PipeBombBase { GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium_HD)}; }; +class APERSMineDispenser_Ammo: PipeBombBase { + GVAR(skip) = 1; +}; class UXO1_Ammo_Base_F: APERSMine_Range_Ammo { // Mk 118 Rockeye GVAR(skip) = 0; - GVAR(force) = 0; - GVAR(classes)[] = {QGVAR(small)}; - GVAR(fragCount) = 200; - GVAR(metal) = 400; GVAR(charge) = 180; + GVAR(metal) = 400; GVAR(gurney_c) = 2700; GVAR(gurney_k) = "1/2"; + GVAR(fragCount) = 200; + GVAR(classes)[] = {QGVAR(small)}; +}; + +class UXO2_Ammo_Base_F: UXO1_Ammo_Base_F { + GVAR(charge) = 100; + GVAR(fragCount) = 304; + GVAR(classes)[] = {QGVAR(small), QGVAR(tiny)}; }; class APERSMineDispenser_Mine_Ammo: APERSMine_Range_Ammo { @@ -314,7 +383,6 @@ class APERSMineDispenser_Mine_Ammo: APERSMine_Range_Ammo { class UXO_deploy_base_f: SubmunitionBase { ACE_FRAG_RM_EH; - GVAR(skip) = 1; }; class ClaymoreDirectionalMine_Remote_Ammo: DirectionalBombBase { @@ -356,6 +424,7 @@ class R_PG7_F: RocketBase { GVAR(gurney_c) = 2730; GVAR(gurney_k) = "1/2"; }; + class R_PG32V_F: RocketBase { ACE_FRAG_RM_EH; GVAR(skip) = 1; @@ -370,21 +439,6 @@ class R_TBG32V_F: R_PG32V_F { // Thermobaric GVAR(gurney_k) = "3/5"; GVAR(classes)[] = {QGVAR(medium_HD)}; }; -class M_Titan_AA: MissileBase { - GVAR(skip) = 1; -}; -class M_Titan_AT: MissileBase { - GVAR(skip) = 1; -}; -class M_Titan_AP: M_Titan_AT { - GVAR(skip) = 0; - GVAR(fragCount) = 800; // guesstimate / provides ~80 m frag range - GVAR(metal) = 400; - GVAR(charge) = 210; - GVAR(gurney_c) = 2800; - GVAR(gurney_k) = "3/5"; - GVAR(classes)[] = {QGVAR(medium_HD)}; -}; class M_SPG9_HEAT: RocketBase { GVAR(skip) = 0; @@ -430,31 +484,79 @@ class R_MRAAWS_HE_F: R_MRAAWS_HEAT_F { // Table A-6. HE 441D RS GVAR(classes)[] = {QGVAR(small)}; }; +class R_80mm_HE: RocketBase { // S-8D + GVAR(skip) = 0; + GVAR(charge) = 2150; + GVAR(metal) = 1650; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/2"; + GVAR(fragCount) = 1200; + GVAR(classes)[] = {QGVAR(small), QGVAR(tiny), QGVAR(tiny)}; +}; +class R_60mm_HE: R_80mm_HE { // no idea but looks like a FFAR so made it weaker + GVAR(fragCount) = 1000; + GVAR(metal) = 1040; + GVAR(charge) = 3850; +}; + +class m_70mm_saami: RocketBase {///!!! fix me + GVAR(skip) = 0; + GVAR(charge) = 2150; + GVAR(metal) = 1650; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/2"; + GVAR(fragCount) = 1200; + GVAR(classes)[] = {QGVAR(small), QGVAR(tiny), QGVAR(tiny)}; +}; + +class Rocket_04_HE_F: MissileBase { // Shrieker (Hydra 70) + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) + GVAR(metal) = 3850; + GVAR(charge) = 1040; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/2"; +}; +class Rocket_03_HE_F: Rocket_04_HE_F { // S-8DM makes the most sense + GVAR(fragCount) = 600; // Thermobaric rounds usually have fewer fragments + GVAR(metal) = 1; + GVAR(charge) = 2; + GVAR(gurney_c) = 2300; +}; +class Rocket_04_AP_F: Rocket_04_HE_F { + GVAR(skip) = 1; +}; + +class ammo_Missile_CannonLaunchedBase: MissileBase { + GVAR(skip) =1; +}; + class R_230mm_fly: RocketBase { GVAR(skip) = 0; - GVAR(fragCount) = 17500; - GVAR(metal) = 150000; - GVAR(charge) = 100000; + GVAR(charge) = 100; // kg + GVAR(metal) = 150; // kg GVAR(gurney_c) = 2320; GVAR(gurney_k) = "3/5"; + GVAR(fragCount) = 17500; GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; }; class M_PG_AT: MissileBase { // DAGR M247 warhead GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(tiny), QGVAR(small), QGVAR(small), QGVAR(medium)}; - GVAR(fragCount) = 700; // guesstimate / provides ~80 m frag range (1% chance to hit) - GVAR(metal) = 3085; GVAR(charge) = 910; + GVAR(metal) = 3085; GVAR(gurney_c) = 2700; + GVAR(fragCount) = 700; // guesstimate / provides ~70 m frag range (0.5% chance to hit) GVAR(gurney_k) = "1/2"; }; class M_AT: M_PG_AT { // DAR (Hydra 70) M151 warhead GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) - GVAR(metal) = 3850; GVAR(charge) = 1040; + GVAR(metal) = 3850; GVAR(gurney_c) = 2700; + GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (0.5% chance to hit) }; // ~~~~ Missiles: @@ -462,40 +564,40 @@ class Missile_AGM_02_F: MissileBase { // Source: http://fas.org/man/dod-101/sys/smart/agm-65.htm GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 1600; + GVAR(fragCount) = 500; GVAR(metal) = 56250; GVAR(charge) = 39000; GVAR(gurney_c) = 2700; GVAR(gurney_k) = "1/2"; }; -class Missile_AGM_01_F: Missile_AGM_02_F { // Kh-25MTP - GVAR(skip) = 0; - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; +class Missile_AGM_01_F: Missile_AGM_02_F { // Kh-25MTP !!! fix me GVAR(fragCount) = 1600; - GVAR(metal) = 56250; - GVAR(charge) = 39000; - GVAR(gurney_c) = 2700; - GVAR(gurney_k) = "1/2"; - }; -class Rocket_04_HE_F: MissileBase { // Shrieker (Hydra 70) +class M_Jian_AT: Missile_AGM_01_F { // imaginary missile? Not simiklar to any modern HJ-x or otherwise + GVAR(fragCount) = 600; +}; + +class M_Titan_AA: MissileBase { GVAR(skip) = 0; - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 1200; // guesstimate / provides ~100 m frag range (1% chance to hit) - GVAR(metal) = 3850; - GVAR(charge) = 1040; - GVAR(gurney_c) = 2700; + GVAR(fragCount) = 600; + GVAR(metal) = 1980; + GVAR(charge) = 1020; + GVAR(gurney_c) = 2501; GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(tiny), QGVAR(tiny), QGVAR(small)}; }; -class Rocket_03_HE_F: Rocket_04_HE_F { // S-8D makes the most sense - GVAR(fragCount) = 600; // Thermobaric rounds usually have fewer fragments - GVAR(metal) = 1300; - GVAR(charge) = 2500; - GVAR(gurney_c) = 2300; -}; -class Rocket_04_AP_F: Rocket_04_HE_F { - GVAR(skip) = 1; +class M_Titan_AT: MissileBase; +class M_Titan_AP: M_Titan_AT { + GVAR(skip) = 0; + GVAR(fragCount) = 800; // guesstimate / provides ~80 m frag range + GVAR(metal) = 400; + GVAR(charge) = 210; + GVAR(gurney_c) = 2800; + GVAR(gurney_k) = "3/5"; + GVAR(classes)[] = {QGVAR(medium_HD)}; }; + + class M_Scalpel_AT: MissileBase { // 9K121 Vikhr GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium_HD)}; @@ -519,7 +621,6 @@ class ACE_Hellfire_AGM114K: M_Scalpel_AT { class ammo_Missile_CruiseBase: MissileBase { class EventHandlers: EventHandlers {}; - GVAR(skip) = 1; }; class ammo_missile_cruise_01: ammo_Missile_CruiseBase { class EventHandlers: EventHandlers {}; @@ -536,50 +637,122 @@ class ammo_Missile_Cruise_01_Cluster: ammo_missile_cruise_01 { }; class ammo_Missile_AntiRadiationBase: MissileBase { - GVAR(skip) = 1; GVAR(gurney_k) = "1/2"; GVAR(gurney_c) = 2400; }; class ammo_Missile_HARM: ammo_Missile_AntiRadiationBase { GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(large)}; - GVAR(fragCount) = 5000; - GVAR(metal) = 58000; GVAR(charge) = 10000; + GVAR(metal) = 58000; + GVAR(fragCount) = 5000; }; class ammo_Missile_KH58: ammo_Missile_AntiRadiationBase { GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(large)}; - GVAR(fragCount) = 7500; - GVAR(metal) = 129000; GVAR(charge) = 20000; + GVAR(metal) = 129000; + GVAR(fragCount) = 7500; }; +class M_Zephyr: M_Titan_AA { // model is an AMRAAM- WDU-41/B warhead + GVAR(skip) = 0; + GVAR(metal) = 12800; + GVAR(charge) = 4000; + GVAR(gurney_c) = 2900; + GVAR(gurney_k) = "1/2"; + GVAR(fragCount) = 2000; + GVAR(classes)[] = {QGVAR(tiny), QGVAR(medium), QGVAR(small), QGVAR(small)}; +}; -// No AA fragging -class M_Air_AA: MissileBase { - GVAR(skip) = 1; - ACE_FRAG_RM_EH; +class M_Air_AA: MissileBase { // Looks not real, maybe r-73 inspired? + GVAR(skip) = 0; + GVAR(charge) = 2450; + GVAR(metal) = 4950; + GVAR(gurney_c) = 2700; + GVAR(gurney_k) = "1/2"; + GVAR(fragCount) = 1000; + GVAR(classes)[] = {QGVAR(tiny), QGVAR(medium), QGVAR(small), QGVAR(small)}; }; + class Missile_AA_04_F: MissileBase { - GVAR(skip) = 1; - ACE_FRAG_RM_EH; + GVAR(skip) = 0; + GVAR(charge) = 4400; + GVAR(metal) = 5000; + GVAR(gurney_c) = 2830; + GVAR(gurney_k) = "1/2"; + GVAR(fragCount) = 1600; }; -class ammo_Missile_LongRangeAABase: MissileBase { - GVAR(skip) = 1; - ACE_FRAG_RM_EH; +class Missile_AA_03_F: Missile_AA_04_F { + GVAR(charge) = 2450; + GVAR(metal) = 4950; + GVAR(gurney_c) = 2700; + GVAR(fragCount) = 200; }; + +class ammo_Missile_ShortRangeAABase: MissileBase { + GVAR(gurney_k) = "1/2"; + GVAR(fragCount) = 1200; +}; +class ammo_Missile_rim116: ammo_Missile_ShortRangeAABase { + GVAR(skip) = 0; + GVAR(charge) = 40; // dg + GVAR(metal) = 73; // dg + GVAR(gurney_c) = 2400; + GVAR(fragCount) = 2000; + GVAR(classes)[] = {QGVAR(tiny), QGVAR(small)}; +}; +class ammo_Missile_BIM9X: ammo_Missile_ShortRangeAABase { + GVAR(skip) = 0; + GVAR(charge) = 44; // dg + GVAR(metal) = 50; // dg + GVAR(gurney_c) = 2900; + GVAR(fragCount) = 1600; + GVAR(classes)[] = {QGVAR(small), QGVAR(tiny)}; +}; +class ammo_Missile_AA_R73: ammo_Missile_ShortRangeAABase { + GVAR(skip) = 0; + GVAR(charge) = 245; // cg + GVAR(metal) = 495; // cg + GVAR(gurney_c) = 2700; + GVAR(classes)[] = {QGVAR(small), QGVAR(small), QGVAR(tiny)}; +}; + class ammo_Missile_MediumRangeAABase: MissileBase { - GVAR(skip) = 1; - ACE_FRAG_RM_EH; + GVAR(gurney_c) = 2900; + GVAR(gurney_k) = "1/2"; + GVAR(fragCount) = 2000; }; -class ammo_Missile_ShortRangeAABase: MissileBase { - GVAR(skip) = 1; - ACE_FRAG_RM_EH; +class ammo_Missile_rim162: ammo_Missile_MediumRangeAABase { + GVAR(skip) = 0; + GVAR(charge) = 138; // dg + GVAR(metal) = 252; // dg + GVAR(gurney_c) = 2400; + GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium), QGVAR(large)}; +}; +class ammo_Missile_AMRAAM_C: ammo_Missile_MediumRangeAABase { + GVAR(skip) = 0; + GVAR(charge) = 70; // dg + GVAR(metal) = 128; // dg + GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium)}; +}; +class ammo_Missile_AMRAAM_D: ammo_Missile_MediumRangeAABase { + GVAR(skip) = 0; + GVAR(charge) = 70; // dg + GVAR(metal) = 128; // dg + GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium)}; }; -class m_70mm_saami: RocketBase { +class ammo_Missile_AA_R77: ammo_Missile_MediumRangeAABase { + GVAR(skip) = 0; + GVAR(charge) = 80; // dg + GVAR(metal) = 145; // dg + GVAR(gurney_c) = 2700; + GVAR(fragCount) = 1200; + GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(large), QGVAR(large)}; +}; + +class ammo_Missile_LongRangeAABase: MissileBase { GVAR(skip) = 1; - ACE_FRAG_RM_EH; }; class M_Vorona_HEAT: MissileBase { @@ -597,7 +770,7 @@ class M_Vorona_HE: M_Vorona_HEAT { GVAR(classes)[] = {QGVAR(tiny)}; }; -class M_127mm_Firefist_AT: RocketBase { +class M_127mm_Firefist_AT: RocketBase { // HOT missile GVAR(skip) = 1; }; @@ -607,89 +780,107 @@ class M_NLAW_AT_F: MissileBase { }; // ~~~~ Shell -class Sh_125mm_HEAT; +class Sh_75mm_Railgun_APFSDS: ShellBase { + GVAR(skip) = 1; +}; +class Sh_120mm_APFSDS: ShellBase { + GVAR(skip) = 1; +}; +class Sh_125mm_APFSDS: ShellBase { + GVAR(skip) = 1; +}; + class Sh_155mm_AMOS: ShellBase { // Source: http://www.globalsecurity.org/military/systems/munitions/m795.htm GVAR(skip) = 0; - - GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; - GVAR(fragCount) = 3250; // http://18.195.19.6/bitstream/handle/20.500.12242/1200/15-01916.pdf?sequence=1&isAllowed=y - GVAR(metal) = 36000; GVAR(charge) = 9979; + GVAR(metal) = 36000; GVAR(gurney_c) = 2440; GVAR(gurney_k) = "1/2"; + GVAR(fragCount) = 3250; // http://18.195.19.6/bitstream/handle/20.500.12242/1200/15-01916.pdf?sequence=1&isAllowed=y + GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; }; -class Sh_82mm_AMOS: Sh_155mm_AMOS { - //http://65.175.100.54/uxofiles/mulvaney/techdatasheets/81mm-HE-M821.pdf - GVAR(skip) = 0; - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; +class Sh_82mm_AMOS: Sh_155mm_AMOS { // VO-832DU + GVAR(charge) = 420; + GVAR(metal) = 2680; GVAR(fragCount) = 1600; // based on mass and fragment energy/count - GVAR(metal) = 2500; - GVAR(charge) = 726; - GVAR(gurney_c) = 2440; - GVAR(gurney_k) = "1/2"; -}; -class ModuleOrdnanceMortar_F_Ammo: Sh_82mm_AMOS { - GVAR(skip) = 0; - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(metal) = 800; - GVAR(charge) = 4200; - GVAR(gurney_c) = 2320; - GVAR(gurney_k) = "1/2"; -}; -class Sh_105mm_HEAT_MP: Sh_125mm_HEAT { - GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 1600; // based on mass and fragment energy/count - GVAR(metal) = 11400; - GVAR(charge) = 7100; - GVAR(gurney_c) = 2800; - GVAR(gurney_k) = "1/2"; }; + class Sh_120mm_HE: ShellBase { GVAR(skip) = 0; - GVAR(fragCount) = 2000; - GVAR(metal) = 23000; GVAR(charge) = 3148; + GVAR(metal) = 23000; GVAR(gurney_c) = 2830; GVAR(gurney_k) = "1/2"; - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; + GVAR(fragCount) = 2000; + GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium), QGVAR(medium_HD)}; }; class Sh_120mm_HEAT_MP: ShellBase { - GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium), QGVAR(medium_HD)}; - GVAR(fragCount) = 1000; - GVAR(metal) = 5000; + GVAR(skip) = 0; GVAR(charge) = 2500; + GVAR(metal) = 5000; GVAR(gurney_c) = 2500; GVAR(gurney_k) = "1/2"; + GVAR(fragCount) = 1000; + GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium), QGVAR(medium_HD)}; +}; + +class ammo_ShipCannon_120mm_HE: Sh_155mm_AMOS { + GVAR(charge) = 3148; + GVAR(metal) = 23000; + GVAR(gurney_c) = 2830; + GVAR(fragCount) = 2000; + GVAR(classes)[] = {QGVAR(small), QGVAR(small), QGVAR(medium), QGVAR(large)}; +}; + +class Sh_125mm_HEAT: Sh_120mm_HE { + GVAR(skip) = 1; + GVAR(fragCount) = 400; + GVAR(metal) = 16760; + GVAR(charge) = 1640; + GVAR(gurney_c) = 2901; }; class Sh_125mm_HE: Sh_120mm_HE { - GVAR(skip) = 0; + GVAR(metal) = 19900; + GVAR(charge) = 3400; + GVAR(gurney_c) = 2901; +}; - GVAR(classes)[] = {QGVAR(medium), QGVAR(medium_HD)}; - GVAR(metal) = 16000; - GVAR(charge) = 3200; - GVAR(gurney_c) = 2440; - GVAR(gurney_k) = "1/2"; +class Sh_105mm_HEAT_MP: Sh_125mm_HEAT { + GVAR(skip) = 0; + GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(medium), QGVAR(medium_HD)}; + GVAR(fragCount) = 1600; // based on mass and fragment energy/count + GVAR(metal) = 11400; + GVAR(charge) = 7100; + GVAR(gurney_c) = 2800; }; + class ModuleOrdnanceHowitzer_F_ammo: Sh_155mm_AMOS { GVAR(skip) = 0; - - GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; GVAR(metal) = 1950; GVAR(charge) = 15800; GVAR(gurney_c) = 2320; GVAR(gurney_k) = "1/2"; + GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; }; class ammo_Penetrator_Base: ShellBase { GVAR(skip) = 1; }; // ~~~~ Special +class ProbingBeam_01_F: BulletBase { + ACE_FRAG_RM_EH; + GVAR(skip) = 1; +}; + class IRStrobeBase: GrenadeCore { GVAR(skip) = 1; }; +class FlareCore: GrenadeCore { // flares shouldn't have EH, but in case + GVAR(skip) = 1; +}; class Default; class Laserbeam: Default { From d6c400ee54f2165130b848da4d054258b390578c Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 13 Apr 2024 21:30:23 -0500 Subject: [PATCH 251/282] Missed variable when updating --- addons/frag/functions/fnc_doFrag.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index d6bb56c18d3..4b3ece1e4a4 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -53,5 +53,5 @@ if (GVAR(fragSimComplexity) != 1 && _fragRange > 3) then { }; if (GVAR(fragSimComplexity) > 0 && _maxFragCount >= ACE_FRAG_MIN_FRAG_BUDGET_FOR_RANDOM) then { - [_posASL, _velocity, _fragTypes, _maxFragCount, _shotParents] call FUNC(doFragRandom); + [_posASL, _fragVelocity, _fragTypes, _maxFragCount, _shotParents] call FUNC(doFragRandom); }; From 283b80645ecf6379ca1992028032e55433fc389b Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sat, 13 Apr 2024 21:38:28 -0500 Subject: [PATCH 252/282] Added unneeded class details to make PBOproject happy --- addons/frag/CfgAmmoFragParameters.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/addons/frag/CfgAmmoFragParameters.hpp b/addons/frag/CfgAmmoFragParameters.hpp index e89b966c281..7425a7d9aa0 100644 --- a/addons/frag/CfgAmmoFragParameters.hpp +++ b/addons/frag/CfgAmmoFragParameters.hpp @@ -529,7 +529,7 @@ class Rocket_04_AP_F: Rocket_04_HE_F { }; class ammo_Missile_CannonLaunchedBase: MissileBase { - GVAR(skip) =1; + GVAR(skip) = 1; }; class R_230mm_fly: RocketBase { @@ -586,7 +586,9 @@ class M_Titan_AA: MissileBase { GVAR(gurney_k) = "1/2"; GVAR(classes)[] = {QGVAR(tiny), QGVAR(tiny), QGVAR(small)}; }; -class M_Titan_AT: MissileBase; +class M_Titan_AT: MissileBase { + GVAR(skip) = 1; +}; class M_Titan_AP: M_Titan_AT { GVAR(skip) = 0; GVAR(fragCount) = 800; // guesstimate / provides ~80 m frag range From 868c6135bfd1b50096689325ad2f0299687a0642 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sun, 14 Apr 2024 03:34:42 -0500 Subject: [PATCH 253/282] Forgot to update doFragRandom docs with previous changes --- addons/frag/functions/fnc_doFrag.sqf | 6 +++--- addons/frag/functions/fnc_doFragRandom.sqf | 13 +++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 4b3ece1e4a4..5476533b9c0 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -20,8 +20,8 @@ #define ACE_FRAG_MIN_FRAG_BUDGET_FOR_RANDOM 3 -params ["_posASL", "_velocity", "_ammo", "_shotParents"]; -TRACE_4("doFrag",_posASL,_velocity,_ammo,_shotParents); +params ["_posASL", "_projectileVelocity", "_ammo", "_shotParents"]; +TRACE_4("doFrag",_posASL,_projectileVelocity,_ammo,_shotParents); // Don't let a single object cause all fragmentation events _shotParents params ["_shotParentVehicle"]; @@ -53,5 +53,5 @@ if (GVAR(fragSimComplexity) != 1 && _fragRange > 3) then { }; if (GVAR(fragSimComplexity) > 0 && _maxFragCount >= ACE_FRAG_MIN_FRAG_BUDGET_FOR_RANDOM) then { - [_posASL, _fragVelocity, _fragTypes, _maxFragCount, _shotParents] call FUNC(doFragRandom); + [_posASL, _fragVelocity, _projectileVelocity, _fragTypes, _maxFragCount, _shotParents] call FUNC(doFragRandom); }; diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index 0e434830a39..0aebb3fc3f4 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -6,10 +6,11 @@ * * Arguments: * 0: Position (posASL) of fragmenting projectile - * 1: Velocity of the fragmenting projectile - * 2: Type of fragments to generate - * 3: Remaining fragment budget - * 4: Shot parents + * 1: Initial fragment velocity from Gurney equation + * 2: Velocity of the fragmenting projectile + * 3: Type of fragments to generate + * 4: Remaining fragment budget + * 5: Shot parents * * Return Value: * None @@ -20,7 +21,7 @@ * Public: No */ -params ["_posASL", "_fragVelocity", "_fragType", "_maxFragCount", "_shotParents"]; +params ["_posASL", "_fragVelocity", "_projectileVelocity", "_fragType", "_maxFragCount", "_shotParents"]; TRACE_5("doFragRandom",_posASL,_fragVelocity,_fragType,_maxFragCount,_shotParents); // See CfgAmmoFragSpawner for different frag types @@ -43,7 +44,7 @@ _maxFragCount = switch (true) do { private _fragSpawner = createVehicle [_type + _maxFragCount + _hMode, ASLToATL _posASL, [], 0, "CAN_COLLIDE"]; private _randDir = random 360; _fragSpawner setVectorDirandUp [[0,0,-1], [cos _randDir, sin _randDir,0]]; -_fragSpawner setVelocity [0, 0, -0.5*_fragVelocity]; +_fragSpawner setVelocity (_projectileVelocity vectorAdd [0, 0, -0.5*_fragVelocity]); _fragSpawner setShotParents _shotParents; TRACE_2("spawnedRandomFragmenter",typeOf _fragSpawner,getObjectID _fragSpawner); From 559c611fdbcdf2e34e81511f5f8091abcabb7218 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sun, 14 Apr 2024 03:43:24 -0500 Subject: [PATCH 254/282] and the debug context --- addons/frag/functions/fnc_doFragRandom.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index 0aebb3fc3f4..5e7146bbfd2 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -22,7 +22,7 @@ */ params ["_posASL", "_fragVelocity", "_projectileVelocity", "_fragType", "_maxFragCount", "_shotParents"]; -TRACE_5("doFragRandom",_posASL,_fragVelocity,_fragType,_maxFragCount,_shotParents); +TRACE_6("doFragRandom",_posASL,_fragVelocity,_projectileVelocity,_fragType,_maxFragCount,_shotParents); // See CfgAmmoFragSpawner for different frag types private _heightATL = (ASLToATL _posASL)#2; From e2dce5e10240dd863fd086a4370f62ffa8d8c2dc Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sat, 18 May 2024 11:16:43 +0200 Subject: [PATCH 255/282] Readd blacklist --- addons/frag/XEH_PREP.hpp | 1 + addons/frag/functions/fnc_addBlacklist.sqf | 21 +++++++++++++++++++++ addons/frag/functions/fnc_initRound.sqf | 8 ++++++++ 3 files changed, 30 insertions(+) create mode 100644 addons/frag/functions/fnc_addBlacklist.sqf diff --git a/addons/frag/XEH_PREP.hpp b/addons/frag/XEH_PREP.hpp index 845f59a38e9..868931fa6fe 100644 --- a/addons/frag/XEH_PREP.hpp +++ b/addons/frag/XEH_PREP.hpp @@ -1,3 +1,4 @@ +PREP(addBlackList); PREP(dev_addRound); PREP(dev_clearTraces); PREP(dev_debugAmmo); diff --git a/addons/frag/functions/fnc_addBlacklist.sqf b/addons/frag/functions/fnc_addBlacklist.sqf new file mode 100644 index 00000000000..40a3b1434c4 --- /dev/null +++ b/addons/frag/functions/fnc_addBlacklist.sqf @@ -0,0 +1,21 @@ +#include "..\script_component.hpp" +/* + * Author: Jaynus, NouberNou + * Adds a round to the blacklist (will be ignored). + * + * Arguments: + * 0: Projectile + * + * Return Value: + * None + * + * Example: + * [_projectile] call ace_frag_fnc_addBlackList + * + * Public: No + */ + +params ["_projectile"]; +TRACE_1("addBlackList",_projectile); + +_projectile setVariable [QGVAR(blacklisted), true, true]; diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index 22f5814470d..46d4281c6a3 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -25,11 +25,16 @@ if (_ammo isEqualTo "" || {isNull _projectile}) exitWith { TRACE_2("bad ammo or projectile",_ammo,_projectile); }; +if (_projectile getVariable [QGVAR(blacklisted), false]) exitWith {}; + if (GVAR(enabled) && {_ammo call FUNC(shouldFrag)}) then { _projectile addEventHandler [ "Explode", { params ["_projectile", "_posASL", "_velocity"]; + + if (_projectile getVariable [QGVAR(blacklisted), false]) exitWith {}; + private _shotParents = _projectile getVariable [QGVAR(shotParent), getShotParents _projectile]; private _ammo = typeOf _projectile; // wait for frag damage to kill units before spawning fragments @@ -49,6 +54,9 @@ if (GVAR(spallEnabled) && {_ammo call FUNC(shouldSpall)}) then { "HitPart", { params ["_projectile", "_hitObject", "", "_posASL", "_velocity", "_surfNorm", "", "", "_surfType"]; + + if (_projectile getVariable [QGVAR(blacklisted), false]) exitWith {}; + // starting v2.18 it may be faster to use the instigator parameter, the same as the second entry shotParents, to recreate _shotParent // The "explode" EH does not get the same parameter private _shotParent = getShotParents _projectile; From b9aa3cb65b14faa0a7c372df7ce156ce571a0ee2 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sun, 19 May 2024 00:14:14 -0500 Subject: [PATCH 256/282] Fixed an issue with fragments being created above water for explosions below the surface --- addons/frag/functions/fnc_doFragRandom.sqf | 2 +- addons/frag/functions/fnc_doFragTargeted.sqf | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index 5e7146bbfd2..41d4dde8149 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -41,7 +41,7 @@ _maxFragCount = switch (true) do { }; // Spawn the fragment spawner -private _fragSpawner = createVehicle [_type + _maxFragCount + _hMode, ASLToATL _posASL, [], 0, "CAN_COLLIDE"]; +private _fragSpawner = createVehicle [_type + _maxFragCount + _hMode, ASLToAGL _posASL, [], 0, "CAN_COLLIDE"]; private _randDir = random 360; _fragSpawner setVectorDirandUp [[0,0,-1], [cos _randDir, sin _randDir,0]]; _fragSpawner setVelocity (_projectileVelocity vectorAdd [0, 0, -0.5*_fragVelocity]); diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index dec759f9620..e148e38936e 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -38,9 +38,10 @@ if (_fragTypes isEqualTo []) then { ]; }; +private _posAGL = ASLToAGL _posASL; // Post 2.18 change - uncomment line 41, and remove lines 43, 50-55, 64-66 // private _targets = [ASLToAGL _posASL, _fragRange, _fragRange, 0, false, _fragRange] nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], false, true, true]; -private _objects = (ASLToAGL _posASL) nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], _fragRange]; +private _objects = _posAGL nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], _fragRange]; if (_objects isEqualTo []) exitWith { TRACE_2("No nearby targets",_posASL,_fragRange); 0 @@ -152,7 +153,7 @@ private _totalFragCount = 0; // Create fragment private _vectorDir = _posASL vectorFromTo _targetPos; - private _fragObj = createVehicle [_fragSpawner, ASLtoATL _posASL, [], 0, "CAN_COLLIDE"]; + private _fragObj = createVehicle [_fragSpawner, _posAGL, [], 0, "CAN_COLLIDE"]; _fragObj setVectorDir _vectorDir; _fragObj setVelocity (_vectorDir vectorMultiply _locFragVel); _fragObj setShotParents _shotParents; From eaff498f3f46c62fa9ebe8b4272a690f8870e93a Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sun, 19 May 2024 00:15:05 -0500 Subject: [PATCH 257/282] Exposed projectile event handlers for both blacklist use and other shenanigans. --- addons/frag/functions/fnc_addBlacklist.sqf | 2 ++ addons/frag/functions/fnc_initRound.sqf | 17 +++++++---------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/addons/frag/functions/fnc_addBlacklist.sqf b/addons/frag/functions/fnc_addBlacklist.sqf index 40a3b1434c4..213d84ee32e 100644 --- a/addons/frag/functions/fnc_addBlacklist.sqf +++ b/addons/frag/functions/fnc_addBlacklist.sqf @@ -19,3 +19,5 @@ params ["_projectile"]; TRACE_1("addBlackList",_projectile); _projectile setVariable [QGVAR(blacklisted), true, true]; +_projectile removeEventHandler ["HitPart", _projectile getVariable [QGVAR(hitPartEH), -1]]; +_projectile removeEventHandler ["Explode", _projectile getVariable [QGVAR(explodeEH), -1]]; \ No newline at end of file diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index 46d4281c6a3..b04408360b3 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -21,20 +21,17 @@ if (!isServer) exitWith {}; params ["_projectile"]; private _ammo = typeOf _projectile; -if (_ammo isEqualTo "" || {isNull _projectile}) exitWith { - TRACE_2("bad ammo or projectile",_ammo,_projectile); +if (_ammo isEqualTo "" || {isNull _projectile} + || {_projectile getVariable [QGVAR(blacklisted), false]}) exitWith { + TRACE_2("bad ammo or projectile, or blackList",_ammo,_projectile); }; -if (_projectile getVariable [QGVAR(blacklisted), false]) exitWith {}; - if (GVAR(enabled) && {_ammo call FUNC(shouldFrag)}) then { - _projectile addEventHandler [ + private _explodeEH = _projectile addEventHandler [ "Explode", { params ["_projectile", "_posASL", "_velocity"]; - if (_projectile getVariable [QGVAR(blacklisted), false]) exitWith {}; - private _shotParents = _projectile getVariable [QGVAR(shotParent), getShotParents _projectile]; private _ammo = typeOf _projectile; // wait for frag damage to kill units before spawning fragments @@ -47,16 +44,15 @@ if (GVAR(enabled) && {_ammo call FUNC(shouldFrag)}) then { }; } ]; + _projectile setVariable [QGVAR(explodeEH), _explodeEH]; }; if (GVAR(spallEnabled) && {_ammo call FUNC(shouldSpall)}) then { - _projectile addEventHandler [ + private _hitPartEH = _projectile addEventHandler [ "HitPart", { params ["_projectile", "_hitObject", "", "_posASL", "_velocity", "_surfNorm", "", "", "_surfType"]; - if (_projectile getVariable [QGVAR(blacklisted), false]) exitWith {}; - // starting v2.18 it may be faster to use the instigator parameter, the same as the second entry shotParents, to recreate _shotParent // The "explode" EH does not get the same parameter private _shotParent = getShotParents _projectile; @@ -72,6 +68,7 @@ if (GVAR(spallEnabled) && {_ammo call FUNC(shouldSpall)}) then { ] call CBA_fnc_execNextFrame; } ]; + _projectile setVariable [QGVAR(hitPartEH), _hitPartEH]; }; #ifdef DEBUG_MODE_DRAW if (GVAR(debugOptions) && {_ammo call FUNC(shouldFrag) || {_ammo call FUNC(shouldSpall)}}) then { From f1483c59c30dc978b8f9d5aa54344ca55cbbfd57 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sun, 19 May 2024 13:40:02 -0500 Subject: [PATCH 258/282] Revert "Exposed projectile event handlers for both blacklist use and other shenanigans." This reverts commit eaff498f3f46c62fa9ebe8b4272a690f8870e93a. --- addons/frag/functions/fnc_addBlacklist.sqf | 2 -- addons/frag/functions/fnc_initRound.sqf | 17 ++++++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/addons/frag/functions/fnc_addBlacklist.sqf b/addons/frag/functions/fnc_addBlacklist.sqf index 213d84ee32e..40a3b1434c4 100644 --- a/addons/frag/functions/fnc_addBlacklist.sqf +++ b/addons/frag/functions/fnc_addBlacklist.sqf @@ -19,5 +19,3 @@ params ["_projectile"]; TRACE_1("addBlackList",_projectile); _projectile setVariable [QGVAR(blacklisted), true, true]; -_projectile removeEventHandler ["HitPart", _projectile getVariable [QGVAR(hitPartEH), -1]]; -_projectile removeEventHandler ["Explode", _projectile getVariable [QGVAR(explodeEH), -1]]; \ No newline at end of file diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index b04408360b3..46d4281c6a3 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -21,17 +21,20 @@ if (!isServer) exitWith {}; params ["_projectile"]; private _ammo = typeOf _projectile; -if (_ammo isEqualTo "" || {isNull _projectile} - || {_projectile getVariable [QGVAR(blacklisted), false]}) exitWith { - TRACE_2("bad ammo or projectile, or blackList",_ammo,_projectile); +if (_ammo isEqualTo "" || {isNull _projectile}) exitWith { + TRACE_2("bad ammo or projectile",_ammo,_projectile); }; +if (_projectile getVariable [QGVAR(blacklisted), false]) exitWith {}; + if (GVAR(enabled) && {_ammo call FUNC(shouldFrag)}) then { - private _explodeEH = _projectile addEventHandler [ + _projectile addEventHandler [ "Explode", { params ["_projectile", "_posASL", "_velocity"]; + if (_projectile getVariable [QGVAR(blacklisted), false]) exitWith {}; + private _shotParents = _projectile getVariable [QGVAR(shotParent), getShotParents _projectile]; private _ammo = typeOf _projectile; // wait for frag damage to kill units before spawning fragments @@ -44,15 +47,16 @@ if (GVAR(enabled) && {_ammo call FUNC(shouldFrag)}) then { }; } ]; - _projectile setVariable [QGVAR(explodeEH), _explodeEH]; }; if (GVAR(spallEnabled) && {_ammo call FUNC(shouldSpall)}) then { - private _hitPartEH = _projectile addEventHandler [ + _projectile addEventHandler [ "HitPart", { params ["_projectile", "_hitObject", "", "_posASL", "_velocity", "_surfNorm", "", "", "_surfType"]; + if (_projectile getVariable [QGVAR(blacklisted), false]) exitWith {}; + // starting v2.18 it may be faster to use the instigator parameter, the same as the second entry shotParents, to recreate _shotParent // The "explode" EH does not get the same parameter private _shotParent = getShotParents _projectile; @@ -68,7 +72,6 @@ if (GVAR(spallEnabled) && {_ammo call FUNC(shouldSpall)}) then { ] call CBA_fnc_execNextFrame; } ]; - _projectile setVariable [QGVAR(hitPartEH), _hitPartEH]; }; #ifdef DEBUG_MODE_DRAW if (GVAR(debugOptions) && {_ammo call FUNC(shouldFrag) || {_ammo call FUNC(shouldSpall)}}) then { From 8d071f9eb59a2825e787509992bdd2be9f7581be Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sun, 19 May 2024 13:40:26 -0500 Subject: [PATCH 259/282] added debug information and folded if statements --- addons/frag/functions/fnc_initRound.sqf | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index 46d4281c6a3..ab041f763e4 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -21,11 +21,12 @@ if (!isServer) exitWith {}; params ["_projectile"]; private _ammo = typeOf _projectile; -if (_ammo isEqualTo "" || {isNull _projectile}) exitWith { - TRACE_2("bad ammo or projectile",_ammo,_projectile); +if (_ammo isEqualTo "" || {isNull _projectile} || + {_projectile getVariable [QGVAR(blacklisted), false]}) exitWith { + TRACE_2("bad ammo or projectile, or blackList",_ammo,_projectile); }; -if (_projectile getVariable [QGVAR(blacklisted), false]) exitWith {}; +if () exitWith {}; if (GVAR(enabled) && {_ammo call FUNC(shouldFrag)}) then { _projectile addEventHandler [ @@ -33,7 +34,9 @@ if (GVAR(enabled) && {_ammo call FUNC(shouldFrag)}) then { { params ["_projectile", "_posASL", "_velocity"]; - if (_projectile getVariable [QGVAR(blacklisted), false]) exitWith {}; + if (_projectile getVariable [QGVAR(blacklisted), false]) exitWith { + TRACE_2("projectile blackisted",typeOf _projectile,_projectile); + }; private _shotParents = _projectile getVariable [QGVAR(shotParent), getShotParents _projectile]; private _ammo = typeOf _projectile; @@ -55,7 +58,9 @@ if (GVAR(spallEnabled) && {_ammo call FUNC(shouldSpall)}) then { { params ["_projectile", "_hitObject", "", "_posASL", "_velocity", "_surfNorm", "", "", "_surfType"]; - if (_projectile getVariable [QGVAR(blacklisted), false]) exitWith {}; + if (_projectile getVariable [QGVAR(blacklisted), false]) exitWith { + TRACE_2("projectile blackisted",typeOf _projectile,_projectile); + }; // starting v2.18 it may be faster to use the instigator parameter, the same as the second entry shotParents, to recreate _shotParent // The "explode" EH does not get the same parameter From 3d6c4068f43693d68ff78ddd3e90d4292d5ee76f Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sun, 19 May 2024 13:44:31 -0500 Subject: [PATCH 260/282] fixed error (if statement with no argument) --- addons/frag/functions/fnc_initRound.sqf | 2 -- 1 file changed, 2 deletions(-) diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf index ab041f763e4..eef4488df46 100644 --- a/addons/frag/functions/fnc_initRound.sqf +++ b/addons/frag/functions/fnc_initRound.sqf @@ -26,8 +26,6 @@ if (_ammo isEqualTo "" || {isNull _projectile} || TRACE_2("bad ammo or projectile, or blackList",_ammo,_projectile); }; -if () exitWith {}; - if (GVAR(enabled) && {_ammo call FUNC(shouldFrag)}) then { _projectile addEventHandler [ "Explode", From 718c3d61c88f1abeec199288b681fe2eba27943d Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Sun, 19 May 2024 20:06:16 -0500 Subject: [PATCH 261/282] Only send blacklist updates to the server --- addons/frag/functions/fnc_addBlacklist.sqf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/frag/functions/fnc_addBlacklist.sqf b/addons/frag/functions/fnc_addBlacklist.sqf index 40a3b1434c4..ca331a248a5 100644 --- a/addons/frag/functions/fnc_addBlacklist.sqf +++ b/addons/frag/functions/fnc_addBlacklist.sqf @@ -16,6 +16,6 @@ */ params ["_projectile"]; -TRACE_1("addBlackList",_projectile); +TRACE_2("addBlackList",_projectile,typeOf projectile); -_projectile setVariable [QGVAR(blacklisted), true, true]; +_projectile setVariable [QGVAR(blacklisted), true, 2]; From 130037d7e8e13bfdb33f4167ae430a65a4830df6 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 19 Jun 2024 23:20:37 -0500 Subject: [PATCH 262/282] Added default fragCount fallback value based on current ACE frag range calculation --- addons/frag/functions/fnc_getFragInfo.sqf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_getFragInfo.sqf b/addons/frag/functions/fnc_getFragInfo.sqf index 50af9cb5d68..fa1a50df411 100644 --- a/addons/frag/functions/fnc_getFragInfo.sqf +++ b/addons/frag/functions/fnc_getFragInfo.sqf @@ -80,7 +80,9 @@ if (_gurneyConstant == 0) then { private _fragCount = getNumber (_ammoConfig >> QGVAR(fragCount)); if (_fragCount == 0) then { - _fragCount = 250; + private _indirectHitRange = getNumber (_ammoConfig >> "indirectHitRange"); + _fragCount = 4 * pi * ACE_FRAG_MIN_FRAG_HIT_CHANCE * (20 *_indirectHitRange)^2; + _fragCount = _fragCount max 250; _notifyMissingEntries = true; }; From 474321ba7c225334244abec7f56ea512e5ed329b Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 19 Jun 2024 23:21:49 -0500 Subject: [PATCH 263/282] Converted all positions for doFrag to AGL since we're converting to that now --- addons/frag/functions/fnc_doFrag.sqf | 12 +++++-- addons/frag/functions/fnc_doFragRandom.sqf | 22 ++++++------ addons/frag/functions/fnc_doFragTargeted.sqf | 38 +++++++++++--------- 3 files changed, 43 insertions(+), 29 deletions(-) diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 5476533b9c0..4898c751134 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -19,6 +19,7 @@ */ #define ACE_FRAG_MIN_FRAG_BUDGET_FOR_RANDOM 3 +#define ACE_FRAG_NEGATIVE_AGL_OFFSET 0.1 params ["_posASL", "_projectileVelocity", "_ammo", "_shotParents"]; TRACE_4("doFrag",_posASL,_projectileVelocity,_ammo,_shotParents); @@ -47,11 +48,18 @@ if (_modFragCount < ACE_FRAG_LOW_FRAG_MOD_COUNT) then { GVAR(lastFragTime) = CBA_missionTime; }; +// Double check if round is below, or too close to terrain for +private _posAGL = ASLToAGL _posASL; +if (_posAGL#2 < ACE_FRAG_NEGATIVE_AGL_OFFSET) then { + TRACE_1("below 0 AGL",_posAGL); + _posAGL set [2, ACE_FRAG_NEGATIVE_AGL_OFFSET]; +}; + TRACE_3("doFrag choices",_maxFragCount,_fragRange,GVAR(fragSimComplexity)); if (GVAR(fragSimComplexity) != 1 && _fragRange > 3) then { - _maxFragCount = _maxFragCount - ([_posASL, _fragVelocity, _fragRange, _maxFragCount, _fragTypes, _modFragCount, _shotParents] call FUNC(doFragTargeted)); + _maxFragCount = _maxFragCount - ([_posAGL, _fragVelocity, _fragRange, _maxFragCount, _fragTypes, _modFragCount, _shotParents] call FUNC(doFragTargeted)); }; if (GVAR(fragSimComplexity) > 0 && _maxFragCount >= ACE_FRAG_MIN_FRAG_BUDGET_FOR_RANDOM) then { - [_posASL, _fragVelocity, _projectileVelocity, _fragTypes, _maxFragCount, _shotParents] call FUNC(doFragRandom); + [_posAGL, _fragVelocity, _projectileVelocity, _fragTypes, _maxFragCount, _shotParents] call FUNC(doFragRandom); }; diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index 41d4dde8149..c0f2c355af7 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -5,7 +5,7 @@ * This function will spawn 5, 10, or 15 fragments. * * Arguments: - * 0: Position (posASL) of fragmenting projectile + * 0: Position (posAGL) of fragmenting projectile * 1: Initial fragment velocity from Gurney equation * 2: Velocity of the fragmenting projectile * 3: Type of fragments to generate @@ -16,19 +16,19 @@ * None * * Example: - * [getPosASL _projectile, 800, 50, 50, [], 1, [player, player]] call ace_frag_fnc_doFragRandom + * [ASLtoAGL (getPosASL _projectile), 800, 50, 50, [], 1, [player, player]] call ace_frag_fnc_doFragRandom * * Public: No */ -params ["_posASL", "_fragVelocity", "_projectileVelocity", "_fragType", "_maxFragCount", "_shotParents"]; -TRACE_6("doFragRandom",_posASL,_fragVelocity,_projectileVelocity,_fragType,_maxFragCount,_shotParents); +params ["_posAGL", "_fragVelocity", "_projectileVelocity", "_fragType", "_maxFragCount", "_shotParents"]; +TRACE_6("doFragRandom",_posAGL,_fragVelocity,_projectileVelocity,_fragType,_maxFragCount,_shotParents); // See CfgAmmoFragSpawner for different frag types -private _heightATL = (ASLToATL _posASL)#2; +private _heightAGL = _posAGL#2; private _hMode = switch (true) do { - case (_heightATL > 10): {"_top"}; - case (_heightATL > 4): {"_high"}; + case (_heightAGL > 10): {"_top"}; + case (_heightAGL > 4): {"_high"}; default {"_mid"}; }; @@ -41,10 +41,10 @@ _maxFragCount = switch (true) do { }; // Spawn the fragment spawner -private _fragSpawner = createVehicle [_type + _maxFragCount + _hMode, ASLToAGL _posASL, [], 0, "CAN_COLLIDE"]; +private _fragSpawner = createVehicle [_type + _maxFragCount + _hMode, _posAGL, [], 0, "CAN_COLLIDE"]; private _randDir = random 360; -_fragSpawner setVectorDirandUp [[0,0,-1], [cos _randDir, sin _randDir,0]]; -_fragSpawner setVelocity (_projectileVelocity vectorAdd [0, 0, -0.5*_fragVelocity]); +_fragSpawner setVectorDirandUp [[0,0,-1], [cos _randDir, sin _randDir, 0]]; +_fragSpawner setVelocity (_projectileVelocity vectorAdd [0, 0, -_fragVelocity]); _fragSpawner setShotParents _shotParents; TRACE_2("spawnedRandomFragmenter",typeOf _fragSpawner,getObjectID _fragSpawner); @@ -57,6 +57,6 @@ _fragSpawner addEventHandler [ } ]; if (GVAR(dbgSphere)) then { - [_posASL] call FUNC(dev_sphereDraw); + [AGLtoASL _posAGL] call FUNC(dev_sphereDraw); }; #endif diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index e148e38936e..83b4cfbe2a0 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -4,7 +4,7 @@ * This function creates fragments targeted at specific entities, up to _maxFrags. * * Arguments: - * 0: Position of fragmenting projectile ASL + * 0: Position of fragmenting projectile AGL * 1: Velocity of the fragmenting projectile * 2: Maximum range of fragments to calculate * 3: Maximum number of fragments to produce @@ -16,7 +16,7 @@ * Number of fragments created * * Example: - * [getPosASL _projectile, velocity _projectile, 50, 50, [], 1, [player, player]] call ace_frag_fnc_doFragTargeted + * [ASLtoAGL (getPosASL _projectile), velocity _projectile, 50, 50, [], 1, [player, player]] call ace_frag_fnc_doFragTargeted * * Public: No */ @@ -25,8 +25,8 @@ #define ACE_FRAG_DEFAULT_CROSS_AREA 0.75 #define ACE_FRAG_MIN_TARGET_AREA 0.5 -params [ "_posASL", "_fragVelocity", "_fragRange", "_maxFrags", "_fragTypes", "_modFragCount", "_shotParents"]; -TRACE_5("fnc_doFragTargeted",_posASL,_fragRange,_maxFrags,_fragTypes,_modFragCount); +params [ "_posAGL", "_fragVelocity", "_fragRange", "_maxFrags", "_fragTypes", "_modFragCount", "_shotParents"]; +TRACE_5("fnc_doFragTargeted",_posAGL,_fragRange,_maxFrags,_fragTypes,_modFragCount); if (_fragTypes isEqualTo []) then { _fragTypes = [ @@ -38,12 +38,11 @@ if (_fragTypes isEqualTo []) then { ]; }; -private _posAGL = ASLToAGL _posASL; // Post 2.18 change - uncomment line 41, and remove lines 43, 50-55, 64-66 -// private _targets = [ASLToAGL _posASL, _fragRange, _fragRange, 0, false, _fragRange] nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], false, true, true]; +// private _targets = [_posAGL, _fragRange, _fragRange, 0, false, _fragRange] nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], false, true, true]; private _objects = _posAGL nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], _fragRange]; if (_objects isEqualTo []) exitWith { - TRACE_2("No nearby targets",_posASL,_fragRange); + TRACE_2("No nearby targets",_posAGL,_fragRange); 0 }; @@ -55,7 +54,7 @@ private _targets = []; _targets append _crew; } forEach _objects; -TRACE_3("Targets found",_posASL,_fragRange,count _targets); +TRACE_3("Targets found",_posAGL,_fragRange,count _targets); // limit number of fragments per direction (2D) to _fragsPerFragArc using _fragArcs private _fragArcs = createHashMap; @@ -99,7 +98,7 @@ private _totalFragCount = 0; _height = _dims#2; }; - private _distance = _target distance _posASL; + private _distance = _target distance _posAGL; // calculate chance to be hit by a fragment private _fragChance = _crossSectionArea * _modFragCount / _distance^2; @@ -114,7 +113,7 @@ private _totalFragCount = 0; }; // handle limiting fragments per degree arc - private _dir = floor (_posASL getDir _target); + private _dir = floor (_posAGL getDir _target); private _fragPerArc = _fragArcs getOrDefault [_dir, 0]; if (_fragPerArc > _fragsPerFragArc) then { continue; @@ -131,13 +130,13 @@ private _totalFragCount = 0; _targetPos = if (_isPerson) then { private _hitPoint = selectRandom ACE_FRAG_HITPOINTS; private _hitPointPos = _target selectionPosition [_hitPoint, "HitPoints", "AveragePoint"]; - _target modelToWorldWorld _hitPointPos vectorAdd _targetPos; + _target modelToWorld _hitPointPos vectorAdd _targetPos; } else { - _targetPos vectorAdd getPosASL _target vectorAdd [ + ASLtoAGL (_targetPos vectorAdd getPosASL _target vectorAdd [ -0.5 + random 1, -0.5 + random 1, (0.1 + random 0.4) * _height - ]; + ]); }; // select a fragment / submunition frag spawner @@ -152,15 +151,22 @@ private _totalFragCount = 0; TRACE_4("fragments",_fragSpawner,_fragChance,_distance,_locFragVel); // Create fragment - private _vectorDir = _posASL vectorFromTo _targetPos; + private _vectorDir = _posAGL vectorFromTo _targetPos; private _fragObj = createVehicle [_fragSpawner, _posAGL, [], 0, "CAN_COLLIDE"]; - _fragObj setVectorDir _vectorDir; + _fragObj setVectorDirAndUp [_vectorDir, _vectorDir vectorAdd [0, -1, 0]] ; _fragObj setVelocity (_vectorDir vectorMultiply _locFragVel); _fragObj setShotParents _shotParents; #ifdef DEBUG_MODE_DRAW [_fragObj, "purple", true] call FUNC(dev_trackObj); + _fragObj addEventHandler [ + "SubmunitionCreated", + { + params ["","_subProj"]; + [_subProj, "purple", true] call FUNC(dev_trackObj); + } + ]; if (GVAR(dbgSphere)) then { - [_targetPos, "orange"] call FUNC(dev_sphereDraw); + [AGLtoASL _targetPos, "orange"] call FUNC(dev_sphereDraw); }; #endif From 60a0daef66ee8417053279476dce5e19d589e21b Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 19 Jun 2024 23:23:02 -0500 Subject: [PATCH 264/282] removed feet hitpoints & tightened multishot submunitions. Feet hitpoitns aren't used since calculation for trajectory doesn't account for drag, fragments aimed at feet won't hit --- addons/frag/CfgAmmoFragSpawner.hpp | 14 +++++++------- addons/frag/script_component.hpp | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/addons/frag/CfgAmmoFragSpawner.hpp b/addons/frag/CfgAmmoFragSpawner.hpp index 6d5a4c86513..95f9ee5d26c 100644 --- a/addons/frag/CfgAmmoFragSpawner.hpp +++ b/addons/frag/CfgAmmoFragSpawner.hpp @@ -5,7 +5,7 @@ class GVAR(DOUBLES(size,spawner_2_mid)): GVAR(DOUBLES(size,spawner_2_short)) {\ submunitionConeAngle = 2;\ };\ class GVAR(DOUBLES(size,spawner_2_far)): GVAR(DOUBLES(size,spawner_2_short)) {\ - submunitionConeAngle = 0.9;\ + submunitionConeAngle = 0.7;\ };\ class GVAR(DOUBLES(size,spawner_3_short)): GVAR(DOUBLES(size,spawner_2_short)) {\ submunitionConeType[] = {"random", 3};\ @@ -14,26 +14,26 @@ class GVAR(DOUBLES(size,spawner_3_mid)): GVAR(DOUBLES(size,spawner_3_short)) {\ submunitionConeAngle = 2;\ };\ class GVAR(DOUBLES(size,spawner_3_far)): GVAR(DOUBLES(size,spawner_3_short)) {\ - submunitionConeAngle = 0.9;\ + submunitionConeAngle = 0.7;\ } #define RANDOM_SPAWNER_PROTOTYPE(size,count) class GVAR(DOUBLES(TRIPLES(random,size,count),mid)): GVAR(spawnbase) {\ submunitionConeType[] = {"random", count};\ submunitionAmmo = QGVAR(size);\ submunitionConeAngle = 85;\ - triggerSpeedCoef[] = {-1.5, 1.5};\ + triggerSpeedCoef[] = {-1.25, 1.25};\ };\ class GVAR(DOUBLES(TRIPLES(random,size,count),high)): GVAR(spawnbase) {\ submunitionConeType[] = {"random", count};\ submunitionAmmo = QGVAR(size);\ submunitionConeAngle = 80;\ - triggerSpeedCoef[] = {0.75, 1.5};\ + triggerSpeedCoef[] = {0.75, 1.25};\ };\ class GVAR(DOUBLES(TRIPLES(random,size,count),top)): GVAR(spawnbase) {\ submunitionConeType[] = {"random", count};\ submunitionAmmo = QGVAR(size);\ submunitionConeAngle = 60;\ - triggerSpeedCoef[] = {0.75, 1.5};\ + triggerSpeedCoef[] = {0.75, 1.25};\ } class GVAR(spawnbase): B_65x39_Caseless { @@ -48,7 +48,7 @@ class GVAR(spawnbase): B_65x39_Caseless { submunitionInitialOffset[] = {0,0,0}; submunitionInitSpeed = 0; submunitionParentSpeedCoef = 1; - triggerSpeedCoef[] = {0.75, 1.5}; + triggerSpeedCoef[] = {0.75, 1.25}; triggerTime = 0; }; @@ -65,7 +65,7 @@ class GVAR(spawnbase): B_65x39_Caseless { class GVAR(spawnbase_targeted): GVAR(spawnbase) { submunitionConeType[] = {"random", 2}; submunitionConeAngle = 4.5; - triggerSpeedCoef[] = {0.5, 1}; + triggerSpeedCoef[] = {0.625, 1}; }; diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index 8c2a614d3ce..194d2011fa0 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -27,7 +27,7 @@ #define ACE_FRAG_COUNT_MAX_TIME 1 #define ACE_FRAG_COUNT_MAX 50 // Default hitpoint targets -#define ACE_FRAG_HITPOINTS ["spine1", "spine1", "spine1", "spine2", "spine2", "spine2", "spine3", "spine3", "spine3", "pelvis", "pelvis", "pelvis", "head", "leftarm", "leftarmroll", "leftforearm", "rightarm", "rightarmroll", "rightforearm", "leftupleg", "leftuplegroll", "leftlegroll", "leftfoot", "rightupleg", "rightuplegroll", "rightleg", "rightlegroll", "rightfoot", "neck"] +#define ACE_FRAG_HITPOINTS ["spine1", "spine1", "spine1", "spine2", "spine2", "spine2", "spine3", "spine3", "spine3", "pelvis", "pelvis", "pelvis", "head", "leftarm", "leftarmroll", "leftforearm", "rightarm", "rightarmroll", "rightforearm", "leftupleg", "leftuplegroll", "leftlegroll", "rightupleg", "rightuplegroll", "rightleg", "rightlegroll", "neck"] // half of gravity approx 9.81/2 #define ACE_FRAG_HALF_GRAVITY_APPROX 4.905 // Lowest chance to hit of 0.5% From d0df8e5e1fac74c8e7b2a087eec3fd3d8bacfa1b Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 19 Jun 2024 23:49:01 -0500 Subject: [PATCH 265/282] Merge branch 'acemod:master' into master --- .../functions/fnc_handleFired.sqf | 2 +- .../functions/fnc_readAmmoDataFromConfig.sqf | 2 +- addons/advanced_fatigue/XEH_postInit.sqf | 2 +- addons/advanced_fatigue/XEH_preInit.sqf | 1 - .../functions/fnc_mainLoop.sqf | 2 +- addons/advanced_throwing/XEH_postInit.sqf | 12 +- addons/advanced_throwing/XEH_preStart.sqf | 18 + .../functions/fnc_drawThrowable.sqf | 11 +- .../functions/fnc_prepare.sqf | 16 +- .../advanced_throwing/functions/fnc_throw.sqf | 2 +- addons/advanced_throwing/stringtable.xml | 2 + addons/ai/stringtable.xml | 2 + .../arsenal/functions/fnc_onArsenalClose.sqf | 2 +- .../arsenal/functions/fnc_onArsenalOpen.sqf | 2 +- .../functions/fnc_onSelChangedLeft.sqf | 6 + .../functions/fnc_onSelChangedRight.sqf | 9 +- addons/arsenal/functions/fnc_showItem.sqf | 2 +- .../missions/Arsenal.VR/fnc_createTarget.sqf | 2 +- addons/arsenal/stringtable.xml | 14 + .../artillerytables/functions/fnc_firedEH.sqf | 2 +- .../functions/fnc_interactMenuOpened.sqf | 2 +- addons/artillerytables/initSettings.inc.sqf | 4 +- addons/atragmx/functions/fnc_initGunList.sqf | 2 +- .../fnc_read_gun_list_entries_from_config.sqf | 2 +- .../fnc_target_speed_assist_timer.sqf | 2 +- ...c_toggle_c1_ballistic_coefficient_data.sqf | 2 +- .../fnc_toggle_muzzle_velocity_data.sqf | 2 +- .../functions/fnc_toggle_truing_drop.sqf | 2 +- .../functions/fnc_update_zero_range.sqf | 2 +- addons/attach/functions/fnc_handleKilled.sqf | 2 +- addons/ballistics/stringtable.xml | 7 + addons/captives/XEH_postInit.sqf | 2 +- .../functions/fnc_doEscortCaptive.sqf | 2 +- .../captives/functions/fnc_setHandcuffed.sqf | 2 +- .../captives/functions/fnc_setSurrendered.sqf | 2 +- addons/captives/stringtable.xml | 2 + addons/cargo/CfgVehicles.hpp | 13 +- addons/cargo/functions/fnc_addCargoItem.sqf | 21 +- addons/cargo/functions/fnc_initVehicle.sqf | 11 +- addons/cargo/initSettings.inc.sqf | 24 +- addons/cargo/stringtable.xml | 10 + addons/common/XEH_PREP.hpp | 3 + addons/common/XEH_postInit.sqf | 6 +- addons/common/XEH_preInit.sqf | 1 + addons/common/dev/test_cfgPatches.sqf | 4 +- .../fnc_actionKeysNamesConverted.sqf | 10 +- addons/common/functions/fnc_addPlayerEH.sqf | 61 +++ addons/common/functions/fnc_addWeapon.sqf | 48 +- .../fnc_cbaSettings_settingChanged.sqf | 8 +- .../common/functions/fnc_defineVariable.sqf | 2 +- .../common/functions/fnc_disableUserInput.sqf | 6 +- addons/common/functions/fnc_errorMessage.sqf | 8 +- .../common/functions/fnc_getSettingData.sqf | 3 +- .../fnc_getWheelHitPointsWithSelections.sqf | 104 ++++ .../functions/fnc_registerItemReplacement.sqf | 15 +- .../functions/fnc_replaceRegisteredItems.sqf | 6 +- addons/common/functions/fnc_setDead.sqf | 44 ++ addons/common/functions/fnc_showHud.sqf | 2 +- addons/common/stringtable.xml | 13 + addons/compat_cup_terrains/CfgVehicles.hpp | 18 +- addons/compat_cup_units/CfgGlasses.hpp | 492 ++++++++++++++++++ addons/compat_cup_units/config.cpp | 1 + .../CfgVehicles.hpp | 5 - .../compat_cup_weapons_csw/stringtable.xml | 34 ++ .../stringtable.xml | 11 + .../compat_gm_refuel/CfgVehicles.hpp | 6 - addons/compat_gm/compat_gm_refuel/config.cpp | 1 - addons/compat_rf/$PBOPREFIX$ | 1 + addons/compat_rf/CfgWeapons.hpp | 42 ++ .../CfgVehicles.hpp | 12 + .../config.cpp | 21 + .../script_component.hpp | 3 + .../compat_rf_realisticnames/Attachments.hpp | 41 ++ .../compat_rf_realisticnames/CfgMagazines.hpp | 24 + .../compat_rf_realisticnames/CfgVehicles.hpp | 134 +++++ .../compat_rf_realisticnames/CfgWeapons.hpp | 111 ++++ .../compat_rf_realisticnames/config.cpp | 23 + .../script_component.hpp | 3 + .../compat_rf_realisticnames/stringtable.xml | 297 +++++++++++ addons/compat_rf/config.cpp | 18 + addons/compat_rf/script_component.hpp | 6 + addons/compat_rhs_afrf3/CfgAmmo.hpp | 4 + .../compat_rhs_afrf3_refuel/CfgVehicles.hpp | 10 - .../compat_rhs_afrf3_refuel/config.cpp | 2 +- .../compat_rhs_usf3_refuel/CfgVehicles.hpp | 15 - .../compat_rhs_usf3_refuel/config.cpp | 1 - addons/compat_sog/CfgAmmo/grenades.hpp | 7 + addons/compat_sog/CfgEventHandlers.hpp | 10 + addons/compat_sog/CfgVehicles/land.hpp | 49 +- addons/compat_sog/CfgVehicles/wheeled.hpp | 2 - addons/compat_sog/config.cpp | 3 +- .../functions/fnc_handlePunjiTrapTrigger.sqf | 4 +- .../compat_spe_refuel/CfgVehicles.hpp | 2 - addons/compat_ws/CfgWeapons.hpp | 5 + .../compat_ws_realisticnames/Attachments.hpp | 75 +++ .../compat_ws_realisticnames/CfgVehicles.hpp | 60 +++ .../compat_ws_realisticnames/CfgWeapons.hpp | 20 + .../compat_ws_realisticnames/config.cpp | 1 + .../compat_ws_realisticnames/stringtable.xml | 215 +++++++- .../functions/fnc_handleDamage.sqf | 2 +- addons/cookoff/ACE_Settings.hpp | 6 +- addons/cookoff/CfgCloudlets.hpp | 1 - addons/cookoff/CfgEden.hpp | 17 +- addons/cookoff/CfgEventHandlers.hpp | 1 - addons/cookoff/CfgSFX.hpp | 1 - addons/cookoff/CfgVehicles.hpp | 37 +- addons/cookoff/XEH_PREP.hpp | 18 +- addons/cookoff/XEH_postInit.sqf | 95 ++-- addons/cookoff/functions/fnc_cookOff.sqf | 129 ----- addons/cookoff/functions/fnc_cookOffBox.sqf | 74 --- .../cookoff/functions/fnc_cookOffBoxLocal.sqf | 52 ++ .../functions/fnc_cookOffBoxServer.sqf | 50 ++ .../cookoff/functions/fnc_cookOffEffect.sqf | 200 ------- addons/cookoff/functions/fnc_cookOffLocal.sqf | 229 ++++++++ .../cookoff/functions/fnc_cookOffServer.sqf | 202 +++++++ .../functions/fnc_detonateAmmunition.sqf | 132 ----- .../fnc_detonateAmmunitionServer.sqf | 54 ++ .../fnc_detonateAmmunitionServerLoop.sqf | 181 +++++++ addons/cookoff/functions/fnc_engineFire.sqf | 51 -- .../cookoff/functions/fnc_engineFireLocal.sqf | 81 +++ .../functions/fnc_engineFireServer.sqf | 34 ++ .../cookoff/functions/fnc_getVehicleAmmo.sqf | 71 +-- .../cookoff/functions/fnc_handleDamageBox.sqf | 80 ++- .../cookoff/functions/fnc_isMagazineFlare.sqf | 12 +- addons/cookoff/functions/fnc_smoke.sqf | 19 +- addons/cookoff/initSettings.inc.sqf | 78 +-- addons/cookoff/script_component.hpp | 13 +- addons/cookoff/stringtable.xml | 252 +++------ .../fnc_reload_handleAddTurretMag.sqf | 2 +- .../fnc_reload_handleRemoveTurretMag.sqf | 2 +- .../functions/fnc_reload_handleReturnAmmo.sqf | 2 +- addons/csw/initSettings.inc.sqf | 9 +- addons/csw/stringtable.xml | 17 + addons/dagr/XEH_postInit.sqf | 2 +- .../functions/fnc_disarmDropItems.sqf | 7 +- .../functions/fnc_eventTargetStart.sqf | 2 +- .../functions/fnc_openDisarmDialog.sqf | 11 +- addons/dogtags/XEH_postInit.sqf | 8 +- addons/dogtags/XEH_preInit.sqf | 2 +- .../dogtags/functions/fnc_canCheckDogtag.sqf | 2 +- .../dogtags/functions/fnc_canTakeDogtag.sqf | 2 +- .../functions/fnc_disableFactionDogtags.sqf | 7 +- .../functions/fnc_dropObject_carry.sqf | 2 +- addons/dragging/stringtable.xml | 6 + addons/dragon/XEH_postInit.sqf | 4 +- addons/dragon/functions/fnc_sightAttach.sqf | 2 +- addons/dragon/functions/fnc_sightDetach.sqf | 2 +- .../explosives/functions/fnc_addClacker.sqf | 2 +- .../functions/fnc_addDetonateActions.sqf | 4 +- .../functions/fnc_onIncapacitated.sqf | 2 +- addons/explosives/stringtable.xml | 4 + addons/fastroping/XEH_postInit.sqf | 6 +- addons/fastroping/initSettings.inc.sqf | 4 +- addons/fastroping/stringtable.xml | 2 + addons/field_rations/XEH_postInit.sqf | 2 +- .../functions/fnc_handleEffects.sqf | 17 +- addons/fieldmanual/stringtable.xml | 90 ++++ addons/fire/XEH_PREP.hpp | 1 - addons/fire/XEH_preInit.sqf | 2 - addons/fire/functions/fnc_burnIndicator.sqf | 2 +- addons/fire/functions/fnc_isBurning.sqf | 5 +- addons/fire/functions/fnc_isPlant.sqf | 20 - addons/fortify/functions/fnc_setupModule.sqf | 4 +- addons/frag/functions/fnc_findReflections.sqf | 2 +- .../functions/fnc_pfhUpdateGForces.sqf | 2 +- addons/grenades/CfgAmmo.hpp | 3 +- addons/grenades/CfgEventHandlers.hpp | 1 - addons/grenades/CfgMagazines.hpp | 1 - addons/grenades/CfgVehicles.hpp | 1 - addons/grenades/CfgWeapons.hpp | 1 - addons/grenades/Effects.hpp | 1 - addons/grenades/XEH_PREP.hpp | 4 +- addons/grenades/XEH_postInit.sqf | 39 +- addons/grenades/XEH_preInit.sqf | 3 + ...nc_addChangeFuseItemContextMenuOptions.sqf | 41 +- .../functions/fnc_damageEngineAndWheels.sqf | 44 ++ addons/grenades/functions/fnc_flare.sqf | 3 +- .../functions/fnc_flashbangExplosionEH.sqf | 252 +++++---- .../functions/fnc_flashbangThrownFuze.sqf | 19 +- addons/grenades/functions/fnc_incendiary.sqf | 133 ++--- addons/grenades/functions/fnc_nextMode.sqf | 57 +- .../grenades/functions/fnc_throwGrenade.sqf | 99 ++-- addons/grenades/initSettings.inc.sqf | 9 +- addons/grenades/script_component.hpp | 7 +- addons/grenades/stringtable.xml | 5 + .../functions/fnc_offGunbagCallback.sqf | 31 +- .../functions/fnc_swapGunbagCallback.sqf | 63 +-- .../gunbag/functions/fnc_toGunbagCallback.sqf | 26 +- addons/headless/XEH_PREP.hpp | 1 + addons/headless/XEH_postInit.sqf | 34 ++ addons/headless/functions/fnc_blacklist.sqf | 51 ++ .../headless/functions/fnc_transferGroups.sqf | 184 +++++-- addons/headless/initSettings.inc.sqf | 18 +- addons/headless/script_component.hpp | 4 + addons/hearing/CfgEventHandlers.hpp | 1 - addons/hearing/CfgVehicles.hpp | 4 +- addons/hearing/CfgWeapons.hpp | 2 +- addons/hearing/XEH_PREP.hpp | 2 +- addons/hearing/XEH_postInit.sqf | 26 +- addons/hearing/XEH_preInit.sqf | 7 +- addons/hearing/functions/fnc_addEarPlugs.sqf | 60 ++- addons/hearing/functions/fnc_earRinging.sqf | 9 +- .../hearing/functions/fnc_explosionNear.sqf | 9 +- addons/hearing/functions/fnc_firedNear.sqf | 101 ++-- .../hearing/functions/fnc_getAmmoLoudness.sqf | 44 ++ .../hearing/functions/fnc_handleRespawn.sqf | 20 +- .../hearing/functions/fnc_hasEarPlugsIn.sqf | 7 +- .../hearing/functions/fnc_moduleHearing.sqf | 4 +- .../hearing/functions/fnc_putInEarplugs.sqf | 25 +- .../hearing/functions/fnc_removeEarplugs.sqf | 27 +- .../functions/fnc_updateHearingProtection.sqf | 32 +- .../fnc_updatePlayerVehAttenuation.sqf | 14 +- addons/hearing/functions/fnc_updateVolume.sqf | 34 +- addons/hearing/initKeybinds.inc.sqf | 15 +- addons/hearing/initSettings.inc.sqf | 23 +- addons/hearing/stringtable.xml | 5 + .../hellfire/functions/fnc_setupVehicle.sqf | 2 +- addons/hitreactions/ACE_Settings.hpp | 1 - addons/hitreactions/CfgEventHandlers.hpp | 7 +- addons/hitreactions/XEH_PREP.hpp | 2 +- addons/hitreactions/XEH_postInit.sqf | 94 ++++ addons/hitreactions/XEH_preInit.sqf | 12 + .../functions/fnc_checkWeaponDrop.sqf | 33 ++ addons/hitreactions/initSettings.inc.sqf | 23 +- addons/hitreactions/script_component.hpp | 2 + addons/hitreactions/stringtable.xml | 12 +- addons/interact_menu/XEH_clientInit.sqf | 9 +- addons/interact_menu/XEH_preInit.sqf | 6 +- .../functions/fnc_addActionToClass.sqf | 10 +- .../functions/fnc_addMainAction.sqf | 8 +- .../functions/fnc_compileMenu.sqf | 16 +- .../functions/fnc_compileMenuSelfAction.sqf | 13 +- .../functions/fnc_initMenuReorder.sqf | 2 +- .../interact_menu/functions/fnc_keyDown.sqf | 2 +- .../functions/fnc_removeActionFromClass.sqf | 9 +- .../functions/fnc_renderActionPoints.sqf | 7 +- .../interact_menu/functions/fnc_splitPath.sqf | 12 +- .../fnc_userActions_getHouseActions.sqf | 9 +- addons/interact_menu/initSettings.inc.sqf | 4 +- .../functions/fnc_addPassengerActions.sqf | 6 +- .../functions/fnc_canPullOutBody.sqf | 2 +- addons/interaction/initSettings.inc.sqf | 2 +- addons/irlight/stringtable.xml | 14 + addons/killtracker/XEH_postInit.sqf | 50 +- addons/killtracker/initSettings.inc.sqf | 9 + addons/killtracker/stringtable.xml | 14 +- .../functions/fnc_seekerFindLaserSpot.sqf | 4 +- addons/laser/stringtable.xml | 2 + .../functions/fnc_refuelUAV.sqf | 2 +- .../functions/fnc_magazineRepackFinish.sqf | 2 +- addons/main/script_version.hpp | 4 +- addons/map/XEH_postInitClient.sqf | 2 +- addons/map/functions/fnc_isFlashlight.sqf | 15 +- addons/map/initSettings.inc.sqf | 13 +- addons/map_gestures/XEH_preInit.sqf | 2 +- .../functions/fnc_addGroupColorMapping.sqf | 6 +- .../functions/fnc_drawMapGestures.sqf | 2 +- .../functions/fnc_isValidColorArray.sqf | 2 +- .../functions/fnc_moduleGroupSettings.sqf | 5 +- .../functions/fnc_moduleSettings.sqf | 4 +- .../maptools/functions/fnc_canUseMapGPS.sqf | 7 +- addons/maptools/stringtable.xml | 36 ++ .../markers/functions/fnc_removeTimestamp.sqf | 6 +- addons/markers/stringtable.xml | 2 + addons/medical/dev/test_hitpointConfigs.sqf | 21 +- addons/medical/dev/watchVariable.sqf | 6 +- addons/medical_ai/stringtable.xml | 3 + addons/medical_blood/XEH_postInit.sqf | 2 - addons/medical_blood/XEH_preInit.sqf | 16 +- addons/medical_blood/XEH_preStart.sqf | 5 +- .../functions/fnc_createBlood.sqf | 2 +- .../functions/fnc_handleWoundReceived.sqf | 2 +- .../functions/fnc_isBleeding.sqf | 2 +- .../functions/fnc_onBleeding.sqf | 2 +- addons/medical_damage/stringtable.xml | 2 + addons/medical_engine/XEH_postInit.sqf | 28 +- addons/medical_engine/XEH_preInit.sqf | 16 +- .../functions/fnc_applyAnimAfterRagdoll.sqf | 2 +- .../functions/fnc_handleDamage.sqf | 62 ++- .../medical_engine/script_macros_config.hpp | 18 - addons/medical_engine/stringtable.xml | 2 + addons/medical_gui/XEH_postInit.sqf | 2 +- addons/medical_gui/stringtable.xml | 31 ++ .../functions/fnc_enteredStateDeath.sqf | 3 +- .../medical_status/functions/fnc_setDead.sqf | 12 +- addons/medical_status/stringtable.xml | 2 + addons/medical_treatment/XEH_preInit.sqf | 38 +- .../functions/fnc_checkPulseLocal.sqf | 2 +- .../functions/fnc_checkResponse.sqf | 5 + .../functions/fnc_cprLocal.sqf | 7 +- .../functions/fnc_fullHealLocal.sqf | 4 +- .../functions/fnc_treatment.sqf | 2 +- addons/medical_treatment/initSettings.inc.sqf | 2 +- addons/medical_treatment/stringtable.xml | 40 ++ addons/medical_vitals/stringtable.xml | 6 + addons/microdagr/initSettings.inc.sqf | 4 +- addons/minedetector/XEH_postInit.sqf | 11 +- addons/minedetector/XEH_preStart.sqf | 4 +- .../functions/fnc_getDetectedObject.sqf | 12 +- .../functions/fnc_getDetectorConfig.sqf | 11 +- .../fnc_cycleAttackProfileKeyDown.sqf | 2 +- .../missileguidance/functions/fnc_onFired.sqf | 2 +- .../mk6mortar/functions/fnc_handleFired.sqf | 2 +- .../fnc_handlePlayerVehicleChanged.sqf | 2 +- addons/mk6mortar/stringtable.xml | 14 +- addons/nametags/XEH_postInit.sqf | 2 +- .../functions/fnc_drawNameTagIcon.sqf | 2 +- .../functions/fnc_setFactionRankIcons.sqf | 9 +- addons/nightvision/XEH_postInit.sqf | 4 +- addons/nightvision/stringtable.xml | 12 + addons/nlaw/functions/fnc_keyDown.sqf | 4 +- addons/overheating/stringtable.xml | 12 + .../overpressure/functions/fnc_firedEHBB.sqf | 2 +- .../functions/fnc_overpressureDamage.sqf | 2 +- addons/parachute/CfgVehicles.hpp | 32 ++ addons/parachute/initSettings.inc.sqf | 4 +- addons/pylons/functions/fnc_showDialog.sqf | 2 +- addons/realisticnames/Attachments.hpp | 174 +++++++ addons/realisticnames/CfgVehicles.hpp | 13 + addons/realisticnames/CfgWeapons.hpp | 185 +------ addons/realisticnames/stringtable.xml | 68 ++- addons/rearm/XEH_postInit.sqf | 5 +- addons/rearm/XEH_preStart.sqf | 2 +- .../rearm/functions/fnc_getMagazineName.sqf | 44 +- addons/rearm/initSettings.inc.sqf | 11 +- addons/refuel/ACE_Refuel_Positions.hpp | 96 ++++ addons/refuel/Cfg3DEN.hpp | 7 +- addons/refuel/CfgVehicles.hpp | 36 +- addons/refuel/XEH_PREP.hpp | 1 + addons/refuel/XEH_postInit.sqf | 218 +++++--- addons/refuel/XEH_preStart.sqf | 39 +- addons/refuel/config.cpp | 1 + .../dev/exportTerrainRefuelPositions.sqf | 95 ++++ addons/refuel/dev/test_debugConfigs.sqf | 16 +- addons/refuel/functions/fnc_getFuelCargo.sqf | 20 + addons/refuel/functions/fnc_makeJerryCan.sqf | 7 + addons/refuel/functions/fnc_makeSource.sqf | 34 +- addons/refuel/initSettings.inc.sqf | 22 +- addons/refuel/stringtable.xml | 5 + addons/reload/stringtable.xml | 2 + addons/reloadlaunchers/stringtable.xml | 6 + addons/repair/XEH_PREP.hpp | 1 - addons/repair/dev/draw_showRepairInfo.sqf | 5 +- .../repair/functions/fnc_addRepairActions.sqf | 2 +- addons/repair/functions/fnc_canRepair.sqf | 2 +- .../functions/fnc_getSelectionsToIgnore.sqf | 4 +- .../fnc_getWheelHitPointsWithSelections.sqf | 97 ---- .../functions/fnc_normalizeHitPoints.sqf | 2 +- addons/repair/functions/fnc_repair.sqf | 2 +- .../repair/functions/fnc_repair_failure.sqf | 2 +- .../repair/functions/fnc_repair_success.sqf | 2 +- addons/repair/initSettings.inc.sqf | 30 +- addons/repair/stringtable.xml | 21 + addons/scopes/functions/fnc_adjustScope.sqf | 2 +- addons/scopes/functions/fnc_canAdjustZero.sqf | 2 +- addons/scopes/functions/fnc_canResetZero.sqf | 2 +- addons/scopes/functions/fnc_firedEH.sqf | 2 +- .../functions/fnc_getCurrentZeroRange.sqf | 4 +- addons/scopes/functions/fnc_getOptics.sqf | 2 +- addons/scopes/initKeybinds.inc.sqf | 16 +- addons/sitting/functions/fnc_sit.sqf | 2 +- addons/sitting/initSettings.inc.sqf | 2 +- .../slideshow/functions/fnc_mapImage_init.sqf | 2 +- .../switchunits/functions/fnc_switchUnit.sqf | 2 +- addons/tagging/XEH_postInit.sqf | 8 - addons/tagging/XEH_preStart.sqf | 4 +- .../tagging/functions/fnc_checkTaggable.sqf | 6 +- .../functions/fnc_generateStencilTexture.sqf | 8 +- .../tagging/functions/fnc_stencilVehicle.sqf | 2 +- addons/tagging/functions/fnc_tag.sqf | 4 +- addons/tagging/initSettings.inc.sqf | 5 +- addons/tagging/stringtable.xml | 2 + addons/ui/XEH_PREP.hpp | 1 - addons/ui/XEH_clientInit.sqf | 11 +- addons/ui/functions/fnc_compileConfigUI.sqf | 2 +- .../ui/functions/fnc_handlePlayerChanged.sqf | 32 -- .../ui/functions/fnc_setAdvancedElement.sqf | 6 +- .../ui/functions/fnc_setElementVisibility.sqf | 9 +- addons/vector/functions/fnc_onKeyHold.sqf | 2 +- addons/vehicle_damage/XEH_PREP.hpp | 1 + addons/vehicle_damage/XEH_postInit.sqf | 4 +- .../vehicle_damage/functions/fnc_abandon.sqf | 2 + .../functions/fnc_addDamage.sqf | 4 +- .../vehicle_damage/functions/fnc_detonate.sqf | 20 +- .../functions/fnc_handleCookoff.sqf | 24 +- .../functions/fnc_handleDetonation.sqf | 11 +- .../functions/fnc_handleVehicleDamage.sqf | 2 +- .../functions/fnc_medicalDamage.sqf | 39 ++ .../functions/fnc_processHit.sqf | 16 +- addons/vehicle_damage/initSettings.inc.sqf | 10 - addons/vehicle_damage/stringtable.xml | 24 - .../functions/fnc_addKeyForVehicle.sqf | 8 +- addons/vehiclelock/functions/fnc_lockpick.sqf | 7 +- .../vehiclelock/functions/fnc_moduleSync.sqf | 2 +- addons/vehiclelock/initSettings.inc.sqf | 3 +- addons/viewports/functions/fnc_eachFrame.sqf | 2 +- .../viewports/functions/fnc_getSeatInfo.sqf | 2 +- .../functions/fnc_changeCamera.sqf | 2 +- addons/viewrestriction/initSettings.inc.sqf | 10 +- addons/volume/initSettings.inc.sqf | 24 +- addons/weaponselect/XEH_postInit.sqf | 2 +- addons/weaponselect/XEH_preInit.sqf | 12 +- .../functions/fnc_selectNextGrenade.sqf | 12 +- addons/weaponselect/initSettings.inc.sqf | 4 +- .../functions/fnc_calculateWindSpeed.sqf | 12 +- addons/weather/init3DEN.sqf | 2 +- addons/weather/initSettings.inc.sqf | 3 +- addons/xm157/functions/fnc_keyPress.sqf | 4 +- addons/zeus/CfgVehicles.hpp | 6 + addons/zeus/XEH_PREP.hpp | 2 + addons/zeus/XEH_postInit.sqf | 1 + addons/zeus/config.cpp | 6 + .../zeus/functions/fnc_addObjectToCurator.sqf | 2 +- .../zeus/functions/fnc_bi_moduleCurator.sqf | 64 +-- .../functions/fnc_getModuleDestination.sqf | 4 +- .../functions/fnc_moduleCargoParadrop.sqf | 4 +- .../fnc_moduleCargoParadropWaypoint.sqf | 2 +- addons/zeus/functions/fnc_moduleHeal.sqf | 2 +- addons/zeus/functions/fnc_moduleSetMedic.sqf | 2 +- .../fnc_moduleSetMedicalFacility.sqf | 4 +- .../functions/fnc_moduleSetMedicalVehicle.sqf | 2 +- addons/zeus/functions/fnc_moduleSpectator.sqf | 39 ++ .../functions/fnc_moduleSuicideBomber.sqf | 2 +- addons/zeus/functions/fnc_showMessage.sqf | 2 +- .../zeus/functions/fnc_ui_globalSetSkill.sqf | 6 +- addons/zeus/functions/fnc_ui_groupSide.sqf | 8 +- addons/zeus/functions/fnc_ui_setEngineer.sqf | 2 +- addons/zeus/functions/fnc_ui_spectator.sqf | 265 ++++++++++ .../zeus/functions/fnc_ui_teleportPlayers.sqf | 6 +- addons/zeus/stringtable.xml | 57 +- addons/zeus/ui/RscAttributes.hpp | 228 ++++++++ docs/_config.yml | 4 +- docs/_config_dev.yml | 4 +- docs/wiki/development/coding-guidelines.md | 87 +--- docs/wiki/feature/grenades.md | 2 + docs/wiki/feature/hitreactions.md | 3 + docs/wiki/framework/cargo-framework.md | 18 + docs/wiki/framework/cookoff-framework.md | 37 +- docs/wiki/framework/events-framework.md | 23 +- docs/wiki/framework/grenades-framework.md | 15 + docs/wiki/framework/headless-framework.md | 23 +- docs/wiki/framework/hitreactions-framework.md | 32 ++ .../framework/medical-treatment-framework.md | 7 + docs/wiki/framework/nametags-framework.md | 45 ++ docs/wiki/framework/refuel-framework.md | 2 +- .../wiki/framework/vehicledamage-framework.md | 10 +- 446 files changed, 6934 insertions(+), 3187 deletions(-) create mode 100644 addons/common/functions/fnc_addPlayerEH.sqf create mode 100644 addons/common/functions/fnc_getWheelHitPointsWithSelections.sqf create mode 100644 addons/common/functions/fnc_setDead.sqf create mode 100644 addons/compat_cup_units/CfgGlasses.hpp delete mode 100644 addons/compat_gm/compat_gm_refuel/CfgVehicles.hpp create mode 100644 addons/compat_rf/$PBOPREFIX$ create mode 100644 addons/compat_rf/CfgWeapons.hpp create mode 100644 addons/compat_rf/compat_rf_nouniformrestrictions/CfgVehicles.hpp create mode 100644 addons/compat_rf/compat_rf_nouniformrestrictions/config.cpp create mode 100644 addons/compat_rf/compat_rf_nouniformrestrictions/script_component.hpp create mode 100644 addons/compat_rf/compat_rf_realisticnames/Attachments.hpp create mode 100644 addons/compat_rf/compat_rf_realisticnames/CfgMagazines.hpp create mode 100644 addons/compat_rf/compat_rf_realisticnames/CfgVehicles.hpp create mode 100644 addons/compat_rf/compat_rf_realisticnames/CfgWeapons.hpp create mode 100644 addons/compat_rf/compat_rf_realisticnames/config.cpp create mode 100644 addons/compat_rf/compat_rf_realisticnames/script_component.hpp create mode 100644 addons/compat_rf/compat_rf_realisticnames/stringtable.xml create mode 100644 addons/compat_rf/config.cpp create mode 100644 addons/compat_rf/script_component.hpp delete mode 100644 addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/CfgVehicles.hpp delete mode 100644 addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgVehicles.hpp create mode 100644 addons/compat_ws/compat_ws_realisticnames/Attachments.hpp create mode 100644 addons/compat_ws/compat_ws_realisticnames/CfgVehicles.hpp delete mode 100644 addons/cookoff/functions/fnc_cookOff.sqf delete mode 100644 addons/cookoff/functions/fnc_cookOffBox.sqf create mode 100644 addons/cookoff/functions/fnc_cookOffBoxLocal.sqf create mode 100644 addons/cookoff/functions/fnc_cookOffBoxServer.sqf delete mode 100644 addons/cookoff/functions/fnc_cookOffEffect.sqf create mode 100644 addons/cookoff/functions/fnc_cookOffLocal.sqf create mode 100644 addons/cookoff/functions/fnc_cookOffServer.sqf delete mode 100644 addons/cookoff/functions/fnc_detonateAmmunition.sqf create mode 100644 addons/cookoff/functions/fnc_detonateAmmunitionServer.sqf create mode 100644 addons/cookoff/functions/fnc_detonateAmmunitionServerLoop.sqf delete mode 100644 addons/cookoff/functions/fnc_engineFire.sqf create mode 100644 addons/cookoff/functions/fnc_engineFireLocal.sqf create mode 100644 addons/cookoff/functions/fnc_engineFireServer.sqf delete mode 100644 addons/fire/functions/fnc_isPlant.sqf create mode 100644 addons/grenades/functions/fnc_damageEngineAndWheels.sqf create mode 100644 addons/headless/functions/fnc_blacklist.sqf create mode 100644 addons/hearing/functions/fnc_getAmmoLoudness.sqf create mode 100644 addons/hitreactions/XEH_postInit.sqf create mode 100644 addons/hitreactions/functions/fnc_checkWeaponDrop.sqf create mode 100644 addons/realisticnames/Attachments.hpp create mode 100644 addons/refuel/ACE_Refuel_Positions.hpp create mode 100644 addons/refuel/dev/exportTerrainRefuelPositions.sqf create mode 100644 addons/refuel/functions/fnc_getFuelCargo.sqf delete mode 100644 addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf delete mode 100644 addons/ui/functions/fnc_handlePlayerChanged.sqf create mode 100644 addons/vehicle_damage/functions/fnc_medicalDamage.sqf create mode 100644 addons/zeus/functions/fnc_moduleSpectator.sqf create mode 100644 addons/zeus/functions/fnc_ui_spectator.sqf create mode 100644 docs/wiki/framework/hitreactions-framework.md create mode 100644 docs/wiki/framework/nametags-framework.md diff --git a/addons/advanced_ballistics/functions/fnc_handleFired.sqf b/addons/advanced_ballistics/functions/fnc_handleFired.sqf index b41fd7a7c01..ff2fe85ae4f 100644 --- a/addons/advanced_ballistics/functions/fnc_handleFired.sqf +++ b/addons/advanced_ballistics/functions/fnc_handleFired.sqf @@ -19,7 +19,7 @@ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); -if (!(_ammo isKindOf "BulletBase")) exitWith {}; +if !(_ammo isKindOf "BulletBase") exitWith {}; if (!alive _projectile) exitWith {}; if (underwater _unit) exitWith {}; diff --git a/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf b/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf index 125c3677b88..51907869241 100644 --- a/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf +++ b/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf @@ -40,7 +40,7 @@ if (_transonicStabilityCoef == 0) then { _transonicStabilityCoef = 0.5; }; private _dragModel = getNumber(_ammoConfig >> "ACE_dragModel"); -if (!(_dragModel in [1, 2, 5, 6, 7, 8])) then { +if !(_dragModel in [1, 2, 5, 6, 7, 8]) then { _dragModel = 1; }; private _ballisticCoefficients = getArray(_ammoConfig >> "ACE_ballisticCoefficients"); diff --git a/addons/advanced_fatigue/XEH_postInit.sqf b/addons/advanced_fatigue/XEH_postInit.sqf index f5aa7432f01..08fd827d588 100644 --- a/addons/advanced_fatigue/XEH_postInit.sqf +++ b/addons/advanced_fatigue/XEH_postInit.sqf @@ -46,7 +46,7 @@ if (!hasInterface) exitWith {}; }, true] call CBA_fnc_addPlayerEventHandler; // - Duty factors ------------------------------------------------------------- - if (GVAR(medicalLoaded)) then { + if (GETEGVAR(medical,enabled,false)) then { [QEGVAR(medical,pain), { // 0->1.0, 0.5->1.05, 1->1.1 linearConversion [0, 1, (_this getVariable [QEGVAR(medical,pain), 0]), 1, 1.1, true]; }] call FUNC(addDutyFactor); diff --git a/addons/advanced_fatigue/XEH_preInit.sqf b/addons/advanced_fatigue/XEH_preInit.sqf index 9f58e44fdf2..643b7b0be00 100644 --- a/addons/advanced_fatigue/XEH_preInit.sqf +++ b/addons/advanced_fatigue/XEH_preInit.sqf @@ -13,6 +13,5 @@ GVAR(dutyList) = createHashMap; GVAR(setAnimExclusions) = []; GVAR(inertia) = 0; GVAR(inertiaCache) = createHashMap; -GVAR(medicalLoaded) = ["ace_medical"] call EFUNC(common,isModLoaded); ADDON = true; diff --git a/addons/advanced_fatigue/functions/fnc_mainLoop.sqf b/addons/advanced_fatigue/functions/fnc_mainLoop.sqf index da469b6d218..add9b6e5d81 100644 --- a/addons/advanced_fatigue/functions/fnc_mainLoop.sqf +++ b/addons/advanced_fatigue/functions/fnc_mainLoop.sqf @@ -25,7 +25,7 @@ if (!alive ACE_player) exitWith { private _oxygen = 0.9; // Default AF oxygen saturation -if (GVAR(medicalLoaded) && {EGVAR(medical_vitals,simulateSpo2)}) then { +if (GETEGVAR(medical,enabled,false) && {EGVAR(medical_vitals,simulateSpo2)}) then { _oxygen = (ACE_player getVariable [QEGVAR(medical,spo2), 97]) / 100; }; diff --git a/addons/advanced_throwing/XEH_postInit.sqf b/addons/advanced_throwing/XEH_postInit.sqf index 774c99b3e65..d91129b0250 100644 --- a/addons/advanced_throwing/XEH_postInit.sqf +++ b/addons/advanced_throwing/XEH_postInit.sqf @@ -10,20 +10,10 @@ if (!hasInterface) exitWith {}; // Temporary Wind Info indication GVAR(tempWindInfo) = false; -// Ammo/Magazines look-up hash for correctness of initSpeed -GVAR(ammoMagLookup) = call CBA_fnc_createNamespace; -{ - { - private _ammo = getText (configFile >> "CfgMagazines" >> _x >> "ammo"); - if (_ammo != "") then { GVAR(ammoMagLookup) setVariable [_ammo, _x]; }; - } forEach (getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines")); -} forEach getArray (configFile >> "CfgWeapons" >> "Throw" >> "muzzles"); - - // Add keybinds ["ACE3 Weapons", QGVAR(prepare), localize LSTRING(Prepare), { // Condition - if (!([ACE_player] call FUNC(canPrepare))) exitWith {false}; + if !([ACE_player] call FUNC(canPrepare)) exitWith {false}; if (EGVAR(common,isReloading)) exitWith {true}; // Statement diff --git a/addons/advanced_throwing/XEH_preStart.sqf b/addons/advanced_throwing/XEH_preStart.sqf index 022888575ed..efd2ca1f7eb 100644 --- a/addons/advanced_throwing/XEH_preStart.sqf +++ b/addons/advanced_throwing/XEH_preStart.sqf @@ -1,3 +1,21 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" + +// Ammo/Magazines look-up hash for correctness of initSpeed +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgAmmo = configFile >> "CfgAmmo"; +private _cfgThrow = configFile >> "CfgWeapons" >> "Throw"; + +private _ammoMagLookup = createHashMap; + +{ + { + private _ammo = getText (_cfgMagazines >> _x >> "ammo"); + if (_ammo != "") then { + _ammoMagLookup set [configName (_cfgAmmo >> _ammo), _x]; + }; + } forEach (getArray (_cfgThrow >> _x >> "magazines")); +} forEach (getArray (_cfgThrow >> "muzzles")); + +uiNamespace setVariable [QGVAR(ammoMagLookup), compileFinal _ammoMagLookup]; diff --git a/addons/advanced_throwing/functions/fnc_drawThrowable.sqf b/addons/advanced_throwing/functions/fnc_drawThrowable.sqf index 5bc3f22b571..f85c33dbde2 100644 --- a/addons/advanced_throwing/functions/fnc_drawThrowable.sqf +++ b/addons/advanced_throwing/functions/fnc_drawThrowable.sqf @@ -43,13 +43,10 @@ if ((!_primed) && {!((_throwableMag in (uniformItems ACE_player)) || {_throwable // Get correct throw power for primed grenade if (_primed) then { - private _ammoType = typeOf _activeThrowable; - _throwableMag = GVAR(ammoMagLookup) getVariable _ammoType; - if (isNil "_throwableMag") then { - // What we're trying to throw must not be a normal throwable because it is not in our lookup hash (e.g. 40mm smoke) - // Just use HandGrenade as it has an average initSpeed value - _throwableMag = "HandGrenade"; - }; + // If ammo type is not found: + // What we're trying to throw must not be a normal throwable because it is not in our lookup hash (e.g. 40mm smoke) + // Just use HandGrenade as it has an average initSpeed value + _throwableMag = (uiNamespace getVariable QGVAR(ammoMagLookup)) getOrDefault [typeOf _activeThrowable, "HandGrenade"]; }; // Some throwables have different classname for magazine and ammo diff --git a/addons/advanced_throwing/functions/fnc_prepare.sqf b/addons/advanced_throwing/functions/fnc_prepare.sqf index 7926c2c8649..c158ad51502 100644 --- a/addons/advanced_throwing/functions/fnc_prepare.sqf +++ b/addons/advanced_throwing/functions/fnc_prepare.sqf @@ -18,19 +18,10 @@ params ["_unit"]; TRACE_1("params",_unit); -// Temporarily enable wind info, to aid in throwing smoke grenades effectively -if ( - GVAR(enableTempWindInfo) && - {!(missionNamespace getVariable [QEGVAR(weather,WindInfo), false])} -) then { - [] call EFUNC(weather,displayWindInfo); - GVAR(tempWindInfo) = true; -}; - // Select next throwable if one already in hand if (_unit getVariable [QGVAR(inHand), false]) exitWith { TRACE_1("inHand",_unit); - if (!(_unit getVariable [QGVAR(primed), false])) then { + if !(_unit getVariable [QGVAR(primed), false]) then { TRACE_1("not primed",_unit); // Restore muzzle ammo (setAmmo 1 has no impact if no appliccable throwable in inventory) // selectNextGrenade relies on muzzles array (setAmmo 0 removes the muzzle from the array and current can't be found, cycles between 0 and 1 muzzles) @@ -44,6 +35,11 @@ if (isNull (_unit getVariable [QGVAR(activeThrowable), objNull]) && {(currentThr TRACE_1("no throwables",_unit); }; +// Temporarily enable wind info, to aid in throwing smoke grenades effectively +if (GVAR(enableTempWindInfo) && {!(missionNamespace getVariable [QEGVAR(weather,WindInfo), false])}) then { + [] call EFUNC(weather,displayWindInfo); + GVAR(tempWindInfo) = true; +}; _unit setVariable [QGVAR(inHand), true]; diff --git a/addons/advanced_throwing/functions/fnc_throw.sqf b/addons/advanced_throwing/functions/fnc_throw.sqf index 797f18d7730..d6b38a6a0c7 100644 --- a/addons/advanced_throwing/functions/fnc_throw.sqf +++ b/addons/advanced_throwing/functions/fnc_throw.sqf @@ -20,7 +20,7 @@ TRACE_1("params",_unit); // Prime the throwable if it hasn't been cooking already // Next to proper simulation this also has to happen before delay for orientation of the throwable to be set -if (!(_unit getVariable [QGVAR(primed), false])) then { +if !(_unit getVariable [QGVAR(primed), false]) then { [_unit] call FUNC(prime); }; diff --git a/addons/advanced_throwing/stringtable.xml b/addons/advanced_throwing/stringtable.xml index 1e0b5ae23f7..e0e526e12e7 100644 --- a/addons/advanced_throwing/stringtable.xml +++ b/addons/advanced_throwing/stringtable.xml @@ -193,6 +193,7 @@ 바람 정보 임시로 표시 Afficher temporairement les informations sur le vent Временно показать информацию о ветре + Mostrar información del viento temporalmente Temporarily display Wind Info while throwing, to aid in placing smoke grenades effectively. @@ -202,6 +203,7 @@ 연막탄을 효과적으로 배치하는 데 도움이 되도록 투척하는 동안 일시적으로 바람 정보를 표시합니다. Affiche les informations sur le vent pendant le lancement pour placer les grenades fumigènes plus efficacement. Временно отображайте информацию о ветре во время броска, чтобы помочь эффективно разместить дымовые шашки. + Mostrar información del viento temporalmente mientras se lanza, para ayudar a lanzar las granadas de humo de forma efectiva. Prepare/Change Throwable diff --git a/addons/ai/stringtable.xml b/addons/ai/stringtable.xml index 11a686f6b2e..b9df8bb35a1 100644 --- a/addons/ai/stringtable.xml +++ b/addons/ai/stringtable.xml @@ -91,6 +91,7 @@ Equipar NVGs automaticamente 暗視装置の自動装備 Автоматическое оснащение ПНВ + Auto equipar gafas de visión nocturna Equips NVG in inventory during night time and unequips it during day time.\nDoes not add NVGs to inventory! @@ -102,6 +103,7 @@ Equipa o NVG do inventário durante a noite e desequipa durante o dia.\nNão adiciona NVGs ao inventário! インベントリ内の暗視装置を夜間に装備し、日中は解除し収納します。\nこれはNVGをインベントリに追加しません。 Экипирует ПНВ в ночное время и отключает его в дневное время.\nНе добавляет ПНВ в инвентарь! + Equipa las gafas de visión nocturna en el inventario cuando es de noche, y las desequipa cuando es de día.\nNo añade las gafas al inventario! diff --git a/addons/arsenal/functions/fnc_onArsenalClose.sqf b/addons/arsenal/functions/fnc_onArsenalClose.sqf index f2316bc9d5b..6803d2d5de5 100644 --- a/addons/arsenal/functions/fnc_onArsenalClose.sqf +++ b/addons/arsenal/functions/fnc_onArsenalClose.sqf @@ -18,7 +18,7 @@ (_this select 1) params ["", "_exitCode"]; [QGVAR(displayClosed), []] call CBA_fnc_localEvent; -removeMissionEventHandler ["draw3D", GVAR(camPosUpdateHandle)]; +removeMissionEventHandler ["Draw3D", GVAR(camPosUpdateHandle)]; if (is3DEN) then { private _centerOriginParent = objectParent GVAR(centerOrigin); diff --git a/addons/arsenal/functions/fnc_onArsenalOpen.sqf b/addons/arsenal/functions/fnc_onArsenalOpen.sqf index f307c932b13..0f0a5817c6e 100644 --- a/addons/arsenal/functions/fnc_onArsenalOpen.sqf +++ b/addons/arsenal/functions/fnc_onArsenalOpen.sqf @@ -278,4 +278,4 @@ showCinemaBorder false; //--------------- Reset camera pos [nil, [controlNull, 0, 0]] call FUNC(handleMouse); -GVAR(camPosUpdateHandle) = addMissionEventHandler ["draw3D", {call FUNC(updateCamPos)}]; +GVAR(camPosUpdateHandle) = addMissionEventHandler ["Draw3D", {call FUNC(updateCamPos)}]; diff --git a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf index 5bf08245c88..e25016b303d 100644 --- a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf @@ -382,6 +382,9 @@ switch (GVAR(currentLeftPanel)) do { }; GVAR(currentItems) set [IDX_CURR_VEST, _item]; + + [GVAR(center), ""] call BIS_fnc_setUnitInsignia; + [GVAR(center), GVAR(currentInsignia)] call BIS_fnc_setUnitInsignia; }; TOGGLE_RIGHT_PANEL_CONTAINER @@ -420,6 +423,9 @@ switch (GVAR(currentLeftPanel)) do { }; GVAR(currentItems) set [IDX_CURR_BACKPACK, _item]; + + [GVAR(center), ""] call BIS_fnc_setUnitInsignia; + [GVAR(center), GVAR(currentInsignia)] call BIS_fnc_setUnitInsignia; }; TOGGLE_RIGHT_PANEL_CONTAINER diff --git a/addons/arsenal/functions/fnc_onSelChangedRight.sqf b/addons/arsenal/functions/fnc_onSelChangedRight.sqf index ccb29887651..abec68ceeef 100644 --- a/addons/arsenal/functions/fnc_onSelChangedRight.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedRight.sqf @@ -69,7 +69,14 @@ switch (_currentItemsIndex) do { // Secondary weapon case IDX_CURR_SECONDARY_WEAPON_ITEMS: { private _currentItemInSlot = (GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON_ITEMS) select _itemIndex; - private _isDisposable = CBA_disposable_replaceDisposableLauncher && {!isNil {CBA_disposable_loadedLaunchers getVariable (secondaryWeapon GVAR(center))}}; + private _isDisposable = CBA_disposable_replaceDisposableLauncher && {!isNil "CBA_disposable_loadedLaunchers"} && + { + if (CBA_disposable_loadedLaunchers isEqualType createHashMap) then { // after CBA 3.18 + (secondaryWeapon GVAR(center)) in CBA_disposable_loadedLaunchers + } else { + !isNil {CBA_disposable_loadedLaunchers getVariable (secondaryWeapon player)} + } + }; // If removal if (_item == "") then { diff --git a/addons/arsenal/functions/fnc_showItem.sqf b/addons/arsenal/functions/fnc_showItem.sqf index 7ceda5f0d54..f47f12d2bf4 100644 --- a/addons/arsenal/functions/fnc_showItem.sqf +++ b/addons/arsenal/functions/fnc_showItem.sqf @@ -72,6 +72,6 @@ if (_nextAction != GVAR(currentAction)) then { GVAR(currentAction) = _nextAction; }; -if (!(GVAR(currentAction) in ["Civil", "Salute"])) then { +if !(GVAR(currentAction) in ["Civil", "Salute"]) then { GVAR(center) selectWeapon ([primaryWeapon GVAR(center), secondaryWeapon GVAR(center), handgunWeapon GVAR(center), binocular GVAR(center)] select GVAR(selectedWeaponType)); // select correct weapon, prevents floating weapons }; diff --git a/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf b/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf index a93611d3291..502f7b888dc 100644 --- a/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf +++ b/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf @@ -63,7 +63,7 @@ _target switchMove "amovpercmstpslowwrfldnon"; _target setVariable ["origin", _position]; // When killed, respawn AI -_target addEventHandler ["killed", { +_target addEventHandler ["Killed", { params ["_target"]; // Killed may fire twice, 2nd will be null - https://github.com/acemod/ACE3/pull/7561 diff --git a/addons/arsenal/stringtable.xml b/addons/arsenal/stringtable.xml index 02c35266db9..cf858ec24d8 100644 --- a/addons/arsenal/stringtable.xml +++ b/addons/arsenal/stringtable.xml @@ -1245,6 +1245,8 @@ Интегрирован тепловизор. 열화상 내장 Thermique intégrée + Thermal integriert + Térmica integrada Thermal & Primary integrated @@ -1253,6 +1255,8 @@ Интегрирован тепловизор и осн.прицел. 열화상과 주무기 내장 Thermique et primaire intégrés + Thermal und in Primärwaffe integriert + Térmica y Primaria integrada Not Supported @@ -1609,6 +1613,7 @@ Décroissant Decrescente Нисходящий + Descendiente Ascending @@ -1620,6 +1625,7 @@ Croissant Crescente Восходящий + Ascendiente Tools @@ -1647,6 +1653,7 @@ Nombre de munitions Quantidade de munição Количество боеприпасов + Cantidad de munición Illuminators @@ -1657,6 +1664,7 @@ Iluminadores イルミネーター Осветители + Iluminadores Default to Favorites @@ -1668,6 +1676,7 @@ Favoris par défaut Favoritos por padrão По умолчанию - Избранное + Favoritos por defecto Controls whether the ACE Arsenal defaults to showing all items or favorites. @@ -1679,6 +1688,7 @@ Contrôle si l'arsenal ACE affiche par défaut tous les éléments ou les favoris. Controla se o Arsenal ACE exibe por padrão todos os itens ou favoritos. Определяет, будет ли в арсенале ACE по умолчанию отображаться все предметы или избранное. + Controla si el Arsenal de ACE muestra por defecto todos los objetos o sólo los favoritos Favorites Color @@ -1690,6 +1700,7 @@ Couleurs favorites Cor dos favoritos Избранный цвет + Color de Favoritos Highlight color for favorited items. @@ -1701,6 +1712,7 @@ Met en surbrillance les éléments favoris. Cor de destaque para itens favoritados. Выделите цветом любимые предметы. + Color de marcado para los objetos favoritos Switch between displaying all items or your favorites.\nDouble click while holding Shift to add or remove an item. @@ -1712,6 +1724,7 @@ Change entre l'affichage de tous les éléments ou de vos favoris.\nDouble-cliquez en maintenant la touche Maj enfoncée pour ajouter ou supprimer un élément. Alterna entre a exibição de todos os itens ou seus favoritos.\nClique duas vezes enquanto mantém pressionada a tecla Shift para adicionar ou remover um item. Переключайтесь между отображением всех элементов или ваших избранных.\nДважды щелкните, удерживая Shift, чтобы добавить или удалить элемент. + Alterna entre mostrar todos los objetos o sólo los favoritos.\nDoble click mientras se pulsa Shift para añadir o quitar un objeto. Search\nCTRL + Click to enable live results @@ -1721,6 +1734,7 @@ 검색\nCtrl + 클릭으로 실시간 검색 결과를 활성화 Поиск\nCtrl + Click для включения результатов в реальном времени Recherche\nCTRL + clic pour modifier les résultats tout en écrivant + Buscar\nCTRL + Click habilita los objetos en directo diff --git a/addons/artillerytables/functions/fnc_firedEH.sqf b/addons/artillerytables/functions/fnc_firedEH.sqf index 01947b4ebe0..f735c4c9615 100644 --- a/addons/artillerytables/functions/fnc_firedEH.sqf +++ b/addons/artillerytables/functions/fnc_firedEH.sqf @@ -25,7 +25,7 @@ params ["_vehicle", "", "", "", "", "_magazine", "_projectile", "_gunner"]; TRACE_4("firedEH",_vehicle,_magazine,_projectile,_gunner); -if (!([_gunner] call EFUNC(common,isPlayer))) exitWith {}; // AI don't know how to use (this does give them more range than a player) +if !([_gunner] call EFUNC(common,isPlayer)) exitWith {}; // AI don't know how to use (this does give them more range than a player) if ((gunner _vehicle) != _gunner) exitWith {}; // check if primaryGunner diff --git a/addons/artillerytables/functions/fnc_interactMenuOpened.sqf b/addons/artillerytables/functions/fnc_interactMenuOpened.sqf index b7d6371339e..4ba6342fc83 100644 --- a/addons/artillerytables/functions/fnc_interactMenuOpened.sqf +++ b/addons/artillerytables/functions/fnc_interactMenuOpened.sqf @@ -19,7 +19,7 @@ params ["_menuType"]; TRACE_1("interactMenuOpened",_menuType); if (_menuType != 1) exitWith {}; -if (!("ACE_artilleryTable" in (ace_player call EFUNC(common,uniqueItems)))) exitWith {}; +if !("ACE_artilleryTable" in (ace_player call EFUNC(common,uniqueItems))) exitWith {}; private _vehicleAdded = ace_player getVariable [QGVAR(vehiclesAdded), []]; private _rangeTablesShown = ace_player getVariable [QGVAR(rangeTablesShown), []]; diff --git a/addons/artillerytables/initSettings.inc.sqf b/addons/artillerytables/initSettings.inc.sqf index 762010b2caa..f34190f910a 100644 --- a/addons/artillerytables/initSettings.inc.sqf +++ b/addons/artillerytables/initSettings.inc.sqf @@ -15,7 +15,5 @@ private _categoryName = [format ["ACE %1", localize "str_a3_cfgmarkers_nato_art" [LSTRING(disableArtilleryComputer_displayName), LSTRING(disableArtilleryComputer_description)], _categoryName, false, // default value - true, // isGlobal - {[QGVAR(disableArtilleryComputer), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart + true // isGlobal ] call CBA_fnc_addSetting; diff --git a/addons/atragmx/functions/fnc_initGunList.sqf b/addons/atragmx/functions/fnc_initGunList.sqf index 2ae67bb78df..515bc9013eb 100644 --- a/addons/atragmx/functions/fnc_initGunList.sqf +++ b/addons/atragmx/functions/fnc_initGunList.sqf @@ -23,7 +23,7 @@ if ((profileNamespace getVariable ["ACE_ATragMX_profileNamespaceVersion", 0]) == _resetGunList = false; { // Verify each gun has correct param type - if (!(_x isEqualTypeArray ["", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", [], [], false])) exitWith { + if !(_x isEqualTypeArray ["", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", [], [], false]) exitWith { _resetGunList = true; }; } forEach GVAR(gunList); diff --git a/addons/atragmx/functions/fnc_read_gun_list_entries_from_config.sqf b/addons/atragmx/functions/fnc_read_gun_list_entries_from_config.sqf index 31451c7ff81..cbbb4603e34 100644 --- a/addons/atragmx/functions/fnc_read_gun_list_entries_from_config.sqf +++ b/addons/atragmx/functions/fnc_read_gun_list_entries_from_config.sqf @@ -74,7 +74,7 @@ private _validate_preset = { ERROR(_errorMsg); _valid = false; }; - if (!((_this select 17) in ["ASM", "ICAO"])) then { + if !((_this select 17) in ["ASM", "ICAO"]) then { private _errorMsg = format ["Invalid atmosphere model: %1", _this select 17]; ERROR(_errorMsg); _valid = false; diff --git a/addons/atragmx/functions/fnc_target_speed_assist_timer.sqf b/addons/atragmx/functions/fnc_target_speed_assist_timer.sqf index b34dd666f22..5408edee3af 100644 --- a/addons/atragmx/functions/fnc_target_speed_assist_timer.sqf +++ b/addons/atragmx/functions/fnc_target_speed_assist_timer.sqf @@ -26,7 +26,7 @@ if !(ctrlVisible 9000) then { params ["_args"]; _args params ["_startTime"]; - if (!(GVAR(speedAssistTimer))) exitWith { + if !(GVAR(speedAssistTimer)) exitWith { GVAR(speedAssistTimer) = true; ctrlSetText [8006, Str(Round((CBA_missionTime - _startTime) * 10) / 10)]; diff --git a/addons/atragmx/functions/fnc_toggle_c1_ballistic_coefficient_data.sqf b/addons/atragmx/functions/fnc_toggle_c1_ballistic_coefficient_data.sqf index bb581ad6ea7..a8cd7ce52ae 100644 --- a/addons/atragmx/functions/fnc_toggle_c1_ballistic_coefficient_data.sqf +++ b/addons/atragmx/functions/fnc_toggle_c1_ballistic_coefficient_data.sqf @@ -15,7 +15,7 @@ * Public: No */ -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {}; if (ctrlVisible 17000) then { false call FUNC(show_c1_ballistic_coefficient_data); diff --git a/addons/atragmx/functions/fnc_toggle_muzzle_velocity_data.sqf b/addons/atragmx/functions/fnc_toggle_muzzle_velocity_data.sqf index 562ef305537..34326b251da 100644 --- a/addons/atragmx/functions/fnc_toggle_muzzle_velocity_data.sqf +++ b/addons/atragmx/functions/fnc_toggle_muzzle_velocity_data.sqf @@ -15,7 +15,7 @@ * Public: No */ -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {}; if (ctrlVisible 16000) then { false call FUNC(show_muzzle_velocity_data); diff --git a/addons/atragmx/functions/fnc_toggle_truing_drop.sqf b/addons/atragmx/functions/fnc_toggle_truing_drop.sqf index 2c61b1776ba..2d13619de08 100644 --- a/addons/atragmx/functions/fnc_toggle_truing_drop.sqf +++ b/addons/atragmx/functions/fnc_toggle_truing_drop.sqf @@ -15,7 +15,7 @@ * Public: No */ -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {}; if (ctrlVisible 18000) then { false call FUNC(show_truing_drop); diff --git a/addons/atragmx/functions/fnc_update_zero_range.sqf b/addons/atragmx/functions/fnc_update_zero_range.sqf index 023a5a7ee29..8a3eca13448 100644 --- a/addons/atragmx/functions/fnc_update_zero_range.sqf +++ b/addons/atragmx/functions/fnc_update_zero_range.sqf @@ -35,7 +35,7 @@ if (!GVAR(atmosphereModeTBH)) then { _relativeHumidity = 0.5; }; -private _scopeBaseAngle = if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) then { +private _scopeBaseAngle = if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZero:%1:%2:%3:%4", _zeroRange, _muzzleVelocity, _airFriction, _boreHeight]; (parseNumber _zeroAngle) } else { diff --git a/addons/attach/functions/fnc_handleKilled.sqf b/addons/attach/functions/fnc_handleKilled.sqf index ef08aff3058..2183b05b426 100644 --- a/addons/attach/functions/fnc_handleKilled.sqf +++ b/addons/attach/functions/fnc_handleKilled.sqf @@ -28,7 +28,7 @@ if (_attachedList isEqualTo []) exitWith {}; TRACE_2("detaching",_xObject,_deadUnit); detach _xObject; //If it's a vehicle, also delete the attached - if (!(_deadUnit isKindOf "CAManBase")) then { + if !(_deadUnit isKindOf "CAManBase") then { _xObject setPos ((getPos _deadUnit) vectorAdd [0, 0, -1000]); [{deleteVehicle (_this select 0)}, [_xObject], 2] call CBA_fnc_waitAndExecute; }; diff --git a/addons/ballistics/stringtable.xml b/addons/ballistics/stringtable.xml index aa746e543ff..a4c67c68d53 100644 --- a/addons/ballistics/stringtable.xml +++ b/addons/ballistics/stringtable.xml @@ -3540,6 +3540,7 @@ Utilisation de l'IA Utilização por IA Использование ИИ + Uso de la IA Illum @@ -3551,6 +3552,7 @@ Fusées éclairantes Sinalizadoras Осветители + Iluminación Smoke @@ -3562,6 +3564,7 @@ Fumigènes Fumígenas Дым + Humo Inf @@ -3573,6 +3576,7 @@ Infanterie Infantaria Пехота + Infantería Veh @@ -3584,6 +3588,7 @@ Véhicule Veículo Техника + Vehículo Armor @@ -3595,6 +3600,7 @@ Blindage Blindagem Бронетехника + Blindados Air @@ -3606,6 +3612,7 @@ Aviation Aeronaves Авиация + Aeronaves diff --git a/addons/captives/XEH_postInit.sqf b/addons/captives/XEH_postInit.sqf index 951a710771e..2580e724633 100644 --- a/addons/captives/XEH_postInit.sqf +++ b/addons/captives/XEH_postInit.sqf @@ -24,7 +24,7 @@ if (isServer) then { }]; }; -["unit", FUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; +["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; [QGVAR(moveInCaptive), LINKFUNC(vehicleCaptiveMoveIn)] call CBA_fnc_addEventHandler; [QGVAR(moveOutCaptive), LINKFUNC(vehicleCaptiveMoveOut)] call CBA_fnc_addEventHandler; diff --git a/addons/captives/functions/fnc_doEscortCaptive.sqf b/addons/captives/functions/fnc_doEscortCaptive.sqf index 817745ece3b..7eb25ccc4c5 100644 --- a/addons/captives/functions/fnc_doEscortCaptive.sqf +++ b/addons/captives/functions/fnc_doEscortCaptive.sqf @@ -44,7 +44,7 @@ if (_state) then { }; }; - if (!(_unit getVariable [QGVAR(isEscorting), false])) then { + if !(_unit getVariable [QGVAR(isEscorting), false]) then { [(_this select 1)] call CBA_fnc_removePerFrameHandler; [objNull, _target, false] call EFUNC(common,claim); detach _target; diff --git a/addons/captives/functions/fnc_setHandcuffed.sqf b/addons/captives/functions/fnc_setHandcuffed.sqf index c13da8f9274..0c54d9a70a7 100644 --- a/addons/captives/functions/fnc_setHandcuffed.sqf +++ b/addons/captives/functions/fnc_setHandcuffed.sqf @@ -58,7 +58,7 @@ if (_state) then { // fix anim on mission start (should work on dedicated servers) [{ params ["_unit"]; - if (!(_unit getVariable [QGVAR(isHandcuffed), false])) exitWith {}; + if !(_unit getVariable [QGVAR(isHandcuffed), false]) exitWith {}; if ((vehicle _unit) == _unit) then { [_unit] call EFUNC(common,fixLoweredRifleAnimation); diff --git a/addons/captives/functions/fnc_setSurrendered.sqf b/addons/captives/functions/fnc_setSurrendered.sqf index 393465e08eb..4acc8529bbd 100644 --- a/addons/captives/functions/fnc_setSurrendered.sqf +++ b/addons/captives/functions/fnc_setSurrendered.sqf @@ -81,7 +81,7 @@ if (_state) then { if (_unit == ACE_player) then { //only re-enable HUD if not handcuffed - if (!(_unit getVariable [QGVAR(isHandcuffed), false])) then { + if !(_unit getVariable [QGVAR(isHandcuffed), false]) then { ["captive", []] call EFUNC(common,showHud); //same as showHud true; }; }; diff --git a/addons/captives/stringtable.xml b/addons/captives/stringtable.xml index 174022ea11b..4fc86ec58fe 100644 --- a/addons/captives/stringtable.xml +++ b/addons/captives/stringtable.xml @@ -146,6 +146,7 @@ 포로 눈 가리기 目隠しをする Завязать глаза пленному + Vendar ojos al prisionero Remove blindfold @@ -156,6 +157,7 @@ 눈가리개 풀기 目隠しを外す Снять повязку с глаз + Quitar vendas de los ojos Cable Tie diff --git a/addons/cargo/CfgVehicles.hpp b/addons/cargo/CfgVehicles.hpp index 6f6a93e820b..66fa98159e3 100644 --- a/addons/cargo/CfgVehicles.hpp +++ b/addons/cargo/CfgVehicles.hpp @@ -48,15 +48,7 @@ class CfgVehicles { class Car: LandVehicle { GVAR(space) = 4; GVAR(hasCargo) = 1; - class ACE_Cargo { - /* - class Cargo { - class ACE_medicalSupplyCrate { - type = "ACE_medicalSupplyCrate"; - amount = 1; - }; - };*/ - }; + class ADDON {}; }; class Tank: LandVehicle { @@ -75,7 +67,7 @@ class CfgVehicles { GVAR(hasCargo) = 1; }; - // HEMTTs - Default at 10, some variants are altered based on model size and/or expected level of free space inside. + // HEMTTs - Default at 30, some variants are altered based on model size and/or expected level of free space inside. class Truck_01_base_F: Truck_F { GVAR(space) = 30; }; @@ -523,6 +515,7 @@ class CfgVehicles { class EventHandlers { class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; }; + GVAR(space) = 3; GVAR(hasCargo) = 1; GVAR(size) = 3; diff --git a/addons/cargo/functions/fnc_addCargoItem.sqf b/addons/cargo/functions/fnc_addCargoItem.sqf index 38ccdc0dd94..de262bdcfb5 100644 --- a/addons/cargo/functions/fnc_addCargoItem.sqf +++ b/addons/cargo/functions/fnc_addCargoItem.sqf @@ -7,9 +7,10 @@ * 0: Item to be loaded or * 1: Holder object (vehicle) * 2: Amount (default: 1) + * 3: Ignore interaction distance and stability checks (default: false) * * Return Value: - * None + * Objects loaded * * Example: * ["ACE_Wheel", cursorObject] call ace_cargo_fnc_addCargoItem @@ -17,21 +18,29 @@ * Public: No */ -params ["_item", "_vehicle", ["_amount", 1]]; -TRACE_3("params",_item,_vehicle,_amount); +params ["_item", "_vehicle", ["_amount", 1], ["_ignoreInteraction", false]]; +TRACE_4("params",_item,_vehicle,_amount,_ignoreInteraction); + +private _loaded = 0; // Get config sensitive case name if (_item isEqualType "") then { _item = _item call EFUNC(common,getConfigName); for "_i" from 1 to _amount do { - [_item, _vehicle] call FUNC(loadItem); + if !([_item, _vehicle, _ignoreInteraction] call FUNC(loadItem)) exitWith {}; + + _loaded = _loaded + 1; }; } else { - [_item, _vehicle] call FUNC(loadItem); + _loaded = parseNumber ([_item, _vehicle, _ignoreInteraction] call FUNC(loadItem)); _item = typeOf _item; }; +TRACE_1("loaded",_loaded); + // Invoke listenable event -["ace_cargoAdded", [_item, _vehicle, _amount]] call CBA_fnc_globalEvent; +["ace_cargoAdded", [_item, _vehicle, _loaded]] call CBA_fnc_globalEvent; + +_loaded // return diff --git a/addons/cargo/functions/fnc_initVehicle.sqf b/addons/cargo/functions/fnc_initVehicle.sqf index af80761fe0c..25cebe5b130 100644 --- a/addons/cargo/functions/fnc_initVehicle.sqf +++ b/addons/cargo/functions/fnc_initVehicle.sqf @@ -52,14 +52,21 @@ if (isServer) then { private _cargoClassname = ""; private _cargoCount = 0; + private _loaded = 0; { _cargoClassname = getText (_x >> "type"); _cargoCount = getNumber (_x >> "amount"); - TRACE_3("adding ACE_Cargo",configName _x,_cargoClassname,_cargoCount); + TRACE_3("adding ace_cargo",configName _x,_cargoClassname,_cargoCount); - ["ace_addCargo", [_cargoClassname, _vehicle, _cargoCount]] call CBA_fnc_localEvent; + // Ignore stability check (distance check is also ignored with this, but it's ignored by default if item is a string) + _loaded = [_cargoClassname, _vehicle, _cargoCount, true] call FUNC(addCargoItem); + + // Let loop continue until the end, so that it prints everything into the rpt (there might be smaller items that could still fit in cargo) + if (_loaded != _cargoCount) then { + WARNING_5("%1 (%2) could not fit %3 %4 inside its cargo, only %5 were loaded.",_vehicle,_type,_cargoCount,_cargoClassname,_loaded); + }; } forEach ("true" configClasses (_config >> QUOTE(ADDON) >> "cargo")); }; diff --git a/addons/cargo/initSettings.inc.sqf b/addons/cargo/initSettings.inc.sqf index 029a845a254..4f92934d46a 100644 --- a/addons/cargo/initSettings.inc.sqf +++ b/addons/cargo/initSettings.inc.sqf @@ -6,8 +6,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; [LSTRING(ModuleSettings_enable), LSTRING(ModuleSettings_enable_Description)], _category, true, - 1, - {[QGVAR(enable), _this] call EFUNC(common,cbaSettings_settingChanged)} + 1 ] call CBA_fnc_addSetting; [ @@ -16,8 +15,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; [LSTRING(loadTimeCoefficient), LSTRING(loadTimeCoefficient_description)], _category, [0, 10, 5, 1], - 1, - {[QGVAR(loadTimeCoefficient), _this, true] call EFUNC(common,cbaSettings_settingChanged)} + 1 ] call CBA_fnc_addSetting; [ @@ -26,8 +24,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; [LSTRING(paradropTimeCoefficent), LSTRING(paradropTimeCoefficent_description)], _category, [0, 10, 2.5, 1], - 1, - {[QGVAR(paradropTimeCoefficent), _this, true] call EFUNC(common,cbaSettings_settingChanged)} + 1 ] call CBA_fnc_addSetting; [ @@ -35,9 +32,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; "LIST", [LSTRING(openAfterUnload), LSTRING(openAfterUnload_description)], _category, - [[0, 1, 2, 3], [ELSTRING(common,never), LSTRING(unloadObject), LSTRING(paradropButton), ELSTRING(common,both)], 0], - 0, - {[QGVAR(openAfterUnload), _this, true] call EFUNC(common,cbaSettings_settingChanged)} + [[0, 1, 2, 3], [ELSTRING(common,never), LSTRING(unloadObject), LSTRING(paradropButton), ELSTRING(common,both)], 0] ] call CBA_fnc_addSetting; [ @@ -45,9 +40,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; "CHECKBOX", [LSTRING(carryAfterUnload), LSTRING(carryAfterUnload_description)], _category, - true, - 0, - {[QGVAR(carryAfterUnload), _this] call EFUNC(common,cbaSettings_settingChanged)} + true ] call CBA_fnc_addSetting; [ @@ -56,8 +49,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; [LSTRING(enableDeploy), LSTRING(enableDeploy_description)], _category, true, - 1, - {[QGVAR(enableDeploy), _this] call EFUNC(common,cbaSettings_settingChanged)} + 1 ] call CBA_fnc_addSetting; [ @@ -65,7 +57,5 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; "CHECKBOX", [LSTRING(ModuleSettings_enableRename), LSTRING(ModuleSettings_enableRename_Description)], _category, - true, - 0, - {[QGVAR(enableRename), _this, true] call EFUNC(common,cbaSettings_settingChanged)} + true ] call CBA_fnc_addSetting; diff --git a/addons/cargo/stringtable.xml b/addons/cargo/stringtable.xml index 0a766ab221d..4e8d707f611 100644 --- a/addons/cargo/stringtable.xml +++ b/addons/cargo/stringtable.xml @@ -40,6 +40,8 @@ 配置する 배치하기 Déployer + Aufstellen + Desplegar Raise/Lower | (Ctrl + Scroll) Rotate @@ -287,6 +289,7 @@ Загружаем %1 в %2... %1을(를) %2에 싣는 중... Chargement %1 dans %2... + %1 wird in %2 geladen... Unloading %1 from %2... @@ -296,6 +299,7 @@ Выгружаем %1 из %2... %1을(를) %2(으)로부터 내리는 중... Déchargement %1 de %2... + %1 wird von %2 entladen... %1<br/>could not be loaded @@ -337,6 +341,7 @@ 荷降ろし不可能です 하역할 수가 없습니다 Не может быть выгружен + No puede ser descargado Cargo Size: %1 @@ -346,6 +351,7 @@ 貨物のサイズ: %1 화물 크기: %1 Размер груза: %1 + Tamaño de carga: %1 Custom Name @@ -584,6 +590,8 @@ 配置機能を有効化 배치 활성화 Permettre le placement + Aktiviere Aufbauen + Habilitar despliegue Controls whether cargo items can be unloaded via the deploy method. @@ -592,6 +600,8 @@ 配置機能を介して貨物アイテムを降ろすことが出来るかどうかを制御します。 배치 방법을 통해 화물 아이템을 내릴 수 있는지 여부를 제어합니다. Contrôler si les éléments de cargaison peuvent être déchargés via la méthode de déploiement. + Steuert, ob Frachtgegenstände über die Aufbaumethode entladen werden können. + Controla si los objetos de la carga pueden ser descargados mediante el método de despliegue. diff --git a/addons/common/XEH_PREP.hpp b/addons/common/XEH_PREP.hpp index fb64d464df8..f46d1689f90 100644 --- a/addons/common/XEH_PREP.hpp +++ b/addons/common/XEH_PREP.hpp @@ -103,6 +103,7 @@ PREP(getWeaponAzimuthAndInclination); PREP(getWeaponIndex); PREP(getWeaponState); PREP(getWeight); +PREP(getWheelHitPointsWithSelections); PREP(getWindDirection); PREP(getZoom); PREP(goKneeling); @@ -161,6 +162,7 @@ PREP(sendRequest); PREP(serverLog); PREP(setAimCoef); PREP(setApproximateVariablePublic); +PREP(setDead); PREP(setDefinedVariable); PREP(setDisableUserInputStatus); PREP(setHearingCapability); @@ -264,6 +266,7 @@ PREP(_handleRequestAllSyncedEvents); PREP(addActionEventHandler); PREP(addActionMenuEventHandler); PREP(addMapMarkerCreatedEventHandler); +PREP(addPlayerEH); PREP(removeActionEventHandler); PREP(removeActionMenuEventHandler); diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index f97009808ff..b569a4608e4 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -145,7 +145,7 @@ if (isServer) then { INFO_3("[%1] DC - Was Zeus [%2] while controlling unit [%3] - manually clearing `bis_fnc_moduleRemoteControl_owner`",[_x] call FUNC(getName),_dcPlayer,_x); _x setVariable ["bis_fnc_moduleRemoteControl_owner", nil, true]; }; - } forEach (curatorEditableObjects _zeusLogic); + } forEach (curatorEditableObjects _zeusLogic); }; }]; }; @@ -191,6 +191,7 @@ if (isServer) then { [QGVAR(switchMove), {(_this select 0) switchMove (_this select 1)}] call CBA_fnc_addEventHandler; [QGVAR(setVectorDirAndUp), {(_this select 0) setVectorDirAndUp (_this select 1)}] call CBA_fnc_addEventHandler; [QGVAR(addWeaponItem), {(_this select 0) addWeaponItem [(_this select 1), (_this select 2)]}] call CBA_fnc_addEventHandler; +[QGVAR(removeMagazinesTurret), {(_this select 0) removeMagazinesTurret [_this select 1, _this select 2]}] call CBA_fnc_addEventHandler; [QGVAR(setVanillaHitPointDamage), { params ["_object", "_hitPointAnddamage"]; @@ -222,6 +223,9 @@ if (isServer) then { [QGVAR(claimSafe), LINKFUNC(claimSafeServer)] call CBA_fnc_addEventHandler; }; +["CBA_SettingChanged", { + ["ace_settingChanged", _this] call CBA_fnc_localEvent; +}] call CBA_fnc_addEventHandler; ////////////////////////////////////////////////// // Set up remote execution diff --git a/addons/common/XEH_preInit.sqf b/addons/common/XEH_preInit.sqf index 9b5d27d12ca..b559cb5dd90 100644 --- a/addons/common/XEH_preInit.sqf +++ b/addons/common/XEH_preInit.sqf @@ -10,6 +10,7 @@ PREP_RECOMPILE_END; GVAR(syncedEvents) = createHashMap; GVAR(showHudHash) = createHashMap; GVAR(vehicleIconCache) = createHashMap; // for getVehicleIcon +GVAR(wheelSelections) = createHashMap; GVAR(blockItemReplacement) = false; diff --git a/addons/common/dev/test_cfgPatches.sqf b/addons/common/dev/test_cfgPatches.sqf index e2ce10b2c6b..c5f3c81ef55 100644 --- a/addons/common/dev/test_cfgPatches.sqf +++ b/addons/common/dev/test_cfgPatches.sqf @@ -50,7 +50,7 @@ private _allWeapons = []; private _vics = "(configName _x) select [0,3] == 'ace'" configClasses (configFile >> "CfgVehicles"); { if (((getNumber (_x >> "scope")) == 2) || {((getNumber (_x >> "scopeCurator")) == 2)}) then { - if (!((toLowerANSI configName _x) in _allUnits)) then { + if !((toLowerANSI configName _x) in _allUnits) then { WARNING_2("Not in any units[] - %1 from %2",configName _x,configSourceMod _x); _testPass = false; }; @@ -62,7 +62,7 @@ private _weapons = "(configName _x) select [0,3] == 'ace'" configClasses (config { private _type = toLowerANSI configName _x; if (((getNumber (_x >> "scope")) == 2) || {((getNumber (_x >> "scopeCurator")) == 2)}) then { - if (!((toLowerANSI configName _x) in _allWeapons)) then { + if !((toLowerANSI configName _x) in _allWeapons) then { WARNING_2("Not in any weapons[] - %1 from %2",configName _x,configSourceMod _x); _testPass = false; }; diff --git a/addons/common/functions/fnc_actionKeysNamesConverted.sqf b/addons/common/functions/fnc_actionKeysNamesConverted.sqf index dd62fc87892..27c3597a9b3 100644 --- a/addons/common/functions/fnc_actionKeysNamesConverted.sqf +++ b/addons/common/functions/fnc_actionKeysNamesConverted.sqf @@ -43,10 +43,10 @@ if (isNil "_keyTable") then { }; }; -private _keyCache = uiNamespace getVariable [QGVAR(keyNameCache), locationNull]; +private _keyCache = uiNamespace getVariable QGVAR(keyNameCache); // @TODO: Move cache creation to preStart/somewhere else -if (isNull _keyCache) then { - _keyCache = call CBA_fnc_createNamespace; +if (isNil "_keyCache") then { + _keyCache = createHashMap; uiNamespace setVariable [QGVAR(keyNameCache), _keyCache]; }; @@ -54,7 +54,7 @@ params [["_action", "", [""]]]; private _keybinds = actionKeysNamesArray _action apply { private _keyName = _x; - private _keybind = _keyCache getVariable _keyName; + private _keybind = _keyCache get _keyName; if (isNil "_keybind") then { private _key = -1; @@ -101,7 +101,7 @@ private _keybinds = actionKeysNamesArray _action apply { // cache _keybind = [_key, _shift, _ctrl, _alt]; - _keyCache setVariable [_keyName, _keybind]; + _keyCache set [_keyName, _keybind]; }; _keybind diff --git a/addons/common/functions/fnc_addPlayerEH.sqf b/addons/common/functions/fnc_addPlayerEH.sqf new file mode 100644 index 00000000000..81d030fb62a --- /dev/null +++ b/addons/common/functions/fnc_addPlayerEH.sqf @@ -0,0 +1,61 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Adds event handler just to ACE_player + * + * Arguments: + * 0: Key + * 1: Event Type + * 2: Event Code + * 3: Ignore Virtual Units (spectators, virtual zeus, uav RC) (default: false) + * + * Return Value: + * None + * + * Example: + * ["example", "FiredNear", {systemChat str _this}] call ace_common_fnc_addPlayerEH + * + * Public: Yes +*/ +params [["_key", "", [""]], ["_type", "", [""]], ["_code", {}, [{}]], ["_ignoreVirtual", false, [false]]]; +TRACE_3("addPlayerEH",_key,_type,_ignoreVirtual); + +if (isNil QGVAR(playerEventsHash)) then { // first-run init + GVAR(playerEventsHash) = createHashMap; + ["unit", { + params ["_newPlayer", "_oldPlayer"]; + // uav check only applies to direct controlling UAVs from zeus, no effect on normal UAV operation + private _isVirutal = (unitIsUAV _newPlayer) || {getNumber (configOf _newPlayer >> "isPlayableLogic") == 1}; + + TRACE_4("",_newPlayer,_oldPlayer,_isVirutal,count GVAR(playerEventsHash)); + { + _y params ["_type", "_code", "_ignoreVirtual"]; + + private _oldEH = _oldPlayer getVariable [_x, -1]; + if (_oldEH != -1) then { + _oldPlayer removeEventHandler [_type, _oldEH]; + _oldPlayer setVariable [_x, nil]; + }; + + _oldEH = _newPlayer getVariable [_x, -1]; + if (_oldEH != -1) then { continue }; // if respawned then var and EH already exists + if (_ignoreVirtual && _isVirutal) then { continue }; + + private _newEH = _newPlayer addEventHandler [_type, _code]; + _newPlayer setVariable [_x, _newEH]; + } forEach GVAR(playerEventsHash); + }, false] call CBA_fnc_addPlayerEventHandler; +}; + + +_key = format [QGVAR(playerEvents_%1), toLower _key]; +if (_key in GVAR(playerEventsHash)) exitWith { ERROR_1("bad key %1",_this); }; + +GVAR(playerEventsHash) set [_key, [_type, _code, _ignoreVirtual]]; + +if (isNull ACE_player) exitWith {}; +if (_ignoreVirtual && {(unitIsUAV ACE_player) || {getNumber (configOf ACE_player >> "isPlayableLogic") == 1}}) exitWith {}; + +// Add event now +private _newEH = ACE_player addEventHandler [_type, _code]; +ACE_player setVariable [_key, _newEH]; diff --git a/addons/common/functions/fnc_addWeapon.sqf b/addons/common/functions/fnc_addWeapon.sqf index 16ae92c4f5d..787c9fb24ad 100644 --- a/addons/common/functions/fnc_addWeapon.sqf +++ b/addons/common/functions/fnc_addWeapon.sqf @@ -2,22 +2,33 @@ /* * Author: commy2, johnb43 * Adds weapon to unit without taking a magazine. - * Same as CBA_fnc_addWeaponWithoutItems, but doesn't remove linked items. + * Same as CBA_fnc_addWeaponWithoutItems, but doesn't remove linked items by default. * * Arguments: - * 0: Unit to add the weapon to + * 0: Unit to add the weapon to * 1: Weapon to add + * 2: If linked items should be removed or not (default: false) + * 3: Magazines that should be added to the weapon (default: []) + * - 0: Magazine classname + * - 1: Ammo count * * Return Value: * None * * Example: - * [player, "arifle_AK12_F"] call ace_common_fnc_addWeapon + * [player, "arifle_MX_GL_F", true, [["30Rnd_65x39_caseless_mag", 30], ["1Rnd_HE_Grenade_shell", 1]]] call ace_common_fnc_addWeapon * * Public: Yes */ -params ["_unit", "_weapon"]; +params [ + ["_unit", objNull, [objNull]], + ["_weapon", "", [""]], + ["_removeLinkedItems", false, [false]], + ["_magazines", [], [[]]] +]; + +if (isNull _unit || {_weapon == ""}) exitWith {}; // Config case private _compatibleMagazines = compatibleMagazines _weapon; @@ -45,6 +56,35 @@ private _backpackMagazines = (magazinesAmmoCargo _backpack) select { // Add weapon _unit addWeapon _weapon; +// This doesn't remove magazines, but linked items can't be magazines, so it's fine +if (_removeLinkedItems) then { + switch (_weapon call FUNC(getConfigName)) do { + case (primaryWeapon _unit): { + removeAllPrimaryWeaponItems _unit; + }; + case (secondaryWeapon _unit): { + removeAllSecondaryWeaponItems _unit; + }; + case (handgunWeapon _unit): { + removeAllHandgunItems _unit; + }; + case (binocular _unit): { + removeAllBinocularItems _unit; + }; + }; +}; + +// Add magazines directly now, so that AI don't reload +if (_magazines isNotEqualTo []) then { + { + _x params [["_magazine", "", [""]], ["_ammoCount", -1, [0]]]; + + if (_magazine != "" && {_ammoCount > -1}) then { + _unit addWeaponItem [_weapon, [_magazine, _ammoCount], true]; + }; + } forEach _magazines; +}; + // Add all magazines back { _uniform addMagazineAmmoCargo [_x select 0, 1, _x select 1]; diff --git a/addons/common/functions/fnc_cbaSettings_settingChanged.sqf b/addons/common/functions/fnc_cbaSettings_settingChanged.sqf index 43711d4c970..cf9f18166ab 100644 --- a/addons/common/functions/fnc_cbaSettings_settingChanged.sqf +++ b/addons/common/functions/fnc_cbaSettings_settingChanged.sqf @@ -1,8 +1,8 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Function for handeling a cba setting being changed. - * Adds warning if global setting is changed after ace_settingsInitialized + * Function for handling a cba setting being changed. + * Adds warning if global setting is changed after ace_settingsInitialized. * * Arguments: * 0: Setting Name @@ -21,9 +21,7 @@ params ["_settingName", "_newValue", ["_canBeChanged", false]]; TRACE_2("",_settingName,_newValue); -["ace_settingChanged", [_settingName, _newValue]] call CBA_fnc_localEvent; - -if (!((toLower _settingName) in CBA_settings_needRestart)) exitWith {}; +if !((toLower _settingName) in CBA_settings_needRestart) exitWith {}; if (_canBeChanged) exitWith {WARNING_1("update cba setting [%1] to use correct Need Restart param",_settingName);}; if (!GVAR(settingsInitFinished)) exitWith {}; // Ignore changed event before CBA_settingsInitialized diff --git a/addons/common/functions/fnc_defineVariable.sqf b/addons/common/functions/fnc_defineVariable.sqf index 6cf537b1f8b..85eb7b447f2 100644 --- a/addons/common/functions/fnc_defineVariable.sqf +++ b/addons/common/functions/fnc_defineVariable.sqf @@ -24,7 +24,7 @@ params ["_name", "_value", "_defaultGlobal", "_category", ["_code", 0], ["_persi if (isNil "_defaultGlobal") exitWith {}; -if (!(_name isEqualType "")) exitwith { +if !(_name isEqualType "") exitwith { [format ["Tried to the deinfe a variable with an invalid name: %1 Arguments: %2", _name, _this]] call FUNC(debug); }; diff --git a/addons/common/functions/fnc_disableUserInput.sqf b/addons/common/functions/fnc_disableUserInput.sqf index 8db3c7e8110..b89750e656e 100644 --- a/addons/common/functions/fnc_disableUserInput.sqf +++ b/addons/common/functions/fnc_disableUserInput.sqf @@ -143,11 +143,7 @@ if (_state) then { _ctrl ctrlSetEventHandler ["ButtonClick", toString { closeDialog 0; - if (["ace_medical"] call FUNC(isModLoaded)) then { - [player, "respawn_button"] call EFUNC(medical_status,setDead); - } else { - player setDamage 1; - }; + [player, "respawn_button"] call FUNC(setDead); [false] call FUNC(disableUserInput); }]; diff --git a/addons/common/functions/fnc_errorMessage.sqf b/addons/common/functions/fnc_errorMessage.sqf index 021fdba10cc..72344299f39 100644 --- a/addons/common/functions/fnc_errorMessage.sqf +++ b/addons/common/functions/fnc_errorMessage.sqf @@ -137,11 +137,11 @@ if (_onCancel isEqualTo {}) then { ctrlSetFocus _ctrlButtonCancel; }; -_ctrlButtonOK ctrlAddEventHandler ["buttonClick", {(ctrlParent (_this select 0)) closeDisplay 1; true}]; -_ctrlButtonCancel ctrlAddEventHandler ["buttonClick", {(ctrlParent (_this select 0)) closeDisplay 2; true}]; +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", {(ctrlParent (_this select 0)) closeDisplay 1; true}]; +_ctrlButtonCancel ctrlAddEventHandler ["ButtonClick", {(ctrlParent (_this select 0)) closeDisplay 2; true}]; GVAR(errorOnOK) = _onOK; GVAR(errorOnCancel) = _onCancel; -_display displayAddEventHandler ["unload", {call ([{}, GVAR(errorOnOK), GVAR(errorOnCancel)] select (_this select 1))}]; -_display displayAddEventHandler ["keyDown", {_this select 1 == 1}]; +_display displayAddEventHandler ["Unload", {call ([{}, GVAR(errorOnOK), GVAR(errorOnCancel)] select (_this select 1))}]; +_display displayAddEventHandler ["KeyDown", {_this select 1 == 1}]; diff --git a/addons/common/functions/fnc_getSettingData.sqf b/addons/common/functions/fnc_getSettingData.sqf index a2dceb746c4..eeb8dff1d8a 100644 --- a/addons/common/functions/fnc_getSettingData.sqf +++ b/addons/common/functions/fnc_getSettingData.sqf @@ -32,7 +32,6 @@ scopeName "main"; if (_x select 0 == _name) then { _x breakOut "main"; }; - false -} count GVAR(settings); +} forEach GVAR(settings); [] diff --git a/addons/common/functions/fnc_getWheelHitPointsWithSelections.sqf b/addons/common/functions/fnc_getWheelHitPointsWithSelections.sqf new file mode 100644 index 00000000000..2194c2aca05 --- /dev/null +++ b/addons/common/functions/fnc_getWheelHitPointsWithSelections.sqf @@ -0,0 +1,104 @@ +#include "..\script_component.hpp" +/* + * Author: commy2, johnb43 + * Returns the wheel hitpoints and their selections. + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * 0: Wheel hitpoints + * 1: Wheel hitpoint selections + * + * Example: + * cursorObject call ace_common_fnc_getWheelHitPointsWithSelections + * + * Public: No + */ + +params ["_vehicle"]; +TRACE_1("params",_vehicle); + +// TODO: Fix for GM vehicles +GVAR(wheelSelections) getOrDefaultCall [typeOf _vehicle, { + // Get the vehicles wheel config + private _wheels = configOf _vehicle >> "Wheels"; + + if (isClass _wheels) then { + // Get all hitpoints and selections + (getAllHitPointsDamage _vehicle) params ["_hitPoints", "_hitPointSelections"]; + + // Get all wheels and read selections from config + _wheels = "true" configClasses _wheels; + + private _wheelHitPoints = []; + private _wheelHitPointSelections = []; + + { + private _wheelName = configName _x; + private _wheelCenter = getText (_x >> "center"); + private _wheelBone = getText (_x >> "boneName"); + private _wheelBoneNameResized = _wheelBone select [0, 9]; // Count "wheel_X_Y"; // this is a requirement for physx. Should work for all addon vehicles. + + TRACE_4("",_wheelName,_wheelCenter,_wheelBone,_wheelBoneNameResized); + + private _wheelHitPoint = ""; + private _wheelHitPointSelection = ""; + + // Commy's orginal method + { + if ((_wheelBoneNameResized != "") && {_x find _wheelBoneNameResized == 0}) exitWith { // same as above. Requirement for physx. + _wheelHitPoint = _hitPoints select _forEachIndex; + _wheelHitPointSelection = _hitPointSelections select _forEachIndex; + TRACE_2("wheel found [Orginal]",_wheelName,_wheelHitPoint); + }; + } forEach _hitPointSelections; + + + if (_vehicle isKindOf "Car") then { + // Backup method, search for the closest hitpoint to the wheel's center selection pos. + // Ref #2742 - RHS's HMMWV + if (_wheelHitPoint == "") then { + private _wheelCenterPos = _vehicle selectionPosition _wheelCenter; + if (_wheelCenterPos isEqualTo [0, 0, 0]) exitWith {TRACE_1("no center?",_wheelCenter);}; + + + private _bestDist = 99; + private _bestIndex = -1; + { + if (_x != "") then { + // Filter out things that definitly aren't wheeels (#3759) + if ((toLowerANSI (_hitPoints select _forEachIndex)) in ["hitengine", "hitfuel", "hitbody"]) exitWith {TRACE_1("filter",_x)}; + private _xPos = _vehicle selectionPosition _x; + if (_xPos isEqualTo [0, 0, 0]) exitWith {}; + private _xDist = _wheelCenterPos distance _xPos; + if (_xDist < _bestDist) then { + _bestIndex = _forEachIndex; + _bestDist = _xDist; + }; + }; + } forEach _hitPointSelections; + + TRACE_2("closestPoint",_bestDist,_bestIndex); + if (_bestIndex != -1) then { + _wheelHitPoint = _hitPoints select _bestIndex; + _wheelHitPointSelection = _hitPointSelections select _bestIndex; + TRACE_2("wheel found [Backup]",_wheelName,_wheelHitPoint); + }; + }; + }; + + if ((_wheelHitPoint != "") && {_wheelHitPointSelection != ""}) then { + _wheelHitPoints pushBack _wheelHitPoint; + _wheelHitPointSelections pushBack _wheelHitPointSelection; + }; + } forEach _wheels; + + [_wheelHitPoints, _wheelHitPointSelections] + } else { + // Exit with nothing if the vehicle has no wheels class + TRACE_1("No Wheels",_wheels); + + [[], []] + } +}, true] // return diff --git a/addons/common/functions/fnc_registerItemReplacement.sqf b/addons/common/functions/fnc_registerItemReplacement.sqf index ce2fd7e393b..f1e068c322f 100644 --- a/addons/common/functions/fnc_registerItemReplacement.sqf +++ b/addons/common/functions/fnc_registerItemReplacement.sqf @@ -20,15 +20,23 @@ params [["_oldItem", "", [0,""]], ["_newItems", "", ["", []]], ["_replaceInherited", false, [false]]]; TRACE_3("registerItemReplacement",_oldItem,_newItems,_replaceInherited); - // Setup on first run if (isNil QGVAR(itemReplacements)) then { - GVAR(itemReplacements) = [] call CBA_fnc_createNamespace; + GVAR(itemReplacements) = createHashMap; GVAR(inheritedReplacements) = []; GVAR(oldItems) = []; ["loadout", LINKFUNC(replaceRegisteredItems)] call CBA_fnc_addPlayerEventHandler; }; +// Get config case - if item doesn't exist, "" is returned +if (_oldItem isEqualType "") then { + _oldItem = _oldItem call FUNC(getConfigName); +}; + +if (_oldItem isEqualTo "") exitWith { + ERROR("Item doesn't exist"); +}; + // Save item replacement // $ prefix is used for types (numbers) and replacements with inheritance if (_replaceInherited) then { @@ -42,9 +50,8 @@ if (_newItems isEqualType "") then { _newItems = [_newItems]; }; -private _oldReplacements = GVAR(itemReplacements) getVariable [_oldItem, []]; +private _oldReplacements = GVAR(itemReplacements) getOrDefault [_oldItem, [], true]; _oldReplacements append _newItems; -GVAR(itemReplacements) setVariable [_oldItem, _oldReplacements]; // Force item scan when new replacement was registered in PostInit if !(isNull ACE_player) then { diff --git a/addons/common/functions/fnc_replaceRegisteredItems.sqf b/addons/common/functions/fnc_replaceRegisteredItems.sqf index bfe2e493e01..baa591c8d89 100644 --- a/addons/common/functions/fnc_replaceRegisteredItems.sqf +++ b/addons/common/functions/fnc_replaceRegisteredItems.sqf @@ -42,7 +42,7 @@ for "_i" from 0 to count _newItems - 1 do { private _replacements = []; // Determine replacement items: direct replacements, ... - private _directReplacements = GVAR(itemReplacements) getVariable _item; + private _directReplacements = GVAR(itemReplacements) get _item; if (!isNil "_directReplacements") then { _doReplace = true; _replacements append _directReplacements; @@ -50,7 +50,7 @@ for "_i" from 0 to count _newItems - 1 do { // ... item type replacements ... private _type = getNumber (_cfgWeapons >> _item >> "ItemInfo" >> "type"); - private _typeReplacements = GVAR(itemReplacements) getVariable ("$" + str _type); + private _typeReplacements = GVAR(itemReplacements) get ("$" + str _type); if (!isNil "_typeReplacements") then { _doReplace = true; _replacements append _typeReplacements; @@ -59,7 +59,7 @@ for "_i" from 0 to count _newItems - 1 do { // ... and inherited replacements { if (_item isKindOf [_x, _cfgWeapons]) then { - private _inheritedReplacements = GVAR(itemReplacements) getVariable _x; + private _inheritedReplacements = GVAR(itemReplacements) get _x; if (!isNil "_inheritedReplacements") then { _doReplace = true; _replacements append _inheritedReplacements; diff --git a/addons/common/functions/fnc_setDead.sqf b/addons/common/functions/fnc_setDead.sqf new file mode 100644 index 00000000000..f6d62abd349 --- /dev/null +++ b/addons/common/functions/fnc_setDead.sqf @@ -0,0 +1,44 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Kills a unit without changing visual appearance. + * + * Arguments: + * 0: Unit + * 1: Reason for death (only used if ace_medical is loaded) (default: "") + * 2: Killer (vehicle that killed unit) (default: objNull) + * 3: Instigator (unit who pulled trigger) (default: objNull) + * + * Return Value: + * None + * + * Example: + * [cursorObject, "", player, player] call ace_common_fnc_setDead; + * + * Public: Yes + */ + +params [["_unit", objNull, [objNull]], ["_reason", "", [""]], ["_source", objNull, [objNull]], ["_instigator", objNull, [objNull]]]; + +if (!local _unit) exitWith { + WARNING_1("setDead executed on non-local unit - %1",_this); +}; + +if (GETEGVAR(medical,enabled,false)) then { + [_unit, _reason, _source, _instigator] call EFUNC(medical_status,setDead); +} else { + // From 'ace_medical_status_fnc_setDead': Kill the unit without changing visual appearance + + // (#8803) Reenable damage if disabled to prevent having live units in dead state + // Keep this after death event for compatibility with third party hooks + if (!isDamageAllowed _unit) then { + WARNING_1("setDead executed on unit with damage blocked - %1",_this); + _unit allowDamage true; + }; + + private _currentDamage = _unit getHitPointDamage "HitHead"; + + _unit setHitPointDamage ["HitHead", 1, true, _source, _instigator]; + + _unit setHitPointDamage ["HitHead", _currentDamage, true, _source, _instigator]; +}; diff --git a/addons/common/functions/fnc_showHud.sqf b/addons/common/functions/fnc_showHud.sqf index 1ca7ca81068..5bb0153772d 100644 --- a/addons/common/functions/fnc_showHud.sqf +++ b/addons/common/functions/fnc_showHud.sqf @@ -56,7 +56,7 @@ private _resultMask = []; for "_index" from 0 to 9 do { private _set = true; //Default to true { - if (!(_x select _index)) exitWith { + if !(_x select _index) exitWith { _set = false; //Any false will make it false }; } forEach _masks; diff --git a/addons/common/stringtable.xml b/addons/common/stringtable.xml index 1c960e91739..96ad037cc11 100644 --- a/addons/common/stringtable.xml +++ b/addons/common/stringtable.xml @@ -1834,6 +1834,9 @@ 무기 흔들림 Oscillation de l'arme Колебание оружия + Waffen schwanken + Oscilación del arma + Oscillazione arma Enable Weapon Sway @@ -1841,6 +1844,9 @@ 무기 흔들림 추가 Activer l'oscillation de l'arme Включить колебание оружия + Aktiviere Waffen schwanken + Habilitar oscilación del arma + Abilita oscillazione arma Enables weapon sway influenced by sway factors, such as stance, fatigue and medical condition.\nDisabling this setting will defer sway to vanilla or other mods. @@ -1848,6 +1854,9 @@ 흔들림 계수, 자세, 피로도, 건강 상태 등의 요인에 영향을 받는 무기 흔들림을 활성화합니다.\n이 설정을 비활성화하면 바닐라 또는 다른 모드의 흔들림으로 대체됩니다. Active l'oscillation de l'arme influencé par les facteurs d'oscillation, tels que la position, la fatigue et l'état de santé.\nLa désactivation de ce paramètre reportera l'oscillation à vanilla ou à d'autres mods. Активируйте колебание оружия в зависимости от таких факторов, как стойка, усталость и состояние здоровья.\nОтключение этого параметра приведет к переносу раскачивания на vanilla или другие моды. + Ermöglicht die Beeinflussung des Waffen-Schwankens durch Beeinflussungsfaktoren wie Haltung, Müdigkeit und Gesundheitszustand.\nDie Deaktivierung dieser Einstellung erlaubt die Beeinflussung durch Vanilla oder andere Mods. + Habilita la oscilación del arma afectado por factores como la postura, la fatiga y la condición médica.\nDeshabilitar esta opción hará que el comportamiento de la oscilación venga definido por Vanilla o por otros mods. + Abilita l'oscillazione ACE, influenzata da fattori come postura, fatica e condizione medica.\nDisabilitare questa impostazione farà controllare l'oscillazione al gioco vanilla o altre mod. Sway factor @@ -1888,6 +1897,7 @@ Fattore di Oscillazione Appoggiato 静止依託時の手ぶれ係数 Коэффициент колебания прицела в состоянии покоя + Factor de oscilación apoyado Influences the amount of weapon sway while weapon is rested. @@ -1898,6 +1908,7 @@ Determina la quantità di oscillazione dell'arma quando questa è appoggiata. 静止し壁などに依託している時の武器の手ぶれの大きさに影響します。 Влияет на величину колебания прицела оружия в состоянии покоя. + Afecta la cantidad de oscilación del arma cuando se está apoyado. Deployed sway factor @@ -1908,6 +1919,7 @@ Fattore di Oscillazione su Bipode 接地展開時の手ぶれ係数 Коэффициент колебания прицела при развертывании + Factor de oscilación desplegado Influences the amount of weapon sway while weapon is deployed. @@ -1918,6 +1930,7 @@ Determina la quantità di oscillazione dell'arma quando questa è stabilizzata usando il bipode. 武器の接地展開時の武器の手ぶれの大きさに影響します。 Влияет на величину колебания прицела оружия при его развертывании. + Afecta la cantidad de oscilación del arma cuando se está desplegado. diff --git a/addons/compat_cup_terrains/CfgVehicles.hpp b/addons/compat_cup_terrains/CfgVehicles.hpp index 08176b77fed..3fbd69f2913 100644 --- a/addons/compat_cup_terrains/CfgVehicles.hpp +++ b/addons/compat_cup_terrains/CfgVehicles.hpp @@ -1,3 +1,6 @@ +class CBA_Extended_EventHandlers; +#define XEH_INHERITED class EventHandlers {class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {};} + class CfgVehicles { class House; class House_Small_F; @@ -5,7 +8,7 @@ class CfgVehicles { class House_EP1: House {}; class Land_Benzina_schnell: House { - transportFuel = 0; + XEH_INHERITED; EGVAR(refuel,hooks)[] = {{-1.5,-3.93,-1.25}, {2.35,-3.93,-1.25}}; EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; class ACE_Actions { @@ -18,22 +21,22 @@ class CfgVehicles { }; }; class Land_A_FuelStation_Feed: Strategic { - transportFuel = 0; + XEH_INHERITED; EGVAR(refuel,hooks)[] = {{-0.34,0,0}, {0.34,0,0}}; EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_Ind_FuelStation_Feed_EP1: House_EP1 { - transportFuel = 0; + XEH_INHERITED; EGVAR(refuel,hooks)[] = {{-0.34,0,0}, {0.34,0,0}}; EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_FuelStation_Feed_PMC: Strategic { - transportFuel = 0; + XEH_INHERITED; EGVAR(refuel,hooks)[] = {{-0.34,0,0}, {0.34,0,0}}; EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; }; class FuelStation: House_Small_F { - transportFuel = 0; + XEH_INHERITED; EGVAR(refuel,hooks)[] = {{1.25, .2, -1.1}}; EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; class ACE_Actions { @@ -45,4 +48,9 @@ class CfgVehicles { }; }; }; + class WarfareBBaseStructure; + class Base_WarfareBVehicleServicePoint: WarfareBBaseStructure { + // "vehicle service point" (a conex /w barrels) - need hooks??? + XEH_INHERITED; + }; }; diff --git a/addons/compat_cup_units/CfgGlasses.hpp b/addons/compat_cup_units/CfgGlasses.hpp new file mode 100644 index 00000000000..1620f74212b --- /dev/null +++ b/addons/compat_cup_units/CfgGlasses.hpp @@ -0,0 +1,492 @@ +class CfgGlasses { + + #define ESS_OVERLAY \ + ace_overlay = QPATHTOEF(goggles,textures\hud\combatgoggles.paa); \ + ace_overlayCracked = QPATHTOEF(goggles,textures\hud\combatgogglescracked.paa) + + class None; + class CUP_G_PMC_RadioHeadset_Glasses; + + // ESS Goggles - Dark + class CUP_G_ESS_BLK_Dark: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Blk: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Blk_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Blk_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Face_Blk: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_CBR_Dark: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Dark: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_RGR_Dark: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + + // ESS Goggles - Ember + class CUP_G_ESS_BLK_Ember: None { + ace_color[] = {1, 0, 0}; + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_CBR_Ember: None { + ace_color[] = {1, 0, 0}; + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_RGR_Ember: None { + ace_color[] = {1, 0, 0}; + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Ember: None { + ace_color[] = {1, 0, 0}; + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Facewrap_White: None { + ace_color[] = {1, 0, 0}; + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + + // ESS Goggles - Clear + class CUP_G_ESS_BLK: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_CBR: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_RGR: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Facewrap_Black: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Facewrap_Black_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Face_Grn: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Face_Grn_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Face_Red: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Face_White: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Face_White_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Grn: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Grn_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Grn_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Grn_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Grn_GPS_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Grn_GPS_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Red: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Red_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Red_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_White: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_White_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_White_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_White_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_White_GPS_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_White_GPS_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_CBR_Facewrap_Red: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Facewrap_Tan: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Face_Tan: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Face_Tan_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Tan: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Tan_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Tan_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Tan_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Tan_GPS_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Tan_GPS_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_RGR_Facewrap_Ranger: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_RGR_Facewrap_Skull: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_RGR_Facewrap_Tropical: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + + // Oakleys - Dark + class CUP_G_Oakleys_Drk: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Black_Glasses_Dark: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Black_Glasses_Dark_Headset: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Tan_Glasses_Dark: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Tan_Glasses_Dark_Headset: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Tropical_Glasses_Dark: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Tropical_Glasses_Dark_Headset: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Winter_Glasses_Dark: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Winter_Glasses_Dark_Headset: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_RadioHeadset_Glasses_Dark: CUP_G_PMC_RadioHeadset_Glasses { + ace_resistance = 1; + ace_tintAmount = 8; + }; + + // Oakleys - Ember + class CUP_G_Oakleys_Embr: None { + ace_color[] = {1, 0, 0}; + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Black_Glasses_Ember: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_color[] = {1, 0, 0}; + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Tan_Glasses_Ember: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_color[] = {1, 0, 0}; + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Tropical_Glasses_Ember: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_color[] = {1, 0, 0}; + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Winter_Glasses_Ember: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_color[] = {1, 0, 0}; + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_RadioHeadset_Glasses_Ember: CUP_G_PMC_RadioHeadset_Glasses { + ace_color[] = {1, 0, 0}; + ace_resistance = 1; + ace_tintAmount = 8; + }; + + // Shades - Dark + class CUP_G_Beard_Shades_Black: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_Beard_Shades_Blonde: CUP_G_Beard_Shades_Black { + ace_resistance = 1; + ace_tintAmount = 8; + }; + + // Shades - Clear + class CUP_G_Grn_Scarf_Shades: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_GPS: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_GPS_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_GPS_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_GPSCombo: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_GPSCombo_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_GPSCombo_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_GPS: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_GPS_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_GPS_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_GPSCombo: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_GPSCombo_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_GPSCombo_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_GPS: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_GPS_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_GPS_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_GPSCombo: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_GPSCombo_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_GPSCombo_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + + // Thug - Dark + class CUP_PMC_G_thug: None { + ace_tintAmount = 8; + }; +}; diff --git a/addons/compat_cup_units/config.cpp b/addons/compat_cup_units/config.cpp index bde1052a110..c3ba110e742 100644 --- a/addons/compat_cup_units/config.cpp +++ b/addons/compat_cup_units/config.cpp @@ -15,4 +15,5 @@ class CfgPatches { }; }; +#include "CfgGlasses.hpp" #include "CfgWeapons.hpp" 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 186690908c2..1042c0eacf3 100644 --- a/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/CfgVehicles.hpp +++ b/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/CfgVehicles.hpp @@ -1,35 +1,30 @@ class CfgVehicles { class CUP_T810_Unarmed_Base; class CUP_T810_Refuel_Base: CUP_T810_Unarmed_Base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-1.01, 0.21, -0.5},{1.08, 0.2, -0.5}}; EGVAR(refuel,fuelCargo) = 10000; }; class Truck_02_fuel_base_F; class CUP_Kamaz_5350_Refuel_Base: Truck_02_fuel_base_F { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-0.02, -3.33, -1.05}}; EGVAR(refuel,fuelCargo) = 10000; }; class CUP_Ural_Support_Base; class CUP_Ural_Refuel_Base: CUP_Ural_Support_Base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-0.05, -3.65, -0.42}}; EGVAR(refuel,fuelCargo) = 10000; }; class CUP_V3S_Open_Base; class CUP_V3S_Refuel_Base: CUP_V3S_Open_Base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-0.35, -3.35, -0.4},{0.40, -3.35, -0.4}}; EGVAR(refuel,fuelCargo) = 6500; }; class CUP_MTVR_Base; class CUP_MTVR_Refuel_Base: CUP_MTVR_Base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-1.09, -0.01, -0.5},{1, -0.01, -0.5}}; EGVAR(refuel,fuelCargo) = 10000; }; 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 a23cf87af02..112c3356389 100644 --- a/addons/compat_cup_weapons/compat_cup_weapons_csw/stringtable.xml +++ b/addons/compat_cup_weapons/compat_cup_weapons_csw/stringtable.xml @@ -6,36 +6,48 @@ [CSW] AGS30 ベルト [CSW] Лента AGS 30 [CSW] AGS-30 벨트 + [CSW] AGS30 Gurt + [CSW] Cinta de AGS30 [CSW] MK19 Belt [CSW] Mk19 ベルト [CSW] Лента Mk19 [CSW] Mk.19 벨트 + [CSW] MK19 Gurt + [CSW] Cinta de MK19 [CSW] TOW Tube [CSW] TOW チューブ [CSW] Туба TOW [CSW] TOW 튜브 + [CSW] TOW Rohr + [CSW] Tubo de TOW [CSW] TOW2 Tube [CSW] TOW2 チューブ [CSW] Туба TOW-2 [CSW] TOW2 튜브 + [CSW] TOW2 Rohr + [CSW] Tubo de TOW2 [CSW] PG-9 Round [CSW] PG-9 砲弾 [CSW] Снаряд ПГ-9 [CSW] PG-9 대전차고폭탄 + [CSW] PG-9 Rakete + [CSW] Carga de PG-9 [CSW] OG-9 Round [CSW] OG-9 砲弾 [CSW] Снаряд OГ-9 [CSW] OG-9 고폭파편탄 + [CSW] OG-9 Rakete + [CSW] Carga de OG-9 [CSW] M1 HE @@ -43,6 +55,8 @@ [CSW] M1 HE [CSW] M1 고폭탄 [CSW] M1 HE + [CSW] M1 HE + [CSW] HE de M1 [CSW] M84 Smoke @@ -50,6 +64,8 @@ [CSW] M84 Дымовая [CSW] M84 연막탄 [CSW] M84 Fumigène + [CSW] M84 Rauch + [CSW] Humo M84 [CSW] M60A2 WP @@ -57,6 +73,8 @@ [CSW] M60A2 WP [CSW] M60A2 백린연막탄 [CSW] M60A2 WP + [CSW] M60A2 WP + [CSW] M60A2 WP [CSW] M67 AT Laser Guided @@ -64,6 +82,8 @@ [CSW] M67 AT Laser Guided [CSW] M67 레이저유도 대전차탄 [CSW] M67 AT Guidé laser + [CSW] M67 AT Lasergelenkt + [CSW] AT Guiado por Láser M67 [CSW] M314 Illumination @@ -71,6 +91,8 @@ [CSW] M314 Осветительная [CSW] M314 조명탄 [CSW] M314 Illumination + [CSW] M314 Beleuchtung + [CSW] Iluminación M314 [CSW] 3OF56 HE @@ -78,6 +100,8 @@ [CSW] 3OF56 HE [CSW] 3OF56 고폭탄 [CSW] 3OF56 HE + [CSW] 3OF56 HE + [CSW] HE de 3OF56 [CSW] 3OF69M Laser Guided @@ -85,6 +109,8 @@ [CSW] 3OF69M Laser Guided [CSW] 3OF69M 레이저유도탄 [CSW] 3OF69M Guidé laser + [CSW] 3OF69M Lasergelenkt + [CSW] 3OF69M Guiado por Láser [CSW] 122mm WP @@ -92,6 +118,8 @@ [CSW] 122mm WP [CSW] 122mm 백린탄 [CSW] 122mm WP + [CSW] 122mm WP + [CSW] WP de 122mm [CSW] D-462 Smoke @@ -99,6 +127,8 @@ [CSW] D-462 Дымовая [CSW] D-462 연막탄 [CSW] D-462 Fumigène + [CSW] D-462 Rauch + [CSW] Humo D-462 [CSW] S-463 Illumination @@ -106,6 +136,8 @@ [CSW] S-463 Осветительная [CSW] S-463 조명탄 [CSW] S-463 Eclairante + [CSW] S-463 Beleuchtung + [CSW] Iluminación S-463 [CSW] BK-6M HEAT @@ -113,6 +145,8 @@ [CSW] BK-6M HEAT [CSW] BK-6M 대전차고폭탄 [CSW] BK-6M HEAT + [CSW] BK-6M HEAT + [CSW] BK-6M HEAT diff --git a/addons/compat_cup_weapons/compat_cup_weapons_nightvision/stringtable.xml b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/stringtable.xml index 47d35eba8c4..e1afbe21c8b 100644 --- a/addons/compat_cup_weapons/compat_cup_weapons_nightvision/stringtable.xml +++ b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/stringtable.xml @@ -10,6 +10,7 @@ AN/PVS-14 (백색광) AN/PVS-14 (WP) AN/PVS-14 (БФ) + AN/PVS-14 (WP) AN/PVS-15 (Black, WP) @@ -20,6 +21,7 @@ AN/PVS-15 (검정, 백색광) AN/PVS-15 (Noires, WP) AN/PVS-15 (Чёрный, БФ) + AN/PVS-15 (Negras, WP) AN/PVS-15 (Green, WP) @@ -30,6 +32,7 @@ AN/PVS-15 (녹색, 백색광) AN/PVS-15 (Vertes, WP) AN/PVS-15 (Зелёный, БФ) + AN/PVS-15 (Verdes, WP) AN/PVS-15 (Tan, WP) @@ -40,6 +43,7 @@ AN/PVS-15 (황갈색, 백색광) AN/PVS-15 (Marron clair, WP) AN/PVS-15 (Желтовато-коричневый, БФ) + AN/PVS-15 (Marrones, WP) AN/PVS-15 (Winter, WP) @@ -47,6 +51,8 @@ AN/PVS-15 (설상, 백색광) AN/PVS-15 (Белый, БФ) AN/PVS-15 (Blanc, WP) + AN/PVS-15 (Winter, WP) + AN/PVS-15 (Blancas, WP) GPNVG (Black, WP) @@ -57,6 +63,7 @@ GPNVG (검정, 백색광) GPNVG (Noires, WP) GPNVG (Чёрный, БФ) + GPNVG (Negras, WP) GPNVG (Tan, WP) @@ -67,6 +74,7 @@ GPNVG (황갈색, 백색광) GPNVG (Marron clair, WP) GPNVG (Желтовато-коричневый, БФ) + GPNVG (Marrones, WP) GPNVG (Green, WP) @@ -77,6 +85,7 @@ GPNVG (녹색, 백색광) GPNVG (Vertes, WP) GPNVG (Зелёный, БФ) + GPNVG (Verdes, WP) GPNVG (Winter, WP) @@ -84,6 +93,8 @@ GPNVG (설상, 백색광) AN/PVS-15 (Белый, БФ) GPNVG (Blanc, WP) + GPNVG (Winter, WP) + GPNVG (Blancas, WP) diff --git a/addons/compat_gm/compat_gm_refuel/CfgVehicles.hpp b/addons/compat_gm/compat_gm_refuel/CfgVehicles.hpp deleted file mode 100644 index 46a4deeefd6..00000000000 --- a/addons/compat_gm/compat_gm_refuel/CfgVehicles.hpp +++ /dev/null @@ -1,6 +0,0 @@ -class CfgVehicles { - class gm_ural4320_base; - class gm_ural4320_refuel_base: gm_ural4320_base { - transportFuel = 0; - }; -}; diff --git a/addons/compat_gm/compat_gm_refuel/config.cpp b/addons/compat_gm/compat_gm_refuel/config.cpp index 6becabe70a9..05688eff702 100644 --- a/addons/compat_gm/compat_gm_refuel/config.cpp +++ b/addons/compat_gm/compat_gm_refuel/config.cpp @@ -21,4 +21,3 @@ class CfgPatches { }; #include "CfgEventHandlers.hpp" -#include "CfgVehicles.hpp" diff --git a/addons/compat_rf/$PBOPREFIX$ b/addons/compat_rf/$PBOPREFIX$ new file mode 100644 index 00000000000..78e6f45daf4 --- /dev/null +++ b/addons/compat_rf/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\compat_rf diff --git a/addons/compat_rf/CfgWeapons.hpp b/addons/compat_rf/CfgWeapons.hpp new file mode 100644 index 00000000000..d1daa7c7100 --- /dev/null +++ b/addons/compat_rf/CfgWeapons.hpp @@ -0,0 +1,42 @@ +class CfgWeapons { + // Ballistics + class Pistol_Base_F; + class hgun_Glock19_RF: Pistol_Base_F { + ace_barrelTwist = 254; + ace_barrelLength = 102; + ace_twistDirection = 1; + }; + + class hgun_DEagle_RF: Pistol_Base_F { + ace_barrelTwist = 482; + ace_barrelLength = 127; + ace_twistDirection = 1; + }; + + class Rifle_Long_Base_F; + class srifle_h6_base_rf: Rifle_Long_Base_F { + ace_barrelTwist = 228.6; + ace_barrelLength = 460; + ace_twistDirection = 1; + }; + + class Rifle_Base_F; + class arifle_ash12_base_RF: Rifle_Base_F { + ace_barrelTwist = 228.6; + ace_barrelLength = 400; + ace_twistDirection = 1; + }; + + class arifle_ash12_LR_base_RF: arifle_ash12_base_RF { + ace_barrelLength = 450; + }; + + // Hearing + class H_HelmetIA; + class H_HelmetIA_sb_arid_RF: H_HelmetIA { + ace_hearing_protection = 0.75; + }; + class H_HelmetIA_sb_digital_RF: H_HelmetIA { + ace_hearing_protection = 0.75; + }; +}; diff --git a/addons/compat_rf/compat_rf_nouniformrestrictions/CfgVehicles.hpp b/addons/compat_rf/compat_rf_nouniformrestrictions/CfgVehicles.hpp new file mode 100644 index 00000000000..553c199ee6f --- /dev/null +++ b/addons/compat_rf/compat_rf_nouniformrestrictions/CfgVehicles.hpp @@ -0,0 +1,12 @@ +// Generated using ace_nouniformrestrictions_fnc_exportConfig +class CfgVehicles { + class B_Helipilot_F; + class C_Helipilot_Green_UniformHolder_RF; + + class C_Helipilot_Rescue_UniformHolder_RF: B_Helipilot_F { + modelSides[] = {6}; + }; + class B_Helipilot_Green_UniformHolder_RF: C_Helipilot_Green_UniformHolder_RF { + modelSides[] = {6}; + }; +}; diff --git a/addons/compat_rf/compat_rf_nouniformrestrictions/config.cpp b/addons/compat_rf/compat_rf_nouniformrestrictions/config.cpp new file mode 100644 index 00000000000..2de1cf96735 --- /dev/null +++ b/addons/compat_rf/compat_rf_nouniformrestrictions/config.cpp @@ -0,0 +1,21 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "RF_Data_Loadorder", + "ace_nouniformrestrictions" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Mike"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_rf/compat_rf_nouniformrestrictions/script_component.hpp b/addons/compat_rf/compat_rf_nouniformrestrictions/script_component.hpp new file mode 100644 index 00000000000..0b98185fa03 --- /dev/null +++ b/addons/compat_rf/compat_rf_nouniformrestrictions/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT nouniformrestrictions +#define SUBCOMPONENT_BEAUTIFIED No Uniform Restrictions +#include "..\script_component.hpp" diff --git a/addons/compat_rf/compat_rf_realisticnames/Attachments.hpp b/addons/compat_rf/compat_rf_realisticnames/Attachments.hpp new file mode 100644 index 00000000000..9915ad1d44f --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/Attachments.hpp @@ -0,0 +1,41 @@ +class optic_MRD; +class optic_MRD_khk_RF: optic_MRD { + displayName = SUBCSTRING(optic_mrd_khk_Name); +}; +class optic_MRD_tan_RF: optic_MRD { + displayName = SUBCSTRING(optic_mrd_tan_Name); +}; + +class optic_ACO_grn; +class optic_ACO_grn_desert_RF: optic_ACO_grn { + displayName = SUBCSTRING(optic_aco_grn_desert_Name); +}; +class optic_ACO_grn_wood_RF: optic_ACO_grn { + displayName = SUBCSTRING(optic_aco_grn_wood_Name); +}; + +class optic_Aco; +class optic_ACO_desert_RF: optic_Aco { + displayName = SUBCSTRING(optic_aco_desert_Name); +}; +class optic_ACO_wood_RF: optic_Aco { + displayName = SUBCSTRING(optic_aco_wood_Name); +}; + +class ItemCore; +class optic_rds_RF: ItemCore { + displayName = SUBCSTRING(optic_rds_Name); +}; + +class optic_VRCO_RF: ItemCore { + displayName = SUBCSTRING(optic_vrco_Name); +}; +class optic_VRCO_tan_RF: optic_VRCO_RF { + displayName = SUBCSTRING(optic_vrco_tan_Name); +}; +class optic_VRCO_khk_RF: optic_VRCO_RF { + displayName = SUBCSTRING(optic_vrco_khk_Name); +}; +class optic_VRCO_pistol_RF: optic_VRCO_RF { + displayName = SUBCSTRING(optic_vrco_pistol_Name); +}; diff --git a/addons/compat_rf/compat_rf_realisticnames/CfgMagazines.hpp b/addons/compat_rf/compat_rf_realisticnames/CfgMagazines.hpp new file mode 100644 index 00000000000..52231bcf071 --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/CfgMagazines.hpp @@ -0,0 +1,24 @@ +class CfgMagazines { + class CA_Magazine; + class 1Rnd_RC40_shell_RF: CA_Magazine { + displayName = SUBCSTRING(rc40_Name); + }; + class 1Rnd_RC40_HE_shell_RF: 1Rnd_RC40_shell_RF { + displayName = SUBCSTRING(rc40_he_Name); + }; + class 1Rnd_RC40_SmokeWhite_shell_RF: 1Rnd_RC40_shell_RF { + displayName = SUBCSTRING(rc40_white_Name); + }; + class 1Rnd_RC40_SmokeBlue_shell_RF: 1Rnd_RC40_shell_RF { + displayName = SUBCSTRING(rc40_blue_Name); + }; + class 1Rnd_RC40_SmokeRed_shell_RF: 1Rnd_RC40_shell_RF { + displayName = SUBCSTRING(rc40_red_Name); + }; + class 1Rnd_RC40_SmokeGreen_shell_RF: 1Rnd_RC40_shell_RF { + displayName = SUBCSTRING(rc40_green_Name); + }; + class 1Rnd_RC40_SmokeOrange_shell_RF: 1Rnd_RC40_shell_RF { + displayName = SUBCSTRING(rc40_orange_Name); + }; +}; diff --git a/addons/compat_rf/compat_rf_realisticnames/CfgVehicles.hpp b/addons/compat_rf/compat_rf_realisticnames/CfgVehicles.hpp new file mode 100644 index 00000000000..016a569c501 --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/CfgVehicles.hpp @@ -0,0 +1,134 @@ +class CfgVehicles { + class Heli_light_03_dynamicLoadout_base_F; + class B_Heli_light_03_dynamicLoadout_RF: Heli_light_03_dynamicLoadout_base_F { + displayName = SUBCSTRING(heli_light_03_Name); + }; + + class Heli_light_03_unarmed_base_F; + class B_Heli_light_03_unarmed_RF: Heli_light_03_unarmed_base_F { + displayName = SUBCSTRING(heli_light_03_unarmed_Name); + }; + + class I_Heli_light_03_dynamicLoadout_RF; + class I_E_Heli_light_03_dynamicLoadout_RF: I_Heli_light_03_dynamicLoadout_RF { + displayName = SUBCSTRING(heli_light_03_Name); + }; + + class I_Heli_light_03_unarmed_RF; + class I_E_Heli_light_03_unarmed_RF: I_Heli_light_03_unarmed_RF { + displayName = SUBCSTRING(heli_light_03_unarmed_Name); + }; + + class Heli_EC_01A_base_RF; + class Heli_EC_01A_military_base_RF: Heli_EC_01A_base_RF { + displayName = SUBCSTRING(ec_01a_military_Name); + }; + + class Helicopter_Base_H; + class Heli_EC_01_base_RF: Helicopter_Base_H { + displayName = SUBCSTRING(ec_01_base_Name); + }; + + class Heli_EC_01_civ_base_RF: Heli_EC_01_base_RF { + displayName = SUBCSTRING(ec_01_Name); + }; + + class Heli_EC_01A_civ_base_RF: Heli_EC_01A_base_RF { + displayName = SUBCSTRING(ec_01a_Name); + }; + + class Heli_EC_02_base_RF: Heli_EC_01_base_RF { + displayName = SUBCSTRING(ec_02_Name); + }; + + class Heli_EC_03_base_RF: Heli_EC_01_base_RF { + displayName = SUBCSTRING(ec_03_Name); + }; + + class Heli_EC_04_base_RF: Heli_EC_01_base_RF { + displayName = SUBCSTRING(ec_04_Name); + }; + + // Typhoon + class O_Truck_03_fuel_F; + class C_Truck_03_water_rf: O_Truck_03_fuel_F { + displayName = SUBCSTRING(truck_03_water_Name); + }; + + // RAM 1500 (Pickup) + class Offroad_01_unarmed_base_F; + class Pickup_01_base_rf: Offroad_01_unarmed_base_F { + displayName = SUBCSTRING(pickup_01_Name); + }; + class Pickup_fuel_base_rf: Pickup_01_base_rf { + displayName = SUBCSTRING(pickup_01_fuel_Name); + }; + class Pickup_service_base_rf: Pickup_01_base_rf { + displayName = SUBCSTRING(pickup_01_service_Name); + }; + class Pickup_repair_base_rf: Pickup_service_base_rf { + displayName = SUBCSTRING(pickup_01_repair_Name); + }; + class Pickup_comms_base_rf: Pickup_service_base_rf { + displayName = SUBCSTRING(pickup_01_comms_Name); + }; + class Pickup_repair_ig_base_rf: Pickup_repair_base_rf { + displayName = SUBCSTRING(pickup_01_repair_Name); + }; + class Pickup_01_hmg_base_rf: Pickup_01_base_rf { + displayName = SUBCSTRING(pickup_01_hmg_Name); + }; + class Pickup_01_mmg_base_rf: Pickup_01_base_rf { + displayName = SUBCSTRING(pickup_01_mmg_Name); + }; + class Pickup_01_mrl_base_rf: Pickup_01_base_rf { + displayName = SUBCSTRING(pickup_01_mrl_Name); + }; + class Pickup_01_aat_base_rf: Pickup_01_base_rf { + displayName = SUBCSTRING(pickup_01_aa_Name); + }; + class Pickup_covered_base_rf: Pickup_service_base_rf { + displayName = SUBCSTRING(pickup_01_covered_Name); + }; + + class C_IDAP_Pickup_rf; + class C_IDAP_Pickup_water_rf: C_IDAP_Pickup_rf { + displayName = SUBCSTRING(pickup_01_water_Name); + }; + + class StaticMortar; + class CommandoMortar_base_RF: StaticMortar { + displayName = SUBCSTRING(commando_Name); + }; + + class StaticMGWeapon; + class TwinMortar_base_RF: StaticMGWeapon { + displayName = SUBCSTRING(twinmortar_Name); + }; + + class Helicopter_Base_F; + class UAV_RC40_Base_RF: Helicopter_Base_F { + displayName = SUBCSTRING(rc40_base_Name); + }; + class UAV_RC40_Base_Sensor_RF: UAV_RC40_Base_RF { + displayName = SUBCSTRING(rc40_Name); + }; + class UAV_RC40_Base_HE_RF: UAV_RC40_Base_RF { + displayName = SUBCSTRING(rc40_he_Name); + }; + class UAV_RC40_Base_SmokeWhite_RF: UAV_RC40_Base_HE_RF { + displayName = SUBCSTRING(rc40_white_Name); + }; + class UAV_RC40_Base_SmokeBlue_RF: UAV_RC40_Base_HE_RF { + displayName = SUBCSTRING(rc40_blue_Name); + }; + class UAV_RC40_Base_SmokeRed_RF: UAV_RC40_Base_HE_RF { + displayName = SUBCSTRING(rc40_red_Name); + }; + class UAV_RC40_Base_SmokeGreen_RF: UAV_RC40_Base_HE_RF { + displayName = SUBCSTRING(rc40_green_Name); + }; + class UAV_RC40_Base_SmokeOrange_RF: UAV_RC40_Base_HE_RF { + displayName = SUBCSTRING(rc40_orange_Name); + }; +}; diff --git a/addons/compat_rf/compat_rf_realisticnames/CfgWeapons.hpp b/addons/compat_rf/compat_rf_realisticnames/CfgWeapons.hpp new file mode 100644 index 00000000000..c2d9003f11a --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/CfgWeapons.hpp @@ -0,0 +1,111 @@ +class CfgWeapons { + #include "Attachments.hpp" + + class Pistol_Base_F; + class hgun_Glock19_RF: Pistol_Base_F { + displayName = SUBCSTRING(glock19_Name); + }; + class hgun_Glock19_khk_RF: hgun_Glock19_RF { + displayName = SUBCSTRING(glock19_khk_Name); + }; + class hgun_Glock19_Tan_RF: hgun_Glock19_RF { + displayName = SUBCSTRING(glock19_tan_Name); + }; + class hgun_Glock19_auto_RF: hgun_Glock19_RF { + displayName = SUBCSTRING(glock19_auto_Name); + }; + class hgun_Glock19_auto_khk_RF: hgun_Glock19_auto_RF { + displayName = SUBCSTRING(glock19_auto_khk_Name); + }; + class hgun_Glock19_auto_Tan_RF: hgun_Glock19_auto_RF { + displayName = SUBCSTRING(glock19_auto_tan_Name); + }; + + class hgun_DEagle_RF: Pistol_Base_F { + displayName = SUBCSTRING(deagle_Name); + }; + class hgun_DEagle_classic_RF: hgun_DEagle_RF { + displayName = SUBCSTRING(deagle_classic_Name); + }; + class hgun_DEagle_bronze_RF: hgun_DEagle_RF { + displayName = SUBCSTRING(deagle_bronze_Name); + }; + class hgun_DEagle_copper_RF: hgun_DEagle_RF { + displayName = SUBCSTRING(deagle_copper_Name); + }; + class hgun_DEagle_gold_RF: hgun_DEagle_RF { + displayName = SUBCSTRING(deagle_gold_Name); + }; + + class srifle_h6_base_rf; + class srifle_h6_tan_rf: srifle_h6_base_rf { + displayName = SUBCSTRING(h6_tan_Name); + }; + class srifle_h6_oli_rf: srifle_h6_tan_rf { + displayName = SUBCSTRING(h6_oli_Name); + }; + class srifle_h6_blk_rf: srifle_h6_tan_rf { + displayName = SUBCSTRING(h6_blk_Name); + }; + class srifle_h6_digi_rf: srifle_h6_tan_rf { + displayName = SUBCSTRING(h6_digi_Name); + }; + class srifle_h6_gold_rf: srifle_h6_tan_rf { + displayName = SUBCSTRING(h6_gold_Name); + }; + + class srifle_DMR_01_F; + class srifle_DMR_01_black_RF: srifle_DMR_01_F { + displayName = SUBCSTRING(dmr_01_black_Name); + }; + class srifle_DMR_01_tan_RF: srifle_DMR_01_black_RF { + displayName = SUBCSTRING(dmr_01_tan_Name); + }; + + class SMG_01_F; + class SMG_01_black_RF: SMG_01_F { + displayName = SUBCSTRING(smg_01_black_Name); + }; + + class arifle_ash12_base_RF; + class arifle_ash12_blk_RF: arifle_ash12_base_RF { + displayName = SUBCSTRING(ash12_blk_Name); + }; + class arifle_ash12_desert_RF: arifle_ash12_base_RF { + displayName = SUBCSTRING(ash12_desert_Name); + }; + class arifle_ash12_urban_RF: arifle_ash12_base_RF { + displayName = SUBCSTRING(ash12_urban_Name); + }; + class arifle_ash12_wood_RF: arifle_ash12_base_RF { + displayName = SUBCSTRING(ash12_wood_Name); + }; + + class arifle_ash12_GL_base_RF; + class arifle_ash12_GL_blk_RF: arifle_ash12_GL_base_RF { + displayName = SUBCSTRING(ash12_gl_blk_Name); + }; + class arifle_ash12_GL_desert_RF: arifle_ash12_GL_blk_RF { + displayName = SUBCSTRING(ash12_gl_desert_Name); + }; + class arifle_ash12_GL_urban_RF: arifle_ash12_GL_blk_RF { + displayName = SUBCSTRING(ash12_gl_urban_Name); + }; + class arifle_ash12_GL_wood_RF: arifle_ash12_GL_blk_RF { + displayName = SUBCSTRING(ash12_gl_wood_Name); + }; + + class arifle_ash12_LR_base_RF; + class arifle_ash12_LR_blk_RF: arifle_ash12_LR_base_RF { + displayName = SUBCSTRING(ash12_lr_blk_Name); + }; + class arifle_ash12_LR_desert_RF: arifle_ash12_LR_blk_RF { + displayName = SUBCSTRING(ash12_lr_desert_Name); + }; + class arifle_ash12_LR_urban_RF: arifle_ash12_LR_blk_RF { + displayName = SUBCSTRING(ash12_lr_urban_Name); + }; + class arifle_ash12_LR_wood_RF: arifle_ash12_LR_blk_RF { + displayName = SUBCSTRING(ash12_lr_wood_Name); + }; +}; diff --git a/addons/compat_rf/compat_rf_realisticnames/config.cpp b/addons/compat_rf/compat_rf_realisticnames/config.cpp new file mode 100644 index 00000000000..47003c4a42b --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/config.cpp @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "RF_Data_Loadorder", + "ace_realisticnames" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Mike", "Marc"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgMagazines.hpp" +#include "CfgWeapons.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/compat_rf/compat_rf_realisticnames/script_component.hpp b/addons/compat_rf/compat_rf_realisticnames/script_component.hpp new file mode 100644 index 00000000000..b8d0682fa4f --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT realisticnames +#define SUBCOMPONENT_BEAUTIFIED Realistic Names +#include "..\script_component.hpp" diff --git a/addons/compat_rf/compat_rf_realisticnames/stringtable.xml b/addons/compat_rf/compat_rf_realisticnames/stringtable.xml new file mode 100644 index 00000000000..a31221294cb --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/stringtable.xml @@ -0,0 +1,297 @@ + + + + + EOTech MRDS (Khaki) + EOTech MRDS (カーキ) + + + EOTech MRDS (Tan) + EOTech MRDS (タン) + + + C-More Railway (Green, Desert) + C-More レイルウェイ (グリーン、砂漠迷彩) + + + C-More Railway (Green, Woodland) + C-More レイルウェイ (グリーン、森林迷彩) + + + C-More Railway (Red, Desert) + C-More レイルウェイ (グリーン、砂漠迷彩) + + + C-More Railway (Red, Woodland) + C-More レイルウェイ (グリーン、森林迷彩) + + + Aimpoint Micro R-1 + Aimpoint マイクロ R-1 + + + Vortex Spitfire Prism + Vortex スピットファイア プリズム + + + Vortex Spitfire Prism (Tan) + Vortex スピットファイア プリズム (タン) + + + Vortex Spitfire Prism (Khaki) + Vortex スピットファイア プリズム (カーキ) + + + Vortex Spitfire Prism (Pistol) + Vortex スピットファイア プリズム (ピストル用) + + + Glock 19X + グロック 19X + + + Glock 19X (Khaki) + グロック 19X (カーキ) + + + Glock 19X (Tan) + グロック 19X (タン) + + + Glock 19X Auto + グロック 19X オート + + + Glock 19X Auto (Khaki) + グロック 19X オート (カーキ) + + + Glock 19X Auto (Tan) + グロック 19X オート (タン) + + + Desert Eagle Mark XIX L5 + デザートイーグル Mark XIX L5 + + + Desert Eagle Mark XIX L5 (Classic) + デザートイーグル Mark XIX L5 (クラシック) + + + Desert Eagle Mark XIX L5 (Bronze) + デザートイーグル Mark XIX L5 (ブロンズ) + + + Desert Eagle Mark XIX L5 (Copper) + デザートイーグル Mark XIX L5 (カッパー) + + + Desert Eagle Mark XIX L5 (Gold) + デザートイーグル Mark XIX L5 (ゴールド) + + + Hera H6 (Tan) + ヘラ H6 (タン) + + + Hera H6 (Olive) + ヘラ H6 (オリーブ) + + + Hera H6 (Black) + ヘラ H6 (ブラック) + + + Hera H6 (Digital) + ヘラ H6 (AAF迷彩) + + + Hera H6 (Gold) + ヘラ H6 (ゴールド) + + + VS-121 (Black) + VS-121 (ブラック) + + + VS-121 (Tan) + VS-121 (タン) + + + Vector SMG (Black) + ベクター SMG (ブラック) + + + ASh-12 (Black) + ASh-12 (ブラック) + + + ASh-12 (Desert) + ASh-12 (砂漠迷彩) + + + ASh-12 (Urban) + ASh-12 (市街地迷彩) + + + ASh-12 (Woodland) + ASh-12 (森林迷彩) + + + ASh-12 GL (Black) + ASh-12 GL (ブラック) + + + ASh-12 GL (Desert) + ASh-12 GL (砂漠迷彩) + + + ASh-12 GL (Urban) + ASh-12 GL (市街地迷彩) + + + ASh-12 GL (Woodland) + ASh-12 GL (森林迷彩) + + + ASh-12 LR (Black) + ASh-12 LR (ブラック) + + + ASh-12 LR (Desert) + ASh-12 LR (砂漠迷彩) + + + ASh-12 LR (Urban) + ASh-12 LR (市街地迷彩) + + + ASh-12 LR (Woodland) + ASh-12 LR (森林迷彩) + + + AW159 Wildcat + AW159 ワイルドキャット + + + AW159 Wildcat (Unarmed) + AW159 ワイルドキャット (非武装) + + + H225M Super Cougar HADR + H225M シュペル クーガー HADR + + + H225M Super Cougar Transport + H225M シュペル クーガー 輸送 + + + H225 Super Puma Transport + H225 シュペル ピューマ 輸送 + + + H225 Super Puma VIP + H225 シュペル ピューマ VIP + + + H225M Super Cougar SOCAT + H225M シュペル クーガー SOCAT + + + H225M Super Cougar CSAR + H225M シュペル クーガー CSAR + + + H225 Super Puma SAR + H225 シュペル ピューマ SAR + + + Typhoon Water + タイフーン 給水 + + + Ram 1500 + ラム 1500 + + + Ram 1500 (Fuel) + ラム 1500 (燃料) + + + Ram 1500 (Services) + ラム 1500 (サービス) + + + Ram 1500 (Repair) + ラム 1500 (修理) + + + Ram 1500 (Comms) + ラム 1500 (通信) + + + Ram 1500 (HMG) + ラム 1500 (HMG) + + + Ram 1500 (MMG) + ラム 1500 (MMG) + + + Ram 1500 (MRL) + ラム 1500 (MRL) + + + Ram 1500 (AA) + ラム 1500 (対空) + + + Ram 1500 (Covered) + ラム 1500 (カバー) + + + Ram 1500 (Water) + ラム 1500 (給水) + + + RSG60 + RSG60 + + + AMOS + AMOS + + + Drone40 + ドローン40 + + + Drone40 Scout + ドローン40 偵察型 + + + Drone40 HE + ドローン40 榴弾 + + + Drone40 Smoke (White) + ドローン40 発煙弾 (白) + + + Drone40 Smoke (Blue) + ドローン40 発煙弾 (青) + + + Drone40 Smoke (Red) + ドローン40 発煙弾 (赤) + + + Drone40 Smoke (Green) + ドローン40 発煙弾 (緑) + + + Drone40 Smoke (Orange) + ドローン40 発煙弾 (橙) + + + diff --git a/addons/compat_rf/config.cpp b/addons/compat_rf/config.cpp new file mode 100644 index 00000000000..ab6fb942751 --- /dev/null +++ b/addons/compat_rf/config.cpp @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"RF_Data_Loadorder"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Mike"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgWeapons.hpp" diff --git a/addons/compat_rf/script_component.hpp b/addons/compat_rf/script_component.hpp new file mode 100644 index 00000000000..2cc45da4904 --- /dev/null +++ b/addons/compat_rf/script_component.hpp @@ -0,0 +1,6 @@ +#define COMPONENT compat_rf +#define COMPONENT_BEAUTIFIED Reaction Forces Compatibility + +#include "\z\ace\addons\main\script_mod.hpp" + +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/compat_rhs_afrf3/CfgAmmo.hpp b/addons/compat_rhs_afrf3/CfgAmmo.hpp index 54ff3bd2c2d..11aee03d795 100644 --- a/addons/compat_rhs_afrf3/CfgAmmo.hpp +++ b/addons/compat_rhs_afrf3/CfgAmmo.hpp @@ -219,6 +219,10 @@ class CfgAmmo { EGVAR(frag,force) = 0; }; + class SmokeShell; + class rhs_ammo_rdg2_white: SmokeShell { + EGVAR(grenades,rollVectorDirAndUp)[] = {{0, 1, 0}, {0, 0, 1}}; + }; class Sh_125mm_APFSDS; class Sh_125mm_HE; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/CfgVehicles.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/CfgVehicles.hpp deleted file mode 100644 index 047e264c6ec..00000000000 --- a/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/CfgVehicles.hpp +++ /dev/null @@ -1,10 +0,0 @@ -class CfgVehicles { - class RHS_Ural_Support_MSV_Base_01; - class RHS_Ural_Fuel_MSV_01: RHS_Ural_Support_MSV_Base_01 { - transportFuel = 0; - }; - class rhs_kraz255b1_base; - class rhs_kraz255b1_fuel_base: rhs_kraz255b1_base { - transportFuel = 0; - }; -}; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/config.cpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/config.cpp index 5101a383a31..8e1986b65f9 100644 --- a/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/config.cpp +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/config.cpp @@ -18,4 +18,4 @@ class CfgPatches { }; }; -#include "CfgVehicles.hpp" +// ADDON kept for backward compatiblity diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgVehicles.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgVehicles.hpp deleted file mode 100644 index 5aaf6b4e229..00000000000 --- a/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgVehicles.hpp +++ /dev/null @@ -1,15 +0,0 @@ -class CfgVehicles { - class rhsusf_M1078A1P2_B_M2_fmtv_usarmy; - class rhsusf_M1078A1R_SOV_M2_D_fmtv_socom: rhsusf_M1078A1P2_B_M2_fmtv_usarmy { - transportFuel = 0; - }; - - class rhsusf_M977A4_usarmy_wd; - class rhsusf_M978A4_usarmy_wd: rhsusf_M977A4_usarmy_wd { - transportFuel = 0; - }; - - class rhsusf_M978A4_BKIT_usarmy_wd: rhsusf_M977A4_usarmy_wd { - transportFuel = 0; - }; -}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/config.cpp b/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/config.cpp index 391e22d95e8..bf600d5d5ae 100644 --- a/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/config.cpp +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/config.cpp @@ -21,4 +21,3 @@ class CfgPatches { }; #include "CfgEventHandlers.hpp" -#include "CfgVehicles.hpp" diff --git a/addons/compat_sog/CfgAmmo/grenades.hpp b/addons/compat_sog/CfgAmmo/grenades.hpp index d280443b6e8..6395756f640 100644 --- a/addons/compat_sog/CfgAmmo/grenades.hpp +++ b/addons/compat_sog/CfgAmmo/grenades.hpp @@ -4,6 +4,13 @@ class vn_molotov_grenade_ammo: vn_grenadehand { EGVAR(frag,enabled) = 0; }; +class vn_t67_grenade_ammo: vn_grenadehand { + EGVAR(grenades,rollVectorDirAndUp)[] = {{-1, 0, 0}, {0, 0, 1}}; +}; +class vn_chicom_grenade_ammo: vn_grenadehand { + EGVAR(grenades,rollVectorDirAndUp)[] = {{1, 0, 0}, {0, 0, 1}}; +}; + class SmokeShell; class vn_m14_grenade_ammo: SmokeShell { EGVAR(grenades,incendiary) = 1; diff --git a/addons/compat_sog/CfgEventHandlers.hpp b/addons/compat_sog/CfgEventHandlers.hpp index fc6d80fc5f9..d28b79fb991 100644 --- a/addons/compat_sog/CfgEventHandlers.hpp +++ b/addons/compat_sog/CfgEventHandlers.hpp @@ -32,6 +32,16 @@ class Extended_InitPost_EventHandlers { init = QUOTE((_this select 0) setMass 1e-12); }; }; + class Land_vn_canisterfuel_f { + class ADDON { + init = QUOTE(call (missionNamespace getVariable [ARR_2(QQEFUNC(refuel,makeJerryCan),{})])); + }; + }; + class Land_vn_fuelcan { + class ADDON { + init = QUOTE(call (missionNamespace getVariable [ARR_2(QQEFUNC(refuel,makeJerryCan),{})])); + }; + }; class vn_bicycle_base { class ADDON { init = QUOTE(call FUNC(disableCookoff)); diff --git a/addons/compat_sog/CfgVehicles/land.hpp b/addons/compat_sog/CfgVehicles/land.hpp index c9390265900..70b305a31d2 100644 --- a/addons/compat_sog/CfgVehicles/land.hpp +++ b/addons/compat_sog/CfgVehicles/land.hpp @@ -1,18 +1,19 @@ +#define XEH_INHERITED class EventHandlers {class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {};} // fuel pumps class Land_vn_commercial_base; class Land_vn_fuelstation_01_pump_f: Land_vn_commercial_base { - transportFuel = 0; + XEH_INHERITED; EGVAR(refuel,hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_vn_fuelstation_02_pump_f: Land_vn_commercial_base { - transportFuel = 0; + XEH_INHERITED; EGVAR(refuel,hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_vn_fuelstation_feed_f: Land_vn_commercial_base { - transportFuel = 0; + XEH_INHERITED; EGVAR(refuel,hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; }; @@ -20,13 +21,47 @@ class Land_vn_fuelstation_feed_f: Land_vn_commercial_base { // fuel objects class Land_vn_building_b_base; class Land_vn_usaf_fueltank_75_01: Land_vn_building_b_base { - transportFuel = 0; - EGVAR(refuel,hooks)[] = {{0, -0.4, -0.5}}; + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{-2.52, -2.2, -2.05}, {2.5, 0, -1.3}}; EGVAR(refuel,fuelCargo) = 2840; // 750 * 3.785 }; +class Land_vn_b_prop_fuelbladder_01: Land_vn_usaf_fueltank_75_01 { + EGVAR(refuel,hooks)[] = {{-1.75, -6.7, -1}}; + EGVAR(refuel,fuelCargo) = 3785; // 1000 * 3.785 +}; +class Land_vn_b_prop_fuelbladder_03: Land_vn_b_prop_fuelbladder_01 { + EGVAR(refuel,hooks)[] = {{-1.55, -6.5, -1}}; +}; +class Land_vn_building_industrial_base; +class Land_vn_fuel_tank_stairs: Land_vn_building_industrial_base { + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{0, 0.4, -1.3}, {0, -0.4, -1.3}}; + EGVAR(refuel,fuelCargo) = 10000; // reference is B_Slingload_01_Fuel_F +}; class Land_vn_object_b_base; class Land_vn_b_prop_fueldrum_01: Land_vn_object_b_base { - transportFuel = 0; - EGVAR(refuel,hooks)[] = {{0, 0, 0.5}}; // reference is Land_FlexibleTank_01_F + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{0, 0, 0}}; EGVAR(refuel,fuelCargo) = 300; // reference is Land_FlexibleTank_01_F }; +class Land_vn_b_prop_fueldrum_02: Land_vn_b_prop_fueldrum_01 { + EGVAR(refuel,hooks)[] = {{0, -1.3, -0.15}, {2.3, 1.25, -0.15}}; + EGVAR(refuel,fuelCargo) = 14100; // (23 + 24) * 300 +}; +class vn_b_ammobox_supply_07; +class vn_b_ammobox_supply_09: vn_b_ammobox_supply_07 { // just a pallet + XEH_INHERITED; +}; +class vn_object_c_base_02; +class Land_vn_canisterfuel_f: vn_object_c_base_02 { + EGVAR(cargo,size) = 1; + EGVAR(cargo,canLoad) = 1; + EGVAR(cargo,noRename) = 1; +}; +class Land_vn_object_c_base; +class Land_vn_fuelcan: Land_vn_object_c_base { + XEH_INHERITED; + EGVAR(cargo,size) = 1; + EGVAR(cargo,canLoad) = 1; + EGVAR(cargo,noRename) = 1; +}; diff --git a/addons/compat_sog/CfgVehicles/wheeled.hpp b/addons/compat_sog/CfgVehicles/wheeled.hpp index 3525328d3f4..3a898519dd1 100644 --- a/addons/compat_sog/CfgVehicles/wheeled.hpp +++ b/addons/compat_sog/CfgVehicles/wheeled.hpp @@ -5,7 +5,6 @@ class vn_wheeled_m54_base: vn_wheeled_truck_base { }; class vn_wheeled_m54_cab_base; class vn_wheeled_m54_fuel_base: vn_wheeled_m54_cab_base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-1.15, -2.3, 0.28}}; EGVAR(refuel,fuelCargo) = 4542; }; @@ -25,7 +24,6 @@ class vn_wheeled_z157_base: vn_wheeled_truck_base { EGVAR(refuel,fuelCapacity) = 150; }; class vn_wheeled_z157_fuel_base: vn_wheeled_z157_base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-1.36, -3.575, -0.4}}; EGVAR(refuel,fuelCargo) = 4000; }; diff --git a/addons/compat_sog/config.cpp b/addons/compat_sog/config.cpp index 62b235773b9..04db68293cf 100644 --- a/addons/compat_sog/config.cpp +++ b/addons/compat_sog/config.cpp @@ -1,5 +1,4 @@ #include "script_component.hpp" -// ToDo: move refuel to subconfig #include "\z\ace\addons\refuel\defines.hpp" #include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp" @@ -47,6 +46,8 @@ class CfgPatches { }; }; +class CBA_Extended_EventHandlers; + #include "ACE_CSW_Groups.hpp" #include "ACE_Medical_Injuries.hpp" #include "ACE_Triggers.hpp" diff --git a/addons/compat_sog/functions/fnc_handlePunjiTrapTrigger.sqf b/addons/compat_sog/functions/fnc_handlePunjiTrapTrigger.sqf index d2e9abdbbcb..7cac6829c55 100644 --- a/addons/compat_sog/functions/fnc_handlePunjiTrapTrigger.sqf +++ b/addons/compat_sog/functions/fnc_handlePunjiTrapTrigger.sqf @@ -14,8 +14,10 @@ * * Public: No */ + params ["_trap"]; -if (!(["ace_medical"] call EFUNC(common,isModLoaded))) exitWith {}; + +if !(GETEGVAR(medical,enabled,false)) exitWith {}; private _radius = getNumber (configOf _trap >> "indirectHitRange"); private _affectedUnits = _trap nearEntities ["CAManBase", _radius]; diff --git a/addons/compat_spe/compat_spe_refuel/CfgVehicles.hpp b/addons/compat_spe/compat_spe_refuel/CfgVehicles.hpp index f47d6877f7b..fc1ebc9b4e0 100644 --- a/addons/compat_spe/compat_spe_refuel/CfgVehicles.hpp +++ b/addons/compat_spe/compat_spe_refuel/CfgVehicles.hpp @@ -1,13 +1,11 @@ class CfgVehicles { class SPE_Halftrack_base; class SPE_US_M3_Halftrack_Fuel: SPE_Halftrack_base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-0.23,-2.58,-0.59}}; EGVAR(refuel,fuelCargo) = 2000; }; class SPE_OpelBlitz_base; class SPE_OpelBlitz_Fuel: SPE_OpelBlitz_base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-0.23,-2.58,-0.59}}; EGVAR(refuel,fuelCargo) = 2000; }; diff --git a/addons/compat_ws/CfgWeapons.hpp b/addons/compat_ws/CfgWeapons.hpp index 30e6882b08e..a8b27fb1f3b 100644 --- a/addons/compat_ws/CfgWeapons.hpp +++ b/addons/compat_ws/CfgWeapons.hpp @@ -37,6 +37,11 @@ class CfgWeapons { ACE_twistDirection = 1; }; + class arifle_SLR_V_lxWS; + class arifle_SLR_Para_lxWS: arifle_SLR_V_lxWS { + ACE_barrelLength = 266.7; + }; + // Velko R4/R5 class arifle_Velko_base_lxWS: arifle_Galat_base_lxWS { ACE_barrelLength = 460; diff --git a/addons/compat_ws/compat_ws_realisticnames/Attachments.hpp b/addons/compat_ws/compat_ws_realisticnames/Attachments.hpp new file mode 100644 index 00000000000..95801e04e92 --- /dev/null +++ b/addons/compat_ws/compat_ws_realisticnames/Attachments.hpp @@ -0,0 +1,75 @@ +class optic_Arco; +class optic_arco_hex_lxWS: optic_Arco { + displayName = SUBCSTRING(arco_hex_Name); +}; + +class optic_Holosight; +class optic_Holosight_snake_lxWS: optic_Holosight { + displayName = SUBCSTRING(holosight_snake_Name); +}; + +class optic_Holosight_smg; +class optic_Holosight_smg_snake_lxWS: optic_Holosight_smg { + displayName = SUBCSTRING(holosight_snake_smg_Name); +}; + +class optic_Hamr; +class optic_Hamr_arid_lxWS: optic_Hamr { + displayName = SUBCSTRING(hamr_arid_Name); +}; +class optic_Hamr_lush_lxWS: optic_Hamr { + displayName = SUBCSTRING(hamr_lush_Name); +}; +class optic_Hamr_sand_lxWS: optic_Hamr { + displayName = SUBCSTRING(hamr_sand_Name); +}; +class optic_Hamr_snake_lxWS: optic_Hamr { + displayName = SUBCSTRING(hamr_snake_Name); +}; + +class ItemCore; +class optic_r1_high_lxWS: ItemCore { + displayName = SUBCSTRING(r1_high_black_Name); +}; +class optic_r1_high_khaki_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_high_khaki_Name); +}; +class optic_r1_high_sand_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_high_sand_Name); +}; +class optic_r1_high_snake_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_high_snake_Name); +}; +class optic_r1_high_arid_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_high_arid_Name); +}; +class optic_r1_high_lush_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_high_lush_Name); +}; +class optic_r1_high_black_sand_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_high_black_sand_Name); +}; + +class optic_r1_low_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_low_black_Name); +}; +class optic_r1_low_khaki_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_low_khaki_Name); +}; +class optic_r1_low_sand_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_low_sand_Name); +}; +class optic_r1_low_snake_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_low_snake_Name); +}; +class optic_r1_low_arid_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_low_arid_Name); +}; +class optic_r1_low_lush_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_low_lush_Name); +}; + +class optic_DMS; +class optic_DMS_snake_lxWS: optic_DMS { + displayName = SUBCSTRING(dms_snake_Name); +}; diff --git a/addons/compat_ws/compat_ws_realisticnames/CfgVehicles.hpp b/addons/compat_ws/compat_ws_realisticnames/CfgVehicles.hpp new file mode 100644 index 00000000000..fe1aed7e17d --- /dev/null +++ b/addons/compat_ws/compat_ws_realisticnames/CfgVehicles.hpp @@ -0,0 +1,60 @@ +class CfgVehicles { + class APC_Wheeled_01_base_F; + class APC_Wheeled_01_atgm_base_lxWS: APC_Wheeled_01_base_F { + displayName = SUBCSTRING(apc_wheeled_01_atgm_Name); + }; + class APC_Wheeled_01_command_base_lxWS: APC_Wheeled_01_base_F { + displayName = SUBCSTRING(apc_wheeled_01_command_Name); + }; + class APC_Wheeled_01_mortar_base_lxWS: APC_Wheeled_01_base_F { + displayName = SUBCSTRING(apc_wheeled_01_mortar_Name); + }; + + class Truck_02_base_F; + class Truck_02_aa_base_lxWS: Truck_02_base_F { + displayName = SUBCSTRING(truck_02_aa_Name); + }; + class Truck_02_cargo_base_lxWS: Truck_02_base_F { + displayName = SUBCSTRING(truck_02_cargo_Name); + }; + class Truck_02_box_base_lxWS: Truck_02_base_F { + displayName = SUBCSTRING(truck_02_repair_Name); + }; + class C_Truck_02_racing_lxWS: Truck_02_box_base_lxWS { + displayName = SUBCSTRING(truck_02_racing_Name); + }; + class Truck_02_Ammo_base_lxWS: Truck_02_base_F { + displayName = SUBCSTRING(truck_02_ammo_Name); + }; + class Truck_02_flatbed_base_lxWS: Truck_02_cargo_base_lxWS { + displayName = SUBCSTRING(truck_02_flatbed_Name); + }; + + class Heli_Transport_02_base_F; + class B_UN_Heli_Transport_02_lxWS: Heli_Transport_02_base_F { + displayName = SUBCSTRING(heli_transport_02_Name); + }; + + class O_APC_Tracked_02_cannon_F; + class O_APC_Tracked_02_30mm_lxWS: O_APC_Tracked_02_cannon_F { + displayName = SUBCSTRING(apc_tracked_02_Name); + }; + + class APC_Wheeled_02_base_v2_F; + class APC_Wheeled_02_hmg_base_lxws: APC_Wheeled_02_base_v2_F { + displayName = SUBCSTRING(apc_wheeled_02_hmg_Name); + }; + class APC_Wheeled_02_unarmed_base_lxws: APC_Wheeled_02_base_v2_F { + displayName = SUBCSTRING(apc_wheeled_02_unarmed_Name); + }; + + class O_Heli_Light_02_dynamicLoadout_F; + class B_ION_Heli_Light_02_dynamicLoadout_lxWS: O_Heli_Light_02_dynamicLoadout_F { + displayName = SUBCSTRING(heli_light_02_armed_Name); + }; + + class O_Heli_Light_02_unarmed_F; + class B_ION_Heli_Light_02_unarmed_lxWS: O_Heli_Light_02_unarmed_F { + displayName = SUBCSTRING(heli_light_02_unarmed_Name); + }; +}; diff --git a/addons/compat_ws/compat_ws_realisticnames/CfgWeapons.hpp b/addons/compat_ws/compat_ws_realisticnames/CfgWeapons.hpp index c09400a03c8..e9cf3c6934d 100644 --- a/addons/compat_ws/compat_ws_realisticnames/CfgWeapons.hpp +++ b/addons/compat_ws/compat_ws_realisticnames/CfgWeapons.hpp @@ -1,4 +1,6 @@ class CfgWeapons { + #include "Attachments.hpp" + // AA12 class sgun_aa40_base_lxWS; class sgun_aa40_lxWS: sgun_aa40_base_lxWS { @@ -99,6 +101,12 @@ class CfgWeapons { class arifle_SLR_V_camo_lxWS: arifle_SLR_V_lxWS { displayName = SUBCSTRING(SLR_Camo_Name); }; + class arifle_SLR_Para_lxWS: arifle_SLR_V_lxWS { + displayName = SUBCSTRING(SLR_Para_Name); + }; + class arifle_SLR_Para_snake_lxWS: arifle_SLR_Para_lxWS { + displayName = SUBCSTRING(SLR_Para_Snake_Name); + }; // Vektor R4/R5 class arifle_Velko_base_lxWS; @@ -156,4 +164,16 @@ class CfgWeapons { class arifle_XMS_M_Sand_lxWS: arifle_XMS_M_lxWS { displayName = SUBCSTRING(XMS_SW_Sand_Name); }; + + // GM6 Lynx + class srifle_GM6_F; + class srifle_GM6_snake_lxWS: srifle_GM6_F { + displayName = SUBCSTRING(gm6_snake_Name); + }; + + // RPG-32 + class launch_RPG32_F; + class launch_RPG32_tan_lxWS: launch_RPG32_F { + displayName = SUBCSTRING(rpg32_tan_Name); + }; }; diff --git a/addons/compat_ws/compat_ws_realisticnames/config.cpp b/addons/compat_ws/compat_ws_realisticnames/config.cpp index 5c8e166e000..0eb75926a82 100644 --- a/addons/compat_ws/compat_ws_realisticnames/config.cpp +++ b/addons/compat_ws/compat_ws_realisticnames/config.cpp @@ -19,3 +19,4 @@ class CfgPatches { }; #include "CfgWeapons.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/compat_ws/compat_ws_realisticnames/stringtable.xml b/addons/compat_ws/compat_ws_realisticnames/stringtable.xml index 092fd2a9ea4..30b53b79266 100644 --- a/addons/compat_ws/compat_ws_realisticnames/stringtable.xml +++ b/addons/compat_ws/compat_ws_realisticnames/stringtable.xml @@ -9,6 +9,7 @@ AA12 AA12 AA12 + AA12 AA12 (Sand) @@ -18,14 +19,16 @@ AA12 (サンド) AA12 (Песочный) AA12 (Sable) + AA12 (Arena) AA12 (Snake) AA-12 (뱀 위장) AA12 (Schlange) AA12 (Serpe) - AA12 (ヘビ柄) + AA12 (ヘビ柄迷彩) AA12 (Змея) + AA12 (Serpiente) Galil ARM @@ -35,15 +38,17 @@ ガリル ARM Galil ARM Galil ARM + Galil ARM Galil ARM (Old) 갈릴 ARM (낡음) Galil ARM (Alt) Galil ARM (Vecchio) - ガリル ARM (使い古し) + ガリル ARM (古びた) Galil ARM (Старый) Galil ARM (Ancien) + Galil ARM (Vieja) GLX 160 @@ -53,14 +58,16 @@ GLX 160 GLX 160 GLX 160 + GLX 160 GLX 160 (Snake) GLX-160 (뱀 위장) GLX 160 (Schlange) GLX-160 (Serpe) - GLX 160 (ヘビ柄) + GLX 160 (ヘビ柄迷彩) GLX 160 (Змея) + GLX 160 (Serpiente) GLX 160 (Hex) @@ -70,6 +77,7 @@ GLX 160 (六角形迷彩) GLX 160 (Гекс) GLX 160 (Hex) + GLX 160 (Hex) GLX 160 (Green Hex) @@ -79,15 +87,17 @@ GLX 160 (緑六角形迷彩) GLX 160 (Зеленый Гекс) GLX 160 (Vert Hex) + GLX 160 (Hex Verde) GLX 160 (Camo) GLX-160 (위장) GLX 160 (Tarn) GLX-160 (Mimetica) - GLX 160 (迷彩) + GLX 160 (AAF迷彩) GLX 160 (Камуфляж) GLX 160 (Camo) + GLX 160 (Camo) GLX 160 (Sand) @@ -97,6 +107,7 @@ GLX 160 (サンド) GLX 160 (Песочный) GLX 160 (Sable) + GLX 160 (Arena) Mk14 Mod 1 EBR (Black) @@ -106,14 +117,16 @@ Mk14 Mod 1 EBR (ブラック) Mk14 Mod 1 EBR (Черный) Mk14 Mod 1 EBR (Noir) + Mk14 Mod 1 EBR (Negra) Mk14 Mod 1 EBR (Snake) Mk.14 Mod 1 EBR (뱀 위장) Mk14 Mod 1 EBR (Schlange) Mk14 Mod 1 EBR (Serpe) - Mk14 Mod 1 EBR (ヘビ柄) + Mk14 Mod 1 EBR (ヘビ柄迷彩) Mk14 Mod 1 EBR (Змея) + Mk14 Mod 1 EBR (Serpiente) Vektor SS-77 @@ -122,15 +135,17 @@ ヴェクター SS-77 Vektor SS-77 Vektor SS-77 + Vektor SS-77 Vektor SS-77 (Camo) 벡터 SS-77 (위장) Vektor SS-77 (Tarn) Vektor SS-77 (Mimetica) - ヴェクター SS-77 (迷彩) + ヴェクター SS-77 (AAF迷彩) Vektor SS-77 (Камуфляж) Vektor SS-77 (Camo) + Vektor SS-77 (Camo) Vektor SS-77 (Hex) @@ -140,6 +155,7 @@ ヴェクター SS-77 (六角形迷彩) Vektor SS-77 (гекс) Vektor SS-77 (Hex) + Vektor SS-77 (Hex) Vektor SS-77 (Green Hex) @@ -149,6 +165,7 @@ ヴェクター SS-77 (緑六角形迷彩) Vektor SS-77 (зеленый гекс) Vektor SS-77 (VertHex) + Vektor SS-77 (Hex Verde) Vektor SS-77 (Desert) @@ -158,6 +175,7 @@ ヴェクター SS-77 (砂漠迷彩) Vektor SS-77 (песочныйt) Vektor SS-77 (Désert) + Vektor SS-77 (Desierto) Vektor SS-77 Compact @@ -167,32 +185,36 @@ ヴェクター SS-77 コンパクト Vektor SS-77 Compact Vektor SS-77 Compacte + Vektor SS-77 Compacta Vektor SS-77 Compact (Snake) 벡터 SS-77 단축형 (뱀 위장) Vektor SS-77 Compact (Schlange) Vektor SS-77 Compatto (Serpe) - ヴェクター SS-77 コンパクト (ヘビ柄) + ヴェクター SS-77 コンパクト (ヘビ柄迷彩) Vektor SS-77 Compact (змея) + Vektor SS-77 Compacta (Serpiente) FN FAL 50.00 (Wood) FN FAL 50.00 (목재) FN FAL 50.00 (Holz) FN FAL 50.00 (Legno) - FN FAL 50.00 (森林迷彩) + FN FAL 50.00 (木製) FN FAL 50.00 (лесной) FN FAL 50.00 (Bois) + FN FAL 50.00 (Madera) FN FAL 50.00 GL (Wood) FN FAL 50.00 GL (목재) FN FAL 50.00 GL (Holz) FN FAL 50.00 GL (Legno) - FN FAL 50.00 GL (森林迷彩) + FN FAL 50.00 GL (木製) FN FAL 50.00 GL (лесной) FN FAL 50.00 GL (Bois) + FN FAL 50.00 GL (Madera) FN FAL 50.00 @@ -202,6 +224,7 @@ FN FAL 50.00 FN FAL 50.00 FN FAL 50.00 + FN FAL 50.00 FN FAL 50.00 GL @@ -211,6 +234,7 @@ FN FAL 50.00 GL FN FAL 50.00 GL FN FAL 50.00 GL + FN FAL 50.00 GL FN FAL 50.00 (Desert) @@ -220,6 +244,7 @@ FN FAL 50.00 (砂漠迷彩) FN FAL 50.00 (песочный) FN FAL 50.00 (Désert) + FN FAL 50.00 (Desierto) FN FAL 50.00 (Jungle) @@ -229,15 +254,25 @@ FN FAL 50.00 (熱帯迷彩) FN FAL 50.00 (джунгли) FN FAL 50.00 (Jungle) + FN FAL 50.00 (Jungla) + + + FN FAL OSW Para + FN FAL OSW パラ + + + FN FAL OSW Para (Snake) + FN FAL OSW パラ (ヘビ柄迷彩) Vektor R4 벡터 R4 Vektor R4 Vektor R4 - ヴェクター R5 + ヴェクター R4 Vektor R4 Vektor R4 + Vektor R4 Vektor R5 Carbine @@ -247,6 +282,7 @@ ヴェクター R5 カービン Vektor R5 Carbine Vektor R5 Carbine + Vektor R5 Carabina Vektor R5 Carbine GL @@ -256,22 +292,25 @@ ヴェクター R5 カービン GL Vektor R5 Carbine GL Vektor R5 Carbine GL + Vektor R5 Carabina GL Vektor R5 Carbine (Snake) 벡터 R5 카빈 (뱀 위장) Vektor R5 Carbine (Schlange) Vektor R5 Carabina (Serpe) - ヴェクター R5 カービン (ヘビ柄) + ヴェクター R5 カービン (ヘビ柄迷彩) Vektor R5 Carbine (Змея) + Vektor R5 Carabina (Serpiente) Vektor R5 Carbine GL (Snake) 벡터 R5 카빈 GL (뱀 위장) Vektor R5 Carbine GL (Schlange) Vektor R5 Carabina GL (Serpe) - ヴェクター R5 カービン GL (ヘビ柄) + ヴェクター R5 カービン GL (ヘビ柄迷彩) Vektor R5 Carbine GL (Змея) + Vektor R5 Carabina GL (Serpiente) XMS @@ -417,5 +456,157 @@ XMS SW (모래) XMS SW (サンド) + + GM6 Lynx (Snake) + GM6 リンクス (ヘビ柄迷彩) + + + RPG-32 (Sand) + RPG-32 (サンド) + + + ELCAN SpecterOS (Hex) + ELCAN SpecterOS (六角形迷彩) + + + EOTech XPS3 (Snake) + EOTech XPS3 (ヘビ柄迷彩) + + + EOTech XPS3 SMG (Snake) + EOTech XPS3 SMG (ヘビ柄迷彩) + + + Leupold Mark 4 HAMR (Arid) + Leupold Mark 4 HAMR (乾燥地帯迷彩) + + + Leupold Mark 4 HAMR (Lush) + Leupold Mark 4 HAMR (緑地迷彩) + + + Leupold Mark 4 HAMR (Sand) + Leupold Mark 4 HAMR (サンド) + + + Leupold Mark 4 HAMR (Snake) + Leupold Mark 4 HAMR (ヘビ柄迷彩) + + + Aimpoint Micro R-1 (High, Black) + Aimpoint マイクロ R-1 (ハイマウント、ブラック) + + + Aimpoint Micro R-1 (High, Khaki) + Aimpoint マイクロ R-1 (ハイマウント、カーキ) + + + Aimpoint Micro R-1 (High, Sand) + Aimpoint マイクロ R-1 (ハイマウント、サンド) + + + Aimpoint Micro R-1 (High, Snake) + Aimpoint マイクロ R-1 (ハイマウント、ヘビ柄迷彩) + + + Aimpoint Micro R-1 (High, Arid) + Aimpoint マイクロ R-1 (ハイマウント、乾燥地帯迷彩) + + + Aimpoint Micro R-1 (High, Lush) + Aimpoint マイクロ R-1 (ハイマウント、緑地迷彩) + + + Aimpoint Micro R-1 (High, Black/Sand) + Aimpoint マイクロ R-1 (ハイマウント、ブラック/サンド) + + + Aimpoint Micro R-1 (Low, Black) + Aimpoint マイクロ R-1 (ローマウント、ブラック) + + + Aimpoint Micro R-1 (Low, Khaki) + Aimpoint マイクロ R-1 (ローマウント、カーキ) + + + Aimpoint Micro R-1 (Low, Sand) + Aimpoint マイクロ R-1 (ローマウント、サンド) + + + Aimpoint Micro R-1 (Low, Snake) + Aimpoint マイクロ R-1 (ローマウント、ヘビ柄迷彩) + + + Aimpoint Micro R-1 (Low, Arid) + Aimpoint マイクロ R-1 (ローマウント、乾燥地帯迷彩) + + + Aimpoint Micro R-1 (Low, Lush) + Aimpoint マイクロ R-1 (ローマウント、緑地迷彩) + + + Burris XTR II (Snake) + Burris XTR II (ヘビ柄迷彩) + + + Badger IFV (ATGM) + バジャー IFV (ATGM) + + + Badger IFV (Command) + バジャー IFV (指揮) + + + Badger IFV (Mortar) + バジャー IFV (迫撃砲) + + + KamAZ (Zu-23-2) + KamAZ (Zu-23-2) + + + KamAZ Cargo + KamAZ 貨物 + + + KamAZ Repair + KamAZ 修理 + + + KamAZ Racing + KamAZ レース仕様 + + + KamAZ Ammo + KamAZ 弾薬 + + + KamAZ Flatbed + KamAZ フラットベッド + + + AW101 Merlin + AW101 マーリン + + + BM-2T Stalker (Bumerang-BM) + BM-2T ストーカー (ブーメランク-BM) + + + Otokar ARMA (HMG) + オトカ アルマ (HMG) + + + Otokar ARMA (Unarmed) + オトカ アルマ (非武装) + + + Ka-60 Kasatka (UP) + Ka-60 カサートカ (UP) + + + Ka-60 Kasatka (UP, Unarmed) + Ka-60 カサートカ (UP、非武装) + diff --git a/addons/concertina_wire/functions/fnc_handleDamage.sqf b/addons/concertina_wire/functions/fnc_handleDamage.sqf index 02092044ef3..f5f1177df5d 100644 --- a/addons/concertina_wire/functions/fnc_handleDamage.sqf +++ b/addons/concertina_wire/functions/fnc_handleDamage.sqf @@ -22,7 +22,7 @@ params ["_wire", "", "_damage", "_source", ""]; if (_damage < 0.5) exitWith { 0 }; -if (!(isNull _source)) then { +if (!isNull _source) then { _wire setVariable [QGVAR(lastDamager), _source]; }; diff --git a/addons/cookoff/ACE_Settings.hpp b/addons/cookoff/ACE_Settings.hpp index ba4447dba99..37594bed51b 100644 --- a/addons/cookoff/ACE_Settings.hpp +++ b/addons/cookoff/ACE_Settings.hpp @@ -1,12 +1,8 @@ - class ACE_Settings { - class GVAR(enable) { - movedToSqf = 1; - }; class GVAR(enableAmmobox) { movedToSQF = 1; }; - class GVAR(enableAmmoCookoff) { // For CBA Setting Switch: we can eliminate and just use (ammoCookoffDuration == 0) + class GVAR(enableAmmoCookoff) { movedToSQF = 1; }; class GVAR(ammoCookoffDuration) { diff --git a/addons/cookoff/CfgCloudlets.hpp b/addons/cookoff/CfgCloudlets.hpp index c1671777054..a328451a7b8 100644 --- a/addons/cookoff/CfgCloudlets.hpp +++ b/addons/cookoff/CfgCloudlets.hpp @@ -1,4 +1,3 @@ - class CfgCloudlets { class GVAR(CookOff) { interval = 0.004; diff --git a/addons/cookoff/CfgEden.hpp b/addons/cookoff/CfgEden.hpp index 2b58daa3043..f973ef40261 100644 --- a/addons/cookoff/CfgEden.hpp +++ b/addons/cookoff/CfgEden.hpp @@ -1,28 +1,27 @@ - class Cfg3DEN { class Object { class AttributeCategories { class ace_attributes { class Attributes { - class GVAR(enable) { - property = QGVAR(enable); + class GVAR(enable) { // setting was previously GVAR(enable), so maintain for backwards compatiblity with missions + property = QGVAR(enable); // same as above control = "Checkbox"; - displayName = CSTRING(enable_hd_name); - tooltip = CSTRING(enable_hd_tooltip); - expression = QUOTE(if !(_value) then {_this setVariable [ARR_3('%s',_value,true)];};); + displayName = CSTRING(enableFire_name); + tooltip = CSTRING(enableFire_tooltip); + expression = QUOTE(if (!_value) then {_this setVariable [ARR_3('%s',_value,true)]}); typeName = "BOOL"; condition = "objectVehicle"; - defaultValue = QUOTE((GETMVAR(QGVAR(enable),0)) in [ARR_2(1,2)]); + defaultValue = QUOTE(GETMVAR(QGVAR(enableFire),true)); }; class GVAR(enableAmmoCookoff) { property = QGVAR(enableAmmoCookoff); control = "Checkbox"; displayName = CSTRING(enableAmmoCookoff_name); tooltip = CSTRING(enableAmmoCookoff_tooltip); - expression = QUOTE(if !(_value) then {_this setVariable [ARR_3('%s',_value,true)];};); + expression = QUOTE(if (!_value) then {_this setVariable [ARR_3('%s',_value,true)]}); typeName = "BOOL"; condition = "objectHasInventoryCargo"; - defaultValue = QUOTE(if (_this isKindOf 'ReammoBox_F') then { GETMVAR(QGVAR(enableAmmobox),true) } else { GETMVAR(QGVAR(enableAmmoCookoff),true) };); + defaultValue = QUOTE(if (_this isKindOf 'ReammoBox_F') then {GETMVAR(QGVAR(enableAmmobox),true)} else {GETMVAR(QGVAR(enableAmmoCookoff),true)}); }; }; }; diff --git a/addons/cookoff/CfgEventHandlers.hpp b/addons/cookoff/CfgEventHandlers.hpp index 6c29240403a..f6503c2479b 100644 --- a/addons/cookoff/CfgEventHandlers.hpp +++ b/addons/cookoff/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); diff --git a/addons/cookoff/CfgSFX.hpp b/addons/cookoff/CfgSFX.hpp index 0d670ead863..24329862fc7 100644 --- a/addons/cookoff/CfgSFX.hpp +++ b/addons/cookoff/CfgSFX.hpp @@ -1,4 +1,3 @@ - class CfgSFX { class GVAR(CookOff_low) { name = QGVAR(cookoff_low); diff --git a/addons/cookoff/CfgVehicles.hpp b/addons/cookoff/CfgVehicles.hpp index 78cbd0c6234..4451d120802 100644 --- a/addons/cookoff/CfgVehicles.hpp +++ b/addons/cookoff/CfgVehicles.hpp @@ -1,4 +1,3 @@ - class CfgVehicles { class Sound; class GVAR(Sound_low): Sound { @@ -7,7 +6,6 @@ class CfgVehicles { scope = 1; sound = QGVAR(CookOff_low); }; - class GVAR(Sound_mid): GVAR(Sound_low) { sound = QGVAR(CookOff_mid); }; @@ -17,47 +15,14 @@ class CfgVehicles { class Tank; class Tank_F: Tank { - GVAR(ammoLocation) = "HitHull"; GVAR(cookoffSelections)[] = {"poklop_gunner","poklop_commander"}; - GVAR(probability) = 0.5; - }; - class MBT_02_base_F: Tank_F { - GVAR(ammoLocation) = "HitTurret"; }; class Car_F; class Wheeled_APC_F: Car_F { - GVAR(ammoLocation) = "HitHull"; GVAR(cookoffSelections)[] = {"poklop_gunner","poklop_commander"}; - GVAR(probability) = 0.8; - // big explosions for wheeled APCs (same as for tanks) + // Big explosions for wheeled APCs (same as for tanks) explosionEffect = "FuelExplosionBig"; }; - - - class MRAP_01_base_F: Car_F { - GVAR(engineSmokeOffset)[] = {0,-2,0}; - }; - - class MRAP_02_base_F: Car_F { - GVAR(engineSmokeOffset)[] = {0,-2,0}; - }; - - class MRAP_03_base_F: Car_F { - GVAR(engineSmokeOffset)[] = {0,-2,0}; - }; - - class Quadbike_01_base_F: Car_F { - GVAR(engineSmokeOffset)[] = {0,1,0}; - }; - - class Truck_F; - class Truck_02_base_F: Truck_F { - GVAR(engineSmokeOffset)[] = {0,-2.6,-0.1}; - }; - - class Truck_02_MRL_base_F: Truck_02_base_F { - GVAR(engineSmokeOffset)[] = {0,0.3,-0.1}; - }; }; diff --git a/addons/cookoff/XEH_PREP.hpp b/addons/cookoff/XEH_PREP.hpp index 2cd87efaa7c..94059089535 100644 --- a/addons/cookoff/XEH_PREP.hpp +++ b/addons/cookoff/XEH_PREP.hpp @@ -1,10 +1,12 @@ - -PREP(handleDamageBox); -PREP(engineFire); -PREP(cookOff); -PREP(smoke); -PREP(cookOffEffect); -PREP(cookOffBox); -PREP(detonateAmmunition); +PREP(cookOffBoxLocal); +PREP(cookOffBoxServer); +PREP(cookOffLocal); +PREP(cookOffServer); +PREP(detonateAmmunitionServer); +PREP(detonateAmmunitionServerLoop); +PREP(engineFireLocal); +PREP(engineFireServer); PREP(getVehicleAmmo); +PREP(handleDamageBox); PREP(isMagazineFlare); +PREP(smoke); diff --git a/addons/cookoff/XEH_postInit.sqf b/addons/cookoff/XEH_postInit.sqf index eba4eeced06..63e1486c82b 100644 --- a/addons/cookoff/XEH_postInit.sqf +++ b/addons/cookoff/XEH_postInit.sqf @@ -1,63 +1,64 @@ #include "script_component.hpp" -[QGVAR(engineFire), LINKFUNC(engineFire)] call CBA_fnc_addEventHandler; -[QGVAR(cookOff), { - params ["_vehicle"]; - if (local _vehicle) then { - _this call FUNC(cookOff); - }; -}] call CBA_fnc_addEventHandler; -[QGVAR(cookOffEffect), LINKFUNC(cookOffEffect)] call CBA_fnc_addEventHandler; +[QGVAR(cookOffBoxLocal), LINKFUNC(cookOffBoxLocal)] call CBA_fnc_addEventHandler; +[QGVAR(cookOffLocal), LINKFUNC(cookOffLocal)] call CBA_fnc_addEventHandler; +[QGVAR(engineFireLocal), LINKFUNC(engineFireLocal)] call CBA_fnc_addEventHandler; [QGVAR(smoke), LINKFUNC(smoke)] call CBA_fnc_addEventHandler; -[QGVAR(cookOffBox), LINKFUNC(cookOffBox)] call CBA_fnc_addEventHandler; - -// handle cleaning up effects when vehicle is deleted mid-cookoff -[QGVAR(addCleanupHandlers), { - params ["_vehicle"]; - // Don't add a new EH if cookoff is run multiple times - if ((_vehicle getVariable [QGVAR(deletedEH), -1]) == -1) then { - private _deletedEH = _vehicle addEventHandler ["Deleted", { - params ["_vehicle"]; +if (isServer) then { + [QGVAR(cookOffBoxServer), LINKFUNC(cookOffBoxServer)] call CBA_fnc_addEventHandler; + [QGVAR(cookOffServer), LINKFUNC(cookOffServer)] call CBA_fnc_addEventHandler; + [QGVAR(detonateAmmunitionServer), LINKFUNC(detonateAmmunitionServer)] call CBA_fnc_addEventHandler; + [QGVAR(engineFireServer), LINKFUNC(engineFireServer)] call CBA_fnc_addEventHandler; +}; - [QGVAR(cleanupEffects), [_vehicle]] call CBA_fnc_localEvent; - }]; +// Handle cleaning up effects when objects are deleted mid cook-off +["AllVehicles", "Deleted", { + { + deleteVehicle _x; + } forEach ((_this select 0) getVariable [QGVAR(effects), []]); +}, true, ["CAManBase", "StaticWeapon"], true] call CBA_fnc_addClassEventHandler; - _vehicle setVariable [QGVAR(deletedEH), _deletedEH]; - }; -}] call CBA_fnc_addEventHandler; +["ReammoBox_F", "Deleted", { + { + deleteVehicle _x; + } forEach ((_this select 0) getVariable [QGVAR(effects), []]); +}, true, [], true] call CBA_fnc_addClassEventHandler; +// Raised when the flames have subsided or after the ammo of a box has finished cooking off [QGVAR(cleanupEffects), { - params ["_vehicle", ["_effects", []]]; + params ["_object"]; - _effects = _effects + (_vehicle getVariable [QGVAR(effects), []]); - if (_effects isNotEqualTo []) then { - { deleteVehicle _x } count _effects; - }; + { + deleteVehicle _x; + } forEach (_object getVariable [QGVAR(effects), []]); + + _object setVariable [QGVAR(effects), nil]; }] call CBA_fnc_addEventHandler; +// Ammo box damage handling ["ReammoBox_F", "init", { - (_this select 0) addEventHandler ["HandleDamage", { - if ((_this select 0) getVariable [QGVAR(enableAmmoCookoff), GVAR(enableAmmobox)]) then { - _this call FUNC(handleDamageBox); - }; - }]; -}, nil, nil, true] call CBA_fnc_addClassEventHandler; + // Calling this function inside curly brackets allows the usage of "exitWith", which would be broken with "HandleDamage" otherwise + (_this select 0) addEventHandler ["HandleDamage", {_this call FUNC(handleDamageBox)}]; +}, true, [], true] call CBA_fnc_addClassEventHandler; + +// Vehicle ammo cook-off (secondary explosions) +["AllVehicles", "Killed", { + if (!GVAR(enableAmmoCookoff) || {GVAR(ammoCookoffDuration) == 0}) exitWith {}; -// secondary explosions -["AllVehicles", "killed", { params ["_vehicle", "", "", "_useEffects"]; - if ( - _useEffects && - _vehicle getVariable [QGVAR(enableAmmoCookoff), GVAR(enableAmmoCookoff)] - ) then { - if (GVAR(ammoCookoffDuration) == 0) exitWith {}; - ([_vehicle] call FUNC(getVehicleAmmo)) params ["_mags", "_total"]; - - private _delay = (random MAX_AMMO_DETONATION_START_DELAY) max MIN_AMMO_DETONATION_START_DELAY; - [FUNC(detonateAmmunition), [_vehicle, _mags, _total], _delay] call CBA_fnc_waitAndExecute; + + if (_useEffects && {_vehicle getVariable [QGVAR(enableAmmoCookoff), true]}) then { + // We don't need to pass source and instigator, as vehicle is already dead + [QGVAR(detonateAmmunitionServer), [ + _vehicle, + false, + objNull, + objNull, + random [MIN_AMMO_DETONATION_START_DELAY, (MIN_AMMO_DETONATION_START_DELAY + MAX_AMMO_DETONATION_START_DELAY) / 2, MAX_AMMO_DETONATION_START_DELAY] + ]] call CBA_fnc_serverEvent; }; -}, nil, ["Man","StaticWeapon"]] call CBA_fnc_addClassEventHandler; +}, true, ["CAManBase", "StaticWeapon"], true] call CBA_fnc_addClassEventHandler; if (hasInterface) then { // Plays a sound locally, so that different sounds can be used for various distances @@ -68,7 +69,7 @@ if (hasInterface) then { private _distance = _object distance (positionCameraToWorld [0, 0, 0]); - TRACE_3("",_object,_sound,_maxDistance); + TRACE_2("",_object,_sound); // 3 classes of distances: close, mid and far, each having different sound files private _classDistance = switch (true) do { @@ -94,6 +95,6 @@ if (hasInterface) then { if (!fileExists _sound) exitWith {}; // Obeys speed of sound and takes doppler effects into account - playSound3D [_sound, objNull, insideBuilding _object >= 0.5, getPosASL _object, _volume, _pitch + (random 0.2) - 0.1, _maxDistance, 0, true]; + playSound3D [_sound, objNull, false, getPosASL _object, _volume, _pitch + (random 0.2) - 0.1, _maxDistance, 0, true]; }] call CBA_fnc_addEventHandler; }; diff --git a/addons/cookoff/functions/fnc_cookOff.sqf b/addons/cookoff/functions/fnc_cookOff.sqf deleted file mode 100644 index 57cde71682d..00000000000 --- a/addons/cookoff/functions/fnc_cookOff.sqf +++ /dev/null @@ -1,129 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: tcvm - * Start a cook-off in the given vehicle. - * - * Arguments: - * 0: Vehicle - * 1: Intensity of fire - * - * Return Value: - * None - * - * Example: - * [(vehicle player), 3] call ace_cookoff_fnc_cookOff - * - * Public: No - */ - -params ["_vehicle", "_intensity", ["_instigator", objNull], ["_smokeDelayEnabled", true], ["_ammoDetonationChance", 0], ["_detonateAfterCookoff", false], ["_fireSource", ""], ["_canRing", true], ["_maxIntensity", MAX_COOKOFF_INTENSITY, [0]], ["_canJet", true, [true]]]; - -if (GVAR(enable) == 0) exitWith {}; -if !(GVAR(enableFire)) exitWith {}; -if (_vehicle getVariable [QGVAR(enable), GVAR(enable)] in [0, false]) exitWith {}; -// exit if cook-off enabled only for players and no players in vehicle crew found -if (_vehicle getVariable [QGVAR(enable), GVAR(enable)] isEqualTo 1 && {fullCrew [_vehicle, "", false] findIf {isPlayer (_x select 0)} == -1}) exitWith {}; - - -TRACE_2("cooking off",_vehicle,_intensity); -TRACE_8("",_instigator,_smokeDelayEnabled,_ammoDetonationChance,_detonateAfterCookoff,_fireSource,_canRing,_maxIntensity,_canJet); - -if (_vehicle getVariable [QGVAR(isCookingOff), false]) exitWith {}; -_vehicle setVariable [QGVAR(isCookingOff), true, true]; - -[QGVAR(addCleanupHandlers), [_vehicle]] call CBA_fnc_globalEvent; - -// limit maximum value of intensity to prevent very long cook-off times -_intensity = _intensity min _maxIntensity; - -private _config = configOf _vehicle; -private _positions = getArray (_config >> QGVAR(cookoffSelections)) select {(_vehicle selectionPosition _x) isNotEqualTo [0,0,0]}; - -if (_positions isEqualTo []) then { - WARNING_1("no valid selection for cookoff found. %1",typeOf _vehicle); - { - private _pos = _vehicle selectionPosition _x; - if (_pos isEqualTo [0, 0, 0]) exitWith {}; - _positions pushBack _x; - } forEach DEFAULT_COMMANDER_HATCHES; - - if (_positions isEqualTo []) then { - _positions pushBack "#noselection"; - }; -}; - -private _delay = 0; -if (_smokeDelayEnabled) then { - _delay = SMOKE_TIME + random SMOKE_TIME; -}; -[QGVAR(smoke), [_vehicle, _positions]] call CBA_fnc_globalEvent; - -[{ - params ["_vehicle", "_positions", "_intensity", "_ammoDetonationChance", "_detonateAfterCookoff", "_instigator", "_fireSource", "_canRing", "_canJet"]; - _vehicle setVariable [QGVAR(intensity), _intensity]; - private _smokeEffects = _vehicle getVariable [QGVAR(effects), []]; - - [{ - params ["_args", "_pfh"]; - _args params ["_vehicle", "_positions", "_ammoDetonationChance", "_detonateAfterCookoff", "_instigator", "_fireSource", "_canRing", "_canJet", "_smokeEffects"]; - private _intensity = _vehicle getVariable [QGVAR(intensity), 0]; - if (isNull _vehicle || {_intensity <= 1}) exitWith { - [QGVAR(cleanupEffects), [_vehicle, _smokeEffects]] call CBA_fnc_globalEvent; - _vehicle setVariable [QGVAR(isCookingOff), false, true]; - [_pfh] call CBA_fnc_removePerFrameHandler; - - if (GVAR(destroyVehicleAfterCookoff) || _detonateAfterCookoff) then { - _vehicle setDamage [1, true]; - }; - }; - - private _lastFlameTime = _vehicle getVariable [QGVAR(lastFlame), 0]; - private _nextFlameTime = _vehicle getVariable [QGVAR(nextFlame), 0]; - - // Wait until we are ready for the next flame - // dt = Tcurrent - Tlast - // dt >= Tnext - if ((CBA_missionTime - _lastFlameTime) >= _nextFlameTime) then { - private _ring = (0.2 > random 1); - if (!_ring && _intensity >= 2) then { - _ring = (0.7 > random 1); - }; - - if !(_canRing) then { - _ring = false; - }; - - private _time = linearConversion [0, 10, _intensity, 3, 20] + random COOKOFF_TIME; - - if (_fireSource isEqualTo "") then { - _fireSource = selectRandom _positions; - }; - - [QGVAR(cookOffEffect), [_vehicle, _canJet, _ring, _time, _fireSource, _intensity]] call CBA_fnc_globalEvent; - - _intensity = _intensity - (0.5 max random 1); - _vehicle setVariable [QGVAR(intensity), _intensity]; - _vehicle setVariable [QGVAR(lastFlame), CBA_missionTime]; - _vehicle setVariable [QGVAR(nextFlame), _time + (MIN_TIME_BETWEEN_FLAMES max random MAX_TIME_BETWEEN_FLAMES)]; - - { - [QEGVAR(fire,burn), [_x, _intensity * 1.5, _instigator]] call CBA_fnc_globalEvent; - } forEach crew _vehicle - }; - - if (_ammoDetonationChance > random 1) then { - private _lastExplosiveDetonationTime = _vehicle getVariable [QGVAR(lastExplosiveDetonation), 0]; - private _nextExplosiveDetonation = _vehicle getVariable [QGVAR(nextExplosiveDetonation), 0]; - - if ((CBA_missionTime - _lastExplosiveDetonationTime) > _nextExplosiveDetonation) then { - if (_fireSource isEqualTo "") then { - _fireSource = selectRandom _positions; - }; - createVehicle ["ACE_ammoExplosionLarge", (_vehicle modelToWorld (_vehicle selectionPosition _fireSource)), [], 0 , "CAN_COLLIDE"]; - - _vehicle setVariable [QGVAR(lastExplosiveDetonation), CBA_missionTime]; - _vehicle setVariable [QGVAR(nextExplosiveDetonation), random 60]; - }; - }; - }, 0.25, [_vehicle, _positions, _ammoDetonationChance, _detonateAfterCookoff, _instigator, _fireSource, _canRing, _canJet, _smokeEffects]] call CBA_fnc_addPerFrameHandler -}, [_vehicle, _positions, _intensity, _ammoDetonationChance, _detonateAfterCookoff, _instigator, _fireSource, _canRing, _canJet], _delay] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_cookOffBox.sqf b/addons/cookoff/functions/fnc_cookOffBox.sqf deleted file mode 100644 index 8b8e60891cf..00000000000 --- a/addons/cookoff/functions/fnc_cookOffBox.sqf +++ /dev/null @@ -1,74 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: KoffeinFlummi, commy2, kymckay - * Start a cook-off in the given ammo box. - * - * Arguments: - * 0: Ammo box - * - * Return Value: - * None - * - * Example: - * [_box] call ace_cookoff_fnc_cookOffBox - * - * Public: No - */ - -params ["_box"]; - -if (_box getVariable [QGVAR(isCookingOff), false]) exitWith {}; -_box setVariable [QGVAR(isCookingOff), true]; - -if (local _box) then { - [QGVAR(cookOffBox), _box] call CBA_fnc_globalEvent; -}; - -[{ - params ["_box"]; - - // Box will start smoking - private _smoke = "#particlesource" createVehicleLocal [0,0,0]; - _smoke setParticleClass "AmmoSmokeParticles2"; - _smoke attachTo [_box, [0,0,0]]; - - private _effects = [_smoke]; - - if (isServer) then { - private _sound = createSoundSource ["Sound_Fire", position _box, [], 0]; - _effects pushBack _sound; - }; - - [{ - params ["_box", "_effects"]; - - // These functions are smart and do all the cooking off work - if (local _box) then { - if (GVAR(ammoCookoffDuration) == 0) exitWith {}; - ([_box] call FUNC(getVehicleAmmo)) params ["_mags", "_total"]; - [_box, _mags, _total] call FUNC(detonateAmmunition); - - // This shit is busy being on fire, magazines aren't accessible/usable - clearMagazineCargoGlobal _box; - }; - - // Light the fire (also handles lighting) - private _fire = "#particlesource" createVehicleLocal [0,0,0]; - _fire setParticleClass "AmmoBulletCore"; - _fire attachTo [_box, [0,0,0]]; - - _effects pushBack _fire; - - [{ - params ["_box", "_effects"]; - - { - deleteVehicle _x; - } forEach _effects; - - if (local _box) then { - _box setDamage 1; - }; - }, [_box, _effects], COOKOFF_TIME_BOX] call CBA_fnc_waitAndExecute; // TODO: Change so that box is alive until no ammo left, with locality in mind - }, [_box, _effects], SMOKE_TIME] call CBA_fnc_waitAndExecute; -}, _box, IGNITE_TIME] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_cookOffBoxLocal.sqf b/addons/cookoff/functions/fnc_cookOffBoxLocal.sqf new file mode 100644 index 00000000000..8285104daf8 --- /dev/null +++ b/addons/cookoff/functions/fnc_cookOffBoxLocal.sqf @@ -0,0 +1,52 @@ +#include "..\script_component.hpp" +/* + * Author: KoffeinFlummi, commy2, kymckay, johnb43 + * Spawns local cook-off effects for ammo boxes. + * + * Arguments: + * 0: Box + * 1: Source + * 2: Instigator + * 3: Start time of the cook-off + * + * Return Value: + * None + * + * Example: + * [cursorObject, player, player, CBA_missionTime + 10] call ace_cookoff_fnc_cookOffBoxLocal + * + * Public: No + */ + +params ["", "", "", "_startTime"]; + +[{ + params ["_box", "_source", "_instigator"]; + + // If box was deleted before smoke could be spawned, just exit + if (isNull _box) exitWith {}; + + private _boxPos = ASLToAGL getPosASL _box; + private _effects = []; + + // Box will start smoking + if (hasInterface) then { + private _smoke = createVehicleLocal ["#particlesource", _boxPos, [], 0, "CAN_COLLIDE"]; + _smoke setParticleClass "AmmoSmokeParticles2"; + _smoke attachTo [_box]; + + _effects pushBack _smoke; + }; + + if (isServer) then { + private _sound = createSoundSource ["Sound_Fire", _boxPos, [], 0]; + _sound attachTo [_box]; + + _effects pushBack _sound; + + // Detonate the ammunition + [QGVAR(detonateAmmunitionServer), [_box, true, _source, _instigator, random [DETONATION_DELAY / 2, DETONATION_DELAY, DETONATION_DELAY / 2 * 3]]] call CBA_fnc_localEvent; + }; + + _box setVariable [QGVAR(effects), _effects]; +}, _this, (_startTime - CBA_missionTime) max 0] call CBA_fnc_waitAndExecute; // This delay allows for synchronisation for JIP players diff --git a/addons/cookoff/functions/fnc_cookOffBoxServer.sqf b/addons/cookoff/functions/fnc_cookOffBoxServer.sqf new file mode 100644 index 00000000000..10d57876a72 --- /dev/null +++ b/addons/cookoff/functions/fnc_cookOffBoxServer.sqf @@ -0,0 +1,50 @@ +#include "..\script_component.hpp" +/* + * Author: KoffeinFlummi, commy2, kymckay, johnb43 + * Start an ammo cook-off in the given ammo box. + * + * Arguments: + * 0: Ammo box + * 1: Source (default: objNull) + * 2: Instigator (default: objNull) + * + * Return Value: + * None + * + * Example: + * cursorObject call ace_cookoff_fnc_cookOffBoxServer + * + * Public: No + */ + +if (!isServer) exitWith {}; +if (!GVAR(enableAmmobox) || {GVAR(ammoCookoffDuration) == 0}) exitWith {}; + +params ["_box", ["_source", objNull], ["_instigator", objNull]]; + +// Make sure it's a box (important, because deleted EH is assigned to ReammoBox_F only in postInit) +if !(_box isKindOf "ReammoBox_F") exitWith {}; + +if !(_box getVariable [QGVAR(enableAmmoCookoff), true]) exitWith {}; + +// Allow only 1 cook-off per box at a time +if (_box getVariable [QGVAR(isCookingOff), false]) exitWith {}; + +_box setVariable [QGVAR(isCookingOff), true, true]; + +private _delay = random [SMOKE_DELAY / 2, SMOKE_DELAY, SMOKE_DELAY / 2 * 3]; + +// Spawn cook-off effects on all connected machines and JIP +private _jipID = [QGVAR(cookOffBoxLocal), [ + _box, + _source, + _instigator, + CBA_missionTime + _delay // Generate a globally synced timestamp +]] call CBA_fnc_globalEventJIP; + +[_jipID, _box] call CBA_fnc_removeGlobalEventJIP; + +_box setVariable [QGVAR(cookoffBoxJipID), _jipID]; + +// API +[QGVAR(cookOffBox), [_box, _source, _instigator, _delay]] call CBA_fnc_globalEvent; diff --git a/addons/cookoff/functions/fnc_cookOffEffect.sqf b/addons/cookoff/functions/fnc_cookOffEffect.sqf deleted file mode 100644 index 44282f2f6b8..00000000000 --- a/addons/cookoff/functions/fnc_cookOffEffect.sqf +++ /dev/null @@ -1,200 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: tcvm - * Spawn cook-off effects - * - * Arguments: - * 0: Vehicle - * 1: Spawn fire jet - * 2: Spawn fire ring - * 3: How long effect will last (Max 20 seconds) - * 4: What selection will fire originate from - * 5: Cookoff intensity value - * - * Return Value: - * None - * - * Example: - * [vehicle player, true, false, 15, "commander_turret"] call ace_cookoff_fnc_cookOffEffect - * - * Public: No - */ - -params ["_obj", "_jet", "_ring", "_time", "_fireSelection", "_intensity"]; -private _light = "#lightpoint" createVehicleLocal [0,0,0]; -_light setLightBrightness 5; -_light setLightAmbient [0.8, 0.6, 0.2]; -_light setLightColor [1, 0.5, 0.2]; -_light lightAttachObject [_obj, [0,0,0]]; -_time = 0 max (_time min 20); - -private _sound = objNull; -if (isServer) then { - // ironically biggest performance hit is this. Creating a new sound source takes up aprox 400 milliseconds. - // I dont think there is an alternative that takes into effect distance and whatever, but if you find one please fix! - if (_jet || _ring) then { - private _soundName = selectRandomWeighted [QGVAR(Sound_low), 0.1, QGVAR(Sound_mid), 0.25, QGVAR(Sound_high), 0.65]; - _sound = createSoundSource [_soundName, position _obj, [], 0]; - }; - - if (_ring) then { - private _intensity = 6; - private _radius = 1.5 * ((boundingBoxReal _obj) select 2); - [QEGVAR(fire,addFireSource), [_obj, _radius, _intensity, format [QGVAR(%1), hashValue _obj]]] call CBA_fnc_localEvent; - }; -}; - -[{ - params ["_args", "_pfh"]; - _args params ["_obj", "_jet", "_ring", "_time", "_startTime", "_light", "_fireSelection", "_sound", "_intensity"]; - private _elapsedTime = CBA_missionTime - _startTime; - if (_elapsedTime >= _time) exitWith { - deleteVehicle _light; - deleteVehicle _sound; - if (isServer) then { - [QEGVAR(fire,removeFireSource), [format [QGVAR(%1), hashValue _obj]]] call CBA_fnc_localEvent; - }; - [_pfh] call CBA_fnc_removePerFrameHandler; - }; - private _factor = (1 + (_elapsedTime / 2) min 2); - private _flameSize = 1.5; - - if (_elapsedTime > (_time * (3 / 4))) then { - _factor = _factor * linearConversion [_time * (3 / 4), _time, _elapsedTime, 1, 0.5]; - }; - - _light setLightBrightness 5 * (_factor / 5); - - if (_jet) then { - private _particlePosition = (_obj selectionPosition _fireSelection) vectorAdd [-0.1 + random 0.2, -0.1 + random 0.2, 0]; - - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", - "Billboard", - 1, - (0.1 + (random 0.2)) * _factor, - _particlePosition, - [0, 0, 15 * (_factor / 2)], - 0, - 10, - 7.9, - 0.075, - [1.25 * _factor, 2.5 * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], - 1, - 0, - "", - "", - _obj - ]; - - // make flame push object into ground to make effect seem more "alive" - if (!isGamePaused && { local _obj }) then { - private _force = [0, 0, _factor * -(0.5 min random 1.5) * (0.3 min random 1)] vectorMultiply getMass _obj; - _obj addForce [_force, vectorUpVisual _obj]; - }; - }; - - if (_ring) then { - private _ringOrigin = (_obj selectionPosition _fireSelection) vectorAdd [-0.1 + random 0.2, -0.1 + random 0.2, -1]; - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal",16,2,32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [0, 20 * (_factor / 2), 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [0, -20 * (_factor / 2), 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [20 * (_factor / 2), 0, 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - [-0.1 + random 0.2, -0.1 + random 0.2, -1], - [-20 * (_factor / 2), 0, 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - - private _dir = 20 * (_factor / 2); - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [_dir, _dir, 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2],[1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - - _dir = -20 * (_factor / 2); - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [_dir, _dir, 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2],[1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - - _dir = 20 * (_factor / 2); - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal",16,2,32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [_dir, -_dir, 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - - _dir = 20 * (_factor / 2); - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [-_dir, _dir, 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - }; - - (getVehicleTIPars _obj) params ["_tiEngine", "_tiWheels", "_tiWeapon"]; - _obj setVehicleTIPars [ - // formula is designed to have the temperature ramp up quickly and then level out - (_tiEngine + (_intensity * 0.01))/1.005, - (_tiWheels + (_intensity * 0.004))/1.002, // wheels//tracks are further away from burning parts - (_tiWeapon + (_intensity * 0.01))/1.005 - ]; - -}, 0, [_obj, _jet, _ring, _time, CBA_missionTime, _light, _fireSelection, _sound, _intensity]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/cookoff/functions/fnc_cookOffLocal.sqf b/addons/cookoff/functions/fnc_cookOffLocal.sqf new file mode 100644 index 00000000000..cbd160bba1d --- /dev/null +++ b/addons/cookoff/functions/fnc_cookOffLocal.sqf @@ -0,0 +1,229 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm, johnb43 + * Spawn cook-off fire effects. + * + * Arguments: + * 0: Vehicle + * 1: Spawn fire jet + * 2: Spawn fire ring + * 3: What selection fire will originate from + * 4: Cookoff intensity value + * 5: Start time + * 6: Duration of effect (max 20 seconds) + * + * Return Value: + * None + * + * Example: + * [cursorObject, true, false, "commander_turret", 6, CBA_missionTime, 15] call ace_cookoff_fnc_cookOffLocal + * + * Public: No + */ + +#define FLAME_SIZE 1.5 +#define FIRE_INTENSITY 20 + +params ["_vehicle", "_jet", "_ring", "_fireSelection", "_intensity", "_startTime", "_duration"]; + +// Check if still valid for JIP players +if (isNull _vehicle || {CBA_missionTime - _startTime >= _duration}) exitWith {}; + +// Spawn light +private _light = objNull; + +if (hasInterface) then { + _light = "#lightpoint" createVehicleLocal [0, 0, 0]; + _light setLightBrightness 5; + _light setLightAmbient [0.8, 0.6, 0.2]; + _light setLightColor [1, 0.5, 0.2]; + _light lightAttachObject [_vehicle, [0, 0, 0]]; +}; + +_duration = 0 max _duration min 20; + +private _sound = objNull; +private _fireKey = ""; + +if (isServer) then { + // Spawn sound effect + if (_jet || _ring) then { + private _soundName = selectRandomWeighted [QGVAR(Sound_low), 0.1, QGVAR(Sound_mid), 0.25, QGVAR(Sound_high), 0.65]; + _sound = createSoundSource [_soundName, ASLToAGL getPosASL _vehicle, [], 0]; + _sound attachTo [_vehicle]; + }; + + // Make the ring a source of fire + if (_ring && {["ace_fire"] call EFUNC(common,isModLoaded)}) then { + _fireKey = format [QGVAR(cookoffFire_%1), hashValue _vehicle]; + + [QEGVAR(fire,addFireSource), [_vehicle, FLAME_SIZE * ((boundingBoxReal _vehicle) select 2), FIRE_INTENSITY, _fireKey]] call CBA_fnc_localEvent; + }; +}; + +[{ + (_this select 0) params ["_vehicle", "_jet", "_ring", "_startTime", "_duration", "_light", "_fireSelection", "_sound", "_intensity", "_fireKey"]; + + private _elapsedTime = CBA_missionTime - _startTime; + + // Clean up effects once effects have finished or vehicle has been deleted + if (isNull _vehicle || {_elapsedTime >= _duration}) exitWith { + (_this select 1) call CBA_fnc_removePerFrameHandler; + + deleteVehicle _light; + + if (isServer) then { + deleteVehicle _sound; + + if (["ace_fire"] call EFUNC(common,isModLoaded)) then { + [QEGVAR(fire,removeFireSource), _fireKey] call CBA_fnc_localEvent; + }; + }; + }; + + private _factor = 1 + (_elapsedTime / 2) min 2; + + if (_elapsedTime > _duration * 3 / 4) then { + _factor = _factor * linearConversion [_duration * 3 / 4, _duration, _elapsedTime, 1, 0.5]; + }; + + // Make flame push object into ground to make effect seem more "alive" + if (_jet && !isGamePaused && {local _vehicle} && {_vehicle getVariable [QGVAR(nextForceTime), 0] <= CBA_missionTime}) then { + private _force = [0, 0, _factor * -(0.5 min random 1.5) * (0.3 min random 1)] vectorMultiply getMass _vehicle; + _vehicle addForce [_force, vectorUpVisual _vehicle]; + _vehicle setVariable [QGVAR(nextForceTime), CBA_missionTime + 0.01]; // This prevents bad behaviour when setAccTime is small + }; + + // Don't spawn visual effects on machines without interfaces + if (!hasInterface) exitWith {}; + + _light setLightBrightness _factor; + + if (_jet) then { + private _particlePosition = (_vehicle selectionPosition _fireSelection) vectorAdd [-0.1 + random 0.2, -0.1 + random 0.2, 0]; + + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", + "Billboard", + 1, + (0.1 + random 0.2) * _factor, + _particlePosition, + [0, 0, 15 * (_factor / 2)], + 0, + 10, + 7.9, + 0.075, + [1.25 * _factor, 2.5 * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], + 1, + 0, + "", + "", + _vehicle + ]; + }; + + if (_ring) then { + private _ringOrigin = (_vehicle selectionPosition _fireSelection) vectorAdd [-0.1 + random 0.2, -0.1 + random 0.2, -1]; + + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal",16,2,32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + _ringOrigin, + [0, 20 * (_factor / 2), 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + _ringOrigin, + [0, -20 * (_factor / 2), 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + _ringOrigin, + [20 * (_factor / 2), 0, 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + [-0.1 + random 0.2, -0.1 + random 0.2, -1], + [-20 * (_factor / 2), 0, 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + + private _dir = 20 * (_factor / 2); + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + _ringOrigin, + [_dir, _dir, 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2],[1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + + _dir = -20 * (_factor / 2); + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, + _ringOrigin, + [_dir, _dir, 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2],[1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + + _dir = 20 * (_factor / 2); + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal",16,2,32], + "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, + _ringOrigin, + [_dir, -_dir, 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + + _dir = 20 * (_factor / 2); + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + _ringOrigin, + [-_dir, _dir, 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + }; + + (getVehicleTIPars _vehicle) params ["_tiEngine", "_tiWheels", "_tiWeapon"]; + + // Formula is designed to have the temperature ramp up quickly and then level out + _vehicle setVehicleTIPars [ + (_tiEngine + _intensity * 0.01) / 1.005, + (_tiWheels + _intensity * 0.004) / 1.002, // Wheels/tracks are further away from burning parts + (_tiWeapon + _intensity * 0.01) / 1.005 + ]; +}, 0, [_vehicle, _jet, _ring, _startTime, _duration, _light, _fireSelection, _sound, _intensity, _fireKey]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/cookoff/functions/fnc_cookOffServer.sqf b/addons/cookoff/functions/fnc_cookOffServer.sqf new file mode 100644 index 00000000000..303555ba28b --- /dev/null +++ b/addons/cookoff/functions/fnc_cookOffServer.sqf @@ -0,0 +1,202 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm, johnb43 + * Start a cook-off in the given vehicle. + * Spews flames in multiple directions at the same time (ring) or from the turret towards the sky (jet). + * + * Arguments: + * 0: Vehicle + * 1: Intensity of fire + * 2: Source (default: objNull) + * 3: Instigator (default: objNull) + * 4: Delay between smoke and fire enabled (default: true) + * 5: Ammo detonation chance (default: 0) + * 6: Detonate after cook-off (default: false) + * 7: Selection for fire source (default: "") + * 8: Can spawn fire ring (default: true) + * 9: Can spawn fire jet (default: true) + * 10: Maximum intensity (default: MAX_COOKOFF_INTENSITY) + * + * Return Value: + * None + * + * Example: + * [cursorObject, 3] call ace_cookoff_fnc_cookOffServer + * + * Public: No + */ + +if (!isServer) exitWith {}; +if (!GVAR(enableFire) || {GVAR(cookoffDuration) == 0}) exitWith {}; + +params [ + "_vehicle", + "_intensity", + ["_source", objNull], + ["_instigator", objNull], + ["_delayBetweenSmokeAndFire", true], + ["_ammoDetonationChance", 0], + ["_detonateAfterCookoff", false], + ["_fireSelection", ""], + ["_canRing", true], + ["_canJet", true], + ["_maxIntensity", MAX_COOKOFF_INTENSITY] +]; + +// Make sure it's a vehicle (important, because deleted EH is assigned to AllVehicles only in postInit) +if !(_vehicle isKindOf "AllVehicles") exitWith {}; + +if (_vehicle isKindOf "CAManBase" || {_vehicle isKindOf "StaticWeapon"}) exitWith {}; + +// If under water, ignore +// underwater is not very reliable, so use model center instead +if (underwater _vehicle || {private _posASL = getPosWorld _vehicle; surfaceIsWater _posASL && {(_posASL select 2) < 0}}) exitWith {}; + +// Check if cook-off is disabled on vehicle specifically +if !(_vehicle getVariable [QGVAR(enable), true]) exitWith {}; // QGVAR(enable) is API + +TRACE_3("cooking off",_vehicle,_intensity,_maxIntensity); +TRACE_8("",_source,_instigator,_delayBetweenSmokeAndFire,_ammoDetonationChance,_detonateAfterCookoff,_fireSelection,_canRing,_canJet); + +if (_vehicle getVariable [QGVAR(isCookingOff), false]) exitWith {}; + +_vehicle setVariable [QGVAR(isCookingOff), true, true]; + +// Limit maximum value of intensity to prevent very long cook-off times +_intensity = _intensity min _maxIntensity; + +private _selections = getArray (configOf _vehicle >> QGVAR(cookoffSelections)) select {(_vehicle selectionPosition _x) isNotEqualTo [0, 0, 0]}; + +if (_selections isEqualTo []) then { + WARNING_1("no valid selection for cookoff found. %1",typeOf _vehicle); + + { + if ((_vehicle selectionPosition _x) isNotEqualTo [0, 0, 0]) then { + _selections pushBack _x; + }; + } forEach DEFAULT_COMMANDER_HATCHES; + + if (_selections isEqualTo []) then { + _selections pushBack "#noselection"; + }; +}; + +// Not guaranteed to be active/used, but reserve it nonetheless +private _fireJipID = format [QGVAR(cookOffLocal_%1), hashValue _vehicle]; +[_fireJipID, _vehicle] call CBA_fnc_removeGlobalEventJIP; + +// Spawn smoke +private _smokeJipID = [QGVAR(smoke), [_vehicle, _selections]] call CBA_fnc_globalEventJIP; +[_smokeJipID, _vehicle] call CBA_fnc_removeGlobalEventJIP; + +// Save intensity for looping purposes +_vehicle setVariable [QGVAR(intensity), _intensity]; + +private _delay = 0; + +if (_delayBetweenSmokeAndFire) then { + _delay = random [SMOKE_DELAY, 1.5 * SMOKE_DELAY, 2 * SMOKE_DELAY]; +}; + +[{ + [{ + (_this select 0) params ["_vehicle", "_selections", "_ammoDetonationChance", "_detonateAfterCookoff", "_source", "_instigator", "_fireSelection", "_canRing", "_canJet", "_smokeJipID", "_fireJipID"]; + + if ( + isNull _vehicle || + !GVAR(enableFire) || + {!(_vehicle getVariable [QGVAR(enable), true])} || // QGVAR(enable) is API + {GVAR(cookoffDuration) == 0} || + {underwater _vehicle} || + {private _posASL = getPosWorld _vehicle; surfaceIsWater _posASL && {(_posASL select 2) < 0}} // Underwater is not very reliable, so use model center instead + ) exitWith { + // Effects are deleted when vehicle is deleted + (_this select 1) call CBA_fnc_removePerFrameHandler; + }; + + private _intensity = _vehicle getVariable [QGVAR(intensity), 0]; + + if (_intensity <= 1) exitWith { + (_this select 1) call CBA_fnc_removePerFrameHandler; + + // Wait until the previous flame has finished + private _nextFlameTime = (_vehicle getVariable [QGVAR(endCurrentFlame), CBA_missionTime]) - CBA_missionTime + (MIN_TIME_BETWEEN_FLAMES max random MAX_TIME_BETWEEN_FLAMES); + + if (_fireSelection isEqualTo "") then { + _fireSelection = selectRandom _selections; + }; + + [{ + params ["_vehicle", "_source", "_instigator", "_detonateAfterCookoff", "_fireSelection", "_smokeJipID", "_fireJipID"]; + + // Effects are deleted when vehicle is deleted + if (isNull _vehicle) exitWith {}; + + // Remove effects from JIP + _smokeJipID call CBA_fnc_removeGlobalEventJIP; + _fireJipID call CBA_fnc_removeGlobalEventJIP; + + // Remove effects + [QGVAR(cleanupEffects), _vehicle] call CBA_fnc_globalEvent; + + // Reset variable, so it can cook-off again + _vehicle setVariable [QGVAR(isCookingOff), nil, true]; + + if (GVAR(destroyVehicleAfterCookoff) || _detonateAfterCookoff) then { + createVehicle ["ACE_ammoExplosionLarge", _vehicle modelToWorld (_vehicle selectionPosition _fireSelection), [], 0 , "CAN_COLLIDE"]; + + _vehicle setDamage [1, true, _source, _instigator]; // Because it's running on the server, source and instigator can be set + }; + }, [_vehicle, _source, _instigator, _detonateAfterCookoff, _fireSelection, _smokeJipID, _fireJipID], _nextFlameTime] call CBA_fnc_waitAndExecute; + }; + + // Wait until we are ready for the next flame + if ((_vehicle getVariable [QGVAR(nextFlame), 0]) <= CBA_missionTime) then { + private _ring = false; + + if (_canRing) then { + _ring = 0.2 > random 1; + + if (!_ring && {_intensity >= 2}) then { + _ring = 0.7 > random 1; + }; + }; + + private _duration = linearConversion [0, 10, _intensity, 3, 20] + random COOKOFF_TIME; + + if (_fireSelection isEqualTo "") then { + _fireSelection = selectRandom _selections; + }; + + // Sync for JIP players + [QGVAR(cookOffLocal), [_vehicle, _canJet, _ring, _fireSelection, _intensity, CBA_missionTime, _duration], _fireJipID] call CBA_fnc_globalEventJIP; + + // If there are any crew, burn them + if (["ace_fire"] call EFUNC(common,isModLoaded)) then { + // Use current intensity, in case GVAR(cookoffDuration) is very large and only 1 flameout stage happens + { + [QEGVAR(fire,burn), [_x, _intensity * 1.5, _instigator]] call CBA_fnc_globalEvent; + } forEach (crew _vehicle); + }; + + _intensity = (_intensity - (0.5 max random 1) / GVAR(cookoffDuration)) max 0; + + _vehicle setVariable [QGVAR(intensity), _intensity]; + _vehicle setVariable [QGVAR(endCurrentFlame), CBA_missionTime + _duration]; + _vehicle setVariable [QGVAR(nextFlame), CBA_missionTime + _duration + (MIN_TIME_BETWEEN_FLAMES max random MAX_TIME_BETWEEN_FLAMES)]; + }; + + if (_ammoDetonationChance > random 1 && {_vehicle getVariable [QGVAR(nextExplosiveDetonation), 0] <= CBA_missionTime}) then { + if (_fireSelection isEqualTo "") then { + _fireSelection = selectRandom _selections; + }; + + createVehicle ["ACE_ammoExplosionLarge", _vehicle modelToWorld (_vehicle selectionPosition _fireSelection), [], 0 , "CAN_COLLIDE"]; + + _vehicle setVariable [QGVAR(nextExplosiveDetonation), CBA_missionTime + random 60]; + }; + }, 0.25, _this] call CBA_fnc_addPerFrameHandler; +}, [_vehicle, _selections, _ammoDetonationChance, _detonateAfterCookoff, _source, _instigator, _fireSelection, _canRing, _canJet, _smokeJipID, _fireJipID], _delay] call CBA_fnc_waitAndExecute; + +// API +[QGVAR(cookoff), [_vehicle, _intensity, _instigator, _smokeDelayEnabled, _ammoDetonationChance, _detonateAfterCookoff, _fireSelection, _canRing, _maxIntensity, _canJet]] call CBA_fnc_globalEvent; diff --git a/addons/cookoff/functions/fnc_detonateAmmunition.sqf b/addons/cookoff/functions/fnc_detonateAmmunition.sqf deleted file mode 100644 index 9b3c19ab42d..00000000000 --- a/addons/cookoff/functions/fnc_detonateAmmunition.sqf +++ /dev/null @@ -1,132 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: Glowbal - * Detonates ammunition from a vehicle until no ammo left - * - * Arguments: - * 0: vehicle - * 1: Ammo Array - * - 0: Magazine Classname - * - 1: Ammo Count - * 2: Total Ammo Count - * - * Return Value: - * None - * - * Example: - * [_vehicle, magazinesAmmo _vehicle] call ace_cookoff_fnc_detonateAmmunition - * - * Public: No - */ - -params ["_vehicle", "_magazines", "_totalAmmo"]; - -if (GVAR(enable) == 0) exitWith {}; -if !(GVAR(enableAmmoCookoff)) exitWith {}; - -if (isNull _vehicle) exitWith {}; // vehicle got deleted -if (_magazines isEqualTo []) exitWith {}; // nothing to detonate anymore -if (underwater _vehicle) exitWith {}; - -private _magazineIndex = floor random(count _magazines); -private _magazine = _magazines select _magazineIndex; -_magazine params ["_magazineClassname", "_amountOfMagazines"]; - -if (_amountOfMagazines < 0) exitWith { - ERROR_1("mag with no ammo - %1",_magazine); -}; -private _removed = _amountOfMagazines min floor(1 + random(6 / GVAR(ammoCookoffDuration))); - -_amountOfMagazines = _amountOfMagazines - _removed; -if (_amountOfMagazines <= 0) then { - _magazines deleteAt _magazineIndex; -} else { - _magazine set [1, _amountOfMagazines]; // clear out the magazine -}; -private _timeBetweenAmmoDetonation = (((random 10) / (sqrt _totalAmmo)) min MAX_TIME_BETWEEN_AMMO_DET) max 0.1; -TRACE_2("",_totalAmmo,_timeBetweenAmmoDetonation); -_totalAmmo = _totalAmmo - _removed; - -private _ammo = getText (configFile >> "CfgMagazines" >> _magazineClassname >> "ammo"); -private _ammoCfg = configFile >> "CfgAmmo" >> _ammo; - -private _speedOfAmmo = getNumber (configFile >> "CfgMagazines" >> _magazineClassname >> "initSpeed"); -private _simType = getText (_ammoCfg >> "simulation"); - -private _effect2pos = _vehicle selectionPosition "destructionEffect2"; - -private _spawnProjectile = { - params ["_vehicle", "_ammo", "_speed", "_flyAway"]; - - private _spawnPos = _vehicle modelToWorld [-0.2 + (random 0.4), -0.2 + (random 0.4), random 3]; - if (_spawnPos select 2 < 0) then { - _spawnPos set [2, 0]; - }; - - private _projectile = createVehicle [_ammo, _spawnPos, [], 0, "CAN_COLLIDE"]; - if (_flyAway) then { - private _vectorAmmo = [(-1 + (random 2)), (-1 + (random 2)), -0.2 + (random 1)]; - private _velVec = _vectorAmmo vectorMultiply _speed; - _projectile setVectorDir _velVec; - _projectile setVelocity _velVec; - } else { - _projectile setDamage 1; - }; - - _projectile; -}; - -private _speed = random (_speedOfAmmo / 10) max 1; -_simType = toLowerANSI _simType; -switch (_simType) do { - case ("shotbullet"): { - [QGVAR(playCookoffSound), [_vehicle, _simType]] call CBA_fnc_globalEvent; - if (random 1 < 0.6) then { - [_vehicle, _ammo, _speed, true] call _spawnProjectile; - }; - }; - case ("shotshell"): { - [QGVAR(playCookoffSound), [_vehicle, _simType]] call CBA_fnc_globalEvent; - if (random 1 < 0.15) then { - [_vehicle, _ammo, _speed, true] call _spawnProjectile; - }; - }; - case ("shotgrenade"): { - if (random 1 < 0.9) then { - _speed = 0; - }; - [_vehicle, _ammo, _speed, random 1 < 0.5] call _spawnProjectile; - }; - case ("shotrocket"); - case ("shotmissile"); - case ("shotsubmunitions"): { - if (random 1 < 0.1) then { - [QGVAR(playCookoffSound), [_vehicle, _simType]] call CBA_fnc_globalEvent; - [_vehicle, _ammo, _speed, random 1 < 0.3] call _spawnProjectile; - } else { - createvehicle ["ACE_ammoExplosionLarge", (_vehicle modelToWorld _effect2pos), [], 0 , "CAN_COLLIDE"]; - }; - }; - case ("shotmine"); - case ("shotdirectionalbomb"): { - if (random 1 < 0.5) then { - // Not all explosives detonate on destruction, some have scripted alternatives - private _scripted = getNumber (_ammoCfg >> "triggerWhenDestroyed") == 1; - if !(_scripted) then { - _ammo = getText (_ammoCfg >> "ace_explosives_Explosive"); - }; - // If a scripted alternative doesn't exist use generic explosion - if (_ammo != "") then { - [_vehicle, _ammo, 0, false] call _spawnProjectile; - } else { - createvehicle ["SmallSecondary", (_vehicle modelToWorld _effect2pos), [], 0 , "CAN_COLLIDE"]; - }; - }; - }; - case ("shotilluminating"): { - if (random 1 < 0.15) then { - [_vehicle, _ammo, _speed, random 1 < 0.3] call _spawnProjectile; - }; - }; -}; -[FUNC(detonateAmmunition), [_vehicle, _magazines, _totalAmmo], _timeBetweenAmmoDetonation] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_detonateAmmunitionServer.sqf b/addons/cookoff/functions/fnc_detonateAmmunitionServer.sqf new file mode 100644 index 00000000000..43ac730e09d --- /dev/null +++ b/addons/cookoff/functions/fnc_detonateAmmunitionServer.sqf @@ -0,0 +1,54 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Starts detonating ammunition from an object (e.g. vehicle or crate). + * + * Arguments: + * 0: Object + * 1: Destroy when finished (default: false) + * 2: Source (default: objNull) + * 3: Instigator (default: objNull) + * 4: Initial delay (default: 0) + * + * Return Value: + * None + * + * Example: + * [cursorObject] call ace_cookoff_fnc_detonateAmmunitionServer + * + * Public: No + */ + +if (!isServer) exitWith {}; + +params ["_object", ["_destroyWhenFinished", false], ["_source", objNull], ["_instigator", objNull], ["_initialDelay", 0]]; + +if (isNull _object) exitWith {}; + +// Check if the object can cook its ammo off +if ( + underwater _object || + {private _posASL = getPosWorld _object; surfaceIsWater _posASL && {(_posASL select 2) < 0}} || // Underwater is not very reliable, so use model center instead + {GVAR(ammoCookoffDuration) == 0} || + {!([GVAR(enableAmmoCookoff), GVAR(enableAmmobox)] select (_object isKindOf "ReammoBox_F"))} || + {!(_object getVariable [QGVAR(enableAmmoCookoff), true])} +) exitWith {}; + +// Don't have an object detonate its ammo twice +if (_object getVariable [QGVAR(isAmmoDetonating), false]) exitWith {}; + +_object setVariable [QGVAR(isAmmoDetonating), true, true]; + +_object setVariable [QGVAR(cookoffMagazines), _object call FUNC(getVehicleAmmo)]; + +// TODO: When setMagazineTurretAmmo and magazineTurretAmmo are fixed (https://feedback.bistudio.com/T79689), +// we can add gradual ammo removal during cook-off +if (GVAR(removeAmmoDuringCookoff)) then { + clearMagazineCargoGlobal _object; + + { + [QEGVAR(common,removeMagazinesTurret), [_object, _x select 0, _x select 1], _object, _x select 1] call CBA_fnc_turretEvent; + } forEach (magazinesAllTurrets _object); +}; + +[LINKFUNC(detonateAmmunitionServerLoop), [_object, _destroyWhenFinished, _source, _instigator], _initialDelay] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_detonateAmmunitionServerLoop.sqf b/addons/cookoff/functions/fnc_detonateAmmunitionServerLoop.sqf new file mode 100644 index 00000000000..7fdcedda51d --- /dev/null +++ b/addons/cookoff/functions/fnc_detonateAmmunitionServerLoop.sqf @@ -0,0 +1,181 @@ +#include "..\script_component.hpp" +/* + * Author: Glowbal, johnb43 + * Detonates ammunition from an object (e.g. vehicle or crate) until no ammo is left. + * + * Arguments: + * 0: Object + * 1: Destroy when finished + * 2: Source + * 3: Instigator + * + * Return Value: + * None + * + * Example: + * [cursorObject, true, player, player] call ace_cookoff_fnc_detonateAmmunitionServerLoop + * + * Public: No + */ + +params ["_object", "_destroyWhenFinished", "_source", "_instigator"]; + +if (isNull _object) exitWith {}; + +(_object getVariable QGVAR(cookoffMagazines)) params ["_magazines", "_totalAmmo"]; + +private _hasFinished = _totalAmmo <= 0 || {_magazines isEqualTo []}; + +// If the cook-off has finished or been interrupted, clean up the effects for boxes (no vehicle effects) +if ( + _hasFinished || + {underwater _object} || + {private _posASL = getPosWorld _object; surfaceIsWater _posASL && {(_posASL select 2) < 0}} || // Underwater is not very reliable, so use model center instead + {GVAR(ammoCookoffDuration) == 0} || + {!([GVAR(enableAmmoCookoff), GVAR(enableAmmobox)] select (_object isKindOf "ReammoBox_F"))} || + {!(_object getVariable [QGVAR(enableAmmoCookoff), true])} +) exitWith { + // Box cook-off fire ends after the ammo has detonated (vehicle cook-off fire does not depend on the ammo detonation) + if (_object isKindOf "ReammoBox_F") then { + [QGVAR(cleanupEffects), _object] call CBA_fnc_globalEvent; + + // Reset variable, so the box can cook-off again + _object setVariable [QGVAR(isCookingOff), nil, true]; + + // Remove cook-off effects from box + private _jipID = _object getVariable QGVAR(cookoffBoxJipID); + + if (isNil "_jipID") exitWith {}; + + _jipID call CBA_fnc_removeGlobalEventJIP; + + _object setVariable [QGVAR(cookoffBoxJipID), nil]; + }; + + // Reset variables, so the object can detonate its ammo again + _object setVariable [QGVAR(cookoffMagazines), nil]; + _object setVariable [QGVAR(isAmmoDetonating), nil, true]; + + // If done, destroy the object if necessary + if (_hasFinished && _destroyWhenFinished) then { + _object setDamage [1, true, _source, _instigator]; + }; +}; + +private _magazineIndex = floor random (count _magazines); +private _magazine = _magazines select _magazineIndex; +_magazine params ["_magazineClassname", "_ammoCount", "_spawnProjectile"]; + +// Make sure ammo is at least 0 +_ammoCount = _ammoCount max 0; + +// Remove some ammo, which will be detonated +private _removed = _ammoCount min floor (1 + random (6 / GVAR(ammoCookoffDuration))); + +_ammoCount = _ammoCount - _removed; + +if (_ammoCount <= 0) then { + _magazines deleteAt _magazineIndex; +} else { + _magazine set [1, _ammoCount]; // remove ammo that was detonated +}; + +private _timeBetweenAmmoDetonation = ((random 10 / sqrt _totalAmmo) min MAX_TIME_BETWEEN_AMMO_DET) max 0.1; +TRACE_2("",_totalAmmo,_timeBetweenAmmoDetonation); +_totalAmmo = _totalAmmo - _removed; + +_object setVariable [QGVAR(cookoffMagazines), [_magazines, _totalAmmo]]; + +// Get magazine info, which is used to spawn projectiles +private _configMagazine = configFile >> "CfgMagazines" >> _magazineClassname; +private _ammo = getText (_configMagazine >> "ammo"); +private _configAmmo = configFile >> "CfgAmmo" >> _ammo; + +private _simType = toLower getText (_configAmmo >> "simulation"); +private _speed = linearConversion [0, 1, random 1, 1, 20, true]; +private _effect2pos = _object selectionPosition "destructionEffect2"; + +// Spawns the projectiles, making them either fly in random directions or explode +private _fnc_spawnProjectile = { + // If the magazines are inside of the cargo (inventory), don't let their projectiles escape the interior of the vehicle + if (!_spawnProjectile) exitWith {}; + + params ["_object", "_ammo", "_speed", "_flyAway"]; + + private _spawnPos = _object modelToWorld [-0.2 + random 0.4, -0.2 + random 0.4, random 3]; + + if (_spawnPos select 2 < 0) then { + _spawnPos set [2, 0]; + }; + + private _projectile = createVehicle [_ammo, _spawnPos, [], 0, "CAN_COLLIDE"]; + + if (_flyAway) then { + private _vectorAmmo = [-1 + random 2, -1 + random 2, -0.2 + random 1]; + private _vectorVelocity = _vectorAmmo vectorMultiply _speed; + + _projectile setVectorDir _vectorVelocity; + _projectile setVelocity _vectorVelocity; + } else { + _projectile setDamage 1; + }; +}; + +switch (_simType) do { + case "shotbullet": { + [QGVAR(playCookoffSound), [_object, _simType]] call CBA_fnc_globalEvent; + + if (random 1 < 0.6) then { + [_object, _ammo, _speed, true] call _fnc_spawnProjectile; + }; + }; + case "shotshell": { + [QGVAR(playCookoffSound), [_object, _simType]] call CBA_fnc_globalEvent; + + if (random 1 < 0.15) then { + [_object, _ammo, _speed, true] call _fnc_spawnProjectile; + }; + }; + case "shotgrenade": { + if (random 1 < 0.9) then { + _speed = 0; + }; + + [_object, _ammo, _speed, random 1 < 0.5] call _fnc_spawnProjectile; + }; + case "shotrocket"; + case "shotmissile"; + case "shotsubmunitions": { + if (random 1 < 0.1) then { + [QGVAR(playCookoffSound), [_object, _simType]] call CBA_fnc_globalEvent; + + [_object, _ammo, _speed, random 1 < 0.3] call _fnc_spawnProjectile; + } else { + createVehicle ["ACE_ammoExplosionLarge", _object modelToWorld _effect2pos, [], 0 , "CAN_COLLIDE"]; + }; + }; + case "shotdirectionalbomb"; + case "shotmine": { + if (random 1 < 0.5) then { + // Not all explosives detonate on destruction, some have scripted alternatives + if (getNumber (_configAmmo >> "triggerWhenDestroyed") != 1) then { + _ammo = getText (_configAmmo >> QEGVAR(explosives,explosive)); + }; + + // If a scripted alternative doesn't exist use generic explosion + if (_ammo != "") then { + [_object, _ammo, 0, false] call _fnc_spawnProjectile; + } else { + createVehicle ["SmallSecondary", _object modelToWorld _effect2pos, [], 0 , "CAN_COLLIDE"]; + }; + }; + }; + case "shotilluminating": { + if (random 1 < 0.15) then { + [_object, _ammo, _speed, random 1 < 0.3] call _fnc_spawnProjectile; + }; + }; +}; + +// Detonate the remaining ammo after a delay +[LINKFUNC(detonateAmmunitionServerLoop), [_object, _destroyWhenFinished, _source, _instigator], _timeBetweenAmmoDetonation] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_engineFire.sqf b/addons/cookoff/functions/fnc_engineFire.sqf deleted file mode 100644 index 118537b30a3..00000000000 --- a/addons/cookoff/functions/fnc_engineFire.sqf +++ /dev/null @@ -1,51 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: KoffeinFlummi, commy2 - * Start fire in engine block of a car. - * - * Arguments: - * 0: Vehicle - * - * Return Value: - * None - * - * Example: - * (vehicle player) call ace_cookoff_fnc_engineFire - * - * Public: No - */ - -params ["_vehicle"]; - -if (_vehicle getVariable [QGVAR(isEngineSmoking), false]) exitWith {}; -_vehicle setVariable [QGVAR(isEngineSmoking), true]; - -if (local _vehicle) then { - [QGVAR(engineFire), _vehicle] call CBA_fnc_globalEvent; -}; - -private _offset = getArray (_vehicle call CBA_fnc_getObjectConfig >> QGVAR(engineSmokeOffset)); - -if (_offset isEqualTo []) then { - _offset = [0,0,0]; -}; - -private _position = [ - 0, - (boundingBoxReal _vehicle select 1 select 1) - 2, - (boundingBoxReal _vehicle select 0 select 2) + 2 -] vectorAdd _offset; - -private _smoke = "#particlesource" createVehicleLocal [0,0,0]; -_smoke setParticleClass "ObjectDestructionSmoke1_2Smallx"; -_smoke attachTo [_vehicle, _position]; - -[{ - (_this select 0) params ["_vehicle", "_smoke", "_time"]; - - if (isNull _vehicle || {!alive _vehicle} || {_vehicle getHitPointDamage "HitEngine" < 0.9} || {CBA_missionTime > _time}) then { - deleteVehicle _smoke; - _vehicle setVariable [QGVAR(isEngineSmoking), false]; - [_this select 1] call CBA_fnc_removePerFrameHandler; - }; -}, 5, [_vehicle, _smoke, CBA_missionTime + 240]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/cookoff/functions/fnc_engineFireLocal.sqf b/addons/cookoff/functions/fnc_engineFireLocal.sqf new file mode 100644 index 00000000000..afd6827d6b1 --- /dev/null +++ b/addons/cookoff/functions/fnc_engineFireLocal.sqf @@ -0,0 +1,81 @@ +#include "..\script_component.hpp" +/* + * Author: KoffeinFlummi, commy2, johnb43 + * Start fire in engine block of a car. + * + * Arguments: + * 0: Vehicle + * 1: End time + * + * Return Value: + * None + * + * Example: + * [cursorObject, CBA_missionTime + 10] call ace_cookoff_fnc_engineFireLocal + * + * Public: No + */ + +params ["_vehicle", "_endTime"]; + +// For JIP players and if the time wasn't set properly +if (_endTime < CBA_missionTime) exitWith {}; + +private _smoke = objNull; + +if (hasInterface) then { + private _hitPoints = getAllHitPointsDamage _vehicle; + + // Get hitpoint for engine + private _index = (_hitPoints select 0) findIf {_x == "hitengine"}; + + // Get corresponding selection + private _position = if (_index != -1) then { + _vehicle selectionPosition [(_hitPoints select 1) select _index, "HitPoints", "AveragePoint"] + } else { + [0, 0, 0] + }; + + if (_position isEqualTo [0, 0, 0]) then { + // Get offset for engine smoke if there is one + private _offset = getArray (configOf _vehicle >> QGVAR(engineSmokeOffset)); + + if (_offset isEqualTo []) then { + _offset = [0, 0, 0]; + }; + + _position = [ + 0, + (boundingBoxReal _vehicle select 1 select 1) - 2, + (boundingBoxReal _vehicle select 0 select 2) + 2 + ] vectorAdd _offset; + }; + + // Spawn smoke + _smoke = createVehicleLocal ["#particlesource", ASLToAGL getPosASL _vehicle, [], 0, "CAN_COLLIDE"];; + _smoke setParticleClass "ObjectDestructionSmoke1_2Smallx"; + _smoke attachTo [_vehicle, _position]; +}; + +[{ + (_this select 0) params ["_vehicle", "_smoke", "_endTime"]; + + if (alive _vehicle && {_vehicle getHitPointDamage "HitEngine" >= 0.9} && {CBA_missionTime < _endTime}) exitWith {}; + + (_this select 1) call CBA_fnc_removePerFrameHandler; + + deleteVehicle _smoke; + + if (!isServer || {isNull _vehicle}) exitWith {}; + + // Reset variable, so engine can smoke again in the future + _vehicle setVariable [QGVAR(isEngineSmoking), nil, true]; + + private _jipID = _vehicle getVariable QGVAR(engineFireJipID); + + if (isNil "_jipID") exitWith {}; + + _jipID call CBA_fnc_removeGlobalEventJIP; + + _vehicle setVariable [QGVAR(engineFireJipID), nil]; +}, 5, [_vehicle, _smoke, _endTime]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/cookoff/functions/fnc_engineFireServer.sqf b/addons/cookoff/functions/fnc_engineFireServer.sqf new file mode 100644 index 00000000000..0d435029b8c --- /dev/null +++ b/addons/cookoff/functions/fnc_engineFireServer.sqf @@ -0,0 +1,34 @@ +#include "..\script_component.hpp" +/* + * Author: KoffeinFlummi, commy2, johnb43 + * Start fire in engine block of a car. + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * None + * + * Example: + * cursorObject call ace_cookoff_fnc_engineFireServer + * + * Public: No + */ + +if (!isServer) exitWith {}; + +params ["_vehicle"]; + +// If already smoking, stop +if (_vehicle getVariable [QGVAR(isEngineSmoking), false]) exitWith {}; + +_vehicle setVariable [QGVAR(isEngineSmoking), true, true]; + +// Spawn engine fire effects on all connected machines +private _jipID = [QGVAR(engineFireLocal), [_vehicle, CBA_missionTime + random [ENGINE_FIRE_TIME / 2, ENGINE_FIRE_TIME, ENGINE_FIRE_TIME / 2 * 3]]] call CBA_fnc_globalEventJIP; +[_jipID, _vehicle] call CBA_fnc_removeGlobalEventJIP; + +_vehicle setVariable [QGVAR(engineFireJipID), _jipID]; + +// API +[QGVAR(engineFire), [_vehicle]] call CBA_fnc_globalEvent; diff --git a/addons/cookoff/functions/fnc_getVehicleAmmo.sqf b/addons/cookoff/functions/fnc_getVehicleAmmo.sqf index f6be84c1f90..df4385d30da 100644 --- a/addons/cookoff/functions/fnc_getVehicleAmmo.sqf +++ b/addons/cookoff/functions/fnc_getVehicleAmmo.sqf @@ -1,65 +1,76 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Gets all magazines inside of a vehicle. + * Gets all magazines inside of an object. * * Arguments: - * 0: Vehicle + * 0: Object * * Return Value: - * 0: Ammo Array - * - 0: Magazine Classname - * - 1: Ammo Count - * 1: Total Ammo Count + * 0: Ammo array + * - 0: Magazine classname + * - 1: Ammo count + * - 2: If a projectile should be spawned upon detonation + * 1: Total ammo count * * Example: - * [vehicle player] call ace_cookoff_fnc_getVehicleAmmo + * cursorObject call ace_cookoff_fnc_getVehicleAmmo * * Public: No */ -params ["_vehicle"]; -TRACE_1("getVehicleAmmo",_vehicle); +params ["_object"]; +TRACE_1("getVehicleAmmo",_object); private _ammoToDetonate = []; private _totalAmmo = 0; +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgAmmo = configFile >> "CfgAmmo"; +private _ammo = ""; // Get ammo from turrets { - _x params ["_mag", "_turret", "_count"]; - // if the turret is an FFV seat, it takes magazines from the soldier - if (_count > 0) then { - if (_mag call FUNC(isMagazineFlare)) then {continue}; - private _ammo = getText (configFile >> "CfgMagazines" >> _mag >> "ammo"); - private _model = getText (configFile >> "CfgAmmo" >> _ammo >> "model"); - if (_model == "\A3\weapons_f\empty") exitWith {TRACE_3("skipping",_mag,_ammo,_model);}; - _ammoToDetonate pushBack [_mag, _count]; + // If the turret is an FFV seat, it takes magazines from the soldier + _x params ["_magazine", "", "_count"]; + + if (_count > 0 && {!(_magazine call FUNC(isMagazineFlare))}) then { + _ammo = getText (_cfgMagazines >> _magazine >> "ammo"); + + if (getText (_cfgAmmo >> _ammo >> "model") == "\A3\weapons_f\empty") then { + TRACE_2("skipping",_magazine,_ammo); + + continue; + }; + + _ammoToDetonate pushBack [_magazine, _count, true]; _totalAmmo = _totalAmmo + _count; }; -} forEach (magazinesAllTurrets [_vehicle, true]); +} forEach (magazinesAllTurrets [_object, true]); // Get ammo from cargo space { - _x params ["_mag", "_count"]; - if (_count > 0) then { - if (_mag call FUNC(isMagazineFlare)) then {continue}; - _ammoToDetonate pushBack [_mag, _count]; + _x params ["_magazine", "_count"]; + + if (_count > 0 && {!(_magazine call FUNC(isMagazineFlare))}) then { + _ammoToDetonate pushBack [_magazine, _count, false]; _totalAmmo = _totalAmmo + _count; }; -} forEach (magazinesAmmoCargo _vehicle); +} forEach (magazinesAmmoCargo _object); // Get ammo from transportAmmo / ace_rearm -private _vehCfg = configOf _vehicle; +private _configVehicle = configOf _object; +private _configSupply = (getNumber (_configVehicle >> "transportAmmo")) max (getNumber (_configVehicle >> QEGVAR(rearm,defaultSupply))); -private _configSupply = (getNumber (_vehCfg >> "transportAmmo")) max (getNumber (_vehCfg >> QEGVAR(rearm,defaultSupply))); -if (_vehicle getVariable [QEGVAR(rearm,isSupplyVehicle), (_configSupply > 0)]) then { - TRACE_1("transportAmmo vehicle - adding virtual ammo",typeOf _vehicle); +if (_object getVariable [QEGVAR(rearm,isSupplyVehicle), _configSupply > 0]) then { + TRACE_1("transportAmmo vehicle - adding virtual ammo",typeOf _object); - _ammoToDetonate pushBack ["2000Rnd_65x39_belt", 2000]; + _ammoToDetonate pushBack ["2000Rnd_65x39_belt", 2000, false]; _totalAmmo = _totalAmmo + 2000; - _ammoToDetonate pushBack ["20Rnd_105mm_HEAT_MP", 100]; + + _ammoToDetonate pushBack ["20Rnd_105mm_HEAT_MP", 100, true]; _totalAmmo = _totalAmmo + 100; - _ammoToDetonate pushBack ["SatchelCharge_Remote_Mag", 10]; + + _ammoToDetonate pushBack ["SatchelCharge_Remote_Mag", 10, true]; _totalAmmo = _totalAmmo + 10; }; diff --git a/addons/cookoff/functions/fnc_handleDamageBox.sqf b/addons/cookoff/functions/fnc_handleDamageBox.sqf index 9368cd3193d..2d55db0fd02 100644 --- a/addons/cookoff/functions/fnc_handleDamageBox.sqf +++ b/addons/cookoff/functions/fnc_handleDamageBox.sqf @@ -1,13 +1,13 @@ #include "..\script_component.hpp" /* - * Author: KoffeinFlummi, commy2 - * Handles all incoming damage for boxi + * Author: KoffeinFlummi, commy2, johnb43 + * Handles all incoming damage for boxes. * * Arguments: * HandleDamage EH * * Return Value: - * Damage to be inflicted. + * Damage to be inflicted (can be nil) * * Example: * _this call ace_cookoff_fnc_handleDamageBox @@ -15,58 +15,48 @@ * Public: No */ -params ["_vehicle", "", "_damage", "_source", "_ammo", "_hitIndex", "_shooter"]; +// If cookoff for boxes is disabled, exit +if (!GVAR(enableAmmobox) || {GVAR(ammoCookoffDuration) == 0}) exitWith {}; -// it's already dead, who cares? -if (damage _vehicle >= 1) exitWith {}; +params ["_box", "", "_damage", "_source", "_ammo", "", "_instigator", "_hitPoint"]; -// If cookoff is disabled exit -if (_vehicle getVariable [QGVAR(enable), GVAR(enable)] in [0, false]) exitWith {}; +if (!local _box) exitWith {}; -// get hitpoint name -private _hitpoint = "#structural"; +// If it's already dead, ignore +if (!alive _box) exitWith {}; -if (_hitIndex != -1) then { - _hitpoint = toLowerANSI ((getAllHitPointsDamage _vehicle param [0, []]) select _hitIndex); -}; +if !(_box getVariable [QGVAR(enableAmmoCookoff), true]) exitWith {}; + +if !(_hitPoint == "" && {_damage > 0.5}) exitWith {}; // "" means structural damage -// get change in damage -private _oldDamage = 0; +private _ammoConfig = _ammo call CBA_fnc_getObjectConfig; -if (_hitpoint isEqualTo "#structural") then { - _oldDamage = damage _vehicle; +// Catch fire when hit by an explosive or incendiary round +if ((getNumber (_ammoConfig >> "explosive") >= 0.5) || {getNumber (_ammoConfig >> QEGVAR(vehicle_damage,incendiary)) > random 1}) then { + [QGVAR(cookOffBoxServer), [_box, _source, _instigator]] call CBA_fnc_serverEvent; } else { - _oldDamage = _vehicle getHitIndex _hitIndex; -}; + // There is a small chance of cooking a box off if it's shot by tracer ammo + if (random 1 >= _damage * 0.05) exitWith {}; -if (_hitpoint == "#structural" && _damage > 0.5) then { - // Almost always catch fire when hit by an explosive - if (IS_EXPLOSIVE_AMMO(_ammo)) then { - _vehicle call FUNC(cookOffBox); + // Need magazine to check for tracers + private _magazine = if (_source == _instigator) then { + currentMagazine _source } else { - // Need magazine to check for tracers - private _mag = ""; - if (_source == _shooter) then { - _mag = currentMagazine _source; - } else { - _mag = _source currentMagazineTurret ([_shooter] call CBA_fnc_turretPath); - }; - private _magCfg = configFile >> "CfgMagazines" >> _mag; + _source currentMagazineTurret (_source unitTurret _instigator) + }; - // Magazine could have changed during flight time (just ignore if so) - if (getText (_magCfg >> "ammo") == _ammo) then { - // If magazine's tracer density is high enough then low chance for cook off - private _tracers = getNumber (_magCfg >> "tracersEvery"); - if (_tracers >= 1 && {_tracers <= 4}) then { - if (random 1 < _oldDamage*0.05) then { - _vehicle call FUNC(cookOffBox); - }; - }; + private _configMagazine = configFile >> "CfgMagazines" >> _magazine; + + // Magazine could have changed during flight time (just ignore if so) + if (getText (_configMagazine >> "ammo") == _ammo) then { + // If magazine's tracer density is high enough then low chance for cook off + private _tracers = getNumber (_configMagazine >> "tracersEvery"); + + if (_tracers >= 1 && {_tracers <= 4}) then { + [QGVAR(cookOffBoxServer), [_box, _source, _instigator]] call CBA_fnc_serverEvent; }; }; - - // prevent destruction, let cook-off handle it if necessary - _damage min 0.89 -} else { - _damage }; + +// Prevent destruction, let cook-off handle it if necessary +_damage min 0.89 diff --git a/addons/cookoff/functions/fnc_isMagazineFlare.sqf b/addons/cookoff/functions/fnc_isMagazineFlare.sqf index b6c8a604be3..f856b21a9a4 100644 --- a/addons/cookoff/functions/fnc_isMagazineFlare.sqf +++ b/addons/cookoff/functions/fnc_isMagazineFlare.sqf @@ -1,24 +1,22 @@ #include "..\script_component.hpp" /* * Author: Cyruz - * Checks if the magazine has ammo which is a flare + * Checks if the magazine's ammo are flares. * * Arguments: * 0: Magazine * * Return Value: - * 0: If magazine is type of flare + * If magazine is type of flare * * Example: - * ["3Rnd_UGL_FlareWhite_F"] call ace_cookoff_fnc_isMagazineFlare + * "3Rnd_UGL_FlareWhite_F" call ace_cookoff_fnc_isMagazineFlare * * Public: No */ params ["_magazine"]; -private _ammo = getText (configFile >> "CfgMagazines" >> _magazine >> "ammo"); -private _intensity = getNumber (configFile >> "CfgAmmo" >> _ammo >> "intensity"); -private _flare = getNumber (configFile >> "CfgAmmo" >> _ammo >> QEGVAR(grenades,flare)); +private _configAmmo = configFile >> "CfgAmmo" >> getText (configFile >> "CfgMagazines" >> _magazine >> "ammo"); -_intensity != 0 || _flare == 1 +getNumber (_configAmmo >> "intensity") != 0 || {getNumber (_configAmmo >> QEGVAR(grenades,flare)) == 1} diff --git a/addons/cookoff/functions/fnc_smoke.sqf b/addons/cookoff/functions/fnc_smoke.sqf index ce50043413f..94055041de7 100644 --- a/addons/cookoff/functions/fnc_smoke.sqf +++ b/addons/cookoff/functions/fnc_smoke.sqf @@ -5,7 +5,7 @@ * * Arguments: * 0: Vehicle - * 1. Selections for smoke to come out of (default: []) + * 1: Selections for smoke to come out of * * Return Value: * None @@ -16,12 +16,11 @@ * Public: No */ -params ["_vehicle", ["_positions", []]]; +params ["_vehicle", "_selections"]; -private _turretConfig = [_vehicle, [0]] call CBA_fnc_getTurret; -private _positionBarrelEnd = getText (_turretConfig >> "gunBeg"); +private _positionBarrelEnd = getText ([_vehicle, [0]] call CBA_fnc_getTurret >> "gunBeg"); -// smoke out of cannon and hatches +// Smoke out of cannon and hatches private _smokeBarrel = "#particlesource" createVehicleLocal [0, 0, 0]; _smokeBarrel setParticleClass "MediumDestructionSmoke"; _smokeBarrel attachTo [_vehicle, [0, 0, 0], _positionBarrelEnd]; @@ -29,10 +28,10 @@ _smokeBarrel attachTo [_vehicle, [0, 0, 0], _positionBarrelEnd]; private _effects = [_smokeBarrel]; { - private _position = [0, -2, 0]; - - if (_x isNotEqualTo "#noselection") then { - _position = _vehicle selectionPosition _x; + private _position = if (_x != "#noselection") then { + _vehicle selectionPosition _x + } else { + [0, -2, 0] }; private _smoke = "#particlesource" createVehicleLocal [0, 0, 0]; @@ -40,6 +39,6 @@ private _effects = [_smokeBarrel]; _smoke attachTo [_vehicle, _position]; _effects pushBack _smoke; -} forEach _positions; +} forEach _selections; _vehicle setVariable [QGVAR(effects), _effects]; diff --git a/addons/cookoff/initSettings.inc.sqf b/addons/cookoff/initSettings.inc.sqf index 8912636fd6a..c7f1be8ffde 100644 --- a/addons/cookoff/initSettings.inc.sqf +++ b/addons/cookoff/initSettings.inc.sqf @@ -1,69 +1,71 @@ [ - QGVAR(enable), "LIST", - [LSTRING(enable_hd_name), LSTRING(enable_hd_tooltip)], + QGVAR(enableFire), + "CHECKBOX", + [LSTRING(enableFire_name), LSTRING(enableFire_tooltip)], LSTRING(category_displayName), - [[0, 1, 2], ["STR_A3_OPTIONS_DISABLED", ELSTRING(common,playerOnly), ELSTRING(common,playersAndAI)], 2], - true, // isGlobal - {[QGVAR(enable), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + true, + 1 ] call CBA_fnc_addSetting; [ - QGVAR(enableFire), "CHECKBOX", - [LSTRING(enableFire_name), LSTRING(enableFire_tooltip)], + QGVAR(cookoffDuration), + "SLIDER", + [LSTRING(cookoffDuration_name), LSTRING(cookoffDuration_tooltip)], + LSTRING(category_displayName), + [0, 10, 1, 2], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(probabilityCoef), + "SLIDER", + [LSTRING(probabilityCoef_name), LSTRING(probabilityCoef_tooltip)], LSTRING(category_displayName), - true, // default value - true, // isGlobal - {[QGVAR(enableFire), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart + [0, 10, 1, 2], + 1 ] call CBA_fnc_addSetting; [ - QGVAR(destroyVehicleAfterCookoff), "CHECKBOX", + QGVAR(destroyVehicleAfterCookoff), + "CHECKBOX", [LSTRING(destroyVehicleAfterCookoff_name), LSTRING(destroyVehicleAfterCookoff_tooltip)], LSTRING(category_displayName), - false, // default value - true, // isGlobal - {[QGVAR(destroyVehicleAfterCookoff), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart + false, + 1 ] call CBA_fnc_addSetting; [ - QGVAR(enableAmmoCookoff), "CHECKBOX", + QGVAR(enableAmmoCookoff), + "CHECKBOX", [LSTRING(enableAmmoCookoff_name), LSTRING(enableAmmoCookoff_tooltip)], LSTRING(category_displayName), - true, // default value - true, // isGlobal - {[QGVAR(enableAmmoCookoff), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart + true, + 1 ] call CBA_fnc_addSetting; [ - QGVAR(enableAmmobox), "CHECKBOX", + QGVAR(enableAmmobox), + "CHECKBOX", [LSTRING(enableBoxCookoff_name), LSTRING(enableBoxCookoff_tooltip)], LSTRING(category_displayName), - true, // default value - true, // isGlobal - {[QGVAR(enableAmmobox), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + true, + 1 ] call CBA_fnc_addSetting; [ - QGVAR(ammoCookoffDuration), "SLIDER", + QGVAR(ammoCookoffDuration), + "SLIDER", [LSTRING(ammoCookoffDuration_name), LSTRING(ammoCookoffDuration_tooltip)], LSTRING(category_displayName), - [0,5,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(ammoCookoffDuration), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + [0, 10, 1, 2], + 1 ] call CBA_fnc_addSetting; [ - QGVAR(probabilityCoef), "SLIDER", - [LSTRING(probabilityCoef_name), LSTRING(probabilityCoef_tooltip)], + QGVAR(removeAmmoDuringCookoff), + "CHECKBOX", + [LSTRING(removeAmmoDuringCookoff_name), LSTRING(removeAmmoDuringCookoff_tooltip)], LSTRING(category_displayName), - [0,5,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(probabilityCoef), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + true, + 1 ] call CBA_fnc_addSetting; diff --git a/addons/cookoff/script_component.hpp b/addons/cookoff/script_component.hpp index d41b8f675c3..bf8fd62dd5c 100644 --- a/addons/cookoff/script_component.hpp +++ b/addons/cookoff/script_component.hpp @@ -16,14 +16,12 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define IS_EXPLOSIVE_AMMO(ammo) (getNumber (ammo call CBA_fnc_getObjectConfig >> "explosive") > 0.5) - // Stages of cookoff in order (in seconds) -// Should be no un-synced randomness in these as the effects must be ran on each client -#define IGNITE_TIME 3 -#define SMOKE_TIME 10.5 +// Should be no un-synced randomness in these as the effects must be run on each client +#define SMOKE_DELAY 10.5 +#define DETONATION_DELAY 3 #define COOKOFF_TIME 14 // Cook off time should be 20s at most due to length of sound files -#define COOKOFF_TIME_BOX 82.5 // Cook off time for boxes should be significant to allow time for ammo to burn +#define ENGINE_FIRE_TIME 240 #define MIN_TIME_BETWEEN_FLAMES 5 #define MAX_TIME_BETWEEN_FLAMES 15 #define MAX_TIME_BETWEEN_AMMO_DET 25 @@ -32,9 +30,6 @@ #define MIN_AMMO_DETONATION_START_DELAY 1 // Min time to wait before a vehicle's ammo starts to cookoff #define MAX_AMMO_DETONATION_START_DELAY 6 // Max time to wait before a vehicle's ammo starts to cookoff -// Delay between flame effect for players in a cooking off vehicle -#define FLAME_EFFECT_DELAY 0.4 - // Common commander hatch defines for default vehicles #define DEFAULT_COMMANDER_HATCHES ["osa_poklop_commander", "hatch_commander_axis"] diff --git a/addons/cookoff/stringtable.xml b/addons/cookoff/stringtable.xml index 5f764a24b76..205b8d2b4df 100644 --- a/addons/cookoff/stringtable.xml +++ b/addons/cookoff/stringtable.xml @@ -2,7 +2,7 @@ - ACE Cook off + ACE Cook-off ACE Detonación inducida por calor ACE Detonazione Munizioni ACE 殉爆效果 @@ -16,158 +16,38 @@ ACE Cook off ACE Vznícení munice - - Damage handling and turret effects - Daño y efectos de torreta - Schadensberechnung und Geschützturmeffekte - 損傷処理と砲塔の効果 - Обработка урона и эффектов срыва башни - Manipulação de dano e efeitos de torre - Dégâts et effets de tourelle - 傷害控制及炮塔效果 - 损坏处理和炮塔效果 - Gestione danni ed effetti torretta - Poškodit ovládání a efekty věže - Obsługa obrażeń i efekty wieży - 피해량 조절 및 포탑에 효과 부여 - - - Changes damage handling for cook off and turret explosion effects - Cambia el daño de la detonación inducida por calor y los efectos de la explosión de la torreta - Ändert die Schadensberechnung für die Durchzündung und die Explosionseffekte des Geschützturmes - 誘爆の損傷処理と砲塔の爆発効果を変更します。 - Изменяет обработку урона для возгорания и эффекта срыва башни - Modifica a manipulação de dano para o cozinhamento de munição e efeitos de explosão da torre - Modifie la gestion des dégâts pour l'auto-inflammation et les effets d'explosion de tourelle. - 更改殉爆以及炮塔爆炸之傷害控制 - 改变殉爆和炮塔爆炸的损坏处理效果 - Modifica la gestione dei danni per l'esplosione di munizioni e gli effetti di esplosione della torretta - Změní poškození ovládání a efekty výbuchu veže - Zmienia obsługę obrażeń podczas samozapłonu i eksplozji wieży - 쿡오프로 인해 피해량의 변화와 포탑 터짐현상을 결정합니다. - - - Enable ammo box cook off - Habilitar detonación inducida por calor en las cajas de munición - 弾薬箱の誘爆を有効化 - Durchzündung für Munitionskisten ermöglichen - 탄약 상자 쿡오프 현상 활성화 - Aktywuj samozapłon skrzyń z amunicją - Auto-inflammation des caisses de munitions - Abilita esplosione casse munizioni - 開啟彈藥箱殉爆效果 - 开启弹药箱殉爆效果 - Разрешить детонацию ящиков с боеприпасами - Permitir cozinhar caixas de munição - Povolit vynícení munice v krabicích - - - Enables cooking off of ammo boxes. - Habilita la detonación inducida por calor en las cajas de munición - 弾薬箱が誘爆するようになります。 - Ermöglicht Durchzündung von Munitionskisten. - 탄약 상자에 쿡오프 현상을 적용합니다. - Aktywuje samozapłon skrzyń z amunicją - Permet l'auto-inflammation des caisses de munitions. - Abilita l'esplosione di casse di munizioni distrutte. - 開啟彈藥箱殉爆效果 - 开启弹药箱殉爆效果 - Активирует детонацию ящиков с боеприпасами - Permitir que caixas de munição cozinhem. - Zapíná vznícení munice v krabicích. - - - Enable Ammunition cook off - Habilitar la detonación inducida por calor en la munición - 弾薬の誘爆を有効化 - Durchzündung für Munition ermöglichen - 탄약 쿡오프 현상 활성화 - Aktywuj samozapłon amunicji - Auto-inflammation des munitions - Abilita Esplosione Munizioni - 開啟彈藥殉爆效果 - 开启弹药殉爆效果 - Разрешить детонацию боекомплекта - Permitir cozinhar munição - Povolit vznícení munice + + Enable vehicle cook-off fire + 車両の誘爆火災を有効化 + Вкл. возгорание техники - - Enables Ammunition cook off. Fires ammunition projectiles while vehicle is on fire and has ammunition. - Habilita la detonación inducida por calor en la munición. Dispara proyectiles de munición mientras el vehículo está ardiendo y tiene munición - 弾薬が誘爆します。車両が燃えると、搭載している弾薬が激しく燃え上がります。 - Ermöglicht Durchzündung von Munition. Feuert Projektile der Munition ab, solange das Fahrzeug brennt und Munition besitzt. - Aktywuje samozapłon amunicji. Wystrzeliwuje pociski podczas gdy pojazd płonie i posiada amunicję. - Permet l'auto-inflammation des munitions. Tire des projectiles tant que le véhicule est en feu et contient des munitions. - Abilita l'esplosione di munizioni. Spara proiettili di munizioni quando il veicolo va a fuoco e contiene ancora munizioni. - 開啟彈藥殉爆效果。當一台載有彈藥的載具起火時, 將會有殉爆的效果 - 开启弹药殉爆效果。当一台载有弹药的载具起火时,将会有殉爆的效果。 - 쿡오프 현상을 활성화 합니다. 이것은 탄약에 불이 붙어 있는 동안 주변에 발사체를 발사합니다. - Активирует детонацию боекомплекта в горящей технике. - Permite que a munição cozinhe. Dispara projéteis de munição enquanto o veículo está em chamas e tem munição. - Zapíná vznícení munice. Vystřeluje projektily po dobu kdy vozidlo hoří a má munici. + + Enables vehicle cook-off fire effects.\nThis doesn't include ammunition detonations. + 車両の誘爆火災エフェクトを有効化します。\nこれには弾薬の爆発は含まれません。 + Вкл. эффект горения техники. \nНе включает детонацию боекомплекта - - Ammunition cook off duration - Duración de la detonación inducida por calor de la munición - Munitionsdurchzündungsdauer - Czas trwania samozapłonu amunicji - 弾薬の誘爆持続時間 - Durée d'auto-inflammation des munitions - Durata Esplosione Munizioni - 彈藥殉爆效果持續時間 - 弹药殉爆效果持续时间 - 쿡오프 지속 시간 - Длительность детонации боеприпасов - Duração do cozinhamento de munição - Doba trvání vznícení munice + + Vehicle cook-off fire duration multiplier + 車両の誘爆火災の持続時間倍率 + Увел. продолжительности горения техники - - Multiplier for how long cook off lasts [Setting to 0 will disable ammo cookoff] - Multiplicador de cuanto dura la detonación inducida por calor [Ponerlo a cero la deshabilita] - Faktor für die Munitionsdurchzündungsdauer [0 zum Deaktivieren] - Multiplicateur permettant de régler la durée durant laquelle les munitions continuent d'exploser [Une valeur de 0 désactive l'auto-inflammation]. - Mnożnik decydujący jak długo ma trwać samozapłon amunicji [Ustawienie na 0 spowoduje wyłącznie samozapłonu] - 誘爆の持続時間を乗数で設定します。[0 に設定で誘爆を無効化] - Moltiplicatore della durata delle esplosioni di munizioni [Se impostato su 0 disabiliterà le esplosioni delle munizioni] - 設定彈藥殉爆效果會持續多久時間 [輸入0來關閉殉爆效果] - 设定弹药殉爆效果会持续多久时间 [输入0来关闭殉爆效果] - 쿡오프 지속 시간의 배수 [0 이면 비활성] - Множитель длительности детонации [0 - отключает детонацию боеприпасов] - Multiplicação da duração do cozinhamento [0 faz com que o cozinhamento seja desativado] - Multiplikátor doby trvání vznícení munice [Nastavte 0 pro vypnutí vznícení munice] + + Multiplier for how long vehicle cook-off fire lasts.\nSetting to 0 will disable vehicle cook-off fire. + 車両の誘爆火災の持続時間をどのくらいの長さにするかの倍率。\n0に設定すると車両の誘爆火災が無効化されます。 + Увел. продолжительности горения техники. \nУстановка значения на 0 выключает возгорание техники. - Cook-off probability coefficient - Coeficiente de probabilidad de detonación inducida por calor - 誘爆の可能性係数 - Coefficiente Probabilità Esplosione - Faktor für Wahrscheinlichkeit der Durchzündung - 殉爆發生機率係數 - 殉爆发生机率系数 - Coefficient de probabilité d'auto-inflammation - Współczynnik prawdopodobieństwa samozapłonu - Коэф. вероятности детонации - Probabilidade de Cozinhar - Koeficient pravděpodobnosti vznícení munice - 쿡오프 발생 확률 계수 + Vehicle cook-off fire probability multiplier + 車両の誘爆火災の可能性倍率 + Возможность усиления пожара при детонации техники - Multiplier for cook-off probability. Higher value results in higher cook-off probability - Multiplicador de probabilidad de detonación inducida por calor. Valores más altos producen mayor probabilidad - 誘爆する可能性の乗数。高い値では誘爆する可能性が高まります。 - Moltiplicatore per la probabilità dell'esplosione di munizioni. Un valore più alto aumenta la probabilità. - Faktor für Wahrscheinlichkeit der Durchzündung. Ein höherer Wert führt zu höherer Durchzündungswahrscheinlichkeit. - 調整殉爆發生機率係數。值越高代表越容易發生殉爆 - 调整殉爆发生机率系数。值越高代表越容易发生殉爆。 - Multiplicateur de probabilité de l'auto-inflammation. Plus la valeur est élevée, plus la probabilité de combustion est grande. - Mnożnik prawdopodobieństwa samozapłonu. Większa wartość oznacza większe prawdopodobieństwo samozapłonu - Множитель коэффициента вероятности детонации. Чем выше значение, тем выше вероятность - Multiplicador para a chance de cozinhamento. Valores mais altos aumentam as chances de ocorrer. - Multiplikátor pro pravděpodobnost vznícení munice. Vyšší hodnota znamená vyšší šanci vznícení munice. - 쿡오프가 일어날 확률에 계수를 곱합니다. 더 큰 숫자는 더 높은 확률의 쿡오프를 일으킵니다. + Multiplier for vehicle cook-off fire probability. Higher value results in higher cook-off probability.\nSetting to 0 will disable vehicle cook-off fire. + 車両の誘爆火災がどのくらいの可能性で発生するかの倍率。高い数値は高い誘爆の可能性につながります。\n0に設定すると車両の誘爆火災が無効化されます。 + Увел. вероятности возникновения возгорания техники. Большое значение указывает на высокую вероятность детонации. \nУстановка значения 0 предотвращает возгорание техники. - Destroy Vehicles After Cook-off + Destroy vehicles after cook-off 쿡오프 후 차량 파괴 殉爆发生后摧毁载具 Уничтожать технику после детонации @@ -181,7 +61,7 @@ Controls whether vehicles will always be destroyed after cooking off. - 誘爆後に車両を破壊するかどうかを設定する。 + 誘爆の終了後に車両を必ず完全破壊するかどうかを設定します。 Kontroluje, czy pojazdy będą zawsze niszczone po samozapłonie. Steuert, ob Fahrzeuge nach dem Durchzünden immer zerstört werden. Determina se veicoli saranno sempre distrutti dall'esplosione delle munizioni. @@ -189,32 +69,66 @@ Contrôle si les véhicules seront toujours détruits après l'auto-inflammation. Define se os veículos serão sempre destruídos após cozinhamento. Определяет, всегда ли транспортные средства будут уничтожаться после детонации. + Controla si los vehículos siempre será destruidos despues de la detonación inducida por calor. - - Enable Cook-Off Vehicle Fire - 誘爆火災を有効化 - Véhicules - Feu durant l'auto-inflammation - Вкл. горение техники от детонации - Aktiviert das in Brand setzen des Fahrzeugs während des Durchzündens der Munition - Abilita incendiamento veicoli - Włącz pożar pojazdu podczas samozapłonu - 启用殉爆载具火灾 - 차량 쿡오프 화재 활성화 - Habilitar incendio a causa de la detonación inducida por calor - Ativar incêndio de veículo durante cozinhamento + + Enable vehicle ammo cook-off + 車両弾薬の誘爆を有効化 + Вкл. детонацию боеприпасов в технике. - - Whether or not vehicles will catch on fire during cook-off - 誘爆により車両が炎上するかどうかを設定します。 - Définit si les véhicules prennent feu durant l'auto-inflammation de leurs munitions. - Будет ли техника гореть при детонации боеприпасов - Ob Fahrzeuge in Brand gesetzt werden, während deren Munition durchzündet. - Determina se veicoli cominceranno a bruciare se le loro munizioni esplodono. - Określa, czy pojazdy zapalą się podczas samozapłonu ich amunicji. - 车辆在殉爆过程中是否会起火 - 쿡오프가 일어나면 차량에 불이 붙습니다. - Define si los vehículos salen ardiendo despues de una detonación inducida por calor. - Define se os veículos pegarão fogo durante o cozinhamento. + + Enables cooking off of vehicle ammunition. Fires ammunition projectiles while vehicle has ammunition remaining.\nThis doesn't include fire effects. + 車両弾薬の誘爆を有効化します。車両に積載されたままの弾薬と弾頭が発射されます。\nこれには火災エフェクトは含まれません。 + Вкл. детонацию боеприпасов на технике. Боеприпасы и боеголовки, которые остаются заряженными на транспортном средстве, будут приведены в действие. \nЭто не включает эффекты пожара. + + + Enable ammo box cook-off + Habilitar detonación inducida por calor en las cajas de munición + 弾薬箱の誘爆を有効化 + Durchzündung für Munitionskisten ermöglichen + 탄약 상자 쿡오프 현상 활성화 + Aktywuj samozapłon skrzyń z amunicją + Auto-inflammation des caisses de munitions + Abilita esplosione casse munizioni + 開啟彈藥箱殉爆效果 + 开启弹药箱殉爆效果 + Разрешить детонацию ящиков с боеприпасами + Permitir cozinhar caixas de munição + Povolit vynícení munice v krabicích + + + Enables cooking off of ammo boxes.\nThis doesn't include fire effects. + 弾薬箱の誘爆を有効化します。\nこれには火災エフェクトは含まれません。 + Вкл. детонацию ящика с боеприпасами. \nЭто не включает эффекты огня. + + + Ammo cook-off duration multiplier + 弾薬の誘爆の持続時間倍率 + Увеличение продолжительности детонации боеприпасов. + + + 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. + 弾薬の誘爆の持続時間をどのくらいの長さにするかの倍率。車両弾薬と弾薬箱どちらにも影響します。\n0に設定すると弾薬の誘爆が無効化されます。 + Увеличение продолжительности детонации боеприпасов. Это влияет как на боеприпасы в технике, так и на ящики с боеприпасами. \nУстановка значения 0 отключает детонацию боеприпасов. + + + Enable ammo removal during cook-off + 誘爆による弾薬の除去を有効化 + Retirer les munitions durant l'auto-inflammation + Aktiviert/Deaktiviert Entfernung der Munition beim Durchzünden + Abilita rimozione munizioni dopo l'esplosione + Włącz/Wyłącz usuwanie amunicji podczas samozapłonu + 启用/禁用殉爆过程中的弹药移除功能 + 쿡오프시 탄약 제거 활성화/비활성화 + Вкл. удаление боеприпасов из-за детонации + Habilita/Deshabilita ka eliminación de munición durante la detonación inducida por calor + + + Removes all ammo during cook-off. + Retire des munitions des véhicules durant une auto-inflammation. + Entfernt Munition während dem Durchzünden der Munition eines Fahrzeuges. + 誘爆によって全ての弾薬を除去します。 + Все боеприпасы уничтожаются путем подрыва. diff --git a/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf b/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf index e5aa51d3429..d7af22d319a 100644 --- a/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf +++ b/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf @@ -25,7 +25,7 @@ params ["_vehicle", "_turret", "_magSource", "_carryMag", "_ammoReceived", ["_re TRACE_6("reload_handleAddTurretMag",_vehicle,_turret,_magSource,_carryMag,_ammoReceived,_returnTo); TRACE_2("",local _vehicle,_vehicle turretLocal _turret); -if (!(_vehicle turretLocal _turret)) exitWith {}; +if !(_vehicle turretLocal _turret) exitWith {}; ([_vehicle, _turret, _carryMag] call FUNC(reload_canLoadMagazine)) params ["_canAdd", "_loadedMag", "_neededAmmo", "_isBeltLinking"]; TRACE_4("canLoad",_canAdd,_loadedMag,_neededAmmo,_isBeltLinking); diff --git a/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf b/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf index 59d948ba279..51036b525a3 100644 --- a/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf +++ b/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf @@ -24,7 +24,7 @@ params ["_vehicle", "_turretPath", "_carryMag", "_vehMag", "_unloadTo"]; TRACE_5("removeTurretMag EH",_vehicle,_turretPath,_carryMag,_vehMag,_unloadTo); TRACE_3("",local _vehicle,_vehicle turretLocal _turretPath,local _unloadTo); -if (!(_vehicle turretLocal _turretPath)) exitWith {}; +if !(_vehicle turretLocal _turretPath) exitWith {}; private _magsInWeapon = []; // Check how much ammo it has now: { diff --git a/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf b/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf index da8383b6085..ca445400b02 100644 --- a/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf +++ b/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf @@ -41,7 +41,7 @@ if ((_fullMagazines == 0) && {_bulletsRemaining == 0}) exitWith {}; private _container = _unloadTo getVariable [QGVAR(container), objNull]; if ((_container distance _unloadTo) > 10) then { _container = objNull; }; if (isNull _container) then { - _container = (nearestObjects [_unloadTo, [QGVAR(ammo_holder), "GroundWeaponHolder"], 10]) param [0, objNull]; + _container = (nearestObjects [_unloadTo, [["GroundWeaponHolder"], [QGVAR(ammo_holder)]] select GVAR(handleExtraMagazinesType), 10]) param [0, objNull]; }; diff --git a/addons/csw/initSettings.inc.sqf b/addons/csw/initSettings.inc.sqf index de3976896be..bc157e1164b 100644 --- a/addons/csw/initSettings.inc.sqf +++ b/addons/csw/initSettings.inc.sqf @@ -45,17 +45,12 @@ private _categoryArray = [format ["ACE %1", localize LSTRING(DisplayName)]]; [LSTRING(progressBarTimeCoefficent_displayName), LSTRING(progressBarTimeCoefficent_description)], _categoryArray, [0,2,1,2], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(progressBarTimeCoefficent), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart + true // isGlobal ] call CBA_fnc_addSetting; [ QGVAR(dragAfterDeploy), "CHECKBOX", [LSTRING(dragAfterDeploy_displayName), LSTRING(dragAfterDeploy_description)], _categoryArray, - false, // default value - false, // isGlobal - {[QGVAR(dragAfterDeploy), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart + false // default value ] call CBA_fnc_addSetting; diff --git a/addons/csw/stringtable.xml b/addons/csw/stringtable.xml index 4aea2a24b4f..7c241a8a515 100644 --- a/addons/csw/stringtable.xml +++ b/addons/csw/stringtable.xml @@ -1120,5 +1120,22 @@ [CSW] Сумка с СПГ-9М орудием [CSW] SPG-9M 발사기 가방 + + + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[班组\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + diff --git a/addons/dagr/XEH_postInit.sqf b/addons/dagr/XEH_postInit.sqf index 6996ced7f21..34dc9818437 100644 --- a/addons/dagr/XEH_postInit.sqf +++ b/addons/dagr/XEH_postInit.sqf @@ -30,4 +30,4 @@ GVAR(vectorConnected) = false; GVAR(noVectorData) = true; GVAR(vectorGrid) = "00000000"; -[QEGVAR(vector,rangefinderData), FUNC(handleRangeFinderData)] call CBA_fnc_addEventHandler; +[QEGVAR(vector,rangefinderData), LINKFUNC(handleRangeFinderData)] call CBA_fnc_addEventHandler; diff --git a/addons/disarming/functions/fnc_disarmDropItems.sqf b/addons/disarming/functions/fnc_disarmDropItems.sqf index e1a4c379b4f..6e842e739a4 100644 --- a/addons/disarming/functions/fnc_disarmDropItems.sqf +++ b/addons/disarming/functions/fnc_disarmDropItems.sqf @@ -30,7 +30,7 @@ private _fncSumArray = { }; //Sanity Checks -if (!([_target] call FUNC(canBeDisarmed))) exitWith { +if !([_target] call FUNC(canBeDisarmed)) exitWith { [_caller, _target, "Debug: Cannot disarm target"] call FUNC(eventTargetFinish); }; if (_doNotDropAmmo && {({_x in _listOfItemsToRemove} count (magazines _target)) > 0}) exitWith { @@ -74,7 +74,6 @@ if (_holder getVariable [QGVAR(holderInUse), false]) exitWith { }; _holder setVariable [QGVAR(holderInUse), true]; - //Remove Magazines private _targetMagazinesStart = magazinesAmmo _target; private _holderMagazinesStart = magazinesAmmoCargo _holder; @@ -96,7 +95,7 @@ if (({((_x select 0) in _listOfItemsToRemove) && {(getNumber (configFile >> "Cfg [_caller, _target, "Debug: Didn't Remove Magazines"] call FUNC(eventTargetFinish); }; //Verify holder has mags unit had -if (!([_targetMagazinesStart, _targetMagazinesEnd, _holderMagazinesStart, _holderMagazinesEnd] call FUNC(verifyMagazinesMoved))) then { +if !([_targetMagazinesStart, _targetMagazinesEnd, _holderMagazinesStart, _holderMagazinesEnd] call FUNC(verifyMagazinesMoved)) then { _holder setVariable [QGVAR(holderInUse), false]; [_caller, _target, "Debug: Crate Magazines not in holder"] call FUNC(eventTargetFinish); }; @@ -238,7 +237,7 @@ if (_holderIsEmpty) then { [_caller, _target, "Debug: Drop Actions Timeout"] call FUNC(eventTargetFinish); }; //If target lost disarm status: - if (!([_target] call FUNC(canBeDisarmed))) exitWith { + if !([_target] call FUNC(canBeDisarmed)) exitWith { _holder setVariable [QGVAR(holderInUse), false]; [_caller, _target, "Debug: Target cannot be disarmed"] call FUNC(eventTargetFinish); }; diff --git a/addons/disarming/functions/fnc_eventTargetStart.sqf b/addons/disarming/functions/fnc_eventTargetStart.sqf index 7173f66a76d..a7154ce2e4c 100644 --- a/addons/disarming/functions/fnc_eventTargetStart.sqf +++ b/addons/disarming/functions/fnc_eventTargetStart.sqf @@ -32,7 +32,7 @@ private _itemsToAdd = []; } forEach _listOfObjectsToRemove; { - if (!(_x in _listOfObjectsToRemove)) then { + if !(_x in _listOfObjectsToRemove) then { _listOfObjectsToRemove pushBack _x; }; } forEach _itemsToAdd; diff --git a/addons/disarming/functions/fnc_openDisarmDialog.sqf b/addons/disarming/functions/fnc_openDisarmDialog.sqf index da9a860678a..6cf15f4cad1 100644 --- a/addons/disarming/functions/fnc_openDisarmDialog.sqf +++ b/addons/disarming/functions/fnc_openDisarmDialog.sqf @@ -16,11 +16,14 @@ * * Public: No */ + params ["_caller", "_target"]; -#define DEFUALTPATH "\A3\Ui_f\data\GUI\Cfg\Ranks\%1_gs.paa" + +#define DEFAULTPATH "\A3\Ui_f\data\GUI\Cfg\Ranks\%1_gs.paa" + //Sanity Checks if (_caller != ACE_player) exitWith {ERROR("Player isn't caller?");}; -if (!([_player, _target] call FUNC(canPlayerDisarmUnit))) exitWith {ERROR("Can't Disarm Unit");}; +if !([_player, _target] call FUNC(canPlayerDisarmUnit)) exitWith {ERROR("Can't Disarm Unit");}; if (dialog) then {ERROR("Dialog open when trying to open disarm dialog"); closeDialog 0;}; disableSerialization; @@ -74,8 +77,8 @@ GVAR(disarmTarget) = _target; private _rankPicture = _display displayCtrl 1203; //Show rank and name (just like BIS's inventory) - private _icon = format [DEFUALTPATH, toLowerANSI (rank _target)]; - if (_icon isEqualTo DEFUALTPATH) then {_icon = ""}; + private _icon = format [DEFAULTPATH, toLowerANSI (rank _target)]; + if (_icon isEqualTo DEFAULTPATH) then {_icon = ""}; _rankPicture ctrlSetText _icon; _playerName ctrlSetText ([GVAR(disarmTarget), false, true] call EFUNC(common,getName)); diff --git a/addons/dogtags/XEH_postInit.sqf b/addons/dogtags/XEH_postInit.sqf index d9c35dc172b..dae6b62247a 100644 --- a/addons/dogtags/XEH_postInit.sqf +++ b/addons/dogtags/XEH_postInit.sqf @@ -5,9 +5,11 @@ [QGVAR(getDogtagItem), LINKFUNC(getDogtagItem)] call CBA_fnc_addEventHandler; [QGVAR(addDogtagItem), LINKFUNC(addDogtagItem)] call CBA_fnc_addEventHandler; -// Add actions and event handlers only if ace_medical is loaded +// Add actions and event handlers only if ace_medical is enabled // - Adding actions via config would create a dependency -if (["ace_medical"] call EFUNC(common,isModLoaded)) then { +["CBA_settingsInitialized", { + if !(GETEGVAR(medical,enabled,false)) exitWith {}; + if (hasInterface) then { private _checkTagAction = [ "ACE_CheckDogtag", @@ -44,7 +46,7 @@ if (["ace_medical"] call EFUNC(common,isModLoaded)) then { }; }] call CBA_fnc_addEventHandler; }; -}; +}] call CBA_fnc_addEventHandler; // If the arsenal is loaded, show the custom names for dog tags when in the arsenal if (["ace_arsenal"] call EFUNC(common,isModLoaded)) then { diff --git a/addons/dogtags/XEH_preInit.sqf b/addons/dogtags/XEH_preInit.sqf index 5ad43b02291..f5fcb406b1d 100644 --- a/addons/dogtags/XEH_preInit.sqf +++ b/addons/dogtags/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -GVAR(disabledFactions) = [] call CBA_fnc_createNamespace; +GVAR(disabledFactions) = createHashMap; ADDON = true; diff --git a/addons/dogtags/functions/fnc_canCheckDogtag.sqf b/addons/dogtags/functions/fnc_canCheckDogtag.sqf index 399ad5db252..bec3ef0dfa2 100644 --- a/addons/dogtags/functions/fnc_canCheckDogtag.sqf +++ b/addons/dogtags/functions/fnc_canCheckDogtag.sqf @@ -21,6 +21,6 @@ params ["_player", "_target"]; if (isNull _target) exitWith {false}; // check if disabled for faction -if ([GVAR(disabledFactions) getVariable faction _target] param [0, false]) exitWith {false}; +if ((faction _target) in GVAR(disabledFactions)) exitWith {false}; (!alive _target) || {_target getVariable ["ACE_isUnconscious", false]} diff --git a/addons/dogtags/functions/fnc_canTakeDogtag.sqf b/addons/dogtags/functions/fnc_canTakeDogtag.sqf index 7ae38f7c410..c482d74c1c9 100644 --- a/addons/dogtags/functions/fnc_canTakeDogtag.sqf +++ b/addons/dogtags/functions/fnc_canTakeDogtag.sqf @@ -21,6 +21,6 @@ params ["_player", "_target"]; if (isNull _target) exitWith {false}; // check if disabled for faction -if ([GVAR(disabledFactions) getVariable faction _target] param [0, false]) exitWith {false}; +if ((faction _target) in GVAR(disabledFactions)) exitWith {false}; (!alive _target) || {_target getVariable ["ACE_isUnconscious", false]} diff --git a/addons/dogtags/functions/fnc_disableFactionDogtags.sqf b/addons/dogtags/functions/fnc_disableFactionDogtags.sqf index f1ea5f5c065..c4642ef4b5d 100644 --- a/addons/dogtags/functions/fnc_disableFactionDogtags.sqf +++ b/addons/dogtags/functions/fnc_disableFactionDogtags.sqf @@ -17,4 +17,9 @@ params [["_faction", "", [""]]]; -GVAR(disabledFactions) setVariable [_faction, true]; +_faction = configName (configFile >> "CfgFactionClasses" >> _faction); + +// Faction doesn't exist +if (_faction == "") exitWith {}; + +GVAR(disabledFactions) set [_faction, true]; diff --git a/addons/dragging/functions/fnc_dropObject_carry.sqf b/addons/dragging/functions/fnc_dropObject_carry.sqf index 184b1755c05..7a81d94a059 100644 --- a/addons/dragging/functions/fnc_dropObject_carry.sqf +++ b/addons/dragging/functions/fnc_dropObject_carry.sqf @@ -116,7 +116,7 @@ if (_loadCargo) then { private _vehicles = [_cursorObject, 0, true] call EFUNC(common,nearestVehiclesFreeSeat); if ([_cursorObject] isEqualTo _vehicles) then { - if (["ace_medical"] call EFUNC(common,isModLoaded)) then { + if (GETEGVAR(medical,enabled,false)) then { [_unit, _target, _cursorObject] call EFUNC(medical_treatment,loadUnit); } else { [_unit, _target, _cursorObject] call EFUNC(common,loadPerson); diff --git a/addons/dragging/stringtable.xml b/addons/dragging/stringtable.xml index 9552f50273d..c2f96ce55ac 100644 --- a/addons/dragging/stringtable.xml +++ b/addons/dragging/stringtable.xml @@ -167,6 +167,7 @@ Autoriser la course avec des objets légers Permitir corrida com objetos leves Позволяет работать с легкими объектами + Permitir correr con objetos ligeros Allow the player to run when carrying lightweight objects. @@ -178,6 +179,7 @@ Autorise le joueur à courir lorsqu'il porte un objet léger. Permite ao jogador correr enquanto carrega objetos leves. Разрешите игроку бегать при переноске легких предметов. + Permite al jugador correr cuando porta objetos ligeros. Skip Object Weight @@ -189,6 +191,7 @@ Ignorer le poids de l'objet Ignorar Peso do Objeto Игнорировать вес объекта + Ignora peso del objeto Determines whether object's weight is added onto weight calculations. @@ -200,6 +203,7 @@ Défini si le poids d'un objet est ajouté aux calculs du poids. Determina se o peso do objeto é adicionado aos cálculos de peso. Определяет, добавляется ли вес объекта при расчете веса. + Determina si el peso del objeto es añadido en los cálculos de peso. Max Weight Coefficient @@ -210,6 +214,7 @@ Maximaler Gewichtskoeffizient 最大重量係数 Максимальный коэффициент веса + Máximo Coeficiente de Peso Modifies weight limit calculations. Set to 0 to ignore. @@ -220,6 +225,7 @@ Ändert die Berechnung der Gewichtsbegrenzung. Zum Ignorieren auf 0 setzen. 重量制限の計算を変更します。 無視するには 0 に設定します。 Изменяет расчеты предельного веса. Установите значение 0 для игнорирования. + Modifica el límite de peso de los cálculos. Poner a 0 para que lo ignore. diff --git a/addons/dragon/XEH_postInit.sqf b/addons/dragon/XEH_postInit.sqf index 0305fe772a9..2360a5bd971 100644 --- a/addons/dragon/XEH_postInit.sqf +++ b/addons/dragon/XEH_postInit.sqf @@ -6,7 +6,7 @@ ["vehicle", { params ["","_vehicle"]; TRACE_2("vehicle change",_vehicle,typeOf _vehicle); - if (!(_vehicle isKindOf QGVAR(staticBase))) exitWith {}; + if !(_vehicle isKindOf QGVAR(staticBase)) exitWith {}; _vehicle animate ["rest_rotate", 0]; @@ -14,7 +14,7 @@ [GVAR(pfID)] call CBA_fnc_removePerFrameHandler; private _lastView = cameraView; - if (!(_lastView in ["INTERNAL", "EXTERNAL"])) then { _lastView == "INTERNAL"; }; + if !(_lastView in ["INTERNAL", "EXTERNAL"]) then { _lastView == "INTERNAL"; }; GVAR(pfID) = [{ params ["_args"]; diff --git a/addons/dragon/functions/fnc_sightAttach.sqf b/addons/dragon/functions/fnc_sightAttach.sqf index 76ad9c33565..de085942b7d 100644 --- a/addons/dragon/functions/fnc_sightAttach.sqf +++ b/addons/dragon/functions/fnc_sightAttach.sqf @@ -21,7 +21,7 @@ params ["_target", "_unit", ["_event", false]]; TRACE_3("sightAttach",_target,_unit,_event); if (_event isEqualTo true) then { // this is actually needed as 3rd arg may not be bool - if (!(_target turretLocal [0])) exitWith {}; + if !(_target turretLocal [0]) exitWith {}; _target setVariable [QGVAR(sightAttached), true, true]; _target animate ["optic_hide", 0]; _target addWeapon QGVAR(superStatic); diff --git a/addons/dragon/functions/fnc_sightDetach.sqf b/addons/dragon/functions/fnc_sightDetach.sqf index c9d03e22e64..a5ac159a335 100644 --- a/addons/dragon/functions/fnc_sightDetach.sqf +++ b/addons/dragon/functions/fnc_sightDetach.sqf @@ -23,7 +23,7 @@ params ["_target", "_unit", ["_event", false]]; TRACE_3("sightDetach",_target,_unit,_event); if (_event isEqualTo true) then { // this is actually needed as 3rd arg may not be bool - if (!(_target turretLocal [0])) exitWith {}; + if !(_target turretLocal [0]) exitWith {}; _target setVariable [QGVAR(sightAttached), false, true]; _target animate ["optic_hide", 1]; _target removeWeapon QGVAR(superStatic); diff --git a/addons/explosives/functions/fnc_addClacker.sqf b/addons/explosives/functions/fnc_addClacker.sqf index 2292bfcb79c..794aec0a107 100644 --- a/addons/explosives/functions/fnc_addClacker.sqf +++ b/addons/explosives/functions/fnc_addClacker.sqf @@ -31,7 +31,7 @@ private _detonators = [_unit] call FUNC(getDetonators); if !(_x in _detonators) exitWith{ _hasRequired = false; }; -} count _requiredItems; +} forEach _requiredItems; if !(_hasRequired) exitWith {}; private _config = ConfigFile >> "CfgMagazines" >> _magazineClass >> "ACE_Triggers" >> configName _config; diff --git a/addons/explosives/functions/fnc_addDetonateActions.sqf b/addons/explosives/functions/fnc_addDetonateActions.sqf index ea4b87128a7..d950278c357 100644 --- a/addons/explosives/functions/fnc_addDetonateActions.sqf +++ b/addons/explosives/functions/fnc_addDetonateActions.sqf @@ -53,7 +53,7 @@ private _explosivesList = []; // If the detonator is not active, is a clacker and has assigned explosives, generate an interaction to make it the active detonator for use with the "trigger all" keybind if ( _detonator != GVAR(activeTrigger) && - {_detonator != "Cellphone"} && + {_detonator != "Cellphone"} && { _explosivesList isNotEqualTo [] || {_detonator == "ACE_DeadManSwitch" && {_unit getVariable [QGVAR(deadmanInvExplosive), ""] != ""}} @@ -144,7 +144,7 @@ if (_detonator != "ACE_DeadManSwitch") then { private _procressedMags = []; { private _mag = _x; - if (!(_mag in _procressedMags)) then { + if !(_mag in _procressedMags) then { _procressedMags pushBack _x; private _magConfig = configFile >> "CfgMagazines" >> _mag; private _supportedTriggers = getArray (_magConfig >> "ACE_Triggers" >> "SupportedTriggers"); diff --git a/addons/explosives/functions/fnc_onIncapacitated.sqf b/addons/explosives/functions/fnc_onIncapacitated.sqf index 09d1d7b21f4..5e7b8797e1d 100644 --- a/addons/explosives/functions/fnc_onIncapacitated.sqf +++ b/addons/explosives/functions/fnc_onIncapacitated.sqf @@ -37,7 +37,7 @@ TRACE_2("placed",_deadman,_range); //Handle deadman connected to explosive in inventory private _connectedInventoryExplosive = _unit getVariable [QGVAR(deadmanInvExplosive), ""]; if (_connectedInventoryExplosive != "") then { - if (!(_connectedInventoryExplosive in (magazines _unit))) exitWith {}; + if !(_connectedInventoryExplosive in (magazines _unit)) exitWith {}; //Remove mag and reset variable _unit removeMagazine _connectedInventoryExplosive; diff --git a/addons/explosives/stringtable.xml b/addons/explosives/stringtable.xml index fccc685c4f0..168a8302542 100644 --- a/addons/explosives/stringtable.xml +++ b/addons/explosives/stringtable.xml @@ -76,6 +76,7 @@ 選択した点火装置を全て起爆 활성화된 격발기의 모든 것을 폭파 Détoner tout sur le détonateur actif + Detonar Todos al Activar el detonador Set Active Clacker @@ -85,6 +86,7 @@ この点火装置を選択 격발기 활성 설정 Définir le détonateur actif + Establecer el Detonador Activo Cycle Active Clacker @@ -94,6 +96,7 @@ 点火装置を切り替え 격발기 활성 전환 Modifier le détonateur actif + Ciclar el Detonador Activo Active Clacker @@ -103,6 +106,7 @@ 選択中の点火装置 격발기 활성 Détonateur actif + Activar Detonador Explosive code: %1 diff --git a/addons/fastroping/XEH_postInit.sqf b/addons/fastroping/XEH_postInit.sqf index 650b277dbf8..0ba92312153 100644 --- a/addons/fastroping/XEH_postInit.sqf +++ b/addons/fastroping/XEH_postInit.sqf @@ -9,7 +9,7 @@ // Keybinds ["ACE3 Vehicles", QGVAR(fastRope), localize LSTRING(Interaction_fastRope), { if ((vehicle ACE_player) == ACE_player) exitWith {false}; - if (!([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith))) exitWith {false}; + if !([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith)) exitWith {false}; if ([ACE_player, vehicle ACE_player] call FUNC(canFastRope)) then { [ACE_player, vehicle ACE_player] call FUNC(fastRope); true @@ -20,7 +20,7 @@ ["ACE3 Vehicles", QGVAR(cutRopes), localize LSTRING(Interaction_cutRopes), { if ((vehicle ACE_player) == ACE_player) exitWith {false}; - if (!([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith))) exitWith {false}; + if !([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith)) exitWith {false}; if ([vehicle ACE_player] call FUNC(canCutRopes)) then { [vehicle ACE_player] call FUNC(cutRopes); true @@ -43,7 +43,7 @@ if (isServer) then { #ifdef DRAW_FASTROPE_INFO addMissionEventHandler ["Draw3D", { - if (!(cursorObject isKindOf "Helicopter")) exitWith {}; + if !(cursorObject isKindOf "Helicopter") exitWith {}; private _config = configOf cursorObject; private _enabled = getNumber (_config >> QGVAR(enabled)); drawIcon3D ["", [.5,.5,1,1], (ASLtoAGL getPosASL cursorObject), 0.5, 0.5, 0, format ["%1 = %2", typeOf cursorObject, _enabled], 0.5, 0.025, "TahomaB"]; diff --git a/addons/fastroping/initSettings.inc.sqf b/addons/fastroping/initSettings.inc.sqf index 844de927a23..cde4a32b47e 100644 --- a/addons/fastroping/initSettings.inc.sqf +++ b/addons/fastroping/initSettings.inc.sqf @@ -5,9 +5,7 @@ private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(setting_c [LSTRING(setting_requireRopeItems_displayName)], _category, false, // default value - true, // isGlobal - {[QGVAR(requireRopeItems), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // needRestart + true // isGlobal ] call CBA_fnc_addSetting; [ diff --git a/addons/fastroping/stringtable.xml b/addons/fastroping/stringtable.xml index b68da23d28f..10ea50a7c51 100644 --- a/addons/fastroping/stringtable.xml +++ b/addons/fastroping/stringtable.xml @@ -325,6 +325,7 @@ Equipement automatique FRIES Auto-equipar FRIES Авто-подготовка канатов + Auto-Equipar FRIES Automatically add FRIES to helicopters that support them. @@ -336,6 +337,7 @@ Ajoute automatiquement des FRIES aux hélicoptères qui les supportent. Adiciona automaticamente FRIES a helicópteros que os suportam. Автоматически добавляйте канаты в вертолеты, которые их поддерживают. + Añadir automáticamente el FRIES a los helicópteros que lo soporten. diff --git a/addons/field_rations/XEH_postInit.sqf b/addons/field_rations/XEH_postInit.sqf index 9f643790945..9fc8406abaf 100644 --- a/addons/field_rations/XEH_postInit.sqf +++ b/addons/field_rations/XEH_postInit.sqf @@ -99,7 +99,7 @@ if !(hasInterface) exitWith {}; ["ace_interactMenuOpened", LINKFUNC(addWaterSourceInteractions)] call CBA_fnc_addEventHandler; // Add status modifiers - if (["ace_medical"] call EFUNC(common,isModLoaded)) then { + if (GETEGVAR(medical,enabled,false)) then { [0, { if (_this getVariable [QEGVAR(medical,isBleeding), false]) exitWith { 0.5 diff --git a/addons/field_rations/functions/fnc_handleEffects.sqf b/addons/field_rations/functions/fnc_handleEffects.sqf index 1981cc5f996..ad60a743ad0 100644 --- a/addons/field_rations/functions/fnc_handleEffects.sqf +++ b/addons/field_rations/functions/fnc_handleEffects.sqf @@ -21,24 +21,21 @@ params ["_player", "_thirst", "_hunger"]; // Kill unit with max thirst or hunger if ((_thirst > 99.9 || {_hunger > 99.9}) && {random 1 < 0.5}) exitWith { - if (["ace_medical"] call EFUNC(common,isModLoaded)) then { - [_player, "Hunger/Thirst empty"] call EFUNC(medical_status,setDead); - } else { - _player setDamage 1; - }; + [_player, "Hunger/Thirst empty"] call EFUNC(common,setDead); }; // Exit if unit is not awake, below are animation based consequences if !(_player call EFUNC(common,isAwake)) exitWith {}; // Set unit unconscious (chance based on how high thirst/hunger are) -if ((_thirst > 85 || {_hunger > 85}) && {random 1 < linearConversion [85, 100, _thirst max _hunger, 0.05, 0.1, true]}) exitWith { - if (["ace_medical"] call EFUNC(common,isModLoaded)) then { - [_player, true, 5, true] call EFUNC(medical,setUnconscious); - }; +if ( + GETEGVAR(medical,enabled,false) && + {(_thirst > 85 || {_hunger > 85}) && {random 1 < linearConversion [85, 100, _thirst max _hunger, 0.05, 0.1, true]}} +) exitWith { + [_player, true, 5, true] call EFUNC(medical,setUnconscious); }; // Make unit fall if moving fast -if ((_thirst > 93 || {_hunger > 93}) && {speed _player > 1} && {vehicle _player == _player}) exitWith { +if ((_thirst > 93 || {_hunger > 93}) && {speed _player > 1} && {isNull objectParent _player}) exitWith { [_player, "down"] call EFUNC(common,doGesture); }; diff --git a/addons/fieldmanual/stringtable.xml b/addons/fieldmanual/stringtable.xml index 05c7414f175..78b7ad6fe89 100644 --- a/addons/fieldmanual/stringtable.xml +++ b/addons/fieldmanual/stringtable.xml @@ -28,6 +28,7 @@ 空腹 Голод Faim + Hambre %3Hunger%4 increases linearly with soldier's movement speed. Restore by eating food.<br/><br/>%3Usage:%4<br/>%2Pick up food.<br/>%2Use [%3%12%4] and select %3Survival%4.<br/>%2Choose an item to consume. @@ -39,6 +40,7 @@ %3空腹度%4は兵士の移動速度に比例して増加します。食べ物を食べることで回復します。<br/><br/>%3使用方法:%4<br/>%2食べ物を持つ。<br/>%2[%3%12%4] を使って%3サバイバル%4を選択。<br/>%2食べたいものを選ぶ。 %3Голод%4 линейно увеличивается со скоростью передвижения солдата. Восстанавливайтесь, употребляя пищу.<br/><br/>%3 Использование:%4<br/>%2Возьмите еду.<br/>%2Используйте [%3%12%4] и выберите %3Выживание% 4.<br/>%2Выберите продукт для потребления. %3La faim%4 augmente linéairement avec la vitesse de déplacement du soldat. Il se régénère en consommant de la nourriture.<br/><br/>%3Utilisation:%4<br/>%2Ramasser la nourriture.<br/>%2Utilisez [%3%12%4] et sélectionnez %3Survie%4.<br/>%2Choisissez un article à consommer. + El %3Hambre%4 aumenta linealmente con los movimientos del soldado. Se reestablece comiendo comida.<br/><br/>%3Uso:%4<br/>%2Coger comida.<br/>%2Usar [%3%12%4] y seleccionar %3Sobrevivir%4.<br/>%2Elegir un objeto para consumir. Thirst @@ -50,6 +52,7 @@ 渇き Жажда Soif + Sed %3Thirst%4 increases linearly with soldier's movement speed. Restore by drinking liquids.<br/><br/>%3Usage:%4<br/>%2Pick up a drink.<br/>%2Use [%3%12%4] and select %3Survival%4.<br/>%2Choose an item to consume. @@ -61,6 +64,7 @@ %3喉の渇き%4は兵士の移動速度に比例して増加します。飲み物を飲むことで回復します。<br/><br/>%3使用方法:%4<br/>%2飲み物を持つ。<br/>%2[%3%12%4] を使って%3サバイバル%4を選択。<br/>%2飲みたいものを選ぶ。 %3Жажда%4 линейно увеличивается со скоростью передвижения солдата. Восстанавливайтесь, употребляя напитки.<br/><br/>%3 Использование:%4<br/>%2Возьмите напиток.<br/>%2Используйте [%3%12%4] и выберите %3Выживание% 4.<br/>%2Выберите напиток для потребления. %3La soif%4 augmente linéairement avec la vitesse de déplacement du soldat. Elle se régénère en buvant des liquides.<br/><br/>%3Utilisez [%3%12%4] et choisissez %3survival%4.<br />%2Choisissez un article à boire. + La %3Sed%4 aumenta linealmente con la velocidad de movimiento del soldado. Se restaura bebiendo líquidos.<br/><br/>%3Uso:%4<br/>%2Selecciona una bebida.<br/>%2Usar [%3%12%4] y seleccionar %3Sobrevivir%4.<br/>%2Elegir un objeto para consumir. Medical Treatment @@ -72,6 +76,7 @@ 治療 Медицинское лечение Traitement médical + Tratamiento Médico Decrease Heart Rate @@ -83,6 +88,7 @@ 心拍数を下げる Уменьшить частоту сердечных сокращений Diminution de la fréquence cardiaque + Disminuir Ritmo Cardíaco %3Adenosine%4 is used to decrease heart rate.<br/><br/>%3Usage:%4<br/>%2Use [%3%13%4] or [%3%14%4] and select an appendage.<br/>%2Inject %3Adenosine%4. @@ -94,6 +100,7 @@ %3アデノシン%4は心拍数を下げるのに使われます。<br/><br/>%3使用方法:%4<br/>%2[%3%13%4] または [%3%14%4] を使って四肢を選択します。<br/>%2そして%3アデノシン%4を注射します。 %3Аденозин%4 используется для снижения частоты сердечных сокращений.<br/><br/>%3Применение:%4<br/>%2Используйте [%3%13%4] или [%3%14%4] и выберите конечность.<br/>%2Введите %3Аденозин%4. L'%3adénosine%4 est utilisée pour réduire la fréquence cardiaque.<br/><br/>%3Utilisation:%4<br/>%2Utilisez [%3%13%4] ou [%3%14%4] et sélectionnez un membre.<br/>%2Injectez l'%3Adénosine%4. + La %3Adenosina%4 se usa para disminuir el ritmo cardíaco.<br/><br/>%3Uso:%4<br/>%2Uso [%3%13%4] o [%3%14%4] y selecciona una extremidad.<br/>%2Inyectar %3Adenosina%4. Bandages @@ -105,6 +112,7 @@ 包帯 Бинты Pansements + Vendas Close Wounds @@ -116,6 +124,7 @@ 傷口をふさぐ Закрыть раны Fermer les plaies + Cerrar Heridas %3Bandages%4 stop bleeding and close wounds. Depending on your settings, bandages may reopen if surgery is not performed.<br/><br/>%2%3Field Dressing:%4<br/>%11<t color='#D9D900'>Average</t> In All Categories<br/>%2%3Packing Bandage:%4<br/>%11<t color='#D9D900'>Average</t> Treatment<br/>%11<t color='#E60000'>Higher</t> Reopen Chance<br/>%11<t color='#00CC00'>Longer</t> Reopen Delay<br/>%2%3Elastic Bandage:%4<br/>%11<t color='#00CC00'>Higher</t> Treatment<br/>%11<t color='#E60000'>Higher</t> Reopen Chance<br/>%11<t color='#E60000'>Shorter</t> Reopen Delay<br/>%2%3Quickclot:%4<br/>%11<t color='#E60000'>Lower</t> Treatment<br/>%11<t color='#00CC00'>Lower</t> Reopen Chance<br/>%11<t color='#00CC00'>Longer</t> Reopening Delay<br/><br/>%3Usage:%4<br/>%2Use [%3%13%4] or [%3%14%4] and select a injured body part.<br/>%2Bandage body part by selecting desired %3Bandage%4 type. @@ -125,6 +134,7 @@ %3Verbände%4 stoppen Blutungen und schließen Wunden. Abhängig von Ihren Einstellungen können sich Verbände wieder öffnen, wenn keine Operation durchgeführt wird.<br/><br/>%2%3Einfache Bandage:%4<br/>%11<t color='#D9D900'>Durchschnittlich</t> In allen Kategorien<br/>%2%3Mullbinde:%4<br/>%11<t color='#D9D900'>Durchschnittliche</t> Behandlung<br/>%11<t color='#E60000' >Höhere</t> Wiedereröffnungswahrscheinlichkeit<br/>%11<t color='#00CC00'>Längere</t> Wiedereröffnungsverzögerung<br/>%2%3Elastischer Verband:%4<br/>%11<t color='#00CC00'>Längere</t> Behandlung<br/>%11<t color='#E60000'>Höhere</t> Chance auf Wiedereröffnung<br/>%11<t color='#E60000'> Kürzere</t> Wiedereröffnungsverzögerung<br/>%2%3Quickclot:%4<br/>%11<t color='#E60000'>Kürzere</t> Behandlung<br/>%11<t color=' #00CC00'>Geringere</t> Wiedereröffnungswahrscheinlichkeit<br/>%11<t color='#00CC00'>Längere</t> Wiedereröffnungsverzögerung<br/><br/>%3Verwende:%4<br/> %2Verwenden Sie [%3%13%4] oder [%3%14%4] und wähle ein verletztes Körperteil aus.<br/>%2Verbinde ein Körperteil, indem der gewünschte %3Bandagen%4-Typ ausgewählt wurde. %3Bende%4 fermano emorragie e chiudono ferite. A seconda delle tue impostazioni, ferite bendate potrebbero riaprirsi se non suturate.<br/><br/>%2%3Bendaggio Basico:%4<br/>%11<t color='#D9D900'>Media</t> In tutte le categorie<br/>%2%3Bendaggio Compressivo:%4<br/>%11<t color='#D9D900'>Media</t> Trattamenti<br/>%11<t color='#E60000'>Alta</t> Probabilità di riapertura<br/>%11<t color='#00CC00'>Lungo</t> Tempo di riapertura<br/>%2%3Bendaggio Elastico:%4<br/>%11<t color='#00CC00'>Alto</t> Trattamento<br/>%11<t color='#E60000'>Alto</t> Probabilità di riapertura<br/>%11<t color='#E60000'>Breve</t> Tempo di riapertura<br/>%2%3Quickclot:%4<br/>%11<t color='#E60000'>Basso</t> Trattamento<br/>%11<t color='#00CC00'>Basso</t> Probabilità di riapertura<br/>%11<t color='#00CC00'>Lungo</t> Tempo di riapertura<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%13%4] o [%3%14%4] seleziona una parte del corpo ferita.<br/>%2Benda la parte del corpo ferita selezionando la %3Benda%4 desiderato. %3包帯%4は傷口をとじて出血を止めます。設定によっては、手術を行わないと包帯が解けて傷が再開放し出血が再開する場合があります。<br/><br/>%2%3緊急圧迫包帯:%4<br/>%11<t color='#D9D900'>平均的な</t> 全体性能を持っています<br/>%2%3弾性包帯:%4<br/>%11<t color='#D9D900'>平均的な</t> 治療効果<br/>%11<t color='#E60000'>高い</t> 再解放の可能性<br/>%11<t color='#00CC00'>長い</t> 再解放の再計算間隔<br/>%2%3伸縮包帯:%4<br/>%11<t color='#00CC00'>高い</t> 治療効果<br/>%11<t color='#E60000'>高い</t> 再解放の可能性<br/>%11<t color='#E60000'>短い</t> 再解放の再計算間隔<br/>%2%クイッククロット:%4<br/>%11<t color='#E60000'>低い</t> 治療効果<br/>%11<t color='#00CC00'>低い</t> 再解放の可能性<br/>%11<t color='#00CC00'>長い</t> 再解放の再計算間隔<br/><br/>%3使用方法:%4<br/>%2[%3%13%4] または [%3%14%4] を使って身体の負傷個所を選択します。<br/>%2希望の%3包帯%4の種類を選択して部位に包帯を巻きます。 + Las %3Vendas%4 paran el sangrado y cierran las heridas. Dependiendo de las opciones configuradas, las heridas pueden reabrirse si no se realiza cirugía.<br/><br/>%2%3Vendaje de campaña:%4<br/>%11<t color='#D9D900'>Medio</t> en todas las categorias<br/>%2%3Vendaje compresivo:%4<br/>%11<t color='#D9D900'>Medio</t> Tratamiento<br/>%11<t color='#E60000'>Alto</t> Probabilidad de Reapertura<br/>%11<t color='#00CC00'>Larga</t> Retardo en reapertura<br/>%2%3Vendaje elástico:%4<br/>%11<t color='#00CC00'>Alto</t> Tratamiento<br/>%11<t color='#E60000'>Alto</t> Probabilidad de reapertura<br/>%11<t color='#E60000'>Corto</t> Retardo en reapertura<br/>%2%3Quickclot:%4<br/>%11<t color='#E60000'>Bajo</t> Tratamiento<br/>%11<t color='#00CC00'>Bajo</t> Probabilidad de Reapertura<br/>%11<t color='#00CC00'>Larga</t> Retardo en reapertura<br/><br/>%3Uso:%4<br/>%2Uso [%3%13%4] o [%3%14%4] y selecciona una parte del cuerpo herida.<br/>%2Venda la parte del cuerpo seleccionada eligiendo el tipo de %3Venda%4. IV Fluids @@ -135,6 +145,7 @@ Fluidi EV IV 輸液 IV Fluides + Fluidos IV Restore Blood Volume @@ -146,6 +157,7 @@ 血液量を回復する Внутривенные жидкости Restaurer le volume sanguin + Reestablece el volumen de sangre %3IV fluids%4 restore lost blood volume. Blood, Plasma, and Saline are functionally the same.<br/><br/>%3Usage:%4<br/>%2Use [%3%13%4] or [%3%14%4] and select an appendage.<br/>%2Restore blood volume by selecting desired %3IV Fluid%4 type. @@ -156,6 +168,7 @@ %3Fluidi EV%4 ristorano volume di sangue perso. Sangue, Plasma, e Salina sono funzionalmente identiche.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona un arto.<br/>%2Ristora il volume di sangue selezionando il tipo di %3Fluido EV%4 desiderato. %3IV 輸液%4は失われた血液を回復します。血液、血漿、生理食塩水は機能的には同じです。<br/><br/>%3使用方法:%4<br/>%2[%3%13%4] または [%3%14%4] を使って四肢を選択します。<br/>%2希望の%3IV 輸液%4の種類を選択して、血液量を復元します。 %%3Внутривенные жидкости%4восстанавливают потерянный объем крови. Кровь, плазма и физраствор функционально идентичны.<br/><br/>%3 Использование:%4<br/>%2 Используйте [%3%13%4] или [%3%14%4] и выберите добавку.<br/>%2 Восстановите объем крови выбрав желаемый %4тип %3жидкости + Los %3Fluidos IV%4 restauran el volumen de sangre. Sangre, Plasma, y Salino funcionan de manera similar.<br/><br/>%3Uso:%4<br/>%2Uso [%3%13%4] o [%3%14%4] y seleccionar una extremidad.<br/>%2Restaura el volumen de sangre seleccionando el tipo de %3Fluido IV%4 elegido. Increase Heart Rate | Wake Up Faster @@ -167,6 +180,7 @@ 心拍数を上げる | はやく起こす Увеличьте частоту сердечных сокращений | просыпайтесь быстрее Augmentation de la fréquence cardiaque - Réveil plus rapide + Incrementa el ritmo cardíaco | Despierta más rápido %3Epinephrine%4 increases a patient's pulse as well as potentially decreasing the time between consciousnesss checks (effectively reducing the time needed for the patient to wake up).<br/><br/>%3Usage%4<br/>%2Use [%3%13%4] or [%3%14%4] and select an appendage.<br/>%2Inject %3Epinephrine%4. @@ -176,6 +190,7 @@ %3Epinephrine%4 erhöht den Puls eines Patienten und verkürzt möglicherweise die Zeit zwischen Bewusstseinskontrollen (wodurch die Zeit, die der Patient zum Aufwachen benötigt, effektiv verkürzt wird).<br/><br/>%3Verwendung%4<br/>%2Verwende [%3%13%4] oder [%3%14%4] und wählen ein Körperteil aus.<br/>%2Injiziere %3Epinephrine%4. %3Epinefrina%4 aumenta il ritmo cardiaco di un paziente e riduce potenzialmente gli intervalli tra verifiche di coscienza (effettivamente riducendo il tempo necessario che questo paziente si svegli).<br/><br/>%3Utilizzo%4<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona un arto.<br/>%2Inietta %3Epinefrina%4. %3アドレナリン%4は、患者の脈拍を増加させるだけでなく、意識チェックの間隔を短縮する可能性があります。 (患者が目覚めるまでに必要な時間を効果的に短縮します)<br/><br/>%3使用方法%4<br/>%2[%3%13%4] または [%3%14%4] を使って四肢を選択します。<br/>%2%3アドレナリン%4を注射します。 + La %3Epinefrina%4 aumenta el pulso del paciente así como potencialmente disminuye el tiempo entre las comprobaciones sobre consciencia (reduciendo de manera efectiva el tiempo de despertar del paciente).<br/><br/>%3Uso%4<br/>%2Usa [%3%13%4] o [%3%14%4] y selecciona una extremidad.<br/>%2Inyecta %3Epinefrina%4. Restore Like New @@ -187,6 +202,7 @@ 生まれたてのように回復する Лечение тела Remettre comme neuf + Restaurar como nuevo The %3Personal Aid Kit%4 is an item that allows a soldier to be fully healed. Independent of %3ACE Settings%4, it requires that the patient is in %3Stable Condition%4 before use.<br/><br/>%3Stable Condition%4 qualifies as:<br/>%2Unit is %3Alive%4.<br/>%2Unit is %3Conscious%4.<br/>%2Unit has no active %3Bleeding%4.<br/>%2Heart Rate >= 40.<br/>%2Systolic BP >= 60.<br/>%2Diastolic BP >= 50.<br/><br/>%3Usage:%4<br/>%2Move to appropriate location depending on %3ACE Settings%4.<br/>%2Use [%3%13%4] or [%3%14%4] and select %3Advanced Treatments%4<br/>%2Select %3Use Personal Aid Kit%4. @@ -196,6 +212,7 @@ Das %3Persönliche Erste Hilfe Kit%4 ist ein Gegenstand, der es einem Soldaten ermöglicht, vollständig geheilt zu werden. Unabhängig von den %3ACE-Einstellungen%4 ist es erforderlich, dass sich der Patient vor der Verwendung in einem %3stabilen Zustand%4 befindet.<br/><br/>%3Stabiler Zustand%4 gilt wenn:<br/>%2Einheit ist %3am Leben%4 .<br/>%2Einheit ist %3Bei Bewusstsein%4.<br/>%2Einheit hat keine aktive %3Blutung%4.<br/>%2Herzfrequenz >= 40.<br/>%2Systolischer Blutdruck >= 60.< br/>%2Diastolischer Blutdruck >= 50.<br/><br/>%3Verwende:%4<br/>%2Bewege den Patienten je nach %3ACE-Einstellungen%4 an den entsprechenden Ort.<br/>%2Verwende [%3% 13%4] oder [%3%14%4] und wähle %3Erweiterte Behandlungen%4<br/>%2Wähle %3Persönliche Erste Hilfe Kit verwenden%4. Il %3Kit di Pronto Soccorso%4 è un oggetto che permette di curare completamente un soldato, indipendentemente da %3impostazioni ACE%4, richiede che il paziente sia in %3condizione stabile%4 prima dell'utilizzo.<br/><br/>%3Condizione stabile%4 significa:<br/>%2Paziente è %3Vivo%4.<br/>%2Paziente è %3Conscio%4.<br/>%2Paziente non sta %3Sanguinando%4.<br/>%2Ritmo cardiaco >= 40.<br/>%2Sistolico BC >= 60.<br/>%2Diastolico BC >= 50.<br/><br/>%3Utilizzo:%4<br/>%2Sposta in luogo specifico a seconda delle %3impostazioni ACE%4.<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona %3Trattamenti avanzati%4<br/>%2Seleziona %3Usa Kit di Pronto Soccorso%4. %3個人用治療キット%4は、兵士を完全に回復できるアイテムです。使用時には%3ACE 設定%4と関係なく、対象の患者が%3安定状態%4である必要があります。<br/><br/>%3安定状態%4とは次の状態です:<br/>%2ユニットが %3生存%4している。<br/>%2ユニットが %3覚醒状態%4である。<br/>%2ユニットが %3出血状態%4ではない。<br/>%2心拍数が40以上。<br/>%2収縮期血圧が60以上。<br/>%2拡張期血圧が50以上。<br/><br/>%3使用方法:%4<br/>%2%3ACE 設定%4で使用が許可された場所へ移動する。<br/>%2[%3%13%4] または [%3%14%4] を使って%3高度な治療%4を選択する。<br/>%2%3個人用治療キットを使う%4を選択して使用します。 + El %3Kit de Primeros Auxilios%4 es un objeto que permite al soldado ser curado totalmente. Independientemente de las %3Opciones de ACE%4, requiere que el paciente esté en %3Condición Estable%4 antes de usarse.<br/><br/>%3Condición Estable%4 significa que:<br/>%2La unidad está %3Viva%4.<br/>%2La unidad está %3Consciente%4.<br/>%2La unidad no está %3Sangrando%4.<br/>%2Ritmo Cardíaco >= 40.<br/>%2Presión Sistólica >= 60.<br/>%2Presión Diastólica >= 50.<br/><br/>%3Uso:%4<br/>%2Mover al lugar adecuado dependiendo de las%3Opciones de ACE%4.<br/>%2Uso [%3%13%4] o [%3%14%4] y seleccionar %3Tratamientos Avanzados%4<br/>%2Seleccionar %3Usar Kit de Primeros Auxilios%4. Fix Fractures @@ -207,6 +224,7 @@ 骨折を治す Исправлять переломы Réparation des fractures + Curar Fracturas A %3Splint%4 is used to fix fractures. The %3Splint%4 is consumed when used.<br/><br/>%3Usage:%4<br/>%2Use [%3%13%4] or [%3%14%4] and select an affected appendage.<br/>%2Select %3Apply Splint%4. @@ -216,6 +234,7 @@ Ein %3Splint%4 wird zur Fixierung von Frakturen verwendet. Der %3Splint%4 wird bei Verwendung verbraucht.<br/><br/>%3Verwendung:%4<br/>%2Verwende [%3%13%4] oder [%3%14%4] und wählen ein Körperteil aus.<br/>%2Wähle %3Schiene verwenden%4. Una %3Gessatura%4 è usata per risolvere fratture. La %3Gessatura%4 è consumata quando usata.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona un arto afflitto.<br/>%2Seleziona %3Applica Gessatura%4. %3添え木%4は骨折の治療に使います。%3添え木%4は使用時に消費します。<br/><br/>%3使用方法:%4<br/>%2[%3%13%4] または [%3%14%4] を使って使用したい四肢を選択します。<br/>%2%3添え木を当てる%4を選択して使用します。 + La %3Férula%4 se utiliza para curar fracturas. La %3Férula%4 se consume cuando es usada.<br/><br/>%3Uso:%4<br/>%2Usar [%3%13%4] o [%3%14%4] y seleccionar la extremidad adecuada.<br/>%2Seleccionar %3Aaplicar Férula%4. Prevent Wounds From Reopening @@ -226,6 +245,8 @@ 傷口が開くのを防ぐ Предотвратить повторное открытие ран Empêcher la réouverture des plaies + Verhindert, dass sich Wunden wieder öffnen + Prevenir la reapertura de heridas A %3Surgical Kit%4 is used to prevent wounds from reopening after being bandaged. Depending on settings, it can also clear trauma and may require additional %3Sutures%4 to close wounds. Sutures are consumable, much like bandages, and are not a replacement for the Surgical Kit.<br/><br/>%3Usage:%4<br/>%2Use [%3%13%4] or [%3%14%4] and select %3Advanced Treatment%4.<br/>%2Select %3Use Surgical Kit%4. @@ -234,6 +255,8 @@ O %3Kit Cirúrgico%4 é utilizado para prevenir a reabertura de feridas após a aplicação de bandagens. A depender das configurações, ele também pode remover traumas e pode requerir %3Suturas%4 adicionais para fechar feridas. Suturas são consumíveis, tal como as bandagens, e não são substituem o Kit Cirúrgico.<br/><br/>%3Uso:%4<br/>%2Utilize [%3%13%4] ou [%3%14%4] e selecione %3Tratamento Avançado%4.<br/>%2Selecione %3Usar Kit Cirúrgico%4. Un %3Kit Chirurgico%4 è usato per impedire che ferite bendate si riaprano. A seconda delle impostazioni, può anche azzerare danni o potrebbe richiedere %3Suture%4 aggiuntive per chiudere ferite. Suture sono consumabili proprio come bende, non sono un sostituto per un Kit Chirurgico.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona %3Trattamenti Avanzati%4.<br/>%2Seleziona %3Usa Kit Chirurgico%4. %3手術キット%4は包帯を巻いた傷口が再度開いて出血するのを防ぎます。設定によっては、負傷を取り除いたり、傷口を閉じるのに%3糸付縫合針%4を必要としたりします。糸付縫合針は消耗品で包帯のように使用され、手術キットを代替するものではありません。<br/><br/>%3使用方法:%4<br/>%2[%3%13%4] または [%3%14%4] を使って%3高度な治療%4を選択する。<br/>%2%3手術キット%4を選択して使用します。 + Ein %3Chirurgisches Kit%4 wird verwendet, um zu verhindern, dass sich Wunden nach dem Verbinden wieder öffnen. Abhängig von den Einstellungen kann es auch Traumata beseitigen und erfordert möglicherweise zusätzliche %3Nähte%4, um Wunden zu schließen. Nahtmaterial ist, ähnlich wie Bandagen, Verbrauchsmaterial und kein Ersatz für das Chirurgie-Set.<br/><br/>%3Verwendung:%4<br/>%2Verwenden Sie [%3%13%4] oder [%3% 14%4] und wählen Sie %3Erweiterte Behandlung%4.<br/>%2Wählen Sie %3Chirurgisches Kit verwenden%4. + El %3Kit Quirúrgico%4 se usa para prevenir la reapertura de heridas despues de ser vendadas. Dependiendo de las opciones, tambien puede curar traumatismos y puede requerir %3Sutura%4 adicional para cerrar las heridas. Las Suturas son consumibles, al igual que las vendas, y no son un reemplazo para el Kit Quirúgico.<br/><br/>%3Uso:%4<br/>%2Usar [%3%13%4] o [%3%14%4] y seleccionar %3Tratamientos Avanzados%4.<br/>%2Seleccionar %3Usar Kit Quirúgico%4. Stop Bleeding @@ -244,6 +267,8 @@ 出血を止める Остановить кровотечение Arrêter les saignements + Stoppt Blutung + Parar Sangrado A %3Tourniquet%4 stops bleeding temporarily so that a wound(s) can be bandaged. Can only be used on limbs.<br/><br/>%3Usage:%4<br/>%2Use [%3%13%4] or [%3%14%4] and select an affected appendage.<br/>%2Select %3Apply Tourniquet%4. @@ -252,6 +277,8 @@ O %3Torniquete%4 interrompe o sangramento temporariamente, para que feridas possam ser enfaixadas. Seu uso é restrito aos membros.<br/><br/>%3Uso:%4<br/>%2Utilize [%3%13%4] ou [%3%14%4] e selecione um membro afetado.<br/>%2Selecione %3Aplicar Torniquete%4. Un %3Laccio Emostatico%4 ferma emorragie temporaneamente in modo da poter bendare ferite con calma. Utilizzabile su arti.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona un arto afflitto.<br/>%2Seleziona %3Applica Laccio Emostatico%4. %3止血帯%4は一時的に出血を止め、その間に傷に包帯を巻くことができます。四肢にのみ使用できます。<br/><br/>%3使用方法:%4<br/>%2[%3%13%4] または [%3%14%4] を使って使用したい四肢を選択します。<br/>%2%3止血帯を巻く%4を選択して使用します。 + Ein %3Tourniquet%4 stoppt die Blutung vorübergehend, sodass eine oder mehrere Wunden verbunden werden können. Kann nur an Gliedmaßen verwendet werden.<br/><br/>%3Verwendung:%4<br/>%2Verwenden Sie [%3%13%4] oder [%3%14%4] und wählen Sie ein betroffenes Glied aus.< br/>%2Wählen Sie %3Tourniquet anwenden%4. + El %3Torniquete%4 para temporalmente el sangrado hasta que la herida sea vendada. Sólo puede ser usado en extremidades.<br/><br/>%3Uso:%4<br/>%2Usar [%3%13%4] o [%3%14%4] y seleccionar la extremidad afectada.<br/>%2Seleccionar %3Aplicar Torniquete%4. Medical Menu @@ -277,6 +304,7 @@ Tratamento, Simplificado 治療を簡略化する Traitement, simplifié + Tratamiento, Simplificado The %3Medical Menu%4 is a dedicated %3interface%4 to facilitate %3medical treatment%4. The %3R%4 and %3L%4 letters indicate the side of the patient's body being treated.<br/><br/>%3Usage:%4<br/>%2Use [%3%14%4] while looking at a patient to open the Medical Menu. Opening the menu without a patient allows for self-treatment.<br/>%2Alternatively, use [%3%12%4] or [%3%13%4] and select %3Medical Menu%4.<br/><br/>%3Keybinds:%4<br/>%2Use [%3W, A, S, D, X, and Z%4] to select body parts.<br/>%2Use your %3number keys%4 to select treatment categories. @@ -285,6 +313,7 @@ O %3Menu Médico%4 é uma %3interface%4 dedicada a facilitar o %3tratamento médico%4. As letras %3R%4 e %3L%4 indicam o lado do corpo do paciente que está recebendo o tratamento.<br/><br/>%3Uso:%4<br/>%2Utilize [%3%14%4] enquanto olha o paciente para abrir o Menu Médico. Se não houver paciente, o menu será de auto-tratamento.<br/>%2Alternativamente, utilize [%3%12%4] ou [%3%13%4] e selecione %3Menu Médico%4.<br/><br/>%3Atalhos de teclado:%4<br/>%2Utilize [%3W, A, S, D, X, e Z%4] para selecionar partes do corpo.<br/>%2Utilize as %3teclas numéricas%4 para selecionar as categorias de tratamento. Il %3Menù Medico%4 è un'%3interfaccia%4 dedicata a facilitare %3trattamenti medici%4. Le lettere %3Dx%4 e %3Sx%4 contrassegnano i lati del corpo del paziente che si stanno medicando.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%14%4] guardando il paziente per aprire il Menù Medico. Aprire il menù senza paziente di fronte permette l'automedicazione.<br/>%2In alternativa, usa [%3%12%4] o [%3%13%4] e seleziona %3Menù Medico%4.<br/><br/>%3Comandi:%4<br/>%2Usa [%3W, A, S, D, X, and Z%4] per selezionare parti del corpo.<br/>%2Usa %3tasti numerici%4 per selezionare categorie di cure. %3医療メニュー%4は%3治療%4をしやすくするための専用%3インターフェース%4です。%3右%4と%3左%4の文字は治療を受ける患者の向きを表しています。<br/><br/>%3使用方法:%4<br/>%2[%3%14%4] を患者に視点を合わせながら押すことで患者の医療メニューを開けます。視点を合わせないで押すと、自分の医療メニューを開くことが出来ます。<br/>%2もしくは [%3%12%4] または [%3%13%4] を使って%3医療メニュー%4を選択します。<br/><br/>%3キーバインド:%4<br/>%2[%3W, A, S, D, X, と Zキー%4] を使って身体の部位を選択できます。<br/>%2%3数字キー%4を使って治療項目を選択できます。 + El %3Menú Médico%4 es una %3interfaz%4 dedicada para facilitar el %3tratamiento médico%4. Las letras %3R%4 and %3L%4 indican el lado del paciente siendo tratado.<br/><br/>%3Uso:%4<br/>%2Usar [%3%14%4] mientras se mira al paciente para abrir el Menú Médico. Abrir el menú sin mirar a un paciente permite el tratamiento a uno mismo. <br/>%2Alternativamente, usar [%3%12%4] o [%3%13%4] y seleccionar %3Menú Médico%4.<br/><br/>%3Teclas asociadas:%4<br/>%2Usar [%3W, A, S, D, X, and Z%4] para seleccionar las partes del cuerpo.<br/>%2Usar las %3teclas numéricas%4 para seleccionar las categorías de tratamiento. Portable, Precise, Rugged @@ -294,6 +323,7 @@ Leggero, Preciso, Robusto 高機動、高精度、高耐久 Portable, précis, robuste + Portable, Preciso, Robusto The %3Horus ATragMX%4 considers atmospheric conditions, gun data, ammunition, range, speed, and muzzle velocity to calculate precise aiming solutions with %3Come-Up%4 results - and even accounts for %3Coriolis%4 and %3Spin Drift%4 effects. %3ATragMX%4, loaded on a handheld computer made by %3TDS Recon%4, is easy to use and lightning fast. The %3Recon%4 meets the rigorous %3MIL-STD-810F%4 military standard for drops, vibration, humidity, altitude and extreme temperatures.<br/><br/>%3Usage:%4<br/>Please visit the wiki page for more information. @@ -302,6 +332,7 @@ O %3Horus ATragMX%4 considera condições atmosféricas, dados de armas, munição, alcance, e velocidade do projétil - e até os efeitos Coriolis e Spin - para calcular as configurações necessárias da mira. O %3ATragMX%4, carregado em um computador portátil feito pela %3TDS Recon%4, é rápido e fácil de usar. O %3Recon%4 satisfaz os rigorosos padrões militares %3MIL-STD-810F%4 para quedas, vibrações, umidade, altitude e temperaturas extremas.<br/><br/>%3Uso:%4<br/>Por favor, visite a wiki para mais informações. L'%3Horus ATragMX%4 tiene conto di condizioni atmosferiche, caratteristiche del fucile, munizioni, portata e velocità alla volata per calcolare precise impostazioni di mira con risultati %3Come-Up%4 - considerando anche effetti %3Coriolis%4 e %3Magnus%4. L'%3ATragMX%4, caricato su un computer portabile %3TDS Recon%4, è facile da usare e molto rapido nei calcoli. Il %3Recon%4 soddisfa i rigorosi standard militari %3MIL-STD-810F%4 per cadute, vibrazioni, umidità, altitudine e temperature estreme.<br/><br/>%3Utilizzo:%4<br/>Visitate la pagina wiki per ulteriori informazioni. %3ホルス ATragMX%4は、大気条件、銃のデータ、弾薬、射程、速度、および初速を考慮した%3最適な結果が得られる%4正確な照準のための計算とその解法を提供します。さらに、%3コリオリ効果%4および%3スピン ドリフト効果%4も考慮します。%3ATragMX%4は%3TDS Recon製%4の携帯コンピュータに読み込まれており、使いやすく、超高速です。%3Recon%4はは、落下、振動、湿度、高度、極端な温度に関する厳格な%3MIL-STD-810F%4軍事規格を満たしています。<br/><br/>%3使用方法:%4<br/>詳細については、Wiki ページを参照してください。 + El %3Horus ATragMX%4 tiene en cuenta las condiciones atmosféricas, datos del arma, munición, distancia, velocidad y velocidad en boca para calcular con precisión soluciones de tiro precisas con %3Resultados%4 - e incluso tiene en cuenta los efectos %3Coriolis%4 y %3Movimiento Giroscópico%4. %3ATragMX%4, cargado en un ordenador portátil fabricado por %3TDS Recon%4, es facil de usar y muy rápido. El %3Recon%4 cumple con los rigurosos estándares militares %3MIL-STD-810F%4 en cuanto a caidas, vibraciones, humedad, altitud y temperaturas extremas.<br/><br/>%3Uso:%4<br/>Por favor, visita la página de la Wiki para más información. Bring Out Your Dead @@ -311,6 +342,7 @@ Recupera i tuoi morti 死者を連れ出す Récupérez vos morts + Trae de vuelta a los muertos %3Body Bags%4 are used to transport dead bodies. They can be dragged and loaded into vehicles.<br/><br/>%3Usage:%4<br/>%2Approach a dead body.<br/>%2Use [%3%13%4] or [%3%15%4] and select %3Place Body In Bodybag%4. @@ -319,6 +351,7 @@ OS %3Sacos de Cadáver%4 são utilizados para transportar cadáveres. Eles podem ser arrastados e embarcados em veículos.<br/><br/>%3Uso:%4<br/>%2Aproxime-se de um cadáver.<br/>%2Utilize [%3%13%4] ou [%3%15%4] e selecione %3Colocar cadáver dentro do saco%4. %3Sacche per cadaveri%4 sono usate per trasportare i morti. Possono essere trascinate e caricate su veicoli.<br/><br/>%3Utilizzo:%4<br/>%2Avvicinati ad un morto.<br/>%2Usa [%3%13%4] o [%3%15%4] e seleziona %3Metti il corpo nella sacca per cadaveri%4. %3遺体袋%4は、遺体の輸送に使用されます。引きずって車両に積み込むことができます。<br/><br/>%3使用方法:%4<br/>%2遺体に近寄る。<br/>%2[%3%13%4] または [%3%15%4] を使って%3遺体袋に入れる%4を選択して使用します。 + Las %3Bolsas para Cadáveres%4 se usan para transportar cadáveres. Pueden ser arrastradas y cargadas en vehículos. <br/><br/>%3Uso:%4<br/>%2Acercarse a un cadáver.<br/>%2Usar [%3%13%4] o [%3%15%4] y seleccionar %3Colocar cuerpo en la Bolsa para Cadáveres%4. Take Prisoners @@ -328,6 +361,7 @@ Prendi prigionieri 捕虜の捕り方 Faire des prisonniers + Tomar prisioneros %3Cable Ties%4 enable a soldier to capture and detain another soldier. Once apprehended, the captor gains the ability to inspect the prisoner's belongings, set them free, or accompany them to an alternate area. Transporting escorted prisoners is also possible, including loading them into vehicles if needed. Depending on your settings, units may need to surrender before being taken captive.<br/><br/>%3Usage:%4<br/>%2Approach the unit and use the [%3%13%4].<br/>%2The interaction is located around the hands in the form of a handcuffs icon.<br/>%2Repeat to release. @@ -336,6 +370,7 @@ As %3Algema Plásticas%4 permitem a captura e detenção de soldados. Quando apreendidos, o captor se torna capaz de inspecionar os pertences do prisioneiro, liberá-los, ou acompanhá-los a outro local. Transportes mais longos também são possíveis, podendo colocá-los em veículos, se necessário. A depender das configurações, pode ser necessário que as unidades estejam rendidas antes de serem detidas.<br/><br/>%3Uso:%4<br/>%2Aproxime-se da unidade e use [%3%13%4].<br/>%2A interação encontra-se próxima às mãos simbolizada por uma algema.<br/>%2Faça o mesmo para liberar. %3Fascette%4 permettono a soldati di catturare e ammanettare altri soldati. Una volta catturati è possibile ispezionare il loro inventario, liberarli o scortarli altrove. È inoltre possibile caricarli su veicoli se necessario. A seconda delle impostazioni, potrebbe essere necessaria la resa di unità prima di poterle ammanettare.<br/><br/>%3Uso:%4<br/>%2Avvicinati all'unità e usa [%3%13%4].<br/>%2L'interazione è localizzata intorno alle mani con l'icona di manette.<br/>%2Ripeti per liberare. %3ケーブル タイ%4は兵士が他の兵士を拘束できるようにします。一度拘束すれば、拘束者は捕虜の所持品を検査したり、釈放したり、別の場所に移送することができるようになります。必要に応じて車両に積み込むなどして捕虜の輸送や護送も可能です。設定によっては、ユニットは捕虜になる前に降伏する必要がある場合があります。<br/><br/>%3使用方法:%4<br/>%2対象に近づいて [%3%13%4] を使います。<br/>%2インタラクションは、手錠アイコンの形で手のあたりに表示されます。<br/>%2同様の方法で解放できます。 + Las %3Bridas%4 permiten a un soldado capturar y detener a otro soldado. Una vez atado, el capturador tiene la habilidad de inspeccionar las pertenencias del prisionero, liberarles de nuevo o transportarles a otro área diferente. Transportar prisioneros escoltados tambien es posible, incluído montarles en vehículos si es necesario. Dependiendo de las opciones, puede requerirse que las unidades se rindan antes de ser capturados.<br/><br/>%3Uso:%4<br/>%2Acercarse a la unidad y usar el [%3%13%4].<br/>%2El punto de interacción se situa sobre las manos en forma de un icono de unas esposas.<br/>%2Repetir el paso para liberar. Phone In An Explosion @@ -345,6 +380,7 @@ Cellulare per esplosivi 電話でドカン Explosifs téléphone portable + Teléfono explosivo The %3Cellphone%4 is functionally a %3Clacker%4. Use it to connect and detonate an explosive device. Multiple devices can be linked to the cellphone and called within the phonebook.<br/><br/>%3Usage:%4<br/>%2Place an explosive.<br/>%2Use [%3%13%4], select %3Explosives%4, and select %3Cellphone%4.<br/>%2Open the cellphone interface with [%3%12%4].<br/>%2Navigate the phone book with the arrows and select your calling number.<br/>%2Call the number to detonate. @@ -353,6 +389,7 @@ O %3Celular%4 serve como dispositivo de detonação ao explosivo. Utilize-o para conectar e detonar dispositivos explosivos. Múltiplos dispositivos podem estar conectados ao celular e aparecerão na lista telefônica.<br/><br/>%3Uso:%4<br/>%2Plante o explosivo.<br/>%2Utilize [%3%13%4], selecione %3Explosivos%4, e selecione %3Celular%4.<br/>%2Abra a interface do celular com [%3%12%4].<br/>%2Navegue pela lista telefônica utilizando as setas e selecione o número desejado.<br/>%2Ligue para o número para detonar. Il %3Cellulare%4 è essenzialmente una %3spoletta%4. Usalo per collegare e detonare esplosivi. Molteplici esplosivi possono essere collegati ad un cellulare e detonati chiamando numeri nella rubrica.<br/><br/>%3Utilizzo:%4<br/>%2Piazza un esplosivo.<br/>%2Usa [%3%13%4], seleziona %3Esplosivi%4, seleziona %3Cellulare%4.<br/>%2Apri l'interfaccia del telefono con [%3%12%4].<br/>%2Naviga la rubrica con le freccette e seleziona il numero da chiamare.<br/>%2Chiama il numero del dispositivo da detonare. %3携帯電話%4は%3点火装置%4として機能します。爆破装置を接続して起爆するために使用します。複数のデバイスを携帯電話に繋ぎ、電話帳から呼び出すことができます。<br/><br/>%3使用方法:%4<br/>%2爆発物を設置。<br/>%2[%3%13%4] を使い、%3爆発物%4を選択して、%3携帯電話%4を選択します。<br/>%2[%3%12%4] を使って携帯電話インターフェースを開きます。<br/>%2矢印ボタンで電話帳に移動し、発信番号を選択します。<br/>%2電話を掛けることで起爆します。 + El %3Teléfono%4 es funcionalmente un %3Detonador%4. Úsalo para conectarlo y detonar un dispositivo explosivo. Múltiples dispositivos pueden ser conectados al teléfono y llamados desde la agenda de contactos.<br/><br/>%3Uso:%4<br/>%2Colocar un explosivo.<br/>%2Usar [%3%13%4], seleccionar %3Explosivos%4, y seleccionar %3Teléfono%4.<br/>%2Abrir la interfaz del teléfono con [%3%12%4].<br/>%2Navegar por la agenda de contactos con las flechas y selecciona el número a llamar.<br/>%2Llamar al número para detonarlo. Portable Reading Lights @@ -362,6 +399,7 @@ Luci da Lettura Portabili 携帯読書灯 Lampes de lecture portables + Luces de Lectura Portátiles %3Chemlight Shields%4 give you the ability to read your map, even in dark environments. However, when using %3Chemlight Shields%4, you will have a slight glow around you.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2elect %3Chemlights%4 and %3Prepare Chemlight Shield (Color)%4.<br/>%2Open %3Map%4.<br/>%2Use [%3%12%4] and select %3Flashlights%4 where you will find your chemlight shield. @@ -370,6 +408,7 @@ Os %3Protetores de Bastão de Luz%4 possibilitam a leitura de mapas em ambientes escuros. Todavia, quando utilizados, eles iluminam parcialmente os seus arredores.<br/><br/>%3Uso:%4<br/>%2Utilize [%3%12%4] e selecione %3Equipamento%4.<br/>%2Selecione %3Bastões de Luz%4 e %Preparar Protetor de Bastão de Luz (Cor)%4.<br/>%2Abrir %3Mapa%4.<br/>%2Utilize [%3%12%4] e selecione %3Lanternas%4 onde você encontrará o seu bastão de luz. %3Scudi per Luci Chimiche%4 permettono di leggere la mappa anche in ambienti bui. Il loro utilizzo comporta però un leggero effetto di luminosità intorno alla testa del giocatore.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] e seleziona %3Eqipaggiamenti%4.<br/>%2Seleziona %3Luce Chimica%4 e %3Prepara Scudo Luce Chimica (Colore)%4.<br/>%2Apri %3Mappa%4.<br/>%2Usa [%3%12%4] e seleziona %3Torcia%4 dove troverai il tuo scudo per luce chimica. %3ケミライト シールド%4を使用すると、暗い環境でも地図を読み取ることができます。ただし、%3ケミライト シールド%4を使用すると、周囲がわずかに光ります。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3ケミライト%4を選択し%3ケミライト シールドを使う (色)%4を選択します。<br/>%2%3マップ%4を開きます。<br/>%2[%3%12%4] を使って%3フラッシュライト%4を選択し、ケミライト シールドを選択します。 + Los %3Protectores de Luz Química%4 proveen la habilidad de poder leer mapas en entornos oscuros. No obstante, cuando se usan los, %3Protectores de Luz Química%4, tendrás un ligero brillo alrededor tuyo.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar %3Luces químicas%4 y %3Preparar Protector de Luz Química (Color)%4.<br/>%2Abrir %3Mapa%4.<br/>%2Usar [%3%12%4] y seleccionar %3Linternas%4 donde encontrarás el protector de luz química. Remote Detonation @@ -379,6 +418,7 @@ Detonazione da remoto リモコン爆弾 Détonation à distance + Detonación Remota Use %3Clackers%4 to connect and detonate an explosive device. Multiple devices can be linked to a clacker and detonated on different channels.<br/><br/>%3Usage:%4<br/>%2Place an explosive.<br/>%2Use [%3%13%4], select %3Explosives%4, and select the %3Clacker%4 you wish to link to.<br/>%2Open the ACE interface with [%3%12%4].<br/>%2Select %3Explosives%4 and select a %3Clacker%4.<br/>%2Select the %3Explosive%4 you wish to detonate. @@ -386,6 +426,7 @@ %3격발기%4를 사용하여 폭발물을 연결하고 폭발시킬 수 있습니다. 여러 폭발물을 다른 채널에 연결하여 폭발시킬 수도 있습니다.<br/><br/>%3사용 방법:%4<br/>%2폭발물을 설치합니다.<br/>%2[%3%13%4]를 사용하여 %3폭발물%4을 선택하고 연결할 %3격발기%4를 선택하십시오.<br/>%2[%3%12%4] 키로 ACE 인터페이스를 여십시오.<br/>%2%3폭발물%4을 선택하고 %3격발기%4를 선택하십시오.<br/>%2%3폭발물%4을 선택하면 폭발합니다. Usa %3Spolette%4 per collegare e detonare dispositivi esplosivi. Molteplici dispositivi possono essere collagati a una spoletta e detonati individualmente come vari canali.<br/><br/>%3Utilizzo:%4<br/>%2Piazza esplosivo.<br/>%2Usa [%3%13%4], seleziona %3Esplosivo%4, seleziona la %3Spoletta%4 a cui intendi collegarlo.<br/>%2Apri l'interfaccia ACE con [%3%12%4].<br/>%2Seleziona %3Esplosivi%4 e scegli una %3Spoletta%4.<br/>%2Seleziona un %3Explosivo%4 da detonare. %3点火装置%4を爆破装置に接続し使用することで起爆することが出来ます。複数の爆破装置を接続しそれぞれ違うチャンネルから起爆することもできます。<br/><br/>%3使用方法:%4<br/>%2爆発物を設置。<br/>%2[%3%13%4] を使い、%3爆発物%4を選択して、接続したい%3点火装置%4を選択します。<br/>%2ACEインターフェースを [%3%12%4] で開きます。<br/>%2%3爆発物%4を選択し、%3点火装置%4を選びます。<br/>%2起爆したい%3爆破装置%4を選択します。 + Utiliza los %3Detonadores%4 para conectar y detonar un explosivo. Múltiple dispositivos pueden ser conectados a un detonador y detonados en diferentes canales.<br/><br/>%3Uso:%4<br/>%2 Coloca un explosivo.<br/>%2Usar [%3%13%4], seleccionar %3Explosivos%4, y selecciona el %3Detonador%4 al que quieres conectarlo.<br/>%2Abre la interfaz de ACE con [%3%12%4].<br/>%2Selecciona %3Explosivos%4 y selecciona un %3Detonador%4.<br/>%2Selecciona el %3Explosivo%4 que quieres detonar. Navigate @@ -395,6 +436,7 @@ 測位 Навигация Naviguer + Navegar The %3DAGR%4 is a simpler version of the %3MicroDAGR GPS%4. It has similar features but lacks the topographic and satellite imaging functions of the %3MicroDAGR GPS%4.<br/><br/>%3Usage:%4<br/>%2Equip a %3DAGR%4.<br/>%2Use [%3%12%4] and select %3Configure%4 or %3Toggle%4.<br/><br/>The following menus are available when configuring your %3DAGR:%4<br/>%11%2Data View: WIP<br/>%11%2GoTo WP: Select a waypoint to track.<br/>%11%2WP List: Add/Edit/Remove waypoints.<br/>%11%2Connect To: Connect %3DAGR%4 to the %3Vector 21 Rangefinder%4.<br/>%11%2Options @@ -402,6 +444,7 @@ %3DAGR%4은 %3마이크로DAGR GPS%4의 단순화 버전입니다. 유사한 기능을 가지고 있지만 %3마이크로DAGR GPS%4의 지형 및 위성 이미지 기능이 없습니다.<br/><br/>%3사용 방법:%4<br/>%2%3DAGR%4를 장착하십시오.<br/>%2[%3%12%4를 사용하고 %3DAGR 설정%4 또는 %3DAGR 토글%4을 선택하십시오.<br/><br/>%3DAGR%4을 구성할 때 다음 메뉴를 사용할 수 있습니다:<br/>%11%2Data View: 제작 중<br/>%11%2GoTo WP: 추적할 웨이포인트를 선택합니다.<br/>%11%2WP List: 경유지를 추가/편집/제거합니다.<br/>%11%2Connect To: %3DAGR%4을 %3벡터 21%4 거리계에 연동시킵니다.<br/>%11%2옵션입니다 Il %3DAGR%4 è una versione più semplice del %3GPS MicroDAGR%4. Ha funzioni simili, gli manca però la capacità di visualizzare informazioni topografiche e satellitari come il %3GPS MicroDAGR%4.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia il %3DAGR%4.<br/>%2Usa [%3%12%4] e seleziona %3Configura%4 o %3Apri%4.<br/><br/>I seguenti Menù sono disponibili durante la configurazione del tuo %3DAGR:%4<br/>%11%2Pagina Dati: WIP<br/>%11%2VaiA WP: Seleziona un waypoint da tracciare.<br/>%11%2Lista WP: Aggiungi/Modifica/Rimuovi waypoint.<br/>%11%2Collega A: Collega il %3DAGR%4 al %3Telemetro Vector 21%4.<br/>%11%2Opzioni %3DAGR%4はシンプルなバージョンの%3MicroDAGR GPS%4です。同様の機能を備えていますが、%3MicroDAGR GPS%4のような地形および衛星画像機能はありません。<br/><br/>%3使用方法:%4<br/>%2%3DAGR%4を装備する。<br/>%2[%3%12%4] を使って%3設定%4 もしくは %3表示切替%4を選択します。<br/><br/>%3DAGR%4の設定には次のメニューを使用できます:<br/>%11%2Data View: WIP<br/>%11%2GoTo WP: 追跡するウェイポイントを選択します。<br/>%11%2WP List: ウェイポイントを追加/編集/削除します。<br/>%11%2Connect To: %3DAGR%4を%3ベクター 21 レンジファインダー%4に接続できます。<br/>%11%2Options + El %3DAGR%4 es una versión simplificada del %3MicroDAGR GPS%4. Tiene unas funcionalidades similares pero le faltan las funciones de los mapas topográficos e imágenes satelitales del %3MicroDAGR GPS%4.<br/><br/>%3Usage:%4<br/>%2Equip a %3DAGR%4.<br/>%2Usar [%3%12%4] y seleccionar %3Configurar%4 o %3Activar%4.<br/><br/>Los siguientes menús están disponibles cuando configuras el %3DAGR:%4<br/>%11%2Vista de Datos: WIP<br/>%11%2Ir a WP: Selecciona un Punto de Ruta para seguir.<br/>%11%2Lista de WP: Añadir/Editar/Suprimir puntos de ruta.<br/>%11%2Conectar A: Conectar %3DAGR%4 a %3Telémetro Vector 21%4.<br/>%11%2Opciones Explosive Revenge @@ -411,6 +454,7 @@ 爆発的な復讐 Взрывная месть Homme mort + Venganza Explosiva The %3Dead Man's Switch%4 is a device that allows a soldier to detonate an %3Explosive%4 when the soldier dies.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Explosives%4.<br/>%2Select %3Dead Man's Switch%4 and connect the desired %3Explosive%4.<br/>%2Repeat the process and disconnect to reverse. @@ -418,6 +462,7 @@ %3자폭 장치%4는 병사가 사망했을 때 병사가 %3폭발물%4을 폭발시킬 수 있는 장치입니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4]를 사용하고 %3폭발물%4을 선택하십시오.<br/>%2%3자폭 장치%4를 선택하고 원하는 %3폭발물%4에 연결하십시오.<br/>%2반대로 해제하고 싶다면 같은 행동을 반복하십시오. Il %3Detonatore a rilascio%4 è un dispositivo che permette a soldati di detonare un %3Esplosivo%4 quando perdono i sensi.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] e seleziona %3Esplosivi%4.<br/>%2Seleziona %3Detonatore a rilascio%4 e collega l'%3Esplosivo%4 desiderato.<br/>%2Ripeti il processo e scollega per disarmare il detonatore. %3自爆装置%4は、兵士の死亡時に%3爆発物%4を起爆させることができる装置です。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3爆発物%4を選択します。<br/>%2%3自爆装置%4を選択し、接続したい%3爆発物%4を選びます。<br/>%2同様の手順を逆に行うことで接続を解除できます。 + El %3Detonador de Hombre Muerto%4 es un dispositivo que permite a un soldado detonar un %3Explosivo%4 cuando el soldado muere.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Explosivos%4.<br/>%2Seleccionar %3Detonador de Hombre Muerto%4 y conectar el %3Explosivo%4.<br/> deseado%2Repetir el proceso y desconectar para revertirlo. The %3Defusal Kit%4 allows defusal of explosives.<br/><br/>%3Usage:%4<br/>%2Equip a %3Defusal Kit%4.<br/>%2Safely approach an %3Explosive%4.<br/>%2Use [%3%13%4] and select %3Defuse%4. @@ -425,6 +470,7 @@ %3해체 장비%4를 사용하면 폭발물을 제거할 수 있습니다.<br/><br/>%3사용 방법:%4<br/>%2%3해체 장비%4를 장착하십시오.<br/>%2%3폭발물%4에 안전하게 접근하십시오.<br/>%2[%3%13%4]를 사용하고 %3해체%4를 선택하십시오. The %3Kit E.O.D.%4 permette il disinnesco di esplosivi.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia un %3Kit E.O.D.%4.<br/>%2Avvicinati in modo sicuro ad un %3Esplosivo%4.<br/>%2Usa [%3%13%4] e seleziona %3Disinnesca%4. %3解除キット%4は爆発物の無力化を行うことができます。<br/><br/>%3使用方法:%4<br/>%2%3解除キット%4を装備。<br/>%2慎重に%3爆発物%4に接近します。<br/>%2[%3%13%4] を使って%3無力化%4を選択します。 + El %3Kit de Desactivación%4 permite la desactivación de explosivos.<br/><br/>%3Uso:%4<br/>%2Equipa un %3Kit de Desactivación%4.<br/>%2Aproxímate al %3Explosivo%4<br/> de forma segura.%2Usa [%3%13%4] y selecciona %3Desactivar%4. Defuse Explosives @@ -434,6 +480,7 @@ 爆発物の解除 Обезвреживание взрывчатки Désamorcer les explosifs + Desactivar Explosivos Protect Your Hearing @@ -443,6 +490,7 @@ 聴覚の保護 Защитите свой слух Protéger votre audition + Protege tus oídos %3Ear Plugs%4 help prevent hearing damage from repeat loud noises near a soldier. Insert %3Ear Plugs%4 to lower volume of a soldier's environment and prevent %3Combat Deafness%4.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Insert %3Ear Plugs%4. @@ -450,6 +498,7 @@ %3Tappi auricolari%4 aiutano a prevenire danni all'udito da ripetuti rumori forti in prossimità del soldato. Inserisci %3Tappi auricolari%4 per ridurre il volume dell'ambiente per il soldato e impedire %3Assordamento%4.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] e seleziona %3Equipaggiamento%4.<br/>%2Indossa %3Tappi Auricolari%4. %3귀마개%4는 병사 주변에서 반복되는 시끄러운 소리로 인한 청력 손상을 방지하는 데 도움이 됩니다. %3귀마개%4를 끼워서 병사가 있는 환경의 소리 크기를 낮추고 %3전투로 인한 청력손상%4을 방지하십시오.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4]를 사용하여 %3장비%4를 선택하십시오.<br/>%2%3귀마개%4를 삽입하십시오. %3耳栓%4は、兵士の近くで繰り返される大きな騒音による聴覚障害を防ぐのに役立ちます。%3耳栓%4を耳に挿入することで兵士の環境の音量を下げ、%3戦闘難聴%4を防ぎます。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3耳栓を着ける%4ことで使用できます。 + Los %3Tapones de oídos%4 ayudan a prevenir el daño auditivo de ruidos altos repetidos cerca de un soldado. Inserta los %3Tapones de oídos%4 para reducir el volumen del entorno del soldado y prevenir la %3Sordera de Combate%4.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Insertar %3Tapones de oídos%4. Get To Cover @@ -459,6 +508,7 @@ 遮蔽を造り出す Добраться до укрытия Se mettre à couvert + Ponerse A Cubierto The %3Entrenching Tool%4 allows soldiers to dig trenches to help defend their position. The soldier must be on soil in order to dig a trench.<br/><br/>%3Usage:%4<br/>%2Equip an %3Entrenching Tool%4.<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select the type of trench you wish to build. @@ -466,6 +516,7 @@ La %3Pala da Trincea%4 permette a soldati di scavare trincee per difendere meglio la loro posizione. Il soldato deve trovarsi su suolo scavabile per poter creare trincee.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia una %3Pala da Trincea%4.<br/>%2Usa [%3%12%4] e seleziona %3Equipaggiamento%4.<br/>%2Seleziona il tipo di trincea che vuoi costruire. %3야전삽%4을 사용하면 병사들의 진지 방어를 위한 참호를 팔 수 있습니다. 병사가 참호를 파려면 흙 위에 있어야 합니다.<br/><br/>%3사용 방법:%4<br/>%2%3야전삽%4을 장비하십시오.<br/>%2[%3%12%4]를 사용하여 %3장비%4를 선택하십시오.<br/>%2짓고 싶은 종류의 참호를 선택하십시오. %3塹壕ツール%4を使用すると、兵士は自分の陣地を守るために塹壕を掘ることができます。塹壕を掘るには、兵士は土の上にいる必要があります。<br/><br/>%3使用方法:%4<br/>%2%3塹壕ツール%4を装備します。<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2構築する塹壕の種類を選択します。 + La %3Pala de Trincheras%4 permite a los soldados excavar trincheras para ayudarles a defender su posición. El soldado debe estar sobre tierra para poder excavar una trinchera.<br/><br/>%3Uso:%4<br/>%2Equipar la %3Pala de Trincheras%4.<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar el tipo de trinchera que quieres construir. Flashlights @@ -475,6 +526,7 @@ フラッシュライト Фонари Lampes de poche + Linternas Illuminate Your Map @@ -484,6 +536,7 @@ 地図に光あれ Осветите свою карту Éclairer votre carte + Ilumina Tu Mapa %3Flashlights%4 give you the ability to read your map, even in dark environments. However, when using %3Flashlights%4, you will have a slight glow around you.<br/><br/>%3Usage:%4<br/>%2On the map screen, use [%3%12%4] and select %3Flashlights%4.<br/>%2Select the %3Flashlight%4 you want to use and select %3On%4.<br/><br/>%3Available Flashlight Items%4:<br/>%2 Fulton MX-991<br/>%2 KSF-1<br/>%2 Maglite XL50<br/><br/>%3NOTE:%4<br/>Flashlight states are persistent. @@ -491,6 +544,7 @@ %3Torce%4 permettono di leggere la tua mappa anche in ambienti bui. Però quando le utilizzi avrai un leggero effetto luminoso intorno a te.<br/><br/>%3Utilizzo:%4<br/>%2Sulla mappa usa [%3%12%4] e seleziona %3Torcia%4.<br/>%2Seleziona la %3Torcia%4 che vuoi usare e seleziona %3Accendi%4.<br/><br/>%3Oggetti Torcia Disponibili%4:<br/>%2 Fulton MX-991<br/>%2 KSF-1<br/>%2 Maglite XL50<br/><br/>%3NOTE:%4<br/>Lo stato di una torcia è persistente. %3손전등%4은 어두운 환경에서도 지도를 읽을 수 있는 기능을 제공합니다. 단, %3손전등%4을 사용할 때 주변에 약간 빛이 납니다.<br/><br/>%3사용 방법:%4<br/>%2지도 화면에서 [%3%12%4]를 사용하고 %3손전등%4을 선택하십시오.<br/>%2사용할 %3손전등%4을 선택하고 %3켜기%4를 선택하십시오.<br/><br/>%3사용 가능한 손전등 아이템%4:<br/>%2풀턴 MX-991<br/>%2 KSF-1<br/>%2 매그라이트 XL50<br/><br/>%3참고:%4<br/>손전등 상태는 영구적입니다. %3フラッシュライト%4を使用すると、暗い環境でも地図を読むことができます。ただし、%3フラッシュライト%4を使用すると、周囲がわずかに光ります。<br/><br/>%3使用方法:%4<br/>%2マップ画面で [%3%12%4] を使用し、%3フラッシュライト%4を選択します。<br/>%2%3フラッシュライト%4を選択し、使用したいライトを%3点ける%4。<br/><br/>%3使用可能なフラッシュライトのアイテム%4:<br/>%2 フルトン MX-991<br/>%2 KSF-1<br/>%2 マグライト XL50<br/><br/>%3備考:%4<br/>フラッシュライトの状態は継続します。 + Las %3Linternas%4 proveen la habilidad para leer tu mapa, incluso en entornos oscuros. No obstante, cuando se usen las %3Linternas%4, aparecerá un ligero brillo alrededor tuya.<br/><br/>%3Uso:%4<br/>%2En la pantalla del mapa, utilizar [%3%12%4] y seleccionar %3Linternas%4.<br/>%2Seleccionar la %3Linterna%4 Que quieres utilizar y selecciona %3On%4.<br/><br/>%3Objetos de Linternas disponibles%4:<br/>%2 Fulton MX-991<br/>%2 KSF-1<br/>%2 Maglite XL50<br/><br/>%3NOTA:%4<br/>Los estados de las Linternas son persistentes. Observe From The Skies @@ -500,6 +554,7 @@ 空から戦場を見てみよう Наблюдайте с Небес Observer depuis le ciel + Observar Desde El Cielo The %3High-Altitude Unit Navigated Tactical Imaging Round (HuntIR)%4 is designed to be fired from a grenade launcher. After being fired in the air, the built-in parachute will be deployed and the IR CMOS camera will activate, providing a video stream until it touches the ground or is shot down.<br/><br/>%3Usage:%4<br/>%2Equip a %3HuntIR Monitor%4 and compatible ammunition.<br/>%2Fire the %3HuntIR Round%4 as high as possible over the area you want to observe.<br/>%2Open the %3HuntIR Monitor%4.<br/>%2Use [%3%12%4], select %3Equipment%4.<br/>%2Select %3Activate HuntIR Monitor%4. @@ -507,6 +562,7 @@ Il %3High-Altitude Unit Navigated Tactical Imaging Round (HuntIR)%4 è progettato per essere sparato da un lanciagranate. Dopo essere stato sparato verso l'alto, verrà aperto un paracadute incorporato e attivata una videocamera IR CMOS, inviando una diretta video finché toccherà terra o verrà abbattuto.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia un %3Monitor HuntIR%4 e munizioni compatibili.<br/>%2Spara un %3Colpo HuntIR%4 il più alto possibile sopra l'area che vuoi osservare.<br/>%2Apri il %3Monitor HuntIR%4.<br/>%2Usa [%3%12%4], seleziona %3Equipaggiamento%4.<br/>%2Seleziona %3Attiva Monitor HuntIR%4. %3고고도 유닛 탐색용 전술 영상화 탄약 (HuntIR)%4은 유탄발사기에서 발사될 수 있도록 설계되었습니다.공주에서 발사된 후 내장된 낙하산이 전개되고 적외선 CMOS 카메라가 작동하여 지상에 닿거나 격추될 때까지 비디오 스트림이 제공됩니다.<br/><br/>%3사용 방법:%4<br/>%2%3헌트IR 모니터%4와 호환 탄약을 장착하십시오.<br/>%2%3헌트IR 유탄%4을 발사하려는 구역에서 가능한 한 높게 발사하십시오.<br/>%2%3헌트IR 모니터%4를 여십시오.<br/>%2[%3%12%4]를 사용하여 %3장비%4를 선택하십시오.<br/>%2%3헌트IR 모니터 활성화%4를 선택하십시오. %3High-Altitude Unit Navigated Tactical Imaging Round (HuntIR)%4はグレネードランチャーから発射されるように設計されています。空中で発射された後、内蔵のパラシュートが展開され、IR CMOS カメラが起動し、地面に着くか撃墜されるまでビデオ ストリームを提供します。<br/><br/>%3使用方法:%4<br/>%2%3HuntIR モニター%4と互換性のある弾薬を装備します。<br/>%2観測したいエリアに向けてできるだけ高く%3HuntIR 弾頭%4を発射します。<br/>%2%3HuntIR モニター%4を開きます。<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3HuntIRを起動する%4からモニターを起動します。 + El %3High-Altitude Unit Navigated Tactical Imaging Round (HuntIR)%4 está diseñado para ser disparado desde un lanzagranadas. Despues de ser disparada al aire, desplegará su paracaídas integrado y activará su cámara IR CMOS integrada, proveyendo de un flujo de video hasta que toque el suelo o sea derribado.<br/><br/>%3Uso:%4<br/>%2Equipa un %3Monitor HuntIR%4 y la munición compatible.<br/>%2Dispara la %3Munición HuntIR%4 tan alto como sea posible sobre el área que quieres observar.<br/>%2Abre el %3Monitor HuntIR%4.<br/>%2Usar [%3%12%4], seleccionar %3Equipamiento%4.<br/>%2Seleccionar %3Activar Monitor HuntIR%4. Track Your Team With Stealth @@ -516,6 +572,7 @@ 自分の部隊を追う Следите за своей командой незаметно Suivez votre équipe en toute discrétion + Sigue A Tu Equipo Con Sigilo The %3IR Strobe%4 is a throwable that emits an IR light pulse intermittently. The %3IR Strobe%4 can also be attached to a soldier, making it useful for tracking teammates under night vision devices.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select %3Attach%4 and select the %3IR Strobe%4. @@ -523,6 +580,7 @@ La %3Strobo IR%4 è un lanciabile che emette un impulso intermittente di luce IR. La %3Strobo IR%4 può anche essere attaccata ad un soldato, facilitando l'identificazione di alleati con visori notturni.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] e seleziona %3Equipaggiamento%4.<br/>%2Seleziona %3Attacca%4 e scegli la %3Strobo IR%4. %3적외선 스트로브%4는 던질 수 있는 적외선 광펄스를 간헐적으로 방출하는 투척형 아이템입니다. %3적외선 스트로브%4는 병사에게도 부착 가능하기 때문에 야간투시장치로 팀원을 추적할 때 유용합니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4]를 사용하여 %3장비%4를 선택하십시오.<br/>%2%3아이템 부착%4을 선택하고 %3적외선 스트로브%4를 선택하십시오. %3赤外線ストロボ%4は、赤外線光パルスを断続的に放射します。投擲可能です。%3赤外線ストロボ%4は兵士に取り付けることもできるため、暗視装置の下でチームメイトを追跡するのに役立ちます。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3アイテムを取り付ける%4を選択して%3赤外線ストロボ%4を選び使用します。 + El %3Estroboscópico IR%4 es un objeto lanzable que emite un pulso intermitente de luz IR. El %3Estroboscópico IR%4 tambien puede ser sujeto a un soldado, haciéndolo útil para el seguimiento de los compañeros utilizando gafas de visión nocturna.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar %3Sujetar%4 y seleccionar el %3Estroboscópico IR%4. Pocket Weatherstation @@ -532,6 +590,7 @@ 携帯気象予報所 Карманная метеостанция Station météo de poche + Estación Climática de Bolsillo The %3Kestrel 4500 Pocket Weather Tracker%4 is a mini weather station useful for collecting the the following weather data:<br/>%2Heading and wind direction<br/>%2Crosswind and headwind<br/>%2Altitude and barometric pressure<br/>%2Wet bulb temperature<br/>%2Humidity and dewpoint<br/>%2Density altitude<br/>%2Wind chill and temperature<br/>%2Time and date<br/>%2Minimum, maximum, and average values<br/><br/>%3Usage:%4<br/>%2Equip a %3Kestrel%4.<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select %3Open%4. @@ -539,6 +598,7 @@ Il %3Kestrel 4500 Indicatore Meteorologico Tascabile%4 è una mini-stazione meteo utile per ricavare le seguenti informazioni meteorologiche:<br/>%2Prua e direzione del vento<br/>%2Vento di traverso e frontale<br/>%2Altitudine and pressione barometrica<br/>%2Temperatura di bulbo umido<br/>%2Umidità e punto di rugiada<br/>%2Density altitude<br/>%2Temperatura e gelo del vento<br/>%2Data e Ora<br/>%2Valori minimi, massimi, e medi<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia %3Kestrel%4.<br/>%2Usa [%3%12%4] e seleziona %3Equipaggiamento%4.<br/>%2Seleziona %3Apri%4. %3케스트렐 4500 휴대용 기상 추적 장비%4는 다음 날씨 데이터들을 수집하는 데 유용한 소형 기상 관측 장비입니다:<br/>%2바람이 오는 방향과 가는 방향<br/>%2옆바람과 맞바람<br/>%2고도 및 기압<br/>%2습구온도<br/>%2습도 및 이슬점<br/>%2밀도고도<br/>%2체감온도<br/>%2시간 및 날짜<br/>%2최소, 최대, 평균값<br/><br/>%3사용 방법:%4<br/>%2%3케스트렐 4500NV%4를 장착하십시오.<br/>%2[%3%12%4]를 사용하고 %3장비%4를 선택하십시오.<br/>%2%3열기%4를 선택하십시오. %3ケストレル 4500 携帯気象計%4は、次の気象データの収集に役立つミニ気象ステーションです:<br/>%2方位と風向<br/>%2横風と向かい風<br/>%2高度と気圧<br/>%2湿球温度<br/>%2湿度と露点<br/>%2密度高度<br/>%2ウィンドチルと温度<br/>%2日付と時刻<br/>%2最小値、最大値、平均値<br/><br/>%3使用方法:%4<br/>%2%3ケストレル%4を装備します。<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3ケストレルを開く%4で使用できます。 + La %3Estación Climática de Bolsillo Kestrel 4500%4 es una pequeña estación climática portátil para recolectar la siguiente información del tiempo:<br/>%2Dirección y Sentido del Viento<br/>%2VIento cruzado y Viento en cola<br/>%2Altitud y presión barométrica<br/>%2Temperatura húmeda<br/>%2Humedad y punto de condensación<br/>%2Densidad de altitud<br/>%2Sensación térmica y temperatura<br/>%2Hora y fecha<br/>%2Valores mínimos, máximos y medios<br/><br/>%3Uso:%4<br/>%2Equipa un %3Kestrel%4.<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar %3Abrir%4. Triangulate Your Position @@ -548,6 +608,7 @@ 三角測量で位置を特定 Передавайте свое местоположение Trianguler votre position + Triangular Tu Posición The %3Map Tools%4 are a set of tools that allows a soldier to measure distances and angles. Useful for land, and calculating firing solutions for artillery.<br/><br/>%3Usage:%4<br/>%2Open %3Map%4.<br/>%2Use [%3%12%4] and select %3Map Tools%4.<br/>%2 The Tool can be moved by dragging with [%3Left-Click%4] while holding [%3ALT%4]. @@ -556,6 +617,7 @@ %3독도용 도구%4는 병사가 거리와 각도를 측정할 수 있는 도구 세트입니다. 지상에서 유용하며 포병 사격 솔루션 계산에 유용합니다,<br/><br/>%3사용 방법:%4<br/>%2%3지도%4를 여십시오.<br/>%2[%3%12%4]를 사용하여 %3독도용 도구%4를 선택하십시오.<br/>%2도구는 [%3Alt 키%4]를 누른 상태에서 [%3마우스 왼쪽 클릭%4]으로 드래그하여 이동할 수 있습니다. %3マップ ツール%4は、兵士が距離と角度を測定できるようにするツールのセットです。陸上や大砲の射撃工程の計算を解くのに役立ちます。<br/><br/>%3使用方法:%4<br/>%2%3マップ%4を開きます。<br/>%2[%3%12%4] を使って%3マップ ツール%4を選択します。<br/>%2 [%3ALT%4] を押しながら [%3左クリック%4] でドラッグするとツールを移動できます。 Les %3Outils cartographiques%4 sont un ensemble d'outils permettant au soldat de mesurer des distances et des angles. Utile pour la terre et le calcul des solutions de tir pour l'artillerie.<br/><br/>%3Utilisation:%4<br/>%2Ouvrir la%3Carte%4.<br/>%2Utiliser [%3%12%4] et sélectionner %3Outils cartographiques%4.<br/>%2 L'outil peut être déplacé en le faisant glisser avec [%3Clic gauche%4] tout en maintenant [%3ALT%4]. + Las %3Herramientas de mapa%4 son un conjunto de herramientas que permiten a un soldado medir distancias y ángulos. Util para terrenos, y para calcular soluciones de tiro para artillería.<br/><br/>%3Uso:%4<br/>%2Abrir %3Mapa%4.<br/>%2Usar [%3%12%4] y seleccionar %3Herramientas de Mapa%4.<br/>%2 La herramienta puede ser movida siendo arrastrada con [%3CLick-Izquierdo%4] mientras se pulsa [%3ALT%4]. Advanced DAGR @@ -565,6 +627,7 @@ より高度なDAGR Продвинутый DAGR DAGR avancé + DAGR Avanzado The %3MicroDAGR GPS%4 is an advanced version of the %3DAGR%4. It provides position, navigation, and timing (PNT) data to include:<br/>%2Compass and heading<br/>%2Date and hour synced to the mission<br/>%2Elevation (relative to sea level)<br/>%2Current speed<br/>%2GPS with topographic and satellite view<br/>%2Creating, naming, and deleting waypoints<br/>%2Friendly identification (Requires ACE BLUFOR Tracker Setting)<br/>Connection to the Vector-21 Rangefinder for data import (waypoint creation and grid reference of ranged targets)<br/><br/>%3Usage:%4<br/>%2For usage instructions, please visit the dedicated %3MicroDAGR%4 wiki. @@ -572,6 +635,7 @@ Il %3GPS MicroDAGR%4 è una versione avanzata del %3DAGR%4. Esso mostra dati su posizione, navigazione e tempismo (PNT), includendo:<br/>%2Bussola e azimut<br/>%2Data e ora sincronizzate con la missione<br/>%2Elevazione (dal livello del mare)<br/>%2Velocità attuale<br/>%2GPS con visuale topografica e satellitare<br/>%2Creazione, rinomina e rimozione di waypoint<br/>%2Identificazione di alleati (Richiede Impostazioni ACE BLUFOR Tracker)<br/>Connessione al Telemetro Vector-21 per importazione di dati (creazione waypoint e indicazione di griglia su bersagli puntati)<br/><br/>%3Utilizzo:%4<br/>%2Per informazioni sull'utilizzo sei pregato di visitare la pagina wiki dedicata al %3MicroDAGR%4. %3마이크로DAGR GPS%4는 %3DAGR%4의 고급 버전입니다. 다음과 같이 위치, 내비게이션 및 타이밍(PNT) 데이터를 제공합니다:<br/>%2나침반 및 방향<br/>%2임무와 동기화된 날짜 및 시간<br/>%2고도 (해수면 기준)<br/>%2현재 속도<br/>%2지형 및 위성 시점 기능이 있는 GPS<br/>%2웨이포인트 생성, 작명 및 삭제<br/>%2아군 식별 (ACE의 GPS 피아식별기 켜기 체크 필요)<br/>%2데이터를 가져오기 위한 벡터-21 거리계에 연결(원거리 대상의 웨이포인트 생성 및 좌표 참조)<br/><br/>%3사용 방법:%4<br/>%2사용 방법을 보려면 전용 %3마이크로DAGR%4의 위키를 방문하십시오. %3MicroDAGR GPS%4は%3DAGR%4のより高度なバージョンです。測位、航法、計時(PNT)データが提供されます。これには以下の情報を含みます:<br/>%2コンパスと方位<br/>%2ミッションに同期された日付と時間<br/>%2標高 (海面に対する相対値)<br/>%2現在の速度<br/>%2地形図と衛星ビューを備えたGPS<br/>%2ウェイポイントの作成、名前付け、および削除<br/>%2友軍の識別 (ACE ブルーフォーストラッキング設定が必要)<br/>ベクター21レンジファインダーへの接続とデータのインポート (ウェイポイントの作成と遠距離ターゲットのグリッド参照)<br/><br/>%3使用方法:%4<br/>%2使用手順については、専用の %3MicroDAGR%4 wiki を参照してください。 + El %3GPS MicroDAGR%4 es una versión avanzada del %3DAGR%4. Provee de posicionamiento, navegación y datos de temporización (PNT) que incluye:<br/>%2Brújula y dirección<br/>%2Fecha y hora sincronizada con la misión<br/>%2Elevación (relativa al nivel del mar)<br/>%2Velocidad actual<br/>%2GPS con vista topográfica y satelital<br/>%2Creación, nombrado y borrado de puntos de ruta<br/>%2Identificación de aliados (Requiere la opción de ACE BLUFOR Tracker)<br/>Conexión con el telémetro Vector-21 para importación de datos (creación de puntos de ruta y referenciado en eje de coordenada para objetivos a distancia)<br/><br/>%3Uso:%4<br/>%2Para instrucciones de uso, por favor visita la Wiki dedicada de %3MicroDAGR%4. Range Tables @@ -581,6 +645,7 @@ 射表 Таблицы диапазонов Tables de tir + Tablas de Distancia Get A Firing Solution @@ -590,6 +655,7 @@ 撃ち方の解を得る Получите расчёт Obtenir une solution de tir + Obtener Una Solución de Tiro %3Range Tables%4 allow for a soldier to estimate accurate shot placement on direct or indirect targets (depending on asset). The %3Range Table%4 will automatically fill depending on the soldiers selected weapon/vehicle.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select the desired %3Range Table%4. @@ -597,6 +663,7 @@ %3Tavole di tiro%4 permettono al soldato di stimare piazzamenti accurati di colpi mediante fuoco diretto o indiretto (a seconda dell'arma). La %3Tavola di tiro%4 si modificherà in automatico a seconda dell'arma/veicolo del soldato.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] and seleziona %3Equipaggiamento%4.<br/>%2Seleziona la portata desiderata sulla %3Tavola di tiro%4. %3사거리표%4를 사용하면 병사가 직접 또는 간접 표적(자산에 따라 다름)에 대한 정확한 사격 배치를 추정할 수 있습니다. %3사거리표%4는 선택한 병사의 무기/차량에 따라 자동으로 작성됩니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4]를 사용하고 %3장비%4를 선택하십시오.<br/>%2원하는 %3사거리표%4를 선택하십시오. %3射表%4 を使用すると、兵士は (手段に応じて) 直接的または間接的なターゲットへの正確な射撃位置を推定できます。%3射表%4は、兵士が選択した武器/車両に応じて自動的に入力されます。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2目的の%3射表%4を選択します。 + La %3Tabla de distancias%4 permite a un soldado estimar con precisión el posicionamiento de un disparo sobre un objetivo de manera directa o indirecta (dependiendo del dispositivo). La %3Tabla de distancias%4 se autorellena dependiendo del arma o vehículo seleccionado por el soldado.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Selecciona la %3Tabla de distancias%4 deseada. Ropes @@ -606,6 +673,7 @@ ロープ Канаты Corde + Cuerdas Tow With Ease @@ -615,6 +683,7 @@ 楽々けん引 Буксируйте с легкостью Remorquer avec facilité + Remolcar Con Facilidad %3Ropes%4 have multiple uses including %3Towing%4 vehicles and %3Fast Roping%4 from helicopters.<br/><br/>%3Towing:%4<br/>%2Approach a vehicle.<br/>%2Use [%3%13%4] and select %3Towing%4.<br/>%2Select rope length.<br/>%2Select attachment point on towing vehicle.<br/>%2Select attachment on towed vehicle.<br/><br/>%3Available Rope Lengths:%4<br/>%2 3.2 meters<br/>%2 6.2 meters<br/>%2 12.2 meters<br/>%2 15.2 meters<br/>%2 18.3 meters<br/>%2 27.4 meters<br/>%2 36.6 meters @@ -622,6 +691,7 @@ %3Corde%4 hanno molteplici utilizzi, come %3Trainare%4 veicoli e %3Fast Roping%4 da elicotteri.<br/><br/>%3Traino:%4<br/>%2Avvicinati a un veicolo.<br/>%2Usa [%3%13%4] e seleziona %3Traina%4.<br/>%2Seleziona lunghezza corda.<br/>%2Seleziona punto di attacco su veicolo trainante.<br/>%2Seleziona attacco su veicolo trainato.<br/><br/>%3Lunghezze corde a disposizione:%4<br/>%2 3.2 metri<br/>%2 6.2 metri<br/>%2 12.2 metri<br/>%2 15.2 metri<br/>%2 18.3 metri<br/>%2 27.4 metri<br/>%2 36.6 metri %3로프%4는 차량 %3견인%4 및 헬기의 %3패스트로프%4 등 여러 용도로 사용됩니다.<br/><br/>%3견인 방법:%4<br/>%2차량에 접근하십시오.<br/>%2[%3%13%4]를 사용하고 %3견인%4을 선택하십시오.<br/>%2로프 길이를 선택하십시오.<br/>%2견인할 차량의 부착 지점을 선택하십시오.<br/>%2견인될 차량의 부착 지점을 선택하십시오.<br/><br/>%3사용 가능한 로프 길이:%4<br/>%2 3.2m<br/>%2 6.2m<br/>%2 12.2m<br/>%2 15.2m<br/>%2 18.3m<br/>%2 27.4m<br/>%2 36.6m %3ロープ%4には、車両の%3けん引%4やヘリコプターからの%3ファストロープ%4など、複数の用途があります。<br/><br/>%3けん引方法:%4<br/>%2車両に近づきます。<br/>%2[%3%13%4] を使って%3けん引%4を選択します。<br/>%2ロープの長さを選択します。<br/>%2けん引する車両のロープ取付位置を選択します。<br/>%2けん引される車両のロープ取付位置を選択します。<br/><br/>%3利用可能なロープの長さ:%4<br/>%2 3.2 メートル<br/>%2 6.2 メートル<br/>%2 12.2 メートル<br/>%2 15.2 メートル<br/>%2 18.3 メートル<br/>%2 27.4 メートル<br/>%2 36.6 メートル + Las %3Cuerdas%4 tienen múltiples usos incluyendo el %3Remolcado%4 de vehículos y el %3Descenso con Cuerda%4 desde helicópteros.<br/><br/>%3Remolcado:%4<br/>%2Acércate a un vehículo.<br/>%2Usar [%3%13%4] y seleccionar %3Remolcado%4.<br/>%2Selecciona la longitud de la cuerda.<br/>%2Selecciona un punto de anclaje en el vehículo de remolcado.<br/>%2Selecciona una sujección en el vehículo remolcado.<br/><br/>%3Longitudes de Cuerda Disponibles:%4<br/>%2 3.2 metros<br/>%2 6.2 metros<br/>%2 12.2 metros<br/>%2 15.2 metros<br/>%2 18.3 metros<br/>%2 27.4 metros<br/>%2 36.6 metros Expand Your Fortifications @@ -631,6 +701,7 @@ 要塞を拡張する Расширить свои укрепления Élargissez vos fortifications + Expande Tus Fortificaciones %3Sandbags%4 are sacks made of sturdy material, filled with sand, used for a variety of purposes such as creating barriers or providing stability in construction projects. Useful in expanding larger placed fortifications.<br/><br/>%3Usage:%4<br/>%2Equip a %3Sandbag (Empty)%4.<br/>%2Use [%3%12%4] and select %3Deploy Sandbag%4.<br/>%2Follow on-screen instructions for placement. @@ -638,6 +709,7 @@ %3Sacchi di Sabbia%4 sono sacchi di un materiale robusto, riempiti di sabbia, usati per una varietà di utilizzi come creare barriere o aumentare la stabilità di fortificazioni.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia una %3Sacco di Sabbia (Vuoto)%4.<br/>%2Usa [%3%12%4] e seleziona %3Posiziona Sacco di Sabbia%4.<br/>%2Segui le istruzioni sullo schermo per il piazzamento. %3모래주머니%4는 튼튼한 재료로 만든 주머니로 모래를 채워 장벽을 만들거나 건설 작업에서 안정성을 제공하는 등 다양한 용도로 사용되며, 더 큰 요새를 확장하는 데 유용합니다.<br/><br/>%3사용 방법:%4<br/>%2%3모래주머니(비어있음)%4을 장착하십시오.<br/>%2[%3%12%4]를 사용하고 %3모래주머니 배치%4를 선택하십시오.<br/>%2화면의 지시에 따라 배치하십시오. %3土のう%4は、砂が詰められた頑丈な素材で作られた袋で、建設プロジェクトでの障壁の作成や安定性の提供など、さまざまな目的に使用されます。より大きな配置の要塞を拡張するのに役立ちます。<br/><br/>%3使用方法:%4<br/>%2%3土のう (空)%4を装備します。<br/>%2[%3%12%4] を使って%3土のうを作る%4を選択します。<br/>%2画面上の指示に従って配置します。 + Los %3Sacos de tierra%4 son sacos hechos de un material resistente, rellenados de tierra, usados para una diversa variedad de propósitos como la construcción de barreras o proveer estabilidad en los proyectos de construcción. Son útiles en la expansión de proyectos de construcción más grandes.<br/><br/>%3Uso:%4<br/>%2Equipa un %3Saco de tierra (Vacío)%4.<br/>%2Usar [%3%12%4] y seleccionar %3Desplegar Saco de tierra%4.<br/>%2Seguir las instrucciones en pantalla para su colocación. Lower Firearm Temperature @@ -647,6 +719,7 @@ 銃の熱を冷ます Понизьте температуру оружия Refroidir l'arme + Bajar la Temperatura del Arma %3Spare Barrels%4 allow a soldier to reduce their weapon's heat significantly. After a short delay, the weapon's barrel will be swapped and its heat reduced. A soldier may also check the temperature of any barrels within their inventory. Not all weapons support swapping barrels.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select %3Swap Barrel%4.<br/>%2Resume operation after barrel swap is complete. @@ -654,6 +727,7 @@ %3Canne di Ricambio%4 permettono ai soldati di raffreddare la loro arma notevolmente. Dopo una breve attesa, la canna dell'arma verrà sostituita e la temperatura ridotta. Un soldato può anche controllare la temperatura di canne di ricambio presenti nel proprio inventario. Non tutte le armi consentono lo scambio canna.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] e seleziona %3Equipaggiamento%4.<br/>%2Seleziona %3Sostituisci Canna%4.<br/>%2Continua l'ingaggio dopo sostituzione avvenuta. %3예비 총열%4을 사용하면 병사의 무기의 발열을 크게 줄일 수 있습니다. 잠시 뒤에 무기의 총신이 교체되고 발열이 감소합니다. 군인은 소지품에 있는 총열의 온도도 확인할 수 있습니다. 모든 무기가 총열 교환을 지원하는 것은 아닙니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4]를 사용하고 %3장비%4를 선택하십시오.<br/>%2%3총열 교체%4를 선택하십시오.<br/>%2총열 교체가 완료된 후 작전을 계속하십시오. %3予備銃身%4を使用すると、兵士は武器の熱を大幅に下げることができます。少し経つと、武器の銃身が交換され熱が下がります。兵士はインベントリ内の銃身の温度を確認することもできます。すべての武器が銃身の交換をサポートしているわけではありません。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3銃身を交換%4を選択します。<br/>%2銃身交換が完了すると、再度射撃することが出来ます。 + El %3Cañón de Repuesto%4 permite a un soldado reducir el calor del arma significativamente. Tras un pequeño periodo, el cañón del arma habrá sido sustituido y el calor reducido. Un soldado puede tambien comprobar la temperatura de cualquier cañón en su inventario. No todas las armas soportan el cambio de cañón.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar %3Cambiar Cañón%4.<br/>%2Continuar con la operación una vez se haya cambiado el cañón. Spray Paint @@ -663,6 +737,7 @@ ペイントスプレー Аэрозольная краска Bombe de peinture + Pintura En Spray Tag Your Territory @@ -672,6 +747,7 @@ 自分のテリトリーをマーキング Пометьте свою территорию Marquez votre territoire + Marca Tu Territorio %3Spray Paint%4 is used to tag surfaces with various symbols.<br/><br/>%3Usage:%4<br/>%2Move close to a surface (wall, vehicle, ground, etc).<br/>%2Use [%3%12%4] and select %3Tag%4.<br/>%2Choose a symbol.<br/><br/>%3Available Colors:%4<br/>%2Black<br/>%2Blue<br/>%2Green<br/>%2Red @@ -679,6 +755,7 @@ %3Bombolette Spray%4 vengono usate per marcare superfici con vari simboli.<br/><br/>%3Utilizzo:%4<br/>%2Muoviti vicino a una superfice (muro, veicolo, suolo, etc).<br/>%2Usa [%3%12%4] e seleziona %3Marca%4.<br/>%2Seleziona un simbolo.<br/><br/>%3Colori disponibili:%4<br/>%2Nero<br/>%2Blu<br/>%2Verde<br/>%2Rosso %3스프레이 페인트%4다양한 기호로 표면에 태그를 지정하는 데 사용됩니다.<br/><br/>%3사용 방법:%4<br/>%2표면(벽, 차량, 지면 등)에 가까이 가십시오.<br/>%2[%3%12%4]를 사용하고 %3태그%4를 선택하십시오.<br/>%2모양을 고르십시오.<br/><br/>%3사용 가능 색상:%4<br/>%2검정<br/>%2파랑<br/>%2초록<br/>%2빨강 %3ペイントスプレー%4は、地面や壁、車両の表面などに様々な図形のタグを付けるために使えます。<br/><br/>%3使用方法:%4<br/>%2塗りたい面に近づきます。(壁、車両、地面など)<br/>%2[%3%12%4] を使って%3タグ (スプレーペイント)%4を選択します。<br/>%2図形を選びます。<br/><br/>%3利用可能な色:%4<br/>%2黒<br/>%2白<br/>%2赤<br/>%2青<br/>%2緑<br/>%2黄 + La %3Pintura en Spray%4 se usa para marcar superficies con varios símbolos.<br/><br/>%3Uso:%4<br/>%2Acércate a una superficie (pared, vehículo, suelo, etc).<br/>%2Usar [%3%12%4] y seleccionar %3Tag%4.<br/>%2Elige un símbolo.<br/><br/>%3Colores disponibles:%4<br/>%2Negro<br/>%2Azul<br/>%2Verde<br/>%2Rojo Brace From Anywhere @@ -688,6 +765,7 @@ どこでも支持器 Опора может быть установлена в любом месте Stabilisé partout + Apoyarte En Cualquier Lugar The %3SSWT Kit%4 is a deployable tripod that allows a soldier to brace their aim when deployed. Use it when you need an elevated shooting position and there are no other objects around.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select %3SSWT Kit%4 and follow the on screen prompts to place. @@ -695,6 +773,7 @@ Il %3Kit SSWT%4 è un treppiede piazzabile che permette al soldato di appoggiare la sua arma. Usalo quando ti serve una posizione di tiro rialzata e non ci sono altri oggetti utili nelle vicinanze.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] e seleziona %3Equipaggiamento%4.<br/>%2Seleziona %3Kit SSWT%4 e segui le indicazioni di piazzamento. %3SSWT 키트%4는 병사가 배치 시 조준력을 상승시킬 수 있는 배치 가능한 삼각대입니다. 높이 조절이 된 사격 위치가 필요하고 주위에 다른 물체가 없을 때 사용하십시오.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4] 를 사용하고 %3장비%4를 선택하십시오.<br/>%2%3SSWT 키트%4를 선택하고 화면의 지시에 따라 배치하십시오. %3SSWT キット%4は展開可能な三脚で、展開時に兵士が狙いを定めることができます。高い射撃位置が必要で、周囲に他の物体がない場合に使用してください。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3SSWT キット%4を選択し、画面上の指示に従って配置します。 + El %3Kit SSWT%4 es un trípode desplegable que permite a un soldado apoyarse para apuntar cuando está desplegado. Úsalo cuando necesites una posición de tiro elevada y no hay ningún otro objeto alrededor.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar %3Kit SSWT%4 y sigue las indicaciones en pantalla para colocarlo. Keep Eyes In The Sky @@ -705,6 +784,7 @@ Не Отрывай Глаз От Неба Gardez les yeux au ciel Gardez les yeux au ciel + Manten Tus Ojos En El Cielo %3UAV Batteries%4 are used to recharge a UAV's energy storage. Especially useful for small UAVs.<br/><br/>%3Usage:%4<br/>%2Equip a %3UAV Battery%4<br/>%2Approach a %3UAV%4 with its %3Engine Off%4.<br/>%2Use [%3%13%4] and select %3Recharge%4. @@ -712,6 +792,7 @@ %3Batteria UAV%4 vengono usate per ricaricare gli UAV. Molto utile per piccoli UAV.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia una %3Batteria UAV%4<br/>%2Avvicinati al %3UAV%4 con il %3Motore Spento%4.<br/>%2Usa [%3%13%4] e seleziona %3Ricarica%4. %3무인기 배터리%4는 무인기의 에너지 저장소를 재충전하는 데 사용됩니다. 소형 무인기에 특히 유용합니다.<br/><br/>%3사용 방법:%4<br/>%2%3무인기 배터리%4를 장착하십시오.<br/>%2%3엔진을 끄고%4 %3무인기%4에 접근하십시오.<br/>%2[%3%13%4]를 사용하고 %3재충전%4을 선택하십시오. %3UAVバッテリー%4は、UAVの電源容量を充電するために使用されます。<br/><br/>%3使用方法:%4<br/>%2%3UAV バッテリー%4を装備します。<br/>%2%3エンジンをオフ%4にした%3UAV%4に近づきます。<br/>%2[%3%13%4] を使って%3充電%4を選択します。 + La %3Batería de VANT%4 se utilizan para recargar el almacenamiento de energía de un VANT. Especialmente útiles para pequeños VANTs.<br/><br/>%3Uso:%4<br/>%2Equipa una %3Batería de VANT%4<br/>%2Acércate a un %3VANT%4 con su %3Motor Apagado%4.<br/>%2Usa [%3%13%4] y selecciona %3Recargar%4. Making An Entrance @@ -721,6 +802,7 @@ 堂々入場する Создание собственного входа Faire son entrée + Abriendo Una Entrada %3Wirecutters%4 are a tool that allows a soldier to bypass wired fencing. Useful for creating backdoor entrances into secure areas.<br/><br/>%3Usage:%4<br/>%2Move close to a fence.<br/>%2Use [%3%12%4] and select %3Cut Fence%4. @@ -728,6 +810,7 @@ La %3Trancia%4 è un utensile che permette ai soldati di sorpassare filo spinato e recinzioni. Utile per creare punti di accesso nel retro di zone protette.<br/><br/>%3Utilizzo:%4<br/>%2Avvicinati a una barriera.<br/>%2Usa [%3%12%4] e seleziona %3Taglia%4. %3절단기%4는 병사가 철조망을 통과할 수 있게 해주는 도구입니다. 보안 구역에 뒷입구를 만드는 데 유용합니다.<br/><br/>%3사용 방법:%4<br/>%2철조망에 가까이 가십시오.<br/>%2[%3%13%4]를 사용하고 %3철조망 자르기%4를 선택하십시오. %3ワイヤーカッター%4は、兵士が有線フェンスを回避できるようにするツールです。安全にエリアへの裏口を作成するのに役立ちます。<br/><br/>%3使用方法:%4<br/>%2フェンスの近くに移動します。<br/>%2[%3%12%4] を使って%3フェンスを切断する%4を選択します。 + La %3Cizalla%4 es una herramienta que permite a un soldado atravesar una valla de alambre. Es útil para crear entradas traseras en áreas seguras.<br/><br/>%3Uso:%4<br/>%2Acércate a una valla.<br/>%2Usar [%3%12%4] y seleccionar %3Cortar Valla%4. Items @@ -770,6 +853,7 @@ 要塞を構築する Стройте укрепления Construire des fortifications + Construir Fortificaciones The %3Fortify Tool%4 allows soldiers to build fortifications provided by their mission creator.<br/><br/>%3Usage:%4<br/>%2Pick up a %3Fortify Tool%4.<br/>%2Use [%3%12%4] and select %3Fortify%4.<br/>%2Select an available fortification and follow the on screen prompts for placement. @@ -777,6 +861,7 @@ L'%3Attrezzo di Fortificazione%4 permette ai soldati di costruire fortificazioni permesse dal creatore della missione.<br/><br/>%3Utilizzo:%4<br/>%2Raccogli un %3Attrezzo di Fortificazione%4.<br/>%2Usa [%3%12%4] e seleziona %3Fortifica%4.<br/>%2Seleziona una fortificazione disponibile e segui le indicazioni di piazzamento sullo schermo. %3요새화 도구%4를 사용하면 병사들이 임무 생성자가 제공한 요새를 구축할 수 있습니다.<br/><br/>%3사용 방법:%4<br/>%2%3요새화 도구%4를 가지십시오.<br/>%2[%3%12%4]를 사용하고 %3요새화%4를 선택하십시오.<br/>%2사용 가능한 요새를 선택하고 화면의 지시에 따라 배치하십시오. %3要塞ツール%4を使用すると、兵士はミッション作成者が提供した要塞を構築できます。<br/><br/>%3使用方法:%4<br/>%2%3要塞ツール%4を持つ。<br/>%2[%3%12%4] を使って%3要塞%4を選択します。<br/>%2利用可能な構造物を選択し、画面上の指示に従って配置します。 + La %3Herramienta de Fortificación%4 permite a los soldados construir fortificaciones provistas por su creador de mision.<br/><br/>%3Uso:%4<br/>%2Coge una %3Herramienta de Fortificación%4.<br/>%2Usar [%3%12%4] y seleccionar %3Fortificar%4.<br/>%2Selecciona una fortificación disponible y sigue las instrucciones en pantalla para su colocación. Breaking and Entering @@ -786,6 +871,7 @@ 破壊して乗り込む Взлом и проникновение Entrée par effraction + Romper y Entrar %3Lockpicks%4 are used to gain access to locked vehicles.<br/><br/>%3Usage:%4<br/>%2Equip a %3Lockpick%4.<br/>%2Approach a %3Locked%4 vehicle.<br/>Use [%3%13%4] and select %3Lockpick Vehicle%4.<br/><br/><t underline='1'>%3Note:%4</t> Lockpicks and keys are only available via scripting or ACE Vehicle Key modules. @@ -793,6 +879,7 @@ I %3Grimaldelli%4 sono usati per forzare l'accesso a veicoli bloccati.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia un %3Grimaldello%4.<br/>%2Avvicinati a un veicolo %3Bloccato%4 vehicle.<br/>Usa [%3%13%4] e seleziona %3Scassina Veicolo%4.<br/><br/><t underline='1'>%3Note:%4</t> Grimaldelli e chiavi sono solo reperibili mediante scripting o moduli ACE di assegnazione Chiavi Veicoli. %3해정도구%4는 잠긴 차량에 들어가는 데 사용됩니다.<br/><br/>%3사용 방법:%4<br/>%2%3해정도구%4를 장착하십시오.<br/>%2%3잠긴%4 차량에 접근하십시오.<br/>[%3%13%4]를 사용하고 %3차량 잠금해제%4를 선택하십시오.<br/><br/><t underline='1'>%3참고:%4</t> 해정도구와 열쇠는 스크립팅 또는 ACE 차량 열쇠 모듈에서만 사용할 수 있습니다. %3Lockpick%4は、ロックされた車両にアクセスするために使用されます。<br/><br/>%3使用方法:%4<br/>%2%3Lockpick%4を装備します。<br/>%2%3鍵の掛かった%4車両に近づきます。<br/>[%3%13%4] を使って%3鍵をこじ開ける%4を選択します。<br/><br/><t underline='1'>%3備考:%4</t> ロックピックとキーは、スクリプトまたは ACE Vehicle Key モジュールを介してのみ使用できます。 + La %3Ganzúa%4 es usada para lograr acceso a vehículos bloqueados.<br/><br/>%3Uso:%4<br/>%2Equipar %3Ganzúa%4.<br/>%2Acércate a un vehículo %3Bloqueado%4.<br/>Usar [%3%13%4] y seleccionar %3Ganzuar Vehículo%4.<br/><br/><t underline='1'>%3Nota:%4</t>Ganzúas y Llaves sólo están disponibles mediante scripting o módulos de Llaves de Vehículos ACE. Vehicle Keys @@ -802,6 +889,7 @@ 車両キー Взлом и проникновение Clés de véhicule + Llaves de Vehículos Lock/Unlock Vehicles @@ -811,6 +899,7 @@ 車両のロック/ロック解除 Взлом и проникновение Verrouiller/déverrouiller un véhicule + Bloquear/Desbloquear vehículos %3Vehicle Keys%4 are used to lock/unlock your vehicles. Vehicle keys can exist for the whole side, or keys can be created for a particular vehicle itself.<br/><br/>%3Usage:%4<br/>%2Equip a %3Vehicle Key%4.<br/>%2Approach the vehicle that the key belongs to.<br/>Use [%3%13%4] and select %3Lock/Unlock Vehicle%4.<br/><br/><t underline='1'>%3Note:%4</t> Lockpicks and keys are only available via scripting or ACE Vehicle Key modules. @@ -818,6 +907,7 @@ Le %3Chiavi di Veicoli%4 vengono usate per bloccare/sbloccare i propri veicoli. Chiavi di veicoli possono esistere per un'intera fazione, oppure per un veicolo particolare.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia una %3Chiave di Veicolo%4.<br/>%2Avvicinati al veicolo a cui appartiene la chiave.<br/>Usa [%3%13%4] e seleziona %3Blocca/Sblocca Veicolo%4.<br/><br/><t underline='1'>%3Note:%4</t> Grimaldelli e chiavi sono solo disponibili mediante scripting o moduli ACE Chiavi Veicoli. %3차량 열쇠%4는 차량을 잠그거나 잠금해제하는 데 사용됩니다. 차량 열쇠는 모든 세력에게 존재할 수도 있고, 특정 차량 자체에 대해 열쇠를 생성할 수도 있습니다.<br/><br/>%3사용 방법:%4<br/>%2%3차량 열쇠%4를 장착하십시오.<br/>%2해당 열쇠에 속한 차량에 접근하십시오.<br/>[%3%13%4]를 사용하고 %3차량 잠금/잠금해제%4를 선택하십시오.<br/><br/><t underline='1'>%3참고:%4</t> 해정도구와 열쇠는 스크립팅 또는 ACE 차량 열쇠 모듈에서만 사용할 수 있습니다. %3Vehicle Key%4は、車両のロック/ロック解除に使用されます。車両キーは陣営全体に存在することも、特定の車両だけに対してキーを作成することもできます。<br/><br/>%3使用方法:%4<br/>%2%3Vehicle Key%4を装備します。<br/>%2鍵の対応している車両に近づきます。<br/>[%3%13%4] を使って%3鍵を解錠/施錠%4します。<br/><br/><t underline='1'>%3備考:%4</t> ロックピックとキーは、スクリプトまたは ACE Vehicle Key モジュールを介してのみ使用できます。 + Las %3Llaves de Vehículos%4 son usadas para bloquear/desbloquear tus vehículos. Las Llaves de Vehículos existen para un bando entero o para un vehículo concreto.<br/><br/>%3Uso:%4<br/>%2Equipa una %3Llave de Vehículo%4.<br/>%2Acércate a un vehículo cuya llave corresponda.<br/>Usar [%3%13%4] y selecciona %3Bloquear/Desbloquear Vehículo%4.<br/><br/><t underline='1'>%3Nota:%4</t> Ganzúas y Llaves sólo están disponibles mediante scripting o módulos de Llaves de Vehículos ACE diff --git a/addons/fire/XEH_PREP.hpp b/addons/fire/XEH_PREP.hpp index d9eacfdee00..8b2e8f6bd1f 100644 --- a/addons/fire/XEH_PREP.hpp +++ b/addons/fire/XEH_PREP.hpp @@ -1,6 +1,5 @@ PREP(burn); PREP(isBurning); -PREP(isPlant); PREP(burnIndicator); PREP(burnReaction); PREP(fireManagerPFH); diff --git a/addons/fire/XEH_preInit.sqf b/addons/fire/XEH_preInit.sqf index 2fc794454d3..894773534a4 100644 --- a/addons/fire/XEH_preInit.sqf +++ b/addons/fire/XEH_preInit.sqf @@ -8,6 +8,4 @@ PREP_RECOMPILE_END; #include "initSettings.inc.sqf" -GVAR(burningPlants) = []; - ADDON = true; diff --git a/addons/fire/functions/fnc_burnIndicator.sqf b/addons/fire/functions/fnc_burnIndicator.sqf index 13db8862c9f..d876d18a075 100644 --- a/addons/fire/functions/fnc_burnIndicator.sqf +++ b/addons/fire/functions/fnc_burnIndicator.sqf @@ -30,7 +30,7 @@ if !(IS_UNCONSCIOUS(_unit)) then { _unit setVariable [QGVAR(indicatorIteration), _iteration]; }; -if (!([_unit] call FUNC(isBurning)) || { !alive _unit }) then { +if (!([_unit] call FUNC(isBurning)) || {!alive _unit}) then { [_pfhHandle] call CBA_fnc_removePerFrameHandler; _unit setVariable [QGVAR(burnUIPFH), -1]; }; diff --git a/addons/fire/functions/fnc_isBurning.sqf b/addons/fire/functions/fnc_isBurning.sqf index 3bdbe560be0..7cc06dc01de 100644 --- a/addons/fire/functions/fnc_isBurning.sqf +++ b/addons/fire/functions/fnc_isBurning.sqf @@ -17,7 +17,4 @@ params [["_unit", objNull, [objNull]]]; -_unit getVariable [QGVAR(burning), false] || { - GVAR(burningPlants) = GVAR(burningPlants) select {!isNull _x}; - _unit in GVAR(burningPlants) -} +_unit getVariable [QGVAR(burning), false] diff --git a/addons/fire/functions/fnc_isPlant.sqf b/addons/fire/functions/fnc_isPlant.sqf deleted file mode 100644 index f132fc72be5..00000000000 --- a/addons/fire/functions/fnc_isPlant.sqf +++ /dev/null @@ -1,20 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: commy2 - * Check if object is a map placed bush or tree. - * - * Arguments: - * 0: Object - * - * Return Value: - * Is bush or tree? - * - * Example: - * cursorObject call ace_fire_fnc_isPlant - * - * Public: No - */ - -params [["_object", objNull, [objNull]]]; - -_object in nearestTerrainObjects [_object, ["TREE", "SMALL TREE", "BUSH"], 0.1] diff --git a/addons/fortify/functions/fnc_setupModule.sqf b/addons/fortify/functions/fnc_setupModule.sqf index f032d98ebe0..1215393a467 100644 --- a/addons/fortify/functions/fnc_setupModule.sqf +++ b/addons/fortify/functions/fnc_setupModule.sqf @@ -48,10 +48,10 @@ if IS_NUMBER(_preset) then { // Legacy support }; private _budget = _logic getVariable ["Budget", -1]; -if (!(_budget isEqualType 0)) then {_budget = -1}; +if !(_budget isEqualType 0) then {_budget = -1}; private _addToolItem = _logic getVariable ["AddToolItem", false]; -if (!(_addToolItem isEqualType false)) then {_addToolItem = false}; +if !(_addToolItem isEqualType false) then {_addToolItem = false}; private _objects = [_preset] call FUNC(getPlaceableSet); diff --git a/addons/frag/functions/fnc_findReflections.sqf b/addons/frag/functions/fnc_findReflections.sqf index a028a2f70b3..a753934fe85 100644 --- a/addons/frag/functions/fnc_findReflections.sqf +++ b/addons/frag/functions/fnc_findReflections.sqf @@ -120,7 +120,7 @@ if (_zIndex < 5) then { // _dirvec = _pos vectorFromTo ((player modelToWorldVisualWorld (player selectionPosition "Spine3"))); // _dirvec = _dirvec vectorMultiply 100; // _can setVelocity _dirvec; - [DFUNC(doExplosions), 0, [_explosions, 0]] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(doExplosions), 0, [_explosions, 0]] call CBA_fnc_addPerFrameHandler; [_pfhID] call CBA_fnc_removePerFrameHandler; }; END_COUNTER(fnc_findReflections); diff --git a/addons/gforces/functions/fnc_pfhUpdateGForces.sqf b/addons/gforces/functions/fnc_pfhUpdateGForces.sqf index 7ff3444b7dc..4bb680ee47a 100644 --- a/addons/gforces/functions/fnc_pfhUpdateGForces.sqf +++ b/addons/gforces/functions/fnc_pfhUpdateGForces.sqf @@ -71,7 +71,7 @@ private _suitCoef = if ((uniform ACE_player) != "") then { private _gBlackOut = MAXVIRTUALG / _classCoef + MAXVIRTUALG / _suitCoef - MAXVIRTUALG; // Unconsciousness -if ((_average > _gBlackOut) && {["ace_medical"] call EFUNC(common,isModLoaded) && {!(ACE_player getVariable ["ACE_isUnconscious", false])}}) then { +if (_average > _gBlackOut && {GETEGVAR(medical,enabled,false) && {ACE_player call EFUNC(common,isAwake)}}) then { [ACE_player, true, (10 + floor(random 5)), true] call EFUNC(medical,setUnconscious); }; diff --git a/addons/grenades/CfgAmmo.hpp b/addons/grenades/CfgAmmo.hpp index 5082dd432d9..2b0849d2f71 100644 --- a/addons/grenades/CfgAmmo.hpp +++ b/addons/grenades/CfgAmmo.hpp @@ -1,4 +1,3 @@ - class CfgAmmo { class Default; class Grenade: Default { @@ -153,7 +152,7 @@ class CfgAmmo { class ACE_G_M14: SmokeShell { GVAR(incendiary) = 1; model = QPATHTOF(models\ace_anm14th3_armed.p3d); - hit = 5; + hit = 10; indirectHit = 4; indirectHitRange = 1.1; dangerRadiusHit = 50; diff --git a/addons/grenades/CfgEventHandlers.hpp b/addons/grenades/CfgEventHandlers.hpp index 6c29240403a..f6503c2479b 100644 --- a/addons/grenades/CfgEventHandlers.hpp +++ b/addons/grenades/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); diff --git a/addons/grenades/CfgMagazines.hpp b/addons/grenades/CfgMagazines.hpp index ea4641ab7fb..2ff86c443d4 100644 --- a/addons/grenades/CfgMagazines.hpp +++ b/addons/grenades/CfgMagazines.hpp @@ -1,4 +1,3 @@ - class CfgMagazines { class HandGrenade; class ACE_HandFlare_Base: HandGrenade { diff --git a/addons/grenades/CfgVehicles.hpp b/addons/grenades/CfgVehicles.hpp index f9ac60d9fe6..34cf4196e6c 100644 --- a/addons/grenades/CfgVehicles.hpp +++ b/addons/grenades/CfgVehicles.hpp @@ -1,4 +1,3 @@ - class CfgVehicles { class NATO_Box_Base; class Box_NATO_Grenades_F: NATO_Box_Base { diff --git a/addons/grenades/CfgWeapons.hpp b/addons/grenades/CfgWeapons.hpp index 842862f7f98..683ec7532bc 100644 --- a/addons/grenades/CfgWeapons.hpp +++ b/addons/grenades/CfgWeapons.hpp @@ -1,4 +1,3 @@ - class CfgWeapons { class GrenadeLauncher; class Throw: GrenadeLauncher { diff --git a/addons/grenades/Effects.hpp b/addons/grenades/Effects.hpp index 95c3f12ba89..b4a16c6412f 100644 --- a/addons/grenades/Effects.hpp +++ b/addons/grenades/Effects.hpp @@ -1,4 +1,3 @@ - class ACE_M84FlashbangEffect { // empty }; diff --git a/addons/grenades/XEH_PREP.hpp b/addons/grenades/XEH_PREP.hpp index 6b5fb578016..06ceebc6b4f 100644 --- a/addons/grenades/XEH_PREP.hpp +++ b/addons/grenades/XEH_PREP.hpp @@ -1,8 +1,8 @@ - +PREP(addChangeFuseItemContextMenuOptions); +PREP(damageEngineAndWheels); PREP(flare); PREP(flashbangExplosionEH); PREP(flashbangThrownFuze); PREP(incendiary); PREP(nextMode); PREP(throwGrenade); -PREP(addChangeFuseItemContextMenuOptions); diff --git a/addons/grenades/XEH_postInit.sqf b/addons/grenades/XEH_postInit.sqf index c23640bca59..c13bc81b43d 100644 --- a/addons/grenades/XEH_postInit.sqf +++ b/addons/grenades/XEH_postInit.sqf @@ -1,8 +1,10 @@ // by commy2 #include "script_component.hpp" +#include "\a3\ui_f\hpp\defineDIKCodes.inc" ["ace_flashbangExploded", LINKFUNC(flashbangExplosionEH)] call CBA_fnc_addEventHandler; +[QGVAR(damageEngineAndWheels), LINKFUNC(damageEngineAndWheels)] call CBA_fnc_addEventHandler; // Register fired event handlers ["ace_firedPlayer", LINKFUNC(throwGrenade)] call CBA_fnc_addEventHandler; @@ -15,20 +17,45 @@ GVAR(flashbangPPEffectCC) = ppEffectCreate ["ColorCorrections", 4265]; GVAR(flashbangPPEffectCC) ppEffectForceInNVG true; // Add keybinds -["ACE3 Weapons", QGVAR(switchGrenadeMode), localize LSTRING(SwitchGrenadeMode), { +["ACE3 Weapons", QGVAR(switchGrenadeMode), LLSTRING(SwitchGrenadeMode), { // Conditions: canInteract - if !([ACE_player, objNull, ["isNotEscorting"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if !([ACE_player, objNull, ["isNotEscorting", "isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + if !(ACE_player call CBA_fnc_canUseWeapon) exitWith {false}; + // Don't change mode or show hint if advanced throwing is active if (ACE_player getVariable [QEGVAR(advanced_throwing,inHand), false]) exitWith {false}; // Statement - [] call FUNC(nextMode); -}, {false}, [9, [false, false, false]], false] call CBA_fnc_addKeybind; //8 Key + call FUNC(nextMode) // return +}, {}, [DIK_8, [false, false, false]], false] call CBA_fnc_addKeybind; // 8 Key ["CBA_settingsInitialized", { if (GVAR(convertExplosives)) then { - [] call FUNC(addChangeFuseItemContextMenuOptions); + call FUNC(addChangeFuseItemContextMenuOptions); }; }] call CBA_fnc_addEventHandler; + +["vehicle", { + private _currentThrowable = currentThrowable ACE_player; + + // Make sure grenade can be rolled if in roll mode (detonation time has to be >= 1 second and player isn't in a vehicle) + if !( + GVAR(currentThrowMode) == 3 && + {_currentThrowable isNotEqualTo []} && + { + !isNull objectParent ACE_player || + {getNumber (configFile >> "CfgAmmo" >> getText (configFile >> "CfgMagazines" >> _currentThrowable select 0 >> "ammo") >> "explosionTime") < MIN_EXPLOSION_TIME_FOR_ROLL} + } + ) exitWith {}; + + // If the player can't use throwables, don't change it + if !(ACE_player call CBA_fnc_canUseWeapon) exitWith {}; + + // Force the user into the normal throw mode + // Next throw mode after roll would be drop, which isn't ideal if the user tries to throw unknowingly... + [format [LLSTRING(RollGrenadeDisabled), LLSTRING(NormalThrow)], 2] call EFUNC(common,displayTextStructured); + + GVAR(currentThrowMode) = 0; + GVAR(throwModePFEH) call CBA_fnc_removePerFrameHandler; +}, true] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/grenades/XEH_preInit.sqf b/addons/grenades/XEH_preInit.sqf index 894773534a4..9456dc9c9fb 100644 --- a/addons/grenades/XEH_preInit.sqf +++ b/addons/grenades/XEH_preInit.sqf @@ -6,6 +6,9 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +GVAR(currentThrowMode) = 0; +GVAR(throwModePFEH) = -1; + #include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/grenades/functions/fnc_addChangeFuseItemContextMenuOptions.sqf b/addons/grenades/functions/fnc_addChangeFuseItemContextMenuOptions.sqf index d778ca33497..c0b5c9dc801 100644 --- a/addons/grenades/functions/fnc_addChangeFuseItemContextMenuOptions.sqf +++ b/addons/grenades/functions/fnc_addChangeFuseItemContextMenuOptions.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: Cyruz - * Allows conversion of explosive charges in to throwable versions + * Allows conversion of explosive charges into throwable versions. * * Arguments: * None @@ -14,7 +14,8 @@ * * Public: No */ - TRACE_1("addChangeFuseItemContextMenuOptions",_this); + +LOG("addChangeFuseItemContextMenuOptions"); { _x params ["_mag", "_throwableMag"]; @@ -29,21 +30,25 @@ {true}, { params ["", "", "_item", "", "_magArr"]; - _item isEqualTo (_magArr select 0); + + _item == (_magArr select 0) } ], { params ["_unit", "", "", "_slot", "_magArr"]; - private _container = ""; - switch _slot do { + + private _container = switch (_slot) do { case "UNIFORM_CONTAINER": { - _container = "uniform"; + "uniform" }; case "VEST_CONTAINER": { - _container = "vest"; + "vest" }; case "BACKPACK_CONTAINER": { - _container = "backpack"; + "backpack" + }; + default { + "" }; }; @@ -54,7 +59,7 @@ false }, true, - [_mag,_throwableMag] + [_mag, _throwableMag] ] call CBA_fnc_addItemContextMenuOption; [ @@ -67,21 +72,25 @@ {true}, { params ["", "", "_item", "", "_magArr"]; - _item isEqualTo (_magArr select 1); + + _item == (_magArr select 1) } ], { params ["_unit", "", "", "_slot", "_magArr"]; - private _container = ""; - switch _slot do { + + private _container = switch (_slot) do { case "UNIFORM_CONTAINER": { - _container = "uniform"; + "uniform" }; case "VEST_CONTAINER": { - _container = "vest"; + "vest" }; case "BACKPACK_CONTAINER": { - _container = "backpack"; + "backpack" + }; + default { + "" }; }; @@ -92,7 +101,7 @@ false }, true, - [_mag,_throwableMag] + [_mag, _throwableMag] ] call CBA_fnc_addItemContextMenuOption; } forEach [ ["SatchelCharge_Remote_Mag", "ACE_SatchelCharge_Remote_Mag_Throwable"], diff --git a/addons/grenades/functions/fnc_damageEngineAndWheels.sqf b/addons/grenades/functions/fnc_damageEngineAndWheels.sqf new file mode 100644 index 00000000000..ab95ecbe6a2 --- /dev/null +++ b/addons/grenades/functions/fnc_damageEngineAndWheels.sqf @@ -0,0 +1,44 @@ +#include "..\script_component.hpp" +/* + * Author: commy2, johnb43 + * Damage a vehicle's wheels and engine. + * + * Arguments: + * 0: Vehicle + * 1: Incendiary position AGL + * + * Return Value: + * None + * + * Example: + * [cursorObject, position cursorObject] call ace_grenades_fnc_damageEngineAndWheels + * + * Public: No + */ + +params ["_vehicle", "_position"]; +TRACE_2("damageWheelsAndEngine",_vehicle,_position); + +// Vehicle needs to be local and vulnerable +if !(local _vehicle && {isDamageAllowed _vehicle}) exitWith {}; + +{ + // If wheel is close enough to incendiary, burn it + if (_position distance (_vehicle modelToWorld (_vehicle selectionPosition _x)) < EFFECT_SIZE * 2) then { + _vehicle setHit [_x, 1]; + }; +} forEach ((_vehicle call EFUNC(common,getWheelHitPointsWithSelections)) select 1); + +// Burn car engines only +if (_vehicle isKindOf "Wheeled_APC_F") exitWith {}; + +private _engineSelection = getText (configOf _vehicle >> "HitPoints" >> "HitEngine" >> "name"); +private _enginePosition = _vehicle modelToWorld (_vehicle selectionPosition _engineSelection); + +if (_position distance _enginePosition < EFFECT_SIZE * 2) then { + _vehicle setHit [_engineSelection, 1]; + + if (["ace_cookoff"] call EFUNC(common,isModLoaded)) then { + [QEGVAR(cookoff,engineFireServer), _vehicle] call CBA_fnc_serverEvent; + }; +}; diff --git a/addons/grenades/functions/fnc_flare.sqf b/addons/grenades/functions/fnc_flare.sqf index 8214a5600dc..2db6335a77a 100644 --- a/addons/grenades/functions/fnc_flare.sqf +++ b/addons/grenades/functions/fnc_flare.sqf @@ -4,7 +4,7 @@ * Makes flare shine. * * Arguments: - * 0: The flare + * 0: Flare * 1: Color of flare * 2: Intensity of flare * 3: Flare lifetime @@ -34,6 +34,5 @@ _light setLightFlareMaxDistance 1000; _light setLightDayLight true; _light lightAttachObject [_projectile, [0,0,0]]; -//_light attachTo [_projectile, [0,0,0]]; [{deleteVehicle _this}, _light, _timeToLive] call CBA_fnc_waitAndExecute; diff --git a/addons/grenades/functions/fnc_flashbangExplosionEH.sqf b/addons/grenades/functions/fnc_flashbangExplosionEH.sqf index 5e8d17e50cf..33c4bdffc21 100644 --- a/addons/grenades/functions/fnc_flashbangExplosionEH.sqf +++ b/addons/grenades/functions/fnc_flashbangExplosionEH.sqf @@ -4,7 +4,7 @@ * Creates the flashbang effect and knock out AI units. * * Arguments: - * 0: The flashBang position ASL + * 0: Flashbang position ASL * * Return Value: * None @@ -18,152 +18,148 @@ params ["_grenadePosASL"]; TRACE_1("params",_grenadePosASL); -// Create flash to illuminate environment -if (hasInterface) then { - private _light = "#lightpoint" createVehicleLocal ASLtoAGL _grenadePosASL; - _light setPosASL _grenadePosASL; - - _light setLightBrightness 20; - _light setLightAmbient [1,1,1]; - _light setLightColor [1,1,1]; - _light setLightDayLight true; - _light setLightAttenuation [0, 1, 5, 1000, 0, 20]; - - // Reduce the light after 0.1 seconds - [{ - params ["_light"]; - _light setLightBrightness 5; - // Delete the light after 0.2 more seconds - [{ - params ["_light"]; - deleteVehicle _light; - }, [_light], 0.2] call CBA_fnc_waitAndExecute; - }, [_light], 0.1] call CBA_fnc_waitAndExecute; -}; - // Affect local AI (players are not local, except for ACE_player) // @todo: Affect units in static weapons, turned out, etc -private _affected = (ASLtoAGL _grenadePosASL) nearEntities ["CAManBase", 20]; -_affected = _affected - [ACE_player]; +private _affected = ((ASLtoAGL _grenadePosASL) nearEntities ["CAManBase", 20]) - [ACE_player]; + { - if (local _x && {_x call EFUNC(common,isAwake)}) then { - private _unit = _x; - private _strength = 1 - (((eyePos _unit) vectorDistance _grenadePosASL) min 20) / 20; + private _unit = _x; + private _strength = 1 - (((eyePos _unit) vectorDistance _grenadePosASL) min 20) / 20; + + TRACE_3("FlashBangEffect Start",_unit,((getPosASL _unit) vectorDistance _grenadePosASL),_strength); + + [_unit, true] call EFUNC(common,disableAI); - TRACE_3("FlashBangEffect Start",_unit,((getPosASL _unit) vectorDistance _grenadePosASL),_strength); + // Make AI try to look away + private _dirToFlash = _unit getDir _grenadePosASL; + _unit setDir (_dirToFlash + linearConversion [0.2, 1, _strength, 40, 135] * selectRandom [-1, 1]); - [_unit, true] call EFUNC(common,disableAI); + private _flashReactionDebounce = _unit getVariable [QGVAR(flashReactionDebounce), 0]; + _unit setVariable [QGVAR(flashReactionDebounce), _flashReactionDebounce max (CBA_missionTime + (7 * _strength))]; - // Make AI try to look away - private _dirToFlash = _unit getDir _grenadePosASL; - _unit setDir (_dirToFlash + linearConversion [0.2, 1, _strength, 40, 135] * selectRandom [-1, 1]); + if (_flashReactionDebounce < CBA_missionTime) then { + // Not used internally but could be useful for other mods + _unit setVariable [QGVAR(flashStrength), _strength, true]; + + [QGVAR(flashbangedAI), [_unit, _strength, _grenadePosASL]] call CBA_fnc_localEvent; + + { + _unit setSkill [_x, (_unit skill _x) / 50]; + } forEach SUBSKILLS; + + [{ + CBA_missiontime >= _this getVariable [QGVAR(flashReactionDebounce), 0] + }, { + params ["_unit"]; + + _unit setVariable [QGVAR(flashStrength), 0, true]; + + // Make sure we don't enable AI for unconscious units + if (_unit call EFUNC(common,isAwake)) then { + [_unit, false] call EFUNC(common,disableAI); + }; - private _flashReactionDebounce = _unit getVariable [QGVAR(flashReactionDebounce), 0]; - _unit setVariable [QGVAR(flashReactionDebounce), _flashReactionDebounce max (CBA_missionTime + (7 * _strength))]; - if (_flashReactionDebounce < CBA_missionTime) then { - // Not used interally but could be useful for other mods - _unit setVariable [QGVAR(flashStrength), _strength, true]; - [QGVAR(flashbangedAI), [_unit, _strength, _grenadePosASL]] call CBA_fnc_localEvent; { - _unit setSkill [_x, (_unit skill _x) / 50]; + _unit setSkill [_x, (_unit skill _x) * 50]; } forEach SUBSKILLS; - [{ - params ["_unit"]; - CBA_missiontime >= _unit getVariable [QGVAR(flashReactionDebounce), 0] - },{ - params ["_unit"]; - - _unit setVariable [QGVAR(flashStrength), 0, true]; - - // Make sure we don't enable AI for unconscious units - if !(_unit getVariable ["ace_isUnconscious", false]) then { - [_unit, false] call EFUNC(common,disableAI); - }; - { - _unit setSkill [_x, (_unit skill _x) * 50]; - } forEach SUBSKILLS; - }, [_unit]] call CBA_fnc_waitUntilAndExecute; - }; + }, _unit] call CBA_fnc_waitUntilAndExecute; }; -} forEach _affected; +} forEach (_affected select {local _x && {_x call EFUNC(common,isAwake)}}); -// Affect local player, independently of distance -if (hasInterface && {!isNull ACE_player} && {alive ACE_player}) then { - if ((getNumber (configOf ACE_player >> "isPlayableLogic")) == 1) exitWith { - TRACE_1("skipping playable logic",typeOf ACE_player); // VirtualMan_F (placeable logic zeus / spectator) - }; - // Do effects for player - // is there line of sight to the grenade? - private _eyePos = eyePos ACE_player; //PositionASL - _grenadePosASL set [2, (_grenadePosASL select 2) + 0.2]; // compensate for grenade glitching into ground - - private _strength = 1 - ((_eyePos vectorDistance _grenadePosASL) min 20) / 20; - - // Check for line of sight (check 4 points in case grenade is stuck in an object or underground) - private _losCoefficient = 1; - private _losCount = { - !lineIntersects [_grenadePosASL vectorAdd _x, _eyePos, ACE_player] - } count [[0,0,0], [0,0,0.2], [0.1, 0.1, 0.1], [-0.1, -0.1, 0.1]]; - TRACE_1("Line of sight count (out of 4)",_losCount); - if (_losCount <= 1) then { - _losCoefficient = 0.1; - }; - _strength = _strength * _losCoefficient; +if (!hasInterface) exitWith {}; - // Add ace_hearing ear ringing sound effect - if (["ace_hearing"] call EFUNC(common,isModLoaded) && {_strength > 0 && {EGVAR(hearing,damageCoefficent) > 0.25}}) then { - private _earringingStrength = 40 * _strength; - [_earringingStrength] call EFUNC(hearing,earRinging); - TRACE_1("Earringing Strength",_earringingStrength); - }; +// Create flash to illuminate environment +private _light = "#lightpoint" createVehicleLocal ASLtoAGL _grenadePosASL; +_light setPosASL _grenadePosASL; - // add ace_medical pain effect: - if (["ace_medical"] call EFUNC(common,isModLoaded) && {_strength > 0.1} && {isDamageAllowed _unit} && {_unit getVariable [QEGVAR(medical,allowDamage), true]}) then { - [ACE_player, _strength / 2] call EFUNC(medical,adjustPainLevel); - }; +_light setLightBrightness 20; +_light setLightAmbient [1,1,1]; +_light setLightColor [1,1,1]; +_light setLightDayLight true; +_light setLightAttenuation [0, 1, 5, 1000, 0, 20]; - // Effect on vision has a wider range, with a higher falloff - _strength = 1 - (((_eyePos vectorDistance _grenadePosASL) min 25) / 25) ^ 0.4; - _strength = _strength * _losCoefficient; - // Account for people looking away by slightly reducing the effect for visual effects. - private _eyeDir = ((AGLtoASL positionCameraToWorld [0,0,1]) vectorDiff (AGLtoASL positionCameraToWorld [0,0,0])); - private _dirToUnitVector = _eyePos vectorFromTo _grenadePosASL; - private _angleDiff = acos (_eyeDir vectorDotProduct _dirToUnitVector); - TRACE_2("",_angleDiff,((1 - (_angleDiff - 45) / (120 - 45)) max 0)); - // from 0-45deg, full effect - if (_angleDiff > 45) then { - _strength = _strength * ((1 - (_angleDiff - 45) / (120 - 45)) max 0); - }; +// Reduce the light after 0.1 seconds +[{ + _this setLightBrightness 5; - // Blind player - if (_strength > 0.1) then { - private _blend = [[1,1,1,0], [0.3,0.3,0.3,1]] select EGVAR(common,epilepsyFriendlyMode); + // Delete the light after 0.2 more seconds + [{deleteVehicle _this}, _this, 0.2] call CBA_fnc_waitAndExecute; +}, _light, 0.1] call CBA_fnc_waitAndExecute; - GVAR(flashbangPPEffectCC) ppEffectEnable true; - GVAR(flashbangPPEffectCC) ppEffectAdjust [1, 1, (0.8 + _strength) min 1, _blend, [0,0,0,1], [0,0,0,0]]; - GVAR(flashbangPPEffectCC) ppEffectCommit 0.01; +// Ignore dead and placeable logic (zeus / spectator) +if (!alive ACE_player || {(getNumber (configOf ACE_player >> "isPlayableLogic")) == 1}) exitWith {}; - //PARTIALRECOVERY - start decreasing effect over time - [{ - params ["_strength", "_blend"]; +// Affect local player, independently of distance +// Check for line of sight to the grenade +private _eyePos = eyePos ACE_player; // PositionASL +_grenadePosASL set [2, (_grenadePosASL select 2) + 0.2]; // compensate for grenade glitching into ground + +private _strength = 1 - ((_eyePos vectorDistance _grenadePosASL) min 20) / 20; + +// Check for line of sight (check 4 points in case grenade is stuck in an object or underground) +private _losCount = { + !lineIntersects [_grenadePosASL vectorAdd _x, _eyePos, ACE_player] +} count [[0, 0, 0], [0, 0, 0.2], [0.1, 0.1, 0.1], [-0.1, -0.1, 0.1]]; +TRACE_1("Line of sight count (out of 4)",_losCount); + +private _losCoefficient = [1, 0.1] select (_losCount <= 1); +_strength = _strength * _losCoefficient; + +// Add ace_hearing ear ringing sound effect +if (["ace_hearing"] call EFUNC(common,isModLoaded) && {_strength > 0} && {EGVAR(hearing,damageCoefficent) > 0.25}) then { + private _earringingStrength = 40 * _strength; + [_earringingStrength] call EFUNC(hearing,earRinging); + TRACE_1("Earringing Strength",_earringingStrength); +}; - GVAR(flashbangPPEffectCC) ppEffectAdjust [1, 1, 0, _blend, [0,0,0,1], [0,0,0,0]]; - GVAR(flashbangPPEffectCC) ppEffectCommit (10 * _strength); - }, [_strength, _blend], 7 * _strength] call CBA_fnc_waitAndExecute; +// Add ace_medical pain effect +if (GETEGVAR(medical,enabled,false) && {_strength > 0.1} && {isDamageAllowed _unit} && {_unit getVariable [QEGVAR(medical,allowDamage), true]}) then { + [ACE_player, _strength / 2] call EFUNC(medical,adjustPainLevel); +}; - //FULLRECOVERY - end effect - [{ - GVAR(flashbangPPEffectCC) ppEffectEnable false; - }, [], 17 * _strength] call CBA_fnc_waitAndExecute; - }; +// Effect on vision has a wider range, with a higher falloff +_strength = 1 - (((_eyePos vectorDistance _grenadePosASL) min 25) / 25) ^ 0.4; +_strength = _strength * _losCoefficient; + +// Account for people looking away by slightly reducing the effect for visual effects. +private _eyeDir = ((AGLtoASL positionCameraToWorld [0, 0, 1]) vectorDiff (AGLtoASL positionCameraToWorld [0, 0, 0])); +private _dirToUnitVector = _eyePos vectorFromTo _grenadePosASL; +private _angleDiff = acos (_eyeDir vectorDotProduct _dirToUnitVector); +TRACE_2("",_angleDiff,((1 - (_angleDiff - 45) / (120 - 45)) max 0)); - // Make player flinch - if (_strength <= 0.2) exitWith {}; - private _minFlinch = linearConversion [0.2, 1, _strength, 0, 60, true]; - private _maxFlinch = linearConversion [0.2, 1, _strength, 0, 95, true]; - private _flinch = (_minFlinch + random (_maxFlinch - _minFlinch)) * selectRandom [-1, 1]; - ACE_player setDir (getDir ACE_player + _flinch); +// From 0-45deg, full effect +if (_angleDiff > 45) then { + _strength = _strength * ((1 - (_angleDiff - 45) / (120 - 45)) max 0); +}; + +// Blind player +if (_strength > 0.1) then { + private _blend = [[1, 1, 1, 0], [0.3, 0.3, 0.3, 1]] select EGVAR(common,epilepsyFriendlyMode); + + GVAR(flashbangPPEffectCC) ppEffectEnable true; + GVAR(flashbangPPEffectCC) ppEffectAdjust [1, 1, (0.8 + _strength) min 1, _blend, [0, 0, 0, 1], [0, 0, 0, 0]]; + GVAR(flashbangPPEffectCC) ppEffectCommit 0.01; + + // PARTIALRECOVERY - start decreasing effect over time + [{ + params ["_strength", "_blend"]; - [QGVAR(flashbangedPlayer), [_strength, _grenadePosASL]] call CBA_fnc_localEvent; + GVAR(flashbangPPEffectCC) ppEffectAdjust [1, 1, 0, _blend, [0, 0, 0, 1], [0, 0, 0, 0]]; + GVAR(flashbangPPEffectCC) ppEffectCommit (10 * _strength); + }, [_strength, _blend], 7 * _strength] call CBA_fnc_waitAndExecute; + + // FULLRECOVERY - end effect + [{ + GVAR(flashbangPPEffectCC) ppEffectEnable false; + }, [], 17 * _strength] call CBA_fnc_waitAndExecute; }; -true + +// Make player flinch +if (_strength <= 0.2) exitWith {}; + +private _minFlinch = linearConversion [0.2, 1, _strength, 0, 60, true]; +private _maxFlinch = linearConversion [0.2, 1, _strength, 0, 95, true]; +private _flinch = (_minFlinch + random (_maxFlinch - _minFlinch)) * selectRandom [-1, 1]; +ACE_player setDir (getDir ACE_player + _flinch); + +[QGVAR(flashbangedPlayer), [_strength, _grenadePosASL]] call CBA_fnc_localEvent; diff --git a/addons/grenades/functions/fnc_flashbangThrownFuze.sqf b/addons/grenades/functions/fnc_flashbangThrownFuze.sqf index 7f1a52417cf..89020842d2a 100644 --- a/addons/grenades/functions/fnc_flashbangThrownFuze.sqf +++ b/addons/grenades/functions/fnc_flashbangThrownFuze.sqf @@ -4,7 +4,7 @@ * Waits for the flashbang grenade fuze to trigger and 'explode' * * Arguments: - * 0: projectile - Flashbang Grenade + * 0: Flashbang grenade * * Return Value: * None @@ -18,8 +18,17 @@ params ["_projectile"]; TRACE_1("params",_projectile); -if (alive _projectile) then { - playSound3D ["A3\Sounds_F\arsenal\explosives\grenades\Explosion_HE_grenade_01.wss", _projectile, false, getPosASL _projectile, 5, 1.2, 400]; +if (!alive _projectile) exitWith {}; - ["ace_flashbangExploded", [getPosASL _projectile]] call CBA_fnc_globalEvent; -}; +private _posASL = getPosASL _projectile; +private _sounds = getArray (_projectile call CBA_fnc_getObjectConfig >> QGVAR(flashbangExplodeSound)); + +(if (_sounds isEqualTo []) then { + [format ["A3\Sounds_F\arsenal\explosives\grenades\Explosion_HE_grenade_0%1.wss", floor (random 4) + 1], 5, 1.2, 400] +} else { + selectRandom _sounds +}) params ["_file", "_volume", "_pitch", "_distance"]; + +playSound3D [_file, _projectile, false, _posASL, _volume, _pitch, _distance]; + +["ace_flashbangExploded", [_posASL]] call CBA_fnc_globalEvent; diff --git a/addons/grenades/functions/fnc_incendiary.sqf b/addons/grenades/functions/fnc_incendiary.sqf index 11d89d4ca53..f0caf82ed8e 100644 --- a/addons/grenades/functions/fnc_incendiary.sqf +++ b/addons/grenades/functions/fnc_incendiary.sqf @@ -1,11 +1,12 @@ #include "..\script_component.hpp" /* * Author: commy2 - * Makes incendiary burn. + * Makes an incendiary grenade burn. * * Arguments: - * 0: The grenade + * 0: Incendiary grenade * 1: Incendiary lifetime + * 2: Instigator's side * * Return Value: * None @@ -30,11 +31,11 @@ #define PARTICLE_SMOKE_LIFTING 1 #define PARTICLE_SMOKE_WIND_EFFECT 1 -#define EFFECT_SIZE 1 #define ORIENTATION 5.4 #define EXPANSION 1 #define DESTRUCTION_RADIUS 1.8 +#define SEARCH_RADIUS 5 params ["_projectile", "_timeToLive", "_center"]; @@ -42,16 +43,16 @@ if (isNull _projectile) exitWith {TRACE_1("null",_projectile);}; private _position = position _projectile; -// --- AI +// Alert nearby hostile AI private _nearLocalEnemies = []; { { - if (local _x && {[_center, side _x] call BIS_fnc_sideIsEnemy}) then { // WE WANT THE OBJECTS SIDE HERE! + if (local _x && {[_center, side group _x] call BIS_fnc_sideIsEnemy}) then { // WE WANT THE OBJECT'S SIDE HERE! _nearLocalEnemies pushBackUnique _x; }; } forEach crew _x; -} forEach (_position nearObjects ALERT_NEAR_ENEMY_RANGE); +} forEach (_position nearObjects ALERT_NEAR_ENEMY_RANGE); //@todo replace with nearEntities in 2.18 { if (behaviour _x in ["SAFE", "AWARE"]) then { @@ -59,7 +60,7 @@ private _nearLocalEnemies = []; }; } forEach _nearLocalEnemies; -// --- fire +// Fire particles private _fire = "#particlesource" createVehicleLocal _position; _fire setParticleParams [ @@ -99,7 +100,7 @@ _fire setParticleRandom [PARTICLE_LIFE_TIME / 4, [0.15 * EFFECT_SIZE, 0.15 * EFF _fire setParticleFire [1.2,1.0,0.1]; _fire setDropInterval (1 / PARTICLE_DENSITY); -// --- smoke +// Smoke particles private _smoke = "#particlesource" createVehicleLocal _position; _smoke setParticleParams [ @@ -137,7 +138,7 @@ _smoke setParticleParams [ _smoke setParticleRandom [PARTICLE_SMOKE_LIFE_TIME / 2, [0.5 * EFFECT_SIZE, 0.5 * EFFECT_SIZE, 0.2 * EFFECT_SIZE], [0.3,0.3,0.5], 1, 0, [0,0,0,0.06], 0, 0]; _smoke setDropInterval (1 / PARTICLE_SMOKE_DENSITY); -// --- light +// Light private _light = "#lightpoint" createVehicleLocal (_position vectorAdd [0,0,0.5]); _light setLightBrightness 1.0; @@ -150,92 +151,72 @@ _light setLightDayLight false; _light lightAttachObject [_projectile, [0,0,0]]; -// --- sound +// Sound private _sound = objNull; if (isServer) then { _sound = createSoundSource ["Sound_Fire", _position, [], 0]; private _radius = 1.5 * getNumber (configOf _projectile >> "indirectHitRange"); private _intensity = getNumber (configOf _projectile >> "hit"); - [QEGVAR(fire,addFireSource), [_projectile, _radius, _intensity, _projectile, {CBA_missionTime < _this}, CBA_missionTime + _timeToLive]] call CBA_fnc_serverEvent; -}; - -[{ - {deleteVehicle _x} forEach _this; -}, [_fire, _smoke, _light, _sound], _timeToLive] call CBA_fnc_waitAndExecute; - -// --- damage -{ - if (local _x) then { - //systemChat format ["burn: %1", _x]; - // --- destroy nearby static weapons and ammo boxes - if (_x isKindOf "StaticWeapon" || {_x isKindOf "ACE_RepairItem_Base"}) then { - _x setDamage 1; - }; - if (_x isKindOf "ReammoBox_F") then { - if ( - "ace_cookoff" call EFUNC(common,isModLoaded) && - {GETVAR(_x,EGVAR(cookoff,enableAmmoCookoff),EGVAR(cookoff,enableAmmobox))} - ) then { - _x call EFUNC(cookoff,cookOffBox); - } else { - _x setDamage 1; - }; - }; + [QEGVAR(fire,addFireSource), [_projectile, _radius, _intensity, _projectile, { + params ["_endTime", "_projectile"]; - // --- delete nearby ground weapon holders - if (_x isKindOf "WeaponHolder" || {_x isKindOf "WeaponHolderSimulated"}) then { - deleteVehicle _x; + // If incendiary no longer exists, exit + if (isNull _projectile) exitWith { + false // return }; - // --- inflame fireplace, barrels etc. - _x inflame true; - }; -} forEach (_position nearObjects DESTRUCTION_RADIUS); - -// --- damage local vehicle -private _vehicle = _position nearestObject "Car"; - -if (!local _vehicle) exitWith {}; - -private _config = configOf _vehicle; + // Need to get the position every time, as grenade might have been moved + private _position = position _projectile; -// --- burn tyres -private _fnc_isWheelHitPoint = { - params ["_selectionName"]; + { + // Damage vehicles + [QGVAR(damageEngineAndWheels), [_x, _position], _x] call CBA_fnc_targetEvent; + } forEach (_position nearEntities ["Car", SEARCH_RADIUS]); - // wheels must use a selection named "wheel_X_Y_steering" for PhysX to work - _selectionName select [0, 6] == "wheel_" && { - _selectionName select [count _selectionName - 9] == "_steering" - } // return + CBA_missionTime < _endTime // return + }, [CBA_missionTime + _timeToLive, _projectile]]] call CBA_fnc_serverEvent; }; +[{ + {deleteVehicle _x} forEach _this; +}, [_fire, _smoke, _light, _sound], _timeToLive] call CBA_fnc_waitAndExecute; + +// Damage { - private _wheelSelection = getText (_config >> "HitPoints" >> _x >> "name"); + // Inflame fireplace, barrels etc. + _x inflame true; - if (_wheelSelection call _fnc_isWheelHitPoint) then { - private _wheelPosition = _vehicle modelToWorld (_vehicle selectionPosition _wheelSelection); + // Destroy nearby static weapons and ammo boxes + if (_x isKindOf "StaticWeapon" || {_x isKindOf "ACE_RepairItem_Base"}) then { + _x setDamage 1; - if (_position distance _wheelPosition < EFFECT_SIZE * 2) then { - _vehicle setHit [_wheelSelection, 1]; - }; + continue; }; -} forEach (getAllHitPointsDamage _vehicle param [0, []]); - -// --- burn car engine -if (_vehicle isKindOf "Wheeled_APC_F") exitWith {}; -private _engineSelection = getText (_config >> "HitPoints" >> "HitEngine" >> "name"); -private _enginePosition = _vehicle modelToWorld (_vehicle selectionPosition _engineSelection); + if (_x isKindOf "ReammoBox_F") then { + if ( + (["ace_cookoff"] call EFUNC(common,isModLoaded)) && + {EGVAR(cookoff,enableAmmobox)} && + {EGVAR(cookoff,ammoCookoffDuration) != 0} && + {_x getVariable [QEGVAR(cookoff,enableAmmoCookoff), true]} + ) then { + [QEGVAR(cookOff,cookOffBoxServer), _box] call CBA_fnc_serverEvent; + } else { + _x setDamage 1; + }; -if (_position distance _enginePosition < EFFECT_SIZE * 2) then { - _vehicle setHit [_engineSelection, 1]; + continue; + }; - if ("ace_cookoff" call EFUNC(common,isModLoaded)) then { - private _enabled = _vehicle getVariable [QEGVAR(cookoff,enable), EGVAR(cookoff,enable)]; - if (_enabled in [2, true] || {_enabled isEqualTo 1 && {fullCrew [_vehicle, "", false] findIf {isPlayer (_x select 0)} != -1}}) then { - _vehicle call EFUNC(cookoff,engineFire); - }; + // Delete nearby ground weapon holders + if (_x isKindOf "WeaponHolder" || {_x isKindOf "WeaponHolderSimulated"}) then { + deleteVehicle _x; }; -}; +} forEach ((_position nearObjects DESTRUCTION_RADIUS) select {local _x && {isDamageAllowed _x}}); + +{ + // Damage vehicles (locality is checked in FUNC(damageEngineAndWheels)) + [_x, _position] call FUNC(damageEngineAndWheels); +} forEach (_position nearEntities ["Car", SEARCH_RADIUS]); diff --git a/addons/grenades/functions/fnc_nextMode.sqf b/addons/grenades/functions/fnc_nextMode.sqf index 1a64cf9f7ba..f33fa7a5a5d 100644 --- a/addons/grenades/functions/fnc_nextMode.sqf +++ b/addons/grenades/functions/fnc_nextMode.sqf @@ -7,25 +7,29 @@ * None * * Return Value: - * Handeled + * Handled * * Example: - * [] call ace_grenades_fnc_nextMode + * call ace_grenades_fnc_nextMode * * Public: No */ -private _mode = missionNamespace getVariable [QGVAR(currentThrowMode), 0]; +// _mode is 0-4, don't overflow +private _mode = (GVAR(currentThrowMode) + 1) % 5; -if (_mode == 4) then { - _mode = 0; -} else { - _mode = _mode + 1; -}; +private _currentThrowable = currentThrowable ACE_player; -// ROLL GRENADE DOESN'T WORK RIGHT NOW -if (_mode == 3) then { - _mode = 4; +// Make sure grenade can be rolled if in roll mode (detonation time has to be >= 1 second and player isn't in a vehicle) +if ( + _mode == 3 && + {_currentThrowable isNotEqualTo []} && + { + !isNull objectParent ACE_player || + {getNumber (configFile >> "CfgAmmo" >> getText (configFile >> "CfgMagazines" >> _currentThrowable select 0 >> "ammo") >> "explosionTime") < MIN_EXPLOSION_TIME_FOR_ROLL} + } +) then { + _mode = _mode + 1; }; private _hint = localize ([ @@ -38,6 +42,37 @@ private _hint = localize ([ [_hint] call EFUNC(common,displayTextStructured); +GVAR(throwModePFEH) call CBA_fnc_removePerFrameHandler; GVAR(currentThrowMode) = _mode; +// If in rolling mode, check every frame if current throwable is rollable +if (GVAR(currentThrowMode) == 3) then { + GVAR(currentThrowable) = _currentThrowable; + + GVAR(throwModePFEH) = { + private _currentThrowable = currentThrowable ACE_player; + + if (GVAR(currentThrowable) isEqualTo _currentThrowable) exitWith {}; + + GVAR(currentThrowable) = _currentThrowable; + + // Make sure grenade can be rolled if in roll mode (detonation time has to be >= 1 second and player isn't in a vehicle) + if !( + GVAR(currentThrowMode) == 3 && + {_currentThrowable isNotEqualTo []} && + { + !isNull objectParent ACE_player || + {getNumber (configFile >> "CfgAmmo" >> getText (configFile >> "CfgMagazines" >> _currentThrowable select 0 >> "ammo") >> "explosionTime") < MIN_EXPLOSION_TIME_FOR_ROLL} + } + ) exitWith {}; + + // Force the user into the normal throw mode + // Next throw mode after roll would be drop, which isn't ideal if the user tries to throw unknowingly... + [format [LLSTRING(RollGrenadeDisabled), LLSTRING(NormalThrow)], 2] call EFUNC(common,displayTextStructured); + + GVAR(throwModePFEH) call CBA_fnc_removePerFrameHandler; + GVAR(currentThrowMode) = 0; + } call CBA_fnc_addPerFrameHandler; +}; + true diff --git a/addons/grenades/functions/fnc_throwGrenade.sqf b/addons/grenades/functions/fnc_throwGrenade.sqf index 9a0168da3ea..a440c8fd1b7 100644 --- a/addons/grenades/functions/fnc_throwGrenade.sqf +++ b/addons/grenades/functions/fnc_throwGrenade.sqf @@ -27,40 +27,26 @@ if (isNull _projectile) then { private _config = configFile >> "CfgAmmo" >> _ammo; -// handle special grenades and sounds +// Handle special grenades and sounds if (local _unit) then { - // handle priming sound, if present - private _soundConfig = getArray (configFile >> "CfgAmmo" >> _ammo >> QGVAR(pullPinSound)); + // Handle priming sound, if present + private _soundConfig = getArray (_config >> QGVAR(pullPinSound)); + if (_soundConfig isNotEqualTo []) then { _soundConfig params ["_file", "_volume", "_pitch", "_distance"]; - playSound3D [_file, objNull, false, getPosASL _projectile, _volume, _pitch, _distance]; + playSound3D [_file, objNull, insideBuilding _unit >= 0.5, getPosASL _projectile, _volume, _pitch, _distance]; }; if (getNumber (_config >> QGVAR(flashbang)) == 1) then { - private _bangs = 1; - private _entry = _config >> QGVAR(flashbangBangs); - if (isNumber _entry || isText _entry) then { - _bangs = getNumber _entry; - }; - private _fuzeTimeBase = getNumber (_config >> "explosionTime"); - - private _interval = 0.5; - _entry = _config >> QGVAR(flashbangInterval); - if (isNumber _entry || isText _entry) then { - _interval = getNumber _entry; - }; - - private _maxDeviation = 0.1; - _entry = _config >> QGVAR(flashbangIntervalMaxDeviation); - if (isNumber _entry || isText _entry) then { - _maxDeviation = getNumber _entry; - }; + private _bangs = [_config >> QGVAR(flashbangBangs), "NUMBER", 1] call CBA_fnc_getConfigEntry; + private _interval = [_config >> QGVAR(flashbangInterval), "NUMBER", 0.5] call CBA_fnc_getConfigEntry; + private _maxDeviation = [_config >> QGVAR(flashbangIntervalMaxDeviation), "NUMBER", 0.1] call CBA_fnc_getConfigEntry; for "_i" from 0 to (_bangs - 1) do { - private _fuzeTime = _fuzeTimeBase + _i*_interval + random [- _maxDeviation, 0, _maxDeviation]; + private _fuzeTime = _fuzeTimeBase + _i * _interval + random [-_maxDeviation, 0, _maxDeviation]; - [FUNC(flashbangThrownFuze), [_projectile], _fuzeTime] call CBA_fnc_waitAndExecute; + [LINKFUNC(flashbangThrownFuze), _projectile, _fuzeTime] call CBA_fnc_waitAndExecute; }; }; }; @@ -71,47 +57,56 @@ if (getNumber (_config >> QGVAR(flare)) == 1) then { private _color = getArray (_config >> QGVAR(color)); private _intensity = _color deleteAt 3; - [FUNC(flare), [_projectile, _color, _intensity, _timeToLive], _fuzeTime] call CBA_fnc_waitAndExecute; + [LINKFUNC(flare), [_projectile, _color, _intensity, _timeToLive], _fuzeTime] call CBA_fnc_waitAndExecute; }; if (getNumber (_config >> QGVAR(incendiary)) == 1) then { private _fuzeTime = getNumber (_config >> "explosionTime"); private _timeToLive = getNumber (_config >> "timeToLive"); - [FUNC(incendiary), [_projectile, _timeToLive, side _unit], _fuzeTime] call CBA_fnc_waitAndExecute; // WE WANT THE OBJECTS SIDE HERE! + [LINKFUNC(incendiary), [_projectile, _timeToLive, side group _unit], _fuzeTime] call CBA_fnc_waitAndExecute; // Get the unit's real side (will return civilian if unconscious) }; -// handle throw modes +// Handle throw modes if (_unit != ACE_player) exitWith {}; if (_unit getVariable [QEGVAR(advanced_throwing,primed), false]) exitWith {LOG("advanced_throwing throw");}; -private _mode = missionNamespace getVariable [QGVAR(currentThrowMode), 0]; +if (GVAR(currentThrowMode) == 0) exitWith {}; -if (_mode != 0) then { - private _velocity = velocity _projectile; +private _velocity = velocity _projectile; - switch (_mode) do { - //high throw - case 1 : { - _velocity = [ - 0.5 * (_velocity select 0), - 0.5 * (_velocity select 1), - [0, 0, 0] distance (_velocity vectorMultiply 0.5) - ]; - }; - //precise throw - case 2 : { - _velocity = (_unit weaponDirection _weapon) vectorMultiply (vectorMagnitude _velocity); - }; - //roll grande - case 3 : { - //@todo - }; - //drop grenade - case 4 : { - _velocity = [0, 0, 0]; - }; +switch (GVAR(currentThrowMode)) do { + // High throw + case 1: { + _velocity = _velocity vectorMultiply 0.5; + + _velocity set [2, vectorMagnitude _velocity]; + }; + // Precise throw + case 2: { + _velocity = (_unit weaponDirection _weapon) vectorMultiply (vectorMagnitude _velocity); }; + // Roll grenade + case 3: { + private _posASL = getPosASL _projectile; + + // getPos is unreliable, as surfaces in some ruins are not recognised as surfaces + private _lisPos = (lineIntersectsSurfaces [_posASL, _posASL vectorAdd [0, 0, -1e11], ACE_player, objNull, true, 1, "ROADWAY", "FIRE"]) select 0; + _projectile setPosASL ((_lisPos select 0) vectorAdd [0, 0, 0.2]); + + // Rotate throwables by 90° to the side by default, so cylindrical throwables can be rolled + private _vectorDirAndUp = getArray (_config >> QGVAR(rollVectorDirAndUp)); + _vectorDirAndUp params [["_vectorDir", [0, 1, 0], [[]], 3], ["_vectorUp", [1, 0, 0], [[]], 3]]; - _projectile setVelocity _velocity; + // Do as if object were facing north + _projectile setVectorDirAndUp ([[_vectorDir, _vectorUp], -(direction _projectile), 0, 0] call BIS_fnc_transformVectorDirAndUp); + + _velocity = (vectorDir _unit) vectorMultiply 10; + }; + // Drop grenade + case 4: { + _velocity = [0, 0, 0]; + }; }; + +_projectile setVelocity _velocity; diff --git a/addons/grenades/initSettings.inc.sqf b/addons/grenades/initSettings.inc.sqf index b6fa36f459c..6a6ceb8c37b 100644 --- a/addons/grenades/initSettings.inc.sqf +++ b/addons/grenades/initSettings.inc.sqf @@ -1,9 +1,10 @@ [ - QGVAR(convertExplosives), "CHECKBOX", + QGVAR(convertExplosives), + "CHECKBOX", [LSTRING(convertExplosives_DisplayName), LSTRING(convertExplosives_Description)], LSTRING(Settings_DisplayName), true, - true, - {}, - true + 1, + {[QGVAR(convertExplosives), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_fnc_addSetting; diff --git a/addons/grenades/script_component.hpp b/addons/grenades/script_component.hpp index 49dbe92a3f3..e49fa21ca90 100644 --- a/addons/grenades/script_component.hpp +++ b/addons/grenades/script_component.hpp @@ -16,7 +16,6 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define EFFECT_STAGE_RESETAI 0 -#define EFFECT_STAGE_DELETELIGHT 1 -#define EFFECT_STAGE_PARTIALRECOVERY 2 -#define EFFECT_STAGE_FULLRECOVERY 3 +#define EFFECT_SIZE 1 + +#define MIN_EXPLOSION_TIME_FOR_ROLL 1 diff --git a/addons/grenades/stringtable.xml b/addons/grenades/stringtable.xml index d5c1b142a65..1a571093f8f 100644 --- a/addons/grenades/stringtable.xml +++ b/addons/grenades/stringtable.xml @@ -103,6 +103,11 @@ 下丟投擲 Bombayı Yere Bırak + + Can't roll this grenade, switched to %1 + この手榴弾は転がせません、 %1 に切り替えます + Эта граната не может быть брошена, переключитесь на %1 + M84 Stun Grenade M84 Blendgranate diff --git a/addons/gunbag/functions/fnc_offGunbagCallback.sqf b/addons/gunbag/functions/fnc_offGunbagCallback.sqf index 8edd3e4582b..68b22fb1ef3 100644 --- a/addons/gunbag/functions/fnc_offGunbagCallback.sqf +++ b/addons/gunbag/functions/fnc_offGunbagCallback.sqf @@ -11,7 +11,7 @@ * None * * Example: - * [player, target] call ace_gunbag_fnc_offGunbagCallback + * [player, cursorObject] call ace_gunbag_fnc_offGunbagCallback * * Public: No */ @@ -23,39 +23,28 @@ private _gunbag = backpackContainer _target; private _state = _gunbag getVariable [QGVAR(gunbagWeapon), []]; if (_state isEqualTo []) exitWith { - [localize LSTRING(empty)] call EFUNC(common,displayTextStructured); + [LLSTRING(empty)] call EFUNC(common,displayTextStructured); }; _state params ["_weapon", "_items", "_magazines"]; -_unit addWeapon _weapon; +[_unit, _weapon, true, _magazines] call EFUNC(common,addWeapon); -// Game will auto add magazines from player's inventory, put these back in player inventory as they will be overwritten -([_unit, _weapon] call EFUNC(common,getWeaponState)) params ["", "", "_addedMags", "_addedAmmo"]; +// Add attachments { - if (((_x select 0) != "") && {(_addedMags select _forEachIndex) != ""}) then { - TRACE_2("Re-adding mag",_x,_addedMags select _forEachIndex); - _unit addMagazine [_addedMags select _forEachIndex, _addedAmmo select _forEachIndex]; - }; -} forEach _magazines; - -removeAllPrimaryWeaponItems _unit; - -{ - _unit addWeaponItem [_weapon, _x]; -} forEach (_items + _magazines); + _unit addWeaponItem [_weapon, _x, true]; +} forEach (_items select {_x != ""}); _unit selectWeapon _weapon; -_magazines = _magazines apply {_x select 0}; +private _mass = [_weapon, _items, _magazines apply {_x select 0}] call FUNC(calculateMass); -private _mass = [_weapon, _items, _magazines] call FUNC(calculateMass); - -// remove virtual load +// Remove virtual load [_target, _gunbag, -_mass] call EFUNC(movement,addLoadToUnitContainer); + _gunbag setVariable [QGVAR(gunbagWeapon), [], true]; -// play sound +// Play sound if (["ace_backpacks"] call EFUNC(common,isModLoaded)) then { [_target, _gunbag] call EFUNC(backpacks,backpackOpened); }; diff --git a/addons/gunbag/functions/fnc_swapGunbagCallback.sqf b/addons/gunbag/functions/fnc_swapGunbagCallback.sqf index a7d319506bf..cb4bca2ea4a 100644 --- a/addons/gunbag/functions/fnc_swapGunbagCallback.sqf +++ b/addons/gunbag/functions/fnc_swapGunbagCallback.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author: Ir0n1E and mjc4wilton + * Author: Ir0n1E, mjc4wilton * Swap primary weapon and weapon in gunbag. * * Arguments: @@ -11,66 +11,49 @@ * None * * Example: - * [player, target] call ace_gunbag_fnc_swapGunbagCallback + * [player, cursorObject] call ace_gunbag_fnc_swapGunbagCallback * * Public: No */ params ["_unit", "_target"]; -private _currentWeapon = primaryWeapon _unit; //Get Current Weapon -private _gunbag = backpackContainer _target; - - -//---Set up current weapon for storing -private _currentWeaponState = [_unit, _currentWeapon] call EFUNC(common,getWeaponState); //Gets weapon attachments -/* - * example return value _state - * [["","","optic_Aco",""],["arifle_MX_GL_ACO_F","GL_3GL_F"],["30Rnd_65x39_caseless_mag","1Rnd_HE_Grenade_shell"],[30,1]] - */ +// Set up current weapon for storing +private _gunbag = backpackContainer _target; +private _currentItems = (getUnitLoadout _unit) select 0; -_currentWeaponState params ["_currentWeaponItems", "", "_currentWeaponMagazines", "_currentWeaponAmmo"]; //Extract Weapon Attachments to separate arrays +private _currentMagazines = _currentItems select [4, 2]; +_currentItems deleteRange [4, 2]; -private _currentWeaponMass = [_currentWeapon, _currentWeaponItems, _currentWeaponMagazines] call FUNC(calculateMass); +private _currentWeapon = _currentItems deleteAt 0; -{ - _currentWeaponMagazines set [_forEachIndex, [_x, _currentWeaponAmmo select _forEachIndex]]; -} forEach _currentWeaponMagazines; +private _currentMass = [_currentWeapon, _currentItems, _currentMagazines apply {_x select 0}] call FUNC(calculateMass); -//---Set up weapon in gunbag -private _newWeaponState = _gunbag getVariable [QGVAR(gunbagWeapon), []]; +// Set up weapon in gunbag +private _newState = _gunbag getVariable [QGVAR(gunbagWeapon), []]; -if (_newWeaponState isEqualTo []) exitWith { +if (_newState isEqualTo []) exitWith { [LLSTRING(empty)] call EFUNC(common,displayTextStructured); }; -_newWeaponState params ["_newWeapon", "_newWeaponItems", "_newWeaponMagazines"]; +_newState params ["_newWeapon", "_newItems", "_newMagazines"]; -//---Swap Weapons +// Swap Weapons _unit removeWeapon _currentWeapon; -_unit addWeapon _newWeapon; - -// Game will auto add magazines from player's inventory, put these back in player inventory as they will be overwritten -([_unit, _newWeapon] call EFUNC(common,getWeaponState)) params ["", "", "_addedMags", "_addedAmmo"]; -{ - if (((_x select 0) != "") && {(_addedMags select _forEachIndex) != ""}) then { - TRACE_2("Re-adding mag",_x,_addedMags select _forEachIndex); - _unit addMagazine [_addedMags select _forEachIndex, _addedAmmo select _forEachIndex]; - }; -} forEach _newWeaponMagazines; -removeAllPrimaryWeaponItems _unit; +[_unit, _newWeapon, true, _newMagazines] call EFUNC(common,addWeapon); +// Add attachments { - _unit addWeaponItem [_newWeapon, _x]; -} forEach (_newWeaponItems + _newWeaponMagazines); + _unit addWeaponItem [_newWeapon, _x, true]; +} forEach (_newItems select {_x != ""}); _unit selectWeapon _newWeapon; -_newWeaponMagazines = _newWeaponMagazines apply {_x select 0}; +private _newMass = [_newWeapon, _newItems, _newMagazines apply {_x select 0}] call FUNC(calculateMass); -private _newWeaponMass = [_newWeapon, _newWeaponItems, _newWeaponMagazines] call FUNC(calculateMass); +// Update virtual load +[_target, _gunbag, _currentMass - _newMass] call EFUNC(movement,addLoadToUnitContainer); -// update virtual load -[_target, _gunbag, _currentWeaponMass - _newWeaponMass] call EFUNC(movement,addLoadToUnitContainer); -_gunbag setVariable [QGVAR(gunbagWeapon), [_currentWeapon, _currentWeaponItems, _currentWeaponMagazines], true]; //Replace weapon in gunbag +// Replace weapon in gunbag +_gunbag setVariable [QGVAR(gunbagWeapon), [_currentWeapon, _currentItems, _currentMagazines], true]; diff --git a/addons/gunbag/functions/fnc_toGunbagCallback.sqf b/addons/gunbag/functions/fnc_toGunbagCallback.sqf index 4930d1d95ae..9958eed32b6 100644 --- a/addons/gunbag/functions/fnc_toGunbagCallback.sqf +++ b/addons/gunbag/functions/fnc_toGunbagCallback.sqf @@ -11,38 +11,32 @@ * None * * Example: - * [player, target] call ace_gunbag_fnc_toGunbagCallback + * [player, cursorObject] call ace_gunbag_fnc_toGunbagCallback * * Public: No */ params ["_unit", "_target"]; -private _weapon = primaryWeapon _unit; +// Set up current weapon for storing private _gunbag = backpackContainer _target; +private _items = (getUnitLoadout _unit) select 0; -private _state = [_unit, _weapon] call EFUNC(common,getWeaponState); +private _magazines = _items select [4, 2]; +_items deleteRange [4, 2]; -/* - * example return value _state - * [["","","optic_Aco",""],["arifle_MX_GL_ACO_F","GL_3GL_F"],["30Rnd_65x39_caseless_mag","1Rnd_HE_Grenade_shell"],[30,1]] - */ - -_state params ["_items", "", "_magazines", "_ammo"]; +private _weapon = _items deleteAt 0; -private _mass = [_weapon, _items, _magazines] call FUNC(calculateMass); - -{ - _magazines set [_forEachIndex, [_x, _ammo select _forEachIndex]]; -} forEach _magazines; +private _mass = [_weapon, _items, _magazines apply {_x select 0}] call FUNC(calculateMass); _unit removeWeapon _weapon; -// add virtual load +// Add virtual load [_target, _gunbag, _mass] call EFUNC(movement,addLoadToUnitContainer); + _gunbag setVariable [QGVAR(gunbagWeapon), [_weapon, _items, _magazines], true]; -// play sound +// Play sound if (["ace_backpacks"] call EFUNC(common,isModLoaded)) then { [_target, _gunbag] call EFUNC(backpacks,backpackOpened); }; diff --git a/addons/headless/XEH_PREP.hpp b/addons/headless/XEH_PREP.hpp index 11e09adf100..e1c65cc083d 100644 --- a/addons/headless/XEH_PREP.hpp +++ b/addons/headless/XEH_PREP.hpp @@ -1,3 +1,4 @@ +ACEX_PREP(blacklist); ACEX_PREP(endMissionNoPlayers); ACEX_PREP(handleConnectHC); ACEX_PREP(handleDisconnect); diff --git a/addons/headless/XEH_postInit.sqf b/addons/headless/XEH_postInit.sqf index d1c76a332bd..90677042f45 100644 --- a/addons/headless/XEH_postInit.sqf +++ b/addons/headless/XEH_postInit.sqf @@ -1,5 +1,7 @@ #include "script_component.hpp" +if (!isMultiplayer) exitWith {}; + ["CBA_settingsInitialized", { // Register and remove HCs if not client that is not server and distribution or end mission enabled if ((!hasInterface || isServer) && {XGVAR(enabled) || XGVAR(endMission) != 0}) then { @@ -10,6 +12,38 @@ }; // Add disconnect EH addMissionEventHandler ["HandleDisconnect", {call FUNC(handleDisconnect)}]; + + [QGVAR(transferGroupsRebalance), { + params ["_groups", "_owner", "_rebalance"]; + + if (_groups isNotEqualTo [] && {_owner > 1}) then { + { + _x setGroupOwner _owner; + } forEach _groups; + }; + + // Rebalance units + if (_rebalance in [REBALANCE, FORCED_REBALANCE]) then { + (_rebalance == FORCED_REBALANCE) call FUNC(rebalance); + }; + }] call CBA_fnc_addEventHandler; + + // If CBA's loadout validation is enabled, warn users + if (XGVAR(transferLoadout) > 0 && {(missionNamespace getVariable ["CBA_network_loadoutValidation", 0]) isEqualTo 2}) then { + WARNING("CBA_network_loadoutValidation is enabled - acex_headless_transferLoadout should therefore be disabled"); + [QEGVAR(common,displayTextStructured), ["CBA_network_loadoutValidation is enabled - acex_headless_transferLoadout should therefore be disabled", 3]] call CBA_fnc_globalEvent; + }; + + ["CBA_SettingChanged", { + params ["_setting", "_value"]; + + if (_setting != "CBA_network_loadoutValidation") exitWith {}; + + if (XGVAR(transferLoadout) > 0 && {_value isEqualTo 2}) then { + WARNING("CBA_network_loadoutValidation is enabled - acex_headless_transferLoadout should therefore be disabled"); + [QEGVAR(common,displayTextStructured), ["CBA_network_loadoutValidation is enabled - acex_headless_transferLoadout should therefore be disabled", 3]] call CBA_fnc_globalEvent; + }; + }] call CBA_fnc_addEventHandler; } else { // Register HC (this part happens on HC only) [QXGVAR(headlessClientJoined), [player]] call CBA_fnc_globalEvent; // Global event for API purposes diff --git a/addons/headless/functions/fnc_blacklist.sqf b/addons/headless/functions/fnc_blacklist.sqf new file mode 100644 index 00000000000..1c15406ba61 --- /dev/null +++ b/addons/headless/functions/fnc_blacklist.sqf @@ -0,0 +1,51 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Modifies which units are blacklisted from being transferred to HCs. + * + * Arguments: + * 0: Units + * 1: Add (true) or remove (false) from blacklist (default: true) + * 2: Owner to transfer units to (default: -1) + * 3: Rebalance (default: 0) + * + * Return Value: + * None + * + * Example: + * [cursorObject, true] call ace_headless_fnc_blacklist + * + * Public: Yes + */ + +params [["_units", objNull, [objNull, grpNull, []]], ["_blacklist", true, [false]], ["_owner", -1, [false]], ["_rebalance", NO_REBALANCE, [0]]]; + +if !(_units isEqualType []) then { + _units = [_units]; +}; + +// Make sure passed arguments are objects or groups +_units = _units select {_x isEqualType objNull || {_x isEqualType grpNull}}; +_units = _units select {!isNull _x}; + +if (_units isEqualTo []) exitWith {}; + +private _transfer = _blacklist && {_owner > 1}; +private _groups = []; + +{ + _x setVariable [QXGVAR(blacklist), _blacklist, true]; + + if (_transfer) then { + if (_x isEqualType objNull) then { + _groups pushBack group _x; + } else { + _groups pushBack _x; + }; + }; +} forEach _units; + +// Try to move AI to new owner; Also takes care of rebalancing groups +if (_transfer || {_rebalance in [REBALANCE, FORCED_REBALANCE]}) then { + [QGVAR(transferGroupsRebalance), [_groups arrayIntersect _groups, _owner, _rebalance]] call CBA_fnc_serverEvent; +}; diff --git a/addons/headless/functions/fnc_transferGroups.sqf b/addons/headless/functions/fnc_transferGroups.sqf index 60d3c093d11..0efbe263652 100644 --- a/addons/headless/functions/fnc_transferGroups.sqf +++ b/addons/headless/functions/fnc_transferGroups.sqf @@ -17,6 +17,9 @@ params ["_force"]; +// Filter out any invalid entries +GVAR(headlessClients) = GVAR(headlessClients) select {!isNull _x}; + GVAR(headlessClients) params [ ["_HC1", objNull, [objNull]], ["_HC2", objNull, [objNull]], @@ -36,12 +39,13 @@ private _idHC2 = -1; private _idHC3 = -1; private _currentHC = 0; -if (!local _HC1) then { +// objNull is never local +if (!local _HC1 && !isNull _HC1) then { _idHC1 = owner _HC1; _currentHC = 1; }; -if (!local _HC2) then { +if (!local _HC2 && !isNull _HC2) then { _idHC2 = owner _HC2; if (_currentHC == 0) then { @@ -49,7 +53,7 @@ if (!local _HC2) then { }; }; -if (!local _HC3) then { +if (!local _HC3 && !isNull _HC3) then { _idHC3 = owner _HC3; if (_currentHC == 0) then { @@ -57,84 +61,150 @@ if (!local _HC3) then { }; }; +if (_currentHC == 0) exitWith { + TRACE_1("No Valid HC to transfer to",_currentHC); + + if (XGVAR(log)) then { + INFO("No Valid HC to transfer to"); + }; +}; + // Prepare statistics private _numTransferredHC1 = 0; private _numTransferredHC2 = 0; private _numTransferredHC3 = 0; +private _units = []; +private _transfer = false; +private _previousOwner = -1; + // Transfer AI groups { - // No transfer if empty group - private _transfer = ((units _x) isNotEqualTo []) && {!(_x getVariable [QXGVAR(blacklist), false])}; - if (_transfer) then { - // No transfer if waypoints with synchronized triggers exist for the group - private _allWaypointsWithTriggers = (waypoints _x) select {(synchronizedTriggers _x) isNotEqualTo []}; - if (_allWaypointsWithTriggers isNotEqualTo []) exitWith { + _units = units _x; + + // No transfer if empty group or if group is blacklisted + if (_units isEqualTo [] || {_x getVariable [QXGVAR(blacklist), false]}) then { + continue; + }; + + // No transfer if waypoints with synchronized triggers exist for the group + if (((waypoints _x) select {(synchronizedTriggers _x) isNotEqualTo []}) isNotEqualTo []) then { + continue; + }; + + { + // No transfer if already transferred + if (!_force && {(owner _x) in [_idHC1, _idHC2, _idHC3]}) exitWith { _transfer = false; }; - { - // No transfer if already transferred - if (!_force && {(owner _x) in [_idHC1, _idHC2, _idHC3]}) exitWith { - _transfer = false; - }; + // No transfer if any unit in group is blacklisted + if (_x getVariable [QXGVAR(blacklist), false]) exitWith { + _transfer = false; + }; - // No transfer if player or UAV in this group - if (isPlayer _x || {unitIsUAV _x}) exitWith { - _transfer = false; - }; + // No transfer if player or UAV in this group + if (isPlayer _x || {unitIsUAV _x}) exitWith { + _transfer = false; + }; - // No transfer if any unit in group is blacklisted - if (_x getVariable [QXGVAR(blacklist), false]) exitWith { - _transfer = false; - }; + private _vehicle = objectParent _x; - private _vehicle = objectParent _x; + // No transfer if the vehicle the unit is in or if the crew in that vehicle is blacklisted + if ((_vehicle getVariable [QXGVAR(blacklist), false]) || {unitIsUAV _vehicle}) exitWith { + _transfer = false; + }; - // No transfer if the vehicle the unit is in or if the crew in that vehicle is blacklisted - if ((_vehicle getVariable [QXGVAR(blacklist), false]) || {unitIsUAV _vehicle}) exitWith { - _transfer = false; - }; + // Save gear if unit about to be transferred with current loadout (naked unit work-around) + if (XGVAR(transferLoadout) == 1) then { + _x setVariable [QGVAR(loadout), _x call CBA_fnc_getLoadout, true]; + }; + } forEach _units; - // Save gear if unit about to be transferred with current loadout (naked unit work-around) - if (XGVAR(transferLoadout) == 1) then { - _x setVariable [QGVAR(loadout), _x call CBA_fnc_getLoadout, true]; - }; - } forEach (units _x); + if (!_transfer) then { + continue; }; // Round robin between HCs if load balance enabled, else pass all to one HC - if (_transfer) then { - switch (_currentHC) do { - case 1: { - private _transferred = _x setGroupOwner _idHC1; - if (_loadBalance) then { - _currentHC = [3, 2] select (!local _HC2); - }; - if (_transferred) then { - _numTransferredHC1 = _numTransferredHC1 + 1; + _previousOwner = groupOwner _x; + + switch (_currentHC) do { + case 1: { + if (_loadBalance) then { + // Find the next valid HC + // If none are valid, _currentHC will remain the same + if (_idHC2 != -1) then { + _currentHC = 2; + } else { + if (_idHC3 != -1) then { + _currentHC = 3; + }; }; }; - case 2: { - private _transferred = _x setGroupOwner _idHC2; - if (_loadBalance) then { - _currentHC = [1, 3] select (!local _HC3); - }; - if (_transferred) then { - _numTransferredHC2 = _numTransferredHC2 + 1; - }; + + // Don't transfer if it's already local to HC1 + if (_previousOwner == _idHC1) exitWith {}; + + [QGVAR(groupTransferPre), [_x, _HC1, _previousOwner, _idHC1], [_previousOwner, _idHC1]] call CBA_fnc_targetEvent; // API + + private _transferred = _x setGroupOwner _idHC1; + + [QGVAR(groupTransferPost), [_x, _HC1, _previousOwner, _idHC1, _transferred], [_previousOwner, _idHC1]] call CBA_fnc_targetEvent; // API + + if (_transferred) then { + _numTransferredHC1 = _numTransferredHC1 + 1; }; - case 3: { - private _transferred = _x setGroupOwner _idHC3; - if (_loadBalance) then { - _currentHC = [2, 1] select (!local _HC1); + }; + case 2: { + if (_loadBalance) then { + // Find the next valid HC + // If none are valid, _currentHC will remain the same + if (_idHC3 != -1) then { + _currentHC = 3; + } else { + if (_idHC1 != -1) then { + _currentHC = 1; + }; }; - if (_transferred) then { - _numTransferredHC3 = _numTransferredHC3 + 1; + }; + + // Don't transfer if it's already local to HC2 + if (_previousOwner == _idHC2) exitWith {}; + + [QGVAR(groupTransferPre), [_x, _HC2, _previousOwner, _idHC2], [_previousOwner, _idHC2]] call CBA_fnc_targetEvent; // API + + private _transferred = _x setGroupOwner _idHC2; + + [QGVAR(groupTransferPost), [_x, _HC2, _previousOwner, _idHC2, _transferred], [_previousOwner, _idHC2]] call CBA_fnc_targetEvent; // API + + if (_transferred) then { + _numTransferredHC2 = _numTransferredHC2 + 1; + }; + }; + case 3: { + if (_loadBalance) then { + // Find the next valid HC + // If none are valid, _currentHC will remain the same + if (_idHC1 != -1) then { + _currentHC = 1; + } else { + if (_idHC2 != -1) then { + _currentHC = 2; + }; }; }; - default { - TRACE_1("No Valid HC to transfer to",_currentHC); + + // Don't transfer if it's already local to HC3 + if (_previousOwner == _idHC3) exitWith {}; + + [QGVAR(groupTransferPre), [_x, _HC3, _previousOwner, _idHC3], [_previousOwner, _idHC3]] call CBA_fnc_targetEvent; // API + + private _transferred = _x setGroupOwner _idHC2; + + [QGVAR(groupTransferPost), [_x, _HC3, _previousOwner, _idHC3, _transferred], [_previousOwner, _idHC3]] call CBA_fnc_targetEvent; // API + + if (_transferred) then { + _numTransferredHC3 = _numTransferredHC3 + 1; }; }; }; diff --git a/addons/headless/initSettings.inc.sqf b/addons/headless/initSettings.inc.sqf index d00cb6eb307..ec720fce7c0 100644 --- a/addons/headless/initSettings.inc.sqf +++ b/addons/headless/initSettings.inc.sqf @@ -5,8 +5,8 @@ format ["ACE %1", LLSTRING(Module)], false, 1, - {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + {[QXGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -15,8 +15,7 @@ [LSTRING(Delay), LSTRING(DelayDesc)], format ["ACE %1", LLSTRING(Module)], [0, 60, 15, -1], - 1, - {[QGVAR(delay), _this] call EFUNC(common,cbaSettings_settingChanged)} + 1 ] call CBA_fnc_addSetting; [ @@ -26,8 +25,8 @@ format ["ACE %1", LLSTRING(Module)], [[0, 1, 2], [ELSTRING(Common,Disabled), LSTRING(Instant), LSTRING(Delayed)], 0], 1, - {[QGVAR(delay), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + {[QXGVAR(endMission), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -36,8 +35,7 @@ [LSTRING(Log), LSTRING(LogDesc)], format ["ACE %1", LLSTRING(Module)], false, - 1, - {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)} + 1 ] call CBA_fnc_addSetting; [ @@ -47,6 +45,6 @@ format ["ACE %1", LLSTRING(Module)], [[0, 1, 2], [ELSTRING(Common,Disabled), LSTRING(TransferLoadoutCurrent), LSTRING(TransferLoadoutConfig)], 0], 1, - {}, - true // needs mission restart + {[QXGVAR(transferLoadout), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_fnc_addSetting; diff --git a/addons/headless/script_component.hpp b/addons/headless/script_component.hpp index 73761a7bb16..272b288d5f4 100644 --- a/addons/headless/script_component.hpp +++ b/addons/headless/script_component.hpp @@ -17,3 +17,7 @@ #include "\z\ace\addons\main\script_macros.hpp" #define DELAY_DEFAULT 15 + +#define NO_REBALANCE 0 +#define REBALANCE 1 +#define FORCED_REBALANCE 2 diff --git a/addons/hearing/CfgEventHandlers.hpp b/addons/hearing/CfgEventHandlers.hpp index 8143e2ce0df..59cd1b36296 100644 --- a/addons/hearing/CfgEventHandlers.hpp +++ b/addons/hearing/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); diff --git a/addons/hearing/CfgVehicles.hpp b/addons/hearing/CfgVehicles.hpp index a7625344608..636184ecd22 100644 --- a/addons/hearing/CfgVehicles.hpp +++ b/addons/hearing/CfgVehicles.hpp @@ -5,7 +5,7 @@ class CfgVehicles { class ACE_Equipment { class ACE_PutInEarplugs { displayName = CSTRING(EarPlugs_On); - condition = QUOTE(GVAR(EnableCombatDeafness) && {!([_player] call FUNC(hasEarPlugsIn)) && {'ACE_EarPlugs' in items _player}}); + condition = QUOTE(GVAR(enableCombatDeafness) && {!(_player call FUNC(hasEarPlugsIn)) && {[ARR_2(_player,'ACE_EarPlugs')] call EFUNC(common,hasItem)}}); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; statement = QUOTE([ARR_2(_player,true)] call FUNC(putInEarPlugs)); showDisabled = 0; @@ -13,7 +13,7 @@ class CfgVehicles { }; class ACE_RemoveEarplugs { displayName = CSTRING(EarPlugs_Off); - condition = QUOTE(GVAR(EnableCombatDeafness) && {[_player] call FUNC(hasEarPlugsIn)}); + condition = QUOTE(GVAR(enableCombatDeafness) && {_player call FUNC(hasEarPlugsIn)}); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; statement = QUOTE([ARR_2(_player,true)] call FUNC(removeEarPlugs)); showDisabled = 0; diff --git a/addons/hearing/CfgWeapons.hpp b/addons/hearing/CfgWeapons.hpp index 23ebe5c1d2f..8cef02edfd8 100644 --- a/addons/hearing/CfgWeapons.hpp +++ b/addons/hearing/CfgWeapons.hpp @@ -80,7 +80,7 @@ class CfgWeapons { class H_HelmetO_ocamo: H_HelmetB { HEARING_PROTECTION_PELTOR; - }; // Defender and Assasin Helmet inherit. + }; // Defender and Assassin Helmet inherit. class H_HelmetO_ViperSP_hex_f: H_HelmetB { HEARING_PROTECTION_PELTOR; diff --git a/addons/hearing/XEH_PREP.hpp b/addons/hearing/XEH_PREP.hpp index e06fa5d56c0..a2bcbb708a4 100644 --- a/addons/hearing/XEH_PREP.hpp +++ b/addons/hearing/XEH_PREP.hpp @@ -1,8 +1,8 @@ - PREP(addEarPlugs); PREP(earRinging); PREP(explosionNear); PREP(firedNear); +PREP(getAmmoLoudness); PREP(handleRespawn); PREP(hasEarPlugsIn); PREP(moduleHearing); diff --git a/addons/hearing/XEH_postInit.sqf b/addons/hearing/XEH_postInit.sqf index e6f328ad78c..4261933bd92 100644 --- a/addons/hearing/XEH_postInit.sqf +++ b/addons/hearing/XEH_postInit.sqf @@ -2,9 +2,10 @@ if (isServer) then { ["CBA_settingsInitialized", { - TRACE_1("settingInit - server",GVAR(EnableCombatDeafness)); + TRACE_1("settingInit - server",GVAR(enableCombatDeafness)); + // Only install event handler if combat deafness is enabled - if (!GVAR(EnableCombatDeafness)) exitWith {}; + if (!GVAR(enableCombatDeafness)) exitWith {}; ["CAManBase", "Init", LINKFUNC(addEarPlugs), true, [], true] call CBA_fnc_addClassEventHandler; }] call CBA_fnc_addEventHandler; @@ -14,7 +15,7 @@ if (!hasInterface) exitWith {}; #include "initKeybinds.inc.sqf" -GVAR(cacheAmmoLoudness) = call CBA_fnc_createNamespace; +GVAR(cacheAmmoLoudness) = createHashMap; GVAR(deafnessDV) = 0; GVAR(deafnessPrior) = 0; @@ -26,18 +27,20 @@ GVAR(volumeAttenuation) = 1; GVAR(lastPlayerVehicle) = objNull; ["CBA_settingsInitialized", { - TRACE_1("settingInit",GVAR(EnableCombatDeafness)); + TRACE_1("settingInit",GVAR(enableCombatDeafness)); + // Only run PFEH and install event handlers if combat deafness is enabled - if (!GVAR(EnableCombatDeafness)) exitWith {}; + if (!GVAR(enableCombatDeafness)) exitWith {}; // Spawn volume updating process - [LINKFUNC(updateVolume), 1, [false]] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(updateVolume), 1, false] call CBA_fnc_addPerFrameHandler; [QGVAR(updateVolume), LINKFUNC(updateVolume)] call CBA_fnc_addEventHandler; // Update veh attunation when player veh changes ["vehicle", { params ["_player", "_vehicle"]; + TRACE_2("vehicle change",_player,_vehicle); _this call FUNC(updatePlayerVehAttenuation); @@ -48,6 +51,7 @@ GVAR(lastPlayerVehicle) = objNull; GVAR(lastPlayerVehicle) = objNull; TRACE_2("removed veh eh",_firedEH,GVAR(lastPlayerVehicle)); }; + if ((!isNull _vehicle) && {_player != _vehicle}) then { private _firedEH = _vehicle addEventHandler ["FiredNear", {call FUNC(firedNear)}]; _vehicle setVariable [QGVAR(firedEH), _firedEH]; @@ -55,8 +59,8 @@ GVAR(lastPlayerVehicle) = objNull; TRACE_2("added veh eh",_firedEH,GVAR(lastPlayerVehicle)); }; }, true] call CBA_fnc_addPlayerEventHandler; - ["turret", LINKFUNC(updatePlayerVehAttenuation), false] call CBA_fnc_addPlayerEventHandler; + ["turret", LINKFUNC(updatePlayerVehAttenuation), false] call CBA_fnc_addPlayerEventHandler; // Reset deafness on respawn (or remote control player switch) ["unit", { @@ -67,9 +71,11 @@ GVAR(lastPlayerVehicle) = objNull; private _firedEH = _oldPlayer getVariable [QGVAR(firedEH), -1]; _oldPlayer removeEventHandler ["FiredNear", _firedEH]; _oldPlayer setVariable [QGVAR(firedEH), nil]; + private _explosionEH = _oldPlayer getVariable [QGVAR(explosionEH), -1]; _oldPlayer removeEventHandler ["Explosion", _explosionEH]; _oldPlayer setVariable [QGVAR(explosionEH), nil]; + TRACE_3("removed unit eh",_oldPlayer,_firedEH,_explosionEH); }; // Don't add a new EH if the unit respawned @@ -77,17 +83,21 @@ GVAR(lastPlayerVehicle) = objNull; if ((getNumber (configOf _player >> "isPlayableLogic")) == 1) exitWith { TRACE_1("skipping playable logic",typeOf _player); // VirtualMan_F (placeable logic zeus / spectator) }; + private _firedEH = _player addEventHandler ["FiredNear", {call FUNC(firedNear)}]; _player setVariable [QGVAR(firedEH), _firedEH]; + private _explosionEH = _player addEventHandler ["Explosion", {call FUNC(explosionNear)}]; _player setVariable [QGVAR(explosionEH), _explosionEH]; + TRACE_3("added unit eh",_player,_firedEH,_explosionEH); }; GVAR(deafnessDV) = 0; GVAR(deafnessPrior) = 0; GVAR(time3) = 0; - [] call FUNC(updateHearingProtection); + + call FUNC(updateHearingProtection); }, true] call CBA_fnc_addPlayerEventHandler; // Update protection on possible helmet change diff --git a/addons/hearing/XEH_preInit.sqf b/addons/hearing/XEH_preInit.sqf index 7a6195ec460..e47eafa56e8 100644 --- a/addons/hearing/XEH_preInit.sqf +++ b/addons/hearing/XEH_preInit.sqf @@ -10,15 +10,20 @@ PREP_RECOMPILE_END; ["CBA_loadoutSet", { params ["_unit", "_loadout", "_extendedInfo"]; + if (_extendedInfo getOrDefault ["ace_earplugs", false]) then { _unit setVariable ["ACE_hasEarPlugsIn", true, true]; - [QGVAR(updateVolume), [[true]], _unit] call CBA_fnc_targetEvent; + // Only force update volume if unit is a player (including remote controlled) + if (_unit call EFUNC(common,isPlayer)) then { + [QGVAR(updateVolume), true, _unit] call CBA_fnc_targetEvent; + }; }; }] call CBA_fnc_addEventHandler; ["CBA_loadoutGet", { params ["_unit", "_loadout", "_extendedInfo"]; + if (_unit getVariable ["ACE_hasEarPlugsin", false]) then { _extendedInfo set ["ace_earplugs", true] }; diff --git a/addons/hearing/functions/fnc_addEarPlugs.sqf b/addons/hearing/functions/fnc_addEarPlugs.sqf index fdbcfbc6215..11999f77378 100644 --- a/addons/hearing/functions/fnc_addEarPlugs.sqf +++ b/addons/hearing/functions/fnc_addEarPlugs.sqf @@ -4,7 +4,7 @@ * Called on unit initialization. Adds earplugs if the unit is equipped with either a really loud primary weapon or a rocket launcher. * * Arguments: - * 0: A Soldier + * 0: Unit * * Return Value: * None @@ -15,9 +15,9 @@ * Public: No */ -// only run this after the settings are initialized -if !(EGVAR(common,settingsInitFinished)) exitWith { - EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(addEarPlugs), _this]; +// Only run this after the settings are initialized +if (!EGVAR(common,settingsInitFinished)) exitWith { + EGVAR(common,runAtSettingsInitialized) pushBack [LINKFUNC(addEarPlugs), _this]; }; // Exit if hearing is disabled or if autoAdd is disabled @@ -29,42 +29,48 @@ TRACE_2("params",_unit,typeOf _unit); // Exit if the unit already has earplugs (in ears (persistence scenarios) or inventory) if (_unit call FUNC(hasEarPlugsIn) || {[_unit, "ACE_EarPlugs"] call EFUNC(common,hasItem)}) exitWith {}; -// Add earplugs if enabled for everyone or if the soldier has a rocket launcher +// Add earplugs if enabled for everyone or if the unit has a rocket launcher if (GVAR(autoAddEarplugsToUnits) == 2 || {(secondaryWeapon _unit) != ""}) exitWith { TRACE_1("has launcher - adding",_unit); _unit addItem "ACE_EarPlugs"; }; -// otherwise add earplugs if the soldier has a big rifle -if ((primaryWeapon _unit) == "") exitWith {}; +// Otherwise add earplugs if the unit has a big rifle +private _weapon = primaryWeapon _unit; -(primaryWeaponMagazine _unit) params [["_magazine", ""]]; -if (_magazine == "") exitWith {}; +if (_weapon == "") exitWith {}; -private _cfgMagazine = configFile >> "CfgMagazines" >> _magazine; +if (isNil QGVAR(cacheMaxAmmoLoudness)) then { + GVAR(cacheMaxAmmoLoudness) = createHashMap; +}; -private _initSpeed = getNumber (_cfgMagazine >> "initSpeed"); -private _ammo = getText (_cfgMagazine >> "ammo"); -private _count = getNumber (_cfgMagazine >> "count"); +// Cache maximum loudness for future calls +private _maxLoudness = GVAR(cacheMaxAmmoLoudness) getOrDefaultCall [_weapon, { + // Get the weapon's compatible magazines, so that all magazines are cached + // From all the loudness factors, take the max + private _maxLoudness = selectMax ((compatibleMagazines _weapon) apply {_x call FUNC(getAmmoLoudness)}); -private _cfgAmmo = configFile >> "CfgAmmo"; + // ace_gunbag_fnc_isMachineGun + private _config = _weapon call CBA_fnc_getItemConfig; -private _caliber = getNumber (_cfgAmmo >> _ammo >> "ACE_caliber"); -_caliber = call { - if (_ammo isKindOf ["ShellBase", _cfgAmmo]) exitWith { 80 }; - if (_ammo isKindOf ["RocketBase", _cfgAmmo]) exitWith { 200 }; - if (_ammo isKindOf ["MissileBase", _cfgAmmo]) exitWith { 600 }; - if (_ammo isKindOf ["SubmunitionBase", _cfgAmmo]) exitWith { 80 }; - [_caliber, 6.5] select (_caliber <= 0); -}; -private _loudness = (_caliber ^ 1.25 / 10) * (_initspeed / 1000) / 5; + // Definition of a machine gun by BIS_fnc_itemType + private _cursor = getText (_config >> "cursor"); + + if (toLowerANSI _cursor in ["", "emptycursor"]) then { + _cursor = getText (_config >> "cursorAim"); + }; + + // If unit has a machine gun boost effective loudness 50% + if (_cursor == "MG") then { + _maxLoudness = _maxLoudness * 1.5; + }; -//If unit has a machine gun boost effective loudness 50% -if (_count >= 50) then {_loudness = _loudness * 1.5}; + _maxLoudness +}, true]; -TRACE_2("primaryWeapon",_unit,_loudness); +TRACE_3("primaryWeapon",_unit,_weapon,_maxLoudness); -if (_loudness > 0.2) then { +if (_maxLoudness > 0.2) then { TRACE_1("loud gun - adding",_unit); _unit addItem "ACE_EarPlugs"; }; diff --git a/addons/hearing/functions/fnc_earRinging.sqf b/addons/hearing/functions/fnc_earRinging.sqf index f5a2a714dbd..57888e90a2e 100644 --- a/addons/hearing/functions/fnc_earRinging.sqf +++ b/addons/hearing/functions/fnc_earRinging.sqf @@ -1,24 +1,25 @@ #include "..\script_component.hpp" /* * Author: KoffeinFlummi, commy2, Rocko, Rommel, Ruthberg - * Handle new sound souce near ace_player and apply hearing damage + * Handle new sound souce near ace_player and apply hearing damage. * * Arguments: - * 0: strength of ear ringing + * 0: Strength of ear ringing * * Return Value: * None * * Example: - * [_strength] call ace_hearing_fnc_earRinging + * 10 call ace_hearing_fnc_earRinging * * Public: No */ + params ["_strength"]; if (_strength < 0.05) exitWith {}; if (!isNull curatorCamera) exitWith {}; -if ((!GVAR(enabledForZeusUnits)) && {player != ACE_player}) exitWith {}; +if (!GVAR(enabledForZeusUnits) && {player != ACE_player}) exitWith {}; TRACE_2("adding",_strength * GVAR(damageCoefficent),GVAR(deafnessDV)); diff --git a/addons/hearing/functions/fnc_explosionNear.sqf b/addons/hearing/functions/fnc_explosionNear.sqf index c65cf31c764..583c55749e9 100644 --- a/addons/hearing/functions/fnc_explosionNear.sqf +++ b/addons/hearing/functions/fnc_explosionNear.sqf @@ -4,8 +4,8 @@ * Handles deafness due to explosions going off near the player. * * Arguments: - * 0: vehicle - Object the event handler is assigned to (player) - * 1: damage - Damage inflicted to the object + * 0: Unit + * 1: Damage inflicted to the unit * * Return Value: * None @@ -21,7 +21,6 @@ params ["_unit", "_damage"]; TRACE_2("explosion near player",_unit,_damage); private _strength = (0 max _damage) * 30; -if (_strength < 0.01) exitWith {}; -// Call inmediately, as it will get pick up later anyway by the update thread -[_strength] call FUNC(earRinging); +// Call immediately, as it will get picked up later by the update thread anyway +_strength call FUNC(earRinging); diff --git a/addons/hearing/functions/fnc_firedNear.sqf b/addons/hearing/functions/fnc_firedNear.sqf index 4dd81862b9b..1c9a1c54968 100644 --- a/addons/hearing/functions/fnc_firedNear.sqf +++ b/addons/hearing/functions/fnc_firedNear.sqf @@ -4,97 +4,60 @@ * Handles deafness due to large-caliber weapons going off near the player. * * Arguments: - * 0: Unit - Object the event handler is assigned to - * 1: Firer: Object - Object which fires a weapon near the unit - * 2: Distance - Distance in meters between the unit and firer - * 3: weapon - Fired weapon - * 4: muzzle - Muzzle that was used (not used) - * 5: mode - Current mode of the fired weapon (not used) - * 6: ammo - Ammo used + * 0: Object the event handler is assigned to (unused) + * 1: Object which fires a weapon near the unit + * 2: Distance in meters between the unit and firer + * 3: Weapon + * 4: Muzzle + * 5: Current mode of the fired weapon + * 6: Ammo + * 7: Unit that fired the weapon * * Return Value: * None * * Example: - * [clientFiredNearEvent] call ace_hearing_fnc_firedNear - * [player, player, 10, "arifle_MX_ACO_pointer_F", "arifle_MX_ACO_pointer_F", "single", "B_65x39_Caseless"] call ace_hearing_fnc_firedNear + * [player, player, 10, "arifle_MX_ACO_pointer_F", "arifle_MX_ACO_pointer_F", "single", "B_65x39_Caseless", player] call ace_hearing_fnc_firedNear * * Public: No */ -params ["_object", "_firer", "_distance", "_weapon", "", "", "_ammo"]; +params ["", "_firer", "_distance", "_weapon", "_muzzle", "_mode", "_ammo", "_gunner"]; if (_weapon in ["Throw", "Put"]) exitWith {}; if (_distance > 50) exitWith {}; -private _vehAttenuation = [GVAR(playerVehAttenuation), 1] select ( - (ACE_player == (vehicle ACE_player)) || {isTurnedOut ACE_player} -); -private _distance = 1 max _distance; - -private _silencer = switch (_weapon) do { - case (primaryWeapon _firer) : {(primaryWeaponItems _firer) select 0}; - case (secondaryWeapon _firer) : {(secondaryWeaponItems _firer) select 0}; - case (handgunWeapon _firer) : {(handgunItems _firer) select 0}; - default {""}; -}; - +_distance = 1 max _distance; private _audibleFireCoef = 1; -if (_silencer != "") then { - _audibleFireCoef = getNumber (configFile >> "CfgWeapons" >> _silencer >> "ItemInfo" >> "AmmoCoef" >> "audibleFire"); -}; -private _loudness = GVAR(cacheAmmoLoudness) getVariable (format ["%1%2",_weapon,_ammo]); -if (isNil "_loudness") then { - private _muzzles = getArray (configFile >> "CfgWeapons" >> _weapon >> "muzzles"); - private _weaponMagazines = getArray (configFile >> "CfgWeapons" >> _weapon >> "magazines"); - { - if (_x != "this") then { - private _muzzleMagazines = getArray (configFile >> "CfgWeapons" >> _weapon >> _x >> "magazines"); - _weaponMagazines append _muzzleMagazines; - }; - } forEach _muzzles; - { - private _ammoType = getText(configFile >> "CfgMagazines" >> _x >> "ammo"); - _weaponMagazines set [_forEachIndex, [_x, _ammoType]]; - } forEach _weaponMagazines; +// Unit that fired is on foot +private _magazine = if (_gunner == _firer) then { + // Check if the unit has a suppressor + private _suppressor = (_firer weaponAccessories _weapon) select 0; - private _magazine = ""; - { - _x params ["_magazineType", "_ammoType"]; - if (_ammoType == _ammo) exitWith { - _magazine = _magazineType; - }; - } forEach _weaponMagazines; + if (_suppressor != "") then { + _audibleFireCoef = getNumber (configFile >> "CfgWeapons" >> _suppressor >> "ItemInfo" >> "AmmoCoef" >> "audibleFire"); + }; - if (_magazine == "") then { - _loudness = 0; - TRACE_2("No mag for Weapon/Ammo??",_weapon,_ammo); - } else { - private _initSpeed = getNumber(configFile >> "CfgMagazines" >> _magazine >> "initSpeed"); - private _caliber = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ACE_caliber"); - _caliber = call { - // If explicilty defined, use ACE_caliber - if ((count configProperties [(configFile >> "CfgAmmo" >> _ammo), "configName _x == 'ACE_caliber'", false]) == 1) exitWith {_caliber}; - if (_ammo isKindOf ["ShellBase", (configFile >> "CfgAmmo")]) exitWith { 80 }; - if (_ammo isKindOf ["RocketBase", (configFile >> "CfgAmmo")]) exitWith { 200 }; - if (_ammo isKindOf ["MissileBase", (configFile >> "CfgAmmo")]) exitWith { 600 }; - if (_ammo isKindOf ["SubmunitionBase", (configFile >> "CfgAmmo")]) exitWith { 80 }; - [_caliber, 6.5] select (_caliber <= 0) - }; + (_firer weaponState _muzzle) select 3 +} else { + // Unit that fired is in a vehicle + (weaponState [_firer, _firer unitTurret _gunner, _weapon, _muzzle, _mode]) select 3 +}; - _loudness = (_caliber ^ 1.25 / 10) * (_initspeed / 1000) / 5; - TRACE_6("building cache",_weapon,_ammo,_magazine,_initSpeed,_caliber,_loudness); - }; - GVAR(cacheAmmoLoudness) setVariable [(format ["%1%2",_weapon,_ammo]), _loudness]; +if (_magazine == "") exitWith { + TRACE_5("No mag for weapon/ammo??",_weapon,_muzzle,_ammo,_firer,_gunner); }; +TRACE_6("mag",_magazine,_weapon,_muzzle,_ammo,_firer,_gunner); + +private _vehAttenuation = [GVAR(playerVehAttenuation), 1] select (isNull objectParent ACE_player || {isTurnedOut ACE_player}); +private _loudness = _magazine call FUNC(getAmmoLoudness); + _loudness = _loudness * _audibleFireCoef; private _strength = _vehAttenuation * (_loudness - (_loudness / 50 * _distance)); // linear drop off TRACE_1("result",_strength); -if (_strength < 0.01) exitWith {}; - -// Call inmediately, as it will get pick up later anyway by the update thread -[_strength] call FUNC(earRinging); +// Call immediately, as it will get picked up later by the update thread anyway +_strength call FUNC(earRinging); diff --git a/addons/hearing/functions/fnc_getAmmoLoudness.sqf b/addons/hearing/functions/fnc_getAmmoLoudness.sqf new file mode 100644 index 00000000000..062b96fa718 --- /dev/null +++ b/addons/hearing/functions/fnc_getAmmoLoudness.sqf @@ -0,0 +1,44 @@ +#include "..\script_component.hpp" +/* + * Author: KoffeinFlummi, commy2, johnb43 + * Get the loudness of ammo. + * However, because `initSpeed` is a magazine attribute, the magazine name needs to be used instead of the ammo. + * + * Arguments: + * 0: Magazine + * + * Return Value: + * None + * + * Example: + * "30Rnd_65x39_caseless_mag" call ace_hearing_fnc_getAmmoLoudness + * + * Public: No + */ + +params ["_magazine"]; + +GVAR(cacheAmmoLoudness) getOrDefaultCall [_magazine, { + private _magazineConfig = configFile >> "CfgMagazines" >> _magazine; + private _ammo = getText (_magazineConfig >> "ammo"); + private _initSpeed = getNumber (_magazineConfig >> "initSpeed"); + + private _cfgAmmo = configFile >> "CfgAmmo"; + private _ammoConfig = _cfgAmmo >> _ammo; + private _caliber = getNumber (_ammoConfig >> "ACE_caliber"); + + _caliber = switch (true) do { + // If explicilty defined, use ACE_caliber + case (inheritsFrom (_ammoConfig >> "ACE_caliber") isEqualTo _ammoConfig): {_caliber}; + case (_ammo isKindOf ["ShellBase", _cfgAmmo]): {80}; + case (_ammo isKindOf ["RocketBase", _cfgAmmo]): {200}; + case (_ammo isKindOf ["MissileBase", _cfgAmmo]): {600}; + case (_ammo isKindOf ["SubmunitionBase", _cfgAmmo]): {80}; + default {[_caliber, 6.5] select (_caliber <= 0)}; + }; + + private _loudness = (_caliber ^ 1.25 / 10) * (_initspeed / 1000) / 5; + TRACE_5("building cache",_ammo,_magazine,_initSpeed,_caliber,_loudness); + + _loudness +}, true] diff --git a/addons/hearing/functions/fnc_handleRespawn.sqf b/addons/hearing/functions/fnc_handleRespawn.sqf index b436aa7c410..a075d7901e0 100644 --- a/addons/hearing/functions/fnc_handleRespawn.sqf +++ b/addons/hearing/functions/fnc_handleRespawn.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Reset earplugs on respawn, and then re-add if appropriate + * Reset earplugs on respawn, and then re-add if appropriate. * * Arguments: * 0: Unit @@ -10,29 +10,29 @@ * None * * Example: - * [player] call ACE_hearing_fnc_handleRespawn; + * player call ace_hearing_fnc_handleRespawn; * * Public: No */ +// Do not add or remove earplugs if gear should be preserved +if (missionNamespace getVariable [QEGVAR(respawn,savePreDeathGear), false]) exitWith {}; + params ["_unit"]; TRACE_2("params",_unit,typeOf _unit); -if (!local _unit) exitWith {}; //XEH should only be called on local units - -//Do not add or remove earplugs if gear should be preserved -if (missionNamespace getVariable [QEGVAR(respawn,SavePreDeathGear), false]) exitWith {}; +if (!local _unit) exitWith {}; // XEH should only be called on local units private _respawn = [0] call BIS_fnc_missionRespawnType; -//if respawn is not Group or side: +// If respawn is not group or side: if (_respawn <= 3) then { - //Remove earplugs if they have them: + // Remove earplugs if they have them: if (_unit getVariable ["ACE_hasEarPlugsin", false]) then { TRACE_1("had EarPlugs in - removing",_unit); _unit setVariable ["ACE_hasEarPlugsin", false, true]; }; }; -//Re-add if they need them: -[_unit] call FUNC(addEarPlugs); +// Re-add if they need them +_unit call FUNC(addEarPlugs); diff --git a/addons/hearing/functions/fnc_hasEarPlugsIn.sqf b/addons/hearing/functions/fnc_hasEarPlugsIn.sqf index f4b84281fb6..fd6682e4de2 100644 --- a/addons/hearing/functions/fnc_hasEarPlugsIn.sqf +++ b/addons/hearing/functions/fnc_hasEarPlugsIn.sqf @@ -4,16 +4,17 @@ * Check if the unit has earplugs put in. * * Arguments: - * 0: Unit (player) + * 0: Unit * * Return Value: - * Have Earplugs in + * Has Earplugs in * * Example: - * [ace_player] call ace_hearing_fnc_hasEarPlugsIn + * player call ace_hearing_fnc_hasEarPlugsIn * * Public: No */ + params ["_unit"]; _unit getVariable ["ACE_hasEarPlugsin", false] diff --git a/addons/hearing/functions/fnc_moduleHearing.sqf b/addons/hearing/functions/fnc_moduleHearing.sqf index 924f2baa211..f7943a712e9 100644 --- a/addons/hearing/functions/fnc_moduleHearing.sqf +++ b/addons/hearing/functions/fnc_moduleHearing.sqf @@ -10,7 +10,7 @@ * None * * Example: - * [player] call ACE_hearing_fnc_moduleHearing + * player call ace_hearing_fnc_moduleHearing * * Public: No */ @@ -23,6 +23,8 @@ params ["_logic"]; if ((_logic getVariable "DisableEarRinging") != -1) then { [_logic, QGVAR(DisableEarRinging), "DisableEarRinging"] call EFUNC(common,readSettingFromModule); }; + [_logic, QGVAR(enabledForZeusUnits), "enabledForZeusUnits"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(autoAddEarplugsToUnits), "autoAddEarplugsToUnits"] call EFUNC(common,readSettingFromModule); + INFO("Hearing Module Initialized."); diff --git a/addons/hearing/functions/fnc_putInEarplugs.sqf b/addons/hearing/functions/fnc_putInEarplugs.sqf index 2af4df8e86c..aa2166a112f 100644 --- a/addons/hearing/functions/fnc_putInEarplugs.sqf +++ b/addons/hearing/functions/fnc_putInEarplugs.sqf @@ -1,38 +1,35 @@ #include "..\script_component.hpp" /* - * Author: Hope Johnson and commy2 + * Author: Hope Johnson, commy2 * Puts in earplugs. * * Arguments: - * 0: Unit (player) + * 0: Unit * 1: Display hint (default: false) * * Return Value: * None * * Example: - * [ace_player, false] call ace_hearing_fnc_putInEarplugs + * [player, false] call ace_hearing_fnc_putInEarplugs * * Public: No */ -params ["_player", ["_displayHint", false, [false]]]; +if (!GVAR(enableCombatDeafness)) exitWith {}; -if (!GVAR(EnableCombatDeafness)) exitWith {}; +params ["_unit", ["_displayHint", false]]; // Plugs in inventory, putting them in -_player removeItem "ACE_EarPlugs"; +_unit removeItem "ACE_EarPlugs"; -_player setVariable ["ACE_hasEarPlugsIn", true, true]; +_unit setVariable ["ACE_hasEarPlugsIn", true, true]; if (_displayHint) then { - [localize LSTRING(EarPlugs_Are_On)] call EFUNC(common,displayTextStructured); + [LLSTRING(EarPlugs_Are_On)] call EFUNC(common,displayTextStructured); }; -//Force an immediate fast volume update: -[[true]] call FUNC(updateVolume); +// Force an immediate volume update +true call FUNC(updateVolume); -// No Earplugs in inventory, telling user -//[localize LSTRING(NoPlugs)] call EFUNC(common,displayTextStructured); - -[] call FUNC(updateHearingProtection); +call FUNC(updateHearingProtection); diff --git a/addons/hearing/functions/fnc_removeEarplugs.sqf b/addons/hearing/functions/fnc_removeEarplugs.sqf index 20a49bb5300..743e89ef531 100644 --- a/addons/hearing/functions/fnc_removeEarplugs.sqf +++ b/addons/hearing/functions/fnc_removeEarplugs.sqf @@ -1,39 +1,40 @@ #include "..\script_component.hpp" /* - * Author: Hope Johnson and commy2 + * Author: Hope Johnson, commy2 * Takes out earplugs. * * Arguments: - * 0: Unit (player) - * 1: Display hint (default false) + * 0: Unit + * 1: Display hint (default: false) * * Return Value: * None * * Example: - * [ace_player, false] call ace_hearing_fnc_removeEarplugs + * [player, false] call ace_hearing_fnc_removeEarplugs * * Public: No */ -params ["_player", ["_displayHint", false, [false]]]; +if (!GVAR(enableCombatDeafness)) exitWith {}; -if (!GVAR(EnableCombatDeafness)) exitWith {}; +params ["_unit", ["_displayHint", false]]; -if !([_player, "ACE_EarPlugs"] call CBA_fnc_canAddItem) exitWith { // inventory full +// Inventory full +if !([_unit, "ACE_EarPlugs"] call CBA_fnc_canAddItem) exitWith { [LELSTRING(common,Inventory_Full)] call EFUNC(common,displayTextStructured); }; // Plugs already in and removing them. -_player addItem "ACE_EarPlugs"; +_unit addItem "ACE_EarPlugs"; -_player setVariable ["ACE_hasEarPlugsIn", false, true]; +_unit setVariable ["ACE_hasEarPlugsIn", false, true]; if (_displayHint) then { - [localize LSTRING(EarPlugs_Are_Off)] call EFUNC(common,displayTextStructured); + [LLSTRING(EarPlugs_Are_Off)] call EFUNC(common,displayTextStructured); }; -//Force an immediate fast volume update: -[[true]] call FUNC(updateVolume); +// Force an immediate volume update +true call FUNC(updateVolume); -[] call FUNC(updateHearingProtection); +call FUNC(updateHearingProtection); diff --git a/addons/hearing/functions/fnc_updateHearingProtection.sqf b/addons/hearing/functions/fnc_updateHearingProtection.sqf index 15973b73a92..b9d7f1f9a0b 100644 --- a/addons/hearing/functions/fnc_updateHearingProtection.sqf +++ b/addons/hearing/functions/fnc_updateHearingProtection.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Updates the hearing protection and volume attenuation for player on earbuds/helmet change + * Updates the hearing protection and volume attenuation for player on earbuds/helmet change. * * Arguments: * None @@ -10,12 +10,12 @@ * None * * Example: - * [] call ace_hearing_fnc_updateHearingProtection + * call ace_hearing_fnc_updateHearingProtection * * Public: No */ -TRACE_1("params",_this); +LOG("updateHearingProtection"); if (isNull ACE_player) exitWith { GVAR(damageCoefficent) = 0; @@ -23,22 +23,32 @@ if (isNull ACE_player) exitWith { }; // Handle Earplugs -private _hasEarPlugsIn = [ACE_player] call FUNC(hasEarPlugsIn); +private _hasEarPlugsIn = ACE_player call FUNC(hasEarPlugsIn); GVAR(damageCoefficent) = [1, 0.25] select _hasEarPlugsIn; -GVAR(volumeAttenuation) = [1, GVAR(EarplugsVolume)] select _hasEarPlugsIn; +GVAR(volumeAttenuation) = [1, GVAR(earplugsVolume)] select _hasEarPlugsIn; // Handle Headgear -if (headgear ACE_player != "") then { - private _protection = getNumber (configFile >> "CfgWeapons" >> headgear ACE_player >> QGVAR(protection)) min 1; +private _headgear = headgear ACE_player; + +if (_headgear != "") then { + private _heargearConfig = configFile >> "CfgWeapons" >> _headgear; + + private _protection = getNumber (_heargearConfig >> QGVAR(protection)) min 1; GVAR(damageCoefficent) = GVAR(damageCoefficent) * (1 - _protection); - private _attenuation = getNumber (configFile >> "CfgWeapons" >> headgear ACE_player >> QGVAR(lowerVolume)) min 1; + + private _attenuation = getNumber (_heargearConfig >> QGVAR(lowerVolume)) min 1; GVAR(volumeAttenuation) = GVAR(volumeAttenuation) * (1 - _attenuation); }; // Handle Goggles -if (goggles ACE_player != "") then { - private _protection = getNumber (configFile >> "CfgGlasses" >> goggles ACE_player >> QGVAR(protection)) min 1; +private _goggles = goggles ACE_player; + +if (_goggles != "") then { + private _gogglesConfig = configFile >> "CfgGlasses" >> _goggles; + + private _protection = getNumber (_gogglesConfig >> QGVAR(protection)) min 1; GVAR(damageCoefficent) = GVAR(damageCoefficent) * (1 - _protection); - private _attenuation = getNumber (configFile >> "CfgGlasses" >> goggles ACE_player >> QGVAR(lowerVolume)) min 1; + + private _attenuation = getNumber (_gogglesConfig >> QGVAR(lowerVolume)) min 1; GVAR(volumeAttenuation) = GVAR(volumeAttenuation) * (1 - _attenuation); }; diff --git a/addons/hearing/functions/fnc_updatePlayerVehAttenuation.sqf b/addons/hearing/functions/fnc_updatePlayerVehAttenuation.sqf index 207c0f07a3a..856b694a3f6 100644 --- a/addons/hearing/functions/fnc_updatePlayerVehAttenuation.sqf +++ b/addons/hearing/functions/fnc_updatePlayerVehAttenuation.sqf @@ -7,10 +7,10 @@ * None * * Return Value: - * Ammount that unit can hear outside + * Amount that unit can hear outside * * Example: - * [] call ace_hearing_fnc_updatePlayerVehAttenuation + * call ace_hearing_fnc_updatePlayerVehAttenuation * * Public: No */ @@ -20,12 +20,14 @@ private _vehicle = vehicle ACE_player; if (isNull _vehicle) exitWith {}; private _newAttenuation = 1; + if (ACE_player != _vehicle) then { - private _turretPath = [ACE_player] call EFUNC(common,getTurretIndex); - private _effectType = getText (configOf _vehicle >> "attenuationEffectType"); + private _vehicleConfig = configOf _vehicle; + private _turretPath = _vehicle unitTurret ACE_player; + private _effectType = getText (_vehicleConfig >> "attenuationEffectType"); if (_turretPath isNotEqualTo []) then { - private _turretConfig = [(configOf _vehicle), _turretPath] call EFUNC(common,getTurretConfigPath); + private _turretConfig = [_vehicleConfig, _turretPath] call EFUNC(common,getTurretConfigPath); if ((getNumber (_turretConfig >> "disableSoundAttenuation")) == 1) then { _effectType = ""; @@ -40,7 +42,7 @@ if (ACE_player != _vehicle) then { case (_effectType == ""): {1}; case (_effectType == "CarAttenuation"); case (_effectType == "RHS_CarAttenuation"): { // Increase protection for armored cars - private _armor = getNumber (configOf _vehicle >> "HitPoints" >> "HitBody" >> "armor"); + private _armor = getNumber (_vehicleConfig >> "HitPoints" >> "HitBody" >> "armor"); linearConversion [2, 8, _armor, 0.5, 0.3, true];}; case (_effectType == "OpenCarAttenuation"): {1}; case (_effectType == "TankAttenuation"): {0.1}; diff --git a/addons/hearing/functions/fnc_updateVolume.sqf b/addons/hearing/functions/fnc_updateVolume.sqf index 0029cdc4de2..bb1d57e3c14 100644 --- a/addons/hearing/functions/fnc_updateVolume.sqf +++ b/addons/hearing/functions/fnc_updateVolume.sqf @@ -1,55 +1,61 @@ #include "..\script_component.hpp" /* - * Author: commy2 and esteldunedain and Ruthberg + * Author: commy2, esteldunedain, Ruthberg * Updates and applies the current deafness. Called every 1 sec from a PFEH. * * Arguments: - * 0: Args - * - 0: Just update volume (skip ringing/recovery) (default: false) + * 0: Update volume only (skip ringing/recovery) (default: false) * * Return Value: * None * * Example: - * [] call ace_hearing_fnc_updateVolume + * call ace_hearing_fnc_updateVolume * * Public: No */ +if (isGamePaused) exitWith {}; + if (!alive ACE_player) exitWith { - if (missionNameSpace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {}; + if (missionNamespace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {}; + TRACE_1("dead - removing hearing effects",ACE_player); + [QUOTE(ADDON), 1, true] call EFUNC(common,setHearingCapability); }; -(_this select 0) params [["_justUpdateVolume", false]]; +params [["_updateVolumeOnly", false]]; GVAR(deafnessDV) = (GVAR(deafnessDV) min 20) max 0; GVAR(volume) = (1 - (GVAR(deafnessDV) / 20)) max 0.05; + TRACE_3("",GVAR(volume),GVAR(deafnessDV),GVAR(deafnessDV) - GVAR(deafnessPrior)); -if (!_justUpdateVolume) then { +if (!_updateVolumeOnly) then { // Ring if we got a big increase in the last second or enough accumulated damage if (GVAR(deafnessDV) - GVAR(deafnessPrior) > 1 || GVAR(deafnessDV) > 10) then { if (CBA_missionTime - GVAR(time3) < 3) exitWith {}; + if (!isGameFocused) exitWith {}; // prevent audio from stacking when tabbed out + GVAR(time3) = CBA_missionTime; - if (!isGameFocused) exitWith {}; if (GVAR(deafnessDV) > 19.75) then { - playSound (["ACE_Combat_Deafness_Heavy", "ACE_Combat_Deafness_Heavy_NoRing"] select GVAR(DisableEarRinging)); + playSound (["ACE_Combat_Deafness_Heavy", "ACE_Combat_Deafness_Heavy_NoRing"] select GVAR(disableEarRinging)); } else { - playSound (["ACE_Combat_Deafness_Medium", "ACE_Combat_Deafness_Medium_NoRing"] select GVAR(DisableEarRinging)); + playSound (["ACE_Combat_Deafness_Medium", "ACE_Combat_Deafness_Medium_NoRing"] select GVAR(disableEarRinging)); }; }; + GVAR(deafnessPrior) = GVAR(deafnessDV); // Hearing takes longer to return to normal after it hits rock bottom - GVAR(deafnessDV) = (GVAR(deafnessDV) - (0.5 * (GVAR(volume) max 0.1))) max 0; + GVAR(deafnessDV) = (GVAR(deafnessDV) - (0.5 * (GVAR(volume) max 0.1))) max 0; }; -if (missionNameSpace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {}; +if (missionNamespace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {}; private _volume = GVAR(volume); @@ -57,8 +63,8 @@ private _volume = GVAR(volume); _volume = _volume min GVAR(volumeAttenuation); // Reduce volume if player is unconscious -if (ACE_player getVariable ["ACE_isUnconscious", false]) then { - _volume = _volume min GVAR(UnconsciousnessVolume); +if (lifeState ACE_player == "INCAPACITATED") then { + _volume = _volume min GVAR(unconsciousnessVolume); }; [QUOTE(ADDON), _volume, true] call EFUNC(common,setHearingCapability); diff --git a/addons/hearing/initKeybinds.inc.sqf b/addons/hearing/initKeybinds.inc.sqf index 22cf132add6..d1299661986 100644 --- a/addons/hearing/initKeybinds.inc.sqf +++ b/addons/hearing/initKeybinds.inc.sqf @@ -2,14 +2,17 @@ // Conditions: specific if !([ACE_player, objNull, ["isNotSwimming", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; - if (GVAR(EnableCombatDeafness) && {!([ACE_player] call FUNC(hasEarPlugsIn))} && {[ACE_player, "ACE_EarPlugs"] call EFUNC(common,hasItem)}) exitWith { + if (GVAR(enableCombatDeafness) && {!(ACE_player call FUNC(hasEarPlugsIn))} && {[ACE_player, "ACE_EarPlugs"] call EFUNC(common,hasItem)}) exitWith { [ACE_player, true] call FUNC(putInEarPlugs); - true + + true // return }; - if (GVAR(EnableCombatDeafness) && {[ACE_player] call FUNC(hasEarPlugsIn)}) exitWith { + + if (GVAR(enableCombatDeafness) && {ACE_player call FUNC(hasEarPlugsIn)}) exitWith { [ACE_player, true] call FUNC(removeEarPlugs); - true + + true // return }; - - false + + false // return }] call CBA_fnc_addKeybind; // UNBOUND diff --git a/addons/hearing/initSettings.inc.sqf b/addons/hearing/initSettings.inc.sqf index 61b6d239c58..adc6c6def75 100644 --- a/addons/hearing/initSettings.inc.sqf +++ b/addons/hearing/initSettings.inc.sqf @@ -1,7 +1,8 @@ -private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; +private _category = format ["ACE %1", LLSTRING(Module_DisplayName)]; [ - QGVAR(enableCombatDeafness), "CHECKBOX", + QGVAR(enableCombatDeafness), + "CHECKBOX", [LSTRING(EnableCombatDeafness_DisplayName), LSTRING(EnableCombatDeafness_Description)], _category, true, @@ -11,7 +12,8 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; ] call CBA_fnc_addSetting; [ - QGVAR(earplugsVolume), "SLIDER", + QGVAR(earplugsVolume), + "SLIDER", [LSTRING(earplugsVolume_DisplayName), LSTRING(earplugsVolume_Description)], _category, [0, 1, 0.5, 1], @@ -19,7 +21,8 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; ] call CBA_fnc_addSetting; [ - QGVAR(unconsciousnessVolume), "SLIDER", + QGVAR(unconsciousnessVolume), + "SLIDER", [LSTRING(unconsciousnessVolume_DisplayName), LSTRING(unconsciousnessVolume_Description)], _category, [0, 1, 0.4, 1], @@ -27,15 +30,16 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; ] call CBA_fnc_addSetting; [ - QGVAR(disableEarRinging), "CHECKBOX", + QGVAR(disableEarRinging), + "CHECKBOX", [LSTRING(DisableEarRinging_DisplayName), LSTRING(DisableEarRinging_Description)], _category, - false, - 0 + false ] call CBA_fnc_addSetting; [ - QGVAR(enabledForZeusUnits), "CHECKBOX", + QGVAR(enabledForZeusUnits), + "CHECKBOX", [LSTRING(enabledForZeusUnits_DisplayName), LSTRING(enabledForZeusUnits_Description)], _category, true, @@ -43,7 +47,8 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; ] call CBA_fnc_addSetting; [ - QGVAR(autoAddEarplugsToUnits), "LIST", + QGVAR(autoAddEarplugsToUnits), + "LIST", [LSTRING(autoAddEarplugsToUnits_DisplayName), LSTRING(autoAddEarplugsToUnits_Description)], _category, [[0, 1, 2], [ELSTRING(common,Disabled), LSTRING(heavyWeaponUnits), ELSTRING(common,Enabled)], 1], diff --git a/addons/hearing/stringtable.xml b/addons/hearing/stringtable.xml index 12654786398..5b7c3da0635 100644 --- a/addons/hearing/stringtable.xml +++ b/addons/hearing/stringtable.xml @@ -370,12 +370,17 @@ Metti/Togli tappi 귀마개 토글 Mettre/enlever les bouchons + Ohrstöpsel einsetzen/herausnehmen + Poner/quitar tapones Only units with heavy weapons Uniquement les unités dotées d'armes lourdes Только юниты с тяжелым вооружением + Nur Einheiten mit schweren Waffen 重火器を装備したユニットのみ + Sólo unidades con armas pesadas + Solo a unità con armi pesanti diff --git a/addons/hellfire/functions/fnc_setupVehicle.sqf b/addons/hellfire/functions/fnc_setupVehicle.sqf index 49eefd82746..ce3961d77af 100644 --- a/addons/hellfire/functions/fnc_setupVehicle.sqf +++ b/addons/hellfire/functions/fnc_setupVehicle.sqf @@ -46,7 +46,7 @@ if ((getNumber (configOf _vehicle >> QGVAR(addLaserDesignator))) == 1) then { params ["_vehicle", "_turretPath"]; TRACE_3("checking for laser",_vehicle,_turretPath,_vehicle turretLocal _turretPath); if (!alive _vehicle) exitWith {}; - if (!(_vehicle turretLocal _turretPath)) then {WARNING("Turret not local");}; + if !(_vehicle turretLocal _turretPath) then {WARNING("Turret not local");}; private _hasLaser = false; { // Most addons just use "Laserdesignator_mounted", but this should cover custom ones diff --git a/addons/hitreactions/ACE_Settings.hpp b/addons/hitreactions/ACE_Settings.hpp index 90c1445eba7..78a510a1419 100644 --- a/addons/hitreactions/ACE_Settings.hpp +++ b/addons/hitreactions/ACE_Settings.hpp @@ -1,4 +1,3 @@ - class ACE_Settings { class GVAR(minDamageToTrigger) { movedToSQF = 1; diff --git a/addons/hitreactions/CfgEventHandlers.hpp b/addons/hitreactions/CfgEventHandlers.hpp index eecf08c69da..b737b7bcbfc 100644 --- a/addons/hitreactions/CfgEventHandlers.hpp +++ b/addons/hitreactions/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); @@ -11,6 +10,12 @@ class Extended_PreInit_EventHandlers { }; }; +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; + class Extended_Hit_EventHandlers { class CAManBase { class ADDON { diff --git a/addons/hitreactions/XEH_PREP.hpp b/addons/hitreactions/XEH_PREP.hpp index 7701b8ef19b..eea48dcaa8b 100644 --- a/addons/hitreactions/XEH_PREP.hpp +++ b/addons/hitreactions/XEH_PREP.hpp @@ -1,3 +1,3 @@ - +PREP(checkWeaponDrop); PREP(fallDown); PREP(getRandomAnimation); diff --git a/addons/hitreactions/XEH_postInit.sqf b/addons/hitreactions/XEH_postInit.sqf new file mode 100644 index 00000000000..2750ae11592 --- /dev/null +++ b/addons/hitreactions/XEH_postInit.sqf @@ -0,0 +1,94 @@ +#include "script_component.hpp" + + +[QGVAR(updateFiredEHs), { + TRACE_2("updateFiredEH",GVAR(weaponDropChanceArmHitPlayer),GVAR(weaponDropChanceArmHitAI)); + if (GVAR(weaponDropChanceArmHitPlayer) + GVAR(weaponDropChanceArmHitAI) == 0) then { + if (isNil QGVAR(firedEHs)) exitWith {}; + { + _x call CBA_fnc_removeEventHandler; + } forEach GVAR(firedEHs); + GVAR(firedEHs) = nil; + TRACE_1("removed EHs",GVAR(firedEHs)); + } else { + if (!isNil QGVAR(firedEHs)) exitWith {}; + private _firedEH = { + if (!local (_this select 0)) exitWith {}; + (_this select 6) addEventHandler ["HitPart", { + params ["", "_entity", "", "", "", "", "_selections"]; + [_entity, _selections] call FUNC(checkWeaponDrop); + }]; + }; + GVAR(firedEHs) = []; + { + GVAR(firedEHs) pushBack [_x, [_x, _firedEH] call CBA_fnc_addEventHandler]; + } forEach ["ace_firedNonPlayer", "ace_firedPlayer"]; + TRACE_1("added EHs",GVAR(firedEHs)); + }; +}] call CBA_fnc_addEventHandler; + +[QGVAR(dropWeapon), { + params ["_unit"]; + TRACE_1("dropWeaponEH",_unit); + + if !(_unit getVariable [QGVAR(canDropWeapon), true]) exitWith {}; + + // Prevents AI from losing both primary and pistol when being shot with their pistol out + _unit setVariable [QGVAR(canDropWeapon), false]; + + private _weapon = currentWeapon _unit; + private _thrownWeapon = _unit call EFUNC(common,throwWeapon); + + [{ + params ["_unit"]; + + _unit setVariable [QGVAR(canDropWeapon), nil]; + }, _unit, 0.5] call CBA_fnc_waitAndExecute; + + if (_unit call EFUNC(common,isPlayer)) exitWith {}; // Don't make players pick their own weapons up + + // Wait before executing, as otherwise the unit would pick up the weapon immediately + [{ + [{ + (_this select 0) params ["_unit", "_weapon", "_thrownWeapon", "_timeout"]; + + // If the unit has been deleted or dead, if the weapon doesn't exist anymore or if it's been too long, stop + if (!alive _unit || {!local _unit} || {isNull _thrownWeapon} || {CBA_missionTime >= _timeout}) exitWith { + (_this select 1) call CBA_fnc_removePerFrameHandler; + }; + + // Don't pick up weapon when unit is unconscious + if (lifeState _unit == "INCAPACITATED") exitWith {}; + + // If the unit has no essential weapons, force them to get their weapon, otherwise wait until no enemies are present + if !( + (primaryWeapon _unit == "" && {handgunWeapon _unit == ""}) || + {(_unit distance (_unit findNearestEnemy _unit)) > missionNamespace getVariable [QGVAR(safePickupDistance), DEFAULT_PICKUP_DISTANCE]} + ) exitWith {}; + + // If the unit is too far away, make them move closer + if (_unit distance _thrownWeapon >= 4) exitWith { + private _pos = getPosATL _thrownWeapon; + + _unit setDestination [_pos, "LEADER PLANNED", true]; + _unit doMove _pos; + }; + + (_this select 1) call CBA_fnc_removePerFrameHandler; + + _unit action ["TakeWeapon", _thrownWeapon, _weapon]; + + // Make the unit switch weapons + [{ + (_this select 0) hasWeapon (_this select 1) + }, { + params ["_unit", "_weapon"]; + + if (!alive _unit || {!local _unit} || {primaryWeapon _unit != _weapon}) exitWith {}; + + // Switch to the primary weapon, if it was picked up + _unit selectWeapon _weapon; + }, [_unit, _weapon], 5] call CBA_fnc_waitUntilAndExecute; + }, 5, _this] call CBA_fnc_addPerFrameHandler; + }, [_unit, _weapon, _thrownWeapon, CBA_missionTime + 300], random [2, 3, 4]] call CBA_fnc_waitAndExecute; +}] call CBA_fnc_addEventHandler; diff --git a/addons/hitreactions/XEH_preInit.sqf b/addons/hitreactions/XEH_preInit.sqf index 894773534a4..296279c7ebe 100644 --- a/addons/hitreactions/XEH_preInit.sqf +++ b/addons/hitreactions/XEH_preInit.sqf @@ -8,4 +8,16 @@ PREP_RECOMPILE_END; #include "initSettings.inc.sqf" +GVAR(armSelections) = [ + "leftshoulder", + "rightshoulder", + "lefthand", + "leftforearm", + "leftarmroll", + "rightforearm", + "rightarmroll", + "righthand", + "rightarm" +]; + ADDON = true; diff --git a/addons/hitreactions/functions/fnc_checkWeaponDrop.sqf b/addons/hitreactions/functions/fnc_checkWeaponDrop.sqf new file mode 100644 index 00000000000..ad4e7c4a417 --- /dev/null +++ b/addons/hitreactions/functions/fnc_checkWeaponDrop.sqf @@ -0,0 +1,33 @@ +#include "..\script_component.hpp" +/* + * Author: KJW + * Checks if an entity should drop their weapon based on projectile hit info. + * + * Arguments: + * 0: Entity that was hit + * 1: Selection names that were hit + * + * Return Value: + * None + * + * Example: + * [player, []] call ace_hitreactions_fnc_checkWeaponDrop + * + * Public: No + */ + +params ["_entity", "_selections"]; + +// Make sure entity is a unit +if !(_entity isKindOf "CAManBase") exitWith {}; + +// Don't throw weapon if unit is unconscious or dead +if !(lifeState _entity in ["HEALTHY", "INJURED"]) exitWith {}; + +if (random 1 >= ([GVAR(weaponDropChanceArmHitAI), GVAR(weaponDropChanceArmHitPlayer)] select (_entity call EFUNC(common,isPlayer)))) exitWith {}; + +if (_selections findAny GVAR(armSelections) == -1) exitWith {}; + +if (getNumber ((currentWeapon _entity) call CBA_fnc_getItemConfig >> QGVAR(undroppable)) == 1) exitWith {}; + +[QGVAR(dropWeapon), _entity, _entity] call CBA_fnc_targetEvent; diff --git a/addons/hitreactions/initSettings.inc.sqf b/addons/hitreactions/initSettings.inc.sqf index 2ca4ceaeacd..820f6647670 100644 --- a/addons/hitreactions/initSettings.inc.sqf +++ b/addons/hitreactions/initSettings.inc.sqf @@ -1,9 +1,30 @@ private _category = [LELSTRING(common,categoryUncategorized), QUOTE(COMPONENT_BEAUTIFIED)]; [ - QGVAR(minDamageToTrigger), "SLIDER", + QGVAR(minDamageToTrigger), + "SLIDER", LSTRING(minDamageToTrigger_displayName), _category, [-1, 1, 0.1, 1], 1 ] call CBA_fnc_addSetting; + +[ + QGVAR(weaponDropChanceArmHitPlayer), + "SLIDER", + LSTRING(weaponDropChanceArmHitPlayer_displayName), + _category, + [0, 1, 0, 2, true], + 1, + {[QGVAR(updateFiredEHs)] call CBA_fnc_localEvent} +] call CBA_fnc_addSetting; + +[ + QGVAR(weaponDropChanceArmHitAI), + "SLIDER", + LSTRING(weaponDropChanceArmHitAI_displayName), + _category, + [0, 1, 0, 2, true], + 1, + {[QGVAR(updateFiredEHs)] call CBA_fnc_localEvent} +] call CBA_fnc_addSetting; diff --git a/addons/hitreactions/script_component.hpp b/addons/hitreactions/script_component.hpp index dccbef24f74..dd407a914b3 100644 --- a/addons/hitreactions/script_component.hpp +++ b/addons/hitreactions/script_component.hpp @@ -15,3 +15,5 @@ #endif #include "\z\ace\addons\main\script_macros.hpp" + +#define DEFAULT_PICKUP_DISTANCE 8 diff --git a/addons/hitreactions/stringtable.xml b/addons/hitreactions/stringtable.xml index b07e9be9a03..421f806e32e 100644 --- a/addons/hitreactions/stringtable.xml +++ b/addons/hitreactions/stringtable.xml @@ -6,7 +6,7 @@ Danno Minimo per far cadere 觸發倒下前最低需受到多少傷害 触发倒下前最低需受到多少伤害 - 崩れ落ちるまでの最低損傷値 + 転倒が発生するダメージの最低値 넘어질 때 발생하는 최소 피해량 Mindestschaden, um Sturz auszulösen Minimalne obrażenie, żeby aktywować spadanie @@ -17,5 +17,15 @@ Düşmeyi tetikleyen min hasar Daño mínimo para provocar la caída + + Player Weapon Drop Chance (Arm Hit) + プレイヤーが武器を落とす確率 (腕部への被弾) + Шанс выпадения оружия у игрока (попадание в руку) + + + AI Weapon Drop Chance (Arm Hit) + AIが武器を落とす確率 (腕部への被弾) + Шанс выпадения оружия у ИИ (попадание в руку) + diff --git a/addons/interact_menu/XEH_clientInit.sqf b/addons/interact_menu/XEH_clientInit.sqf index 5c9a2ecae08..d0c6d93940e 100644 --- a/addons/interact_menu/XEH_clientInit.sqf +++ b/addons/interact_menu/XEH_clientInit.sqf @@ -3,16 +3,16 @@ if (!hasInterface) exitWith {}; // Wait until player controls (man,vehicle or uav) a thing before compiling the menu -GVAR(controllableSelfActionsAdded) = [] call CBA_fnc_createNamespace; +GVAR(controllableSelfActionsAdded) = createHashMap; DFUNC(newControllableObject) = { params ["_object"]; private _type = typeOf _object; TRACE_2("newControllableObject",_object,_type); if (_type == "") exitWith {}; - if (!(GVAR(controllableSelfActionsAdded) getVariable [_type, false])) then { + if !(_type in GVAR(controllableSelfActionsAdded)) then { [_type] call FUNC(compileMenuSelfAction); - GVAR(controllableSelfActionsAdded) setVariable [_type, true]; + GVAR(controllableSelfActionsAdded) set [_type, nil]; [{ TRACE_1("sending newControllableObject event",_this); // event for other systems to add self actions, running addActionToClass before this will cause compiling @@ -27,8 +27,7 @@ DFUNC(newControllableObject) = { GVAR(blockDefaultActions) = []; -GVAR(cachedBuildingTypes) = []; -GVAR(cachedBuildingActionPairs) = []; +GVAR(cachedBuildingTypes) = createHashMap; GVAR(ParsedTextCached) = []; diff --git a/addons/interact_menu/XEH_preInit.sqf b/addons/interact_menu/XEH_preInit.sqf index bf3278f0a3b..88269bcc04d 100644 --- a/addons/interact_menu/XEH_preInit.sqf +++ b/addons/interact_menu/XEH_preInit.sqf @@ -12,12 +12,12 @@ if (!hasInterface) exitWith { ADDON = true; }; ["All", "init", LINKFUNC(compileMenu)] call CBA_fnc_addClassEventHandler; -GVAR(ActNamespace) = [] call CBA_fnc_createNamespace; -GVAR(ActSelfNamespace) = [] call CBA_fnc_createNamespace; +GVAR(ActNamespace) = createHashMap; +GVAR(ActSelfNamespace) = createHashMap; // Compile actions for CAManBase now and use for all mans types ["CAManBase"] call FUNC(compileMenu); -GVAR(cacheManActions) = +(GVAR(ActNamespace) getVariable ["CAManBase", []]); // copy +GVAR(cacheManActions) = +(GVAR(ActNamespace) getOrDefault ["CAManBase" call EFUNC(common,getConfigName), []]); // copy // Event handlers for all interact menu controls DFUNC(handleMouseMovement) = { diff --git a/addons/interact_menu/functions/fnc_addActionToClass.sqf b/addons/interact_menu/functions/fnc_addActionToClass.sqf index 93d54c991c2..ccea8c4654d 100644 --- a/addons/interact_menu/functions/fnc_addActionToClass.sqf +++ b/addons/interact_menu/functions/fnc_addActionToClass.sqf @@ -48,6 +48,8 @@ if (param [4, false, [false]]) exitwith { (_parentPath + [_action select 0]) }; +_objectType = _objectType call EFUNC(common,getConfigName); + // Ensure the config menu was compiled first if (_typeNum == 0) then { [_objectType] call FUNC(compileMenu); @@ -56,18 +58,14 @@ if (_typeNum == 0) then { }; private _namespace = [GVAR(ActNamespace), GVAR(ActSelfNamespace)] select _typeNum; -private _actionTrees = _namespace getVariable _objectType; -if (isNil "_actionTrees") then { - _actionTrees = []; - _namespace setVariable [_objectType, _actionTrees]; -}; +private _actionTrees = _namespace getOrDefault [_objectType, [], true]; if (_parentPath isEqualTo ["ACE_MainActions"]) then { [_objectType, _typeNum] call FUNC(addMainAction); }; private _parentNode = [_actionTrees, _parentPath] call FUNC(findActionNode); -if (isNil {_parentNode}) exitWith { +if (isNil "_parentNode") exitWith { ERROR_4("Failed to add action - action (%1) to parent %2 on object %3 [%4]",(_action select 0),_parentPath,_objectType,_typeNum); [] }; diff --git a/addons/interact_menu/functions/fnc_addMainAction.sqf b/addons/interact_menu/functions/fnc_addMainAction.sqf index 83349c21b39..beb02997b9e 100644 --- a/addons/interact_menu/functions/fnc_addMainAction.sqf +++ b/addons/interact_menu/functions/fnc_addMainAction.sqf @@ -19,14 +19,10 @@ params ["_objectType", "_typeNum"]; private _namespace = [GVAR(ActNamespace), GVAR(ActSelfNamespace)] select _typeNum; -private _actionTrees = _namespace getVariable _objectType; -if (isNil "_actionTrees") then { - _actionTrees = []; -}; - +private _actionTrees = _namespace getOrDefault [_objectType, []]; private _parentNode = [_actionTrees, ["ACE_MainActions"]] call FUNC(findActionNode); -if (isNil {_parentNode}) then { +if (isNil "_parentNode") then { TRACE_2("No Main Action on object",_objectType,_typeNum); private _mainAction = ["ACE_MainActions", localize ELSTRING(interaction,MainAction), "", {}, {true}] call FUNC(createAction); [_objectType, _typeNum, [], _mainAction] call EFUNC(interact_menu,addActionToClass); diff --git a/addons/interact_menu/functions/fnc_compileMenu.sqf b/addons/interact_menu/functions/fnc_compileMenu.sqf index 75d759465c2..8c5d3c5fa1a 100644 --- a/addons/interact_menu/functions/fnc_compileMenu.sqf +++ b/addons/interact_menu/functions/fnc_compileMenu.sqf @@ -17,22 +17,22 @@ params ["_target"]; -private _objectType = _target; -if (_target isEqualType objNull) then { - _objectType = typeOf _target; +private _objectType = if (_target isEqualType objNull) then { + typeOf _target +} else { + _target call EFUNC(common,getConfigName) }; -private _namespace = GVAR(ActNamespace); // Exit if the action menu is already compiled for this class -if (!isNil {_namespace getVariable _objectType}) exitWith {}; +if (_objectType in GVAR(ActNamespace)) exitWith {}; if (_objectType isKindOf "VirtualMan_F") exitWith { // these have config: isPlayableLogic = 1 TRACE_1("skipping playable logic",_objectType); - _namespace setVariable [_objectType, []]; + GVAR(ActNamespace) set [_objectType, []]; }; if ((_objectType isKindOf "CAManBase") && {!isNil QGVAR(cacheManActions)}) exitWith { - _namespace setVariable [_objectType, +GVAR(cacheManActions)]; // copy + GVAR(ActNamespace) set [_objectType, +GVAR(cacheManActions)]; // copy }; private _recurseFnc = { @@ -139,7 +139,7 @@ if (_objectType isKindOf "CAManBase") then { }; }; -_namespace setVariable [_objectType, _actions]; +GVAR(ActNamespace) set [_objectType, _actions]; /* [ diff --git a/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf b/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf index ed3a02dd143..8f19dfabbec 100644 --- a/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf +++ b/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf @@ -17,15 +17,14 @@ params ["_target"]; -private _objectType = _target; -if (_target isEqualType objNull) then { - _objectType = typeOf _target; +private _objectType = if (_target isEqualType objNull) then { + typeOf _target +} else { + _target call EFUNC(common,getConfigName) }; -private _namespace = GVAR(ActSelfNamespace); // Exit if the action menu is already compiled for this class -if (!isNil {_namespace getVariable _objectType}) exitWith {}; - +if (_objectType in GVAR(actSelfNamespace)) exitWith {}; private _recurseFnc = { params ["_actionsCfg"]; @@ -131,4 +130,4 @@ private _actions = [ ] ]; -_namespace setVariable [_objectType, _actions]; +GVAR(ActSelfNamespace) set [_objectType, _actions]; diff --git a/addons/interact_menu/functions/fnc_initMenuReorder.sqf b/addons/interact_menu/functions/fnc_initMenuReorder.sqf index 48445b3fa02..d55f2f06ea6 100644 --- a/addons/interact_menu/functions/fnc_initMenuReorder.sqf +++ b/addons/interact_menu/functions/fnc_initMenuReorder.sqf @@ -17,7 +17,7 @@ params ["_class"]; -private _actionTrees = GVAR(ActSelfNamespace) getVariable _class; +private _actionTrees = GVAR(ActSelfNamespace) get _class; private _rootNode = [_actionTrees, ["ACE_SelfActions"]] call FUNC(findActionNode); private _rootActions = _rootNode select 1; private _settingCategoryPrefix = format ["ACE %1 - ", LELSTRING(Interaction,InteractionMenuSelf)]; diff --git a/addons/interact_menu/functions/fnc_keyDown.sqf b/addons/interact_menu/functions/fnc_keyDown.sqf index 5bce40d0a8e..9cb638bcea4 100644 --- a/addons/interact_menu/functions/fnc_keyDown.sqf +++ b/addons/interact_menu/functions/fnc_keyDown.sqf @@ -116,7 +116,7 @@ GVAR(selfMenuOffset) = (AGLtoASL (positionCameraToWorld [0, 0, 2])) vectorDiff ( //Auto expand the first level when self, mounted vehicle or zeus (skips the first animation as there is only one choice) if (GVAR(openedMenuType) == 0) then { if (isNull curatorCamera) then { - if (!(isNull (ACE_controlledUAV select 0))) then { + if !(isNull (ACE_controlledUAV select 0)) then { GVAR(menuDepthPath) = [["ACE_SelfActions", (ACE_controlledUAV select 0)]]; GVAR(expanded) = true; GVAR(expandedTime) = diag_tickTime; diff --git a/addons/interact_menu/functions/fnc_removeActionFromClass.sqf b/addons/interact_menu/functions/fnc_removeActionFromClass.sqf index 6772b61c547..7585616ef6a 100644 --- a/addons/interact_menu/functions/fnc_removeActionFromClass.sqf +++ b/addons/interact_menu/functions/fnc_removeActionFromClass.sqf @@ -19,17 +19,16 @@ params ["_objectType", "_typeNum", "_fullPath"]; +_objectType = _objectType call EFUNC(common,getConfigName); + private _res = _fullPath call FUNC(splitPath); _res params ["_parentPath", "_actionName"]; private _namespace = [GVAR(ActNamespace), GVAR(ActSelfNamespace)] select _typeNum; -private _actionTrees = _namespace getVariable _objectType; -if (isNil "_actionTrees") then { - _actionTrees = []; -}; +private _actionTrees = _namespace getOrDefault [_objectType, []]; private _parentNode = [_actionTrees, _parentPath] call FUNC(findActionNode); -if (isNil {_parentNode}) exitWith {}; +if (isNil "_parentNode") exitWith {}; // Iterate through children of the father private _found = false; diff --git a/addons/interact_menu/functions/fnc_renderActionPoints.sqf b/addons/interact_menu/functions/fnc_renderActionPoints.sqf index 058b5ed8462..62d29be91f4 100644 --- a/addons/interact_menu/functions/fnc_renderActionPoints.sqf +++ b/addons/interact_menu/functions/fnc_renderActionPoints.sqf @@ -61,7 +61,7 @@ private _fnc_renderNearbyActions = { } forEach GVAR(objectActionList); // Iterate through base level class actions and render them if appropiate - private _classActions = GVAR(ActNamespace) getVariable [typeOf _target, []]; + private _classActions = GVAR(ActNamespace) getOrDefault [typeOf _target, []]; { private _action = _x; // Try to render the menu @@ -95,8 +95,7 @@ private _fnc_renderSelfActions = { GVAR(objectActionList) = _target getVariable [QGVAR(selfActions), []]; // Iterate through base level class actions and render them if appropiate - private _namespace = GVAR(ActSelfNamespace); - private _classActions = _namespace getVariable typeOf _target; + private _classActions = GVAR(ActSelfNamespace) get typeOf _target; private _pos = if !(GVAR(useCursorMenu)) then { //Convert to ASL, add offset and then convert back to AGL (handles waves when over water) @@ -124,7 +123,7 @@ GVAR(collectedActionPoints) resize 0; // Render nearby actions, unit self actions or vehicle self actions as appropiate if (GVAR(openedMenuType) == 0) then { if (isNull curatorCamera) then { - if (!(isNull (ACE_controlledUAV select 0))) then { + if !(isNull (ACE_controlledUAV select 0)) then { // Render UAV self actions when in control of UAV AI (ACE_controlledUAV select 0) call _fnc_renderSelfActions; } else { diff --git a/addons/interact_menu/functions/fnc_splitPath.sqf b/addons/interact_menu/functions/fnc_splitPath.sqf index 8c0856d118b..8fabaca5a56 100644 --- a/addons/interact_menu/functions/fnc_splitPath.sqf +++ b/addons/interact_menu/functions/fnc_splitPath.sqf @@ -17,11 +17,13 @@ */ private _parentPath = []; -for [{private _i = 0},{_i < (count _this) - 1},{_i = _i + 1}] do { - _parentPath pushBack (_this select _i); -}; -private _actionName = if (count _this > 0) then { - _this select ((count _this) - 1); + +_parentPath append _this; + +private _count = count _this; + +private _actionName = if (_count > 0) then { + _parentPath deleteAt (_count - 1) // TODO: replace with _parentPath deleteAt [-1] and drop _count in 2.18 } else { "" }; diff --git a/addons/interact_menu/functions/fnc_userActions_getHouseActions.sqf b/addons/interact_menu/functions/fnc_userActions_getHouseActions.sqf index c11da0c2710..8f289508401 100644 --- a/addons/interact_menu/functions/fnc_userActions_getHouseActions.sqf +++ b/addons/interact_menu/functions/fnc_userActions_getHouseActions.sqf @@ -17,8 +17,9 @@ params ["_typeOfBuilding"]; -private _searchIndex = GVAR(cachedBuildingTypes) find _typeOfBuilding; -if (_searchIndex != -1) exitWith {GVAR(cachedBuildingActionPairs) select _searchIndex}; +private _cachedMemPoints = GVAR(cachedBuildingTypes) get _typeOfBuilding; + +if (!isNil "_cachedMemPoints") exitWith {_cachedMemPoints}; private _memPoints = []; private _memPointsActions = []; @@ -148,8 +149,6 @@ private _ladders = getArray (configFile >> "CfgVehicles" >> _typeOfBuilding >> " } forEach _ladders; -GVAR(cachedBuildingTypes) pushBack _typeOfBuilding; -GVAR(cachedBuildingActionPairs) pushBack [_memPoints, _memPointsActions]; - +GVAR(cachedBuildingTypes) set [_typeOfBuilding, [_memPoints, _memPointsActions]]; [_memPoints, _memPointsActions] diff --git a/addons/interact_menu/initSettings.inc.sqf b/addons/interact_menu/initSettings.inc.sqf index 22287189c33..c175bd17c2c 100644 --- a/addons/interact_menu/initSettings.inc.sqf +++ b/addons/interact_menu/initSettings.inc.sqf @@ -46,9 +46,7 @@ private _categoryColors = [_category, format ["| %1 |", LELSTRING(common,subcate QGVAR(textSize), "LIST", LSTRING(textSize), _category, - [[0, 1, 2, 3, 4], ["str_very_small", "str_small", "str_medium", "str_large", "str_very_large"], 2], - 0, - {[QGVAR(textSize), _this] call EFUNC(common,cbaSettings_settingChanged)} + [[0, 1, 2, 3, 4], ["str_very_small", "str_small", "str_medium", "str_large", "str_very_large"], 2] ] call CBA_fnc_addSetting; [ diff --git a/addons/interaction/functions/fnc_addPassengerActions.sqf b/addons/interaction/functions/fnc_addPassengerActions.sqf index a3d8c2eff07..9b8981bfd0d 100644 --- a/addons/interaction/functions/fnc_addPassengerActions.sqf +++ b/addons/interaction/functions/fnc_addPassengerActions.sqf @@ -20,11 +20,7 @@ params ["", "", "_parameters"]; _parameters params ["_unit"]; -private _namespace = EGVAR(interact_menu,ActNamespace); -private _actionTrees = _namespace getVariable typeOf _unit; -if (isNil "_actionTrees") then { - _actionTrees = []; -}; +private _actionTrees = EGVAR(interact_menu,ActNamespace) getOrDefault [typeOf _unit, []]; private _actions = []; diff --git a/addons/interaction/functions/fnc_canPullOutBody.sqf b/addons/interaction/functions/fnc_canPullOutBody.sqf index 167d09ecdb7..2676bfc203c 100644 --- a/addons/interaction/functions/fnc_canPullOutBody.sqf +++ b/addons/interaction/functions/fnc_canPullOutBody.sqf @@ -19,7 +19,7 @@ params ["_body", "_unit"]; // Defer to ACE Medical's unload patient if present -if (["ace_medical"] call EFUNC(common,isModLoaded)) exitWith {false}; +if (GETEGVAR(medical,enabled,false)) exitWith {false}; private _vehicle = objectParent _body; diff --git a/addons/interaction/initSettings.inc.sqf b/addons/interaction/initSettings.inc.sqf index b502ed36b00..2cefb162a76 100644 --- a/addons/interaction/initSettings.inc.sqf +++ b/addons/interaction/initSettings.inc.sqf @@ -20,7 +20,7 @@ false, true, {[QGVAR(disableNegativeRating), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ diff --git a/addons/irlight/stringtable.xml b/addons/irlight/stringtable.xml index 5423a8a8a0f..506e9deb9da 100644 --- a/addons/irlight/stringtable.xml +++ b/addons/irlight/stringtable.xml @@ -11,6 +11,7 @@ DBAL-A3 (vermelho) DBAL-A3 (赤) DBAL-A3 (красный) + DBAL-A3 (rojo) DBAL-A3 (green) @@ -22,6 +23,7 @@ DBAL-A3 (Verde) DBAL-A3 (緑) DBAL-A3 (зеленый) + DBAL-A3 (verde) <t color='#9cf953'>Use: </t>Turn Laser ON/OFF<br>Double click to switch mode @@ -33,6 +35,7 @@ <t color='#9cf953'>Uso: </t>Ligar/Desligar Laser<br>Duplo clique para mudar o modo <t color='#9cf953'>使用方法: </t>レーザーのオン/オフ切り替え<br>ダブルクリックでモード切り替え <t color='#9cf953'>Использование: </t>Включение / выключение лазера <br>Двойной щелчок для переключения режима + <t color='#9cf953'>Uso: </t>Alternar Láser ON/OFF<br>Doble click para cambiar estado Dual Beam Aiming Laser @@ -44,6 +47,7 @@ Laser de Pontaria de Duplo Feixe 複合ビーム照準レーザー Двухлучевой прицельный лазер + Láser de Apuntado de Doble Haz Visible Laser @@ -55,6 +59,7 @@ Laser Visível 可視光レーザー Видимый лазер + Láser Visible IR Laser @@ -66,6 +71,7 @@ Laser IR IRレーザー ИК-лазер + Láser IR IR Illuminator @@ -77,6 +83,7 @@ Iluminador IR IRイルミネーター ИК-осветитель + Iluminador IR IR Laser and Illuminator @@ -88,6 +95,7 @@ Laser e Iluminador IR IRレーザーとイルミネーター ИК-лазер и осветитель + Láser e Iluminador IR Wide Beam @@ -99,6 +107,7 @@ Feixe Largo 広角ビーム Широкий луч + Haz Ancho Medium Beam @@ -110,6 +119,7 @@ Feixe Médio 標準ビーム Средний луч + Haz Medio Narrow Beam @@ -121,6 +131,7 @@ Feixe Estreito 狭角ビーム Узкий луч + Haz Estrecho <t color='#9cf953'>Use: </t>Turn Light ON/OFF<br>Double click to switch mode @@ -132,6 +143,7 @@ <t color='#9cf953'>Uso: </t>Ligar/Desligar Iluminador<br>Duplo clique para mudar o modo <t color='#9cf953'>使用方法: </t>ライトのオン/オフ<br>ダブルクリックでモード切り替え <t color='#9cf953'>Использование: </t>Включение / выключение освещения <br>Двойной щелчок для переключения режима + <t color='#9cf953'>Uso: </t>Alternar Luz ON/OFF<br>Doble click para cambiar estado Special Purpose IR LED Illuminator @@ -143,6 +155,7 @@ Iluminador LED IR de Uso Especial 特殊用途のIR LEDイルミネーター ИК-светодиодный осветитель специального назначения + Iluminador LED IR de Propósito Especial Illuminator / Laser Momentary Switch @@ -154,6 +167,7 @@ Interruptor Momentâneo Iluminador/Laser イルミネーター/レーザーモーメンタリースイッチ Мгновенный переключатель осветителя/лазера + Conmutador Momentáneo Iluminador / Láser diff --git a/addons/killtracker/XEH_postInit.sqf b/addons/killtracker/XEH_postInit.sqf index c5adc266924..35050d1dc30 100644 --- a/addons/killtracker/XEH_postInit.sqf +++ b/addons/killtracker/XEH_postInit.sqf @@ -19,7 +19,8 @@ if ((getText (missionconfigfile >> "CfgDebriefingSections" >> QUOTE(XADDON) >> "variable")) != QXGVAR(outputText)) exitWith { TRACE_1("no mission debriefing config",_this); }; -if (!(["ace_medical"] call EFUNC(common,isModLoaded))) exitWith { + +if !(GETEGVAR(medical,enabled,false)) exitWith { WARNING("No ACE-Medical"); XGVAR(outputText) = "No ACE-Medical"; }; @@ -64,7 +65,7 @@ GVAR(killCount) = 0; private _killInfo = []; if (!isNull _killer) then { - if (!(_killer isKindof "CAManBase")) then { // If killer is a vehicle log the vehicle type + if !(_killer isKindof "CAManBase") then { // If killer is a vehicle log the vehicle type _killInfo pushBack format [LLSTRING(Vehicle), getText ((configOf _killer) >> "displayName")]; }; if (isNull _instigator) then { @@ -73,11 +74,11 @@ GVAR(killCount) = 0; }; }; private _unitIsPlayer = hasInterface && {_unit in [player, ace_player]}; // isPlayer check will fail at this point - private _killerIsPlayer = (!isNull _instigator) && {_unit != _instigator} && {[_instigator] call EFUNC(common,isPlayer)}; - TRACE_2("",_unitIsPlayer,_killerIsPlayer); + private _instigatorIsPlayer = (!isNull _instigator) && {_unit != _instigator} && {[_instigator] call EFUNC(common,isPlayer)}; + TRACE_2("",_unitIsPlayer,_instigatorIsPlayer); // Don't do anything if neither are players - if (!(_unitIsPlayer || _killerIsPlayer)) exitWith {}; + if !(_unitIsPlayer || _instigatorIsPlayer) exitWith {}; // Log firendly fire private _fnc_getSideFromConfig = { @@ -89,7 +90,7 @@ GVAR(killCount) = 0; default {civilian}; }; }; - if ((!isNull _instigator) && {_unit != _instigator} && {_instigator isKindOf "CAManBase"}) then { + if (!isNull _instigator && {_unit != _instigator} && {_instigator isKindOf "CAManBase"}) then { // Because of unconscious group switching/captives it's probably best to just use unit's config side private _unitSide = [_unit] call _fnc_getSideFromConfig; private _killerSide = [_instigator] call _fnc_getSideFromConfig; @@ -110,23 +111,23 @@ GVAR(killCount) = 0; // If unit was player then send event to self if (_unitIsPlayer) then { - private _killerName = "Self?"; - if ((!isNull _killer) && {_unit != _killer}) then { - if (_killerIsPlayer) then { - _killerName = [_killer, true, false] call EFUNC(common,getName); + private _instigatorName = "Self?"; + if ((!isNull _instigator) && {_unit != _instigator}) then { + if (_instigatorIsPlayer) then { + _instigatorName = [_instigator, true, false] call EFUNC(common,getName); } else { - _killerName = _killer getVariable [QGVAR(aiName), ""]; // allow setting a custom AI name (e.g. VIP Target) - if (_killerName == "") then { - _killerName = format ["*AI* - %1", getText ((configOf _killer) >> "displayName")]; + _instigatorName = _instigator getVariable [QGVAR(aiName), ""]; // allow setting a custom AI name (e.g. VIP Target) + if (_instigatorName == "") then { + _instigatorName = format ["*AI* - %1", getText ((configOf _instigator) >> "displayName")]; }; }; }; - TRACE_3("send death event",_unit,_killerName,_killInfo); - [QGVAR(death), [_killerName, _killInfo]] call CBA_fnc_localEvent; + TRACE_3("send death event",_unit,_instigatorName,_killInfo); + [QGVAR(death), [_instigatorName, _killInfo]] call CBA_fnc_localEvent; }; - // If killer was player then send event to killer - if (_killerIsPlayer) then { + // If shooter was player then send event to them (and optionally the whole crew) + if (_instigatorIsPlayer && {_unitIsPlayer || GVAR(trackAI)}) then { private _unitName = ""; if (_unitIsPlayer) then { _unitName = [_unit, true, false] call EFUNC(common,getName); // should be same as profileName @@ -136,9 +137,18 @@ GVAR(killCount) = 0; _unitName = format ["*AI* - %1", getText ((configOf _unit) >> "displayName")]; }; }; - if (_unitIsPlayer || GVAR(trackAI)) then { - TRACE_3("send kill event",_killer,_unitName,_killInfo); - [QGVAR(kill), [_unitName, _killInfo], _killer] call CBA_fnc_targetEvent; + TRACE_3("send kill event",_instigator,_unitName,_killInfo); + [QGVAR(kill), [_unitName, _killInfo], _instigator] call CBA_fnc_targetEvent; + + if (GVAR(showCrewKills) && {!(_killer isKindOf "CAManBase")}) then { + private _crew = [driver _killer, gunner _killer, commander _killer] - [_instigator]; + _crew = _crew select {[_x] call EFUNC(common,isPlayer)}; + _crew = _crew arrayIntersect _crew; + TRACE_1("showCrewKills",_crew); + _killInfo = format [" - [%1, %2", localize "str_a3_rscdisplaygarage_tab_crew", _killInfo select [4]]; + { + [QGVAR(kill), [_unitName, _killInfo], _x] call CBA_fnc_targetEvent; + } forEach _crew; }; }; }] call CBA_fnc_addEventHandler; diff --git a/addons/killtracker/initSettings.inc.sqf b/addons/killtracker/initSettings.inc.sqf index ebe1e55ccb2..9e4775bd7f7 100644 --- a/addons/killtracker/initSettings.inc.sqf +++ b/addons/killtracker/initSettings.inc.sqf @@ -6,3 +6,12 @@ true, 1 ] call CBA_fnc_addSetting; + +[ + QGVAR(showCrewKills), + "CHECKBOX", + [LSTRING(showCrewKills_DisplayName), LSTRING(showCrewKills_Description)], + LSTRING(Category), + false, + 1 +] call CBA_fnc_addSetting; diff --git a/addons/killtracker/stringtable.xml b/addons/killtracker/stringtable.xml index 24c7bcdd56c..916dac68777 100644 --- a/addons/killtracker/stringtable.xml +++ b/addons/killtracker/stringtable.xml @@ -9,11 +9,13 @@ ACE キルトラッカー ACE 킬트래커 ACE Suivi des morts + ACE Abschüsse + ACE Contador de Muertes ACE Killed Events ACE キルイベント - ACE Abgeschossene Ereignisse + ACE Abschusszähler ACE Eventi di Morte ACE Licznik Zabójstw ACE 击杀事件 @@ -103,6 +105,8 @@ プレイヤーに殺害されたAIユニットを追跡 플레이어가 죽인 AI 트래킹 Suivi de l'IA tuée par les joueurs + Zähle vom Spieler getöteten KI-Einheiten + Cuenta las unidades de IA matadas por el jugador Defines if killed AIs will be shown in the kill tracker during mission debriefing. @@ -112,6 +116,14 @@ ミッションデブリーフィングのキルトラッカーに殺害されたAIが表示されるかどうかを定義します。 사후강평 중 살해된 AI가 킬트래킹에 표시되는지 여부를 정의합니다. Définit si les IA tuées seront affichées dans le tracker pendant le débriefing de la mission. + Legt fest, ob getötete KIs während des Endbildschirms der Mission in den Abschüssen angezeigt werden. + Define si las IAs matadas se mostrarán en el contador de muertes en el debiefring de la misión. + + + Show vehicle kills to other crew members + + + Show kills from a vehicle to driver, gunner and commander diff --git a/addons/laser/functions/fnc_seekerFindLaserSpot.sqf b/addons/laser/functions/fnc_seekerFindLaserSpot.sqf index aa3e43d35a7..4ceb15d8148 100644 --- a/addons/laser/functions/fnc_seekerFindLaserSpot.sqf +++ b/addons/laser/functions/fnc_seekerFindLaserSpot.sqf @@ -115,7 +115,7 @@ if (_spots isNotEqualTo []) then { while { count(_spots) != count(_excludes) && _c < (count _spots) } do { scopeName "mainSearch"; { - if (!(_forEachIndex in _excludes)) then { + if !(_forEachIndex in _excludes) then { private _index = _buckets pushBack [_x, [_x]]; _excludes pushBack _forEachIndex; _bucketPos = _x select 0; @@ -124,7 +124,7 @@ if (_spots isNotEqualTo []) then { }; } forEach _spots; { - if (!(_forEachIndex in _excludes)) then { + if !(_forEachIndex in _excludes) then { private _testPos = (_x select 0); if ((_testPos vectorDistanceSqr _bucketPos) <= 100) then { _bucketList pushBack _x; diff --git a/addons/laser/stringtable.xml b/addons/laser/stringtable.xml index f0977c84f79..c6bf7cfc25e 100644 --- a/addons/laser/stringtable.xml +++ b/addons/laser/stringtable.xml @@ -129,6 +129,7 @@ Traqueur laser : activé Rastreador a Laser: Ligado Лазерный точечный трекер: Включен + Rastreador del Puntero Láser: On Laser Spot Tracker: Off @@ -140,6 +141,7 @@ Traqueur laser : désactivé Rastreador a Laser: Desligado Лазерный точечный трекер: выключен + Rastreador del Puntero Láser: Off Draw Laser on Map diff --git a/addons/logistics_uavbattery/functions/fnc_refuelUAV.sqf b/addons/logistics_uavbattery/functions/fnc_refuelUAV.sqf index 8c73052c453..a471e82cbf7 100644 --- a/addons/logistics_uavbattery/functions/fnc_refuelUAV.sqf +++ b/addons/logistics_uavbattery/functions/fnc_refuelUAV.sqf @@ -17,7 +17,7 @@ */ params ["_caller", "_target"]; -if (!(_this call FUNC(canRefuelUAV))) exitWith {}; +if !(_this call FUNC(canRefuelUAV)) exitWith {}; private _onFinish = { (_this select 0) params ["_caller", "_target"]; diff --git a/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf b/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf index 9383089d284..c2785c5fadb 100644 --- a/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf +++ b/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf @@ -25,7 +25,7 @@ _args params ["_magazineClassname", "_lastAmmoCount"]; private _fullMagazineCount = getNumber (configFile >> "CfgMagazines" >> _magazineClassname >> "count"); // Don't show anything if player can't interact -if (!([ACE_player, objNull, ["isNotInside", "isNotSitting", "isNotSwimming"]] call EFUNC(common,canInteractWith))) exitWith {}; +if !([ACE_player, objNull, ["isNotInside", "isNotSitting", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {}; // Count mags private _fullMags = 0; diff --git a/addons/main/script_version.hpp b/addons/main/script_version.hpp index 501b3095dc8..75b323ede34 100644 --- a/addons/main/script_version.hpp +++ b/addons/main/script_version.hpp @@ -1,4 +1,4 @@ #define MAJOR 3 #define MINOR 17 -#define PATCHLVL 0 -#define BUILD 83 +#define PATCHLVL 1 +#define BUILD 86 diff --git a/addons/map/XEH_postInitClient.sqf b/addons/map/XEH_postInitClient.sqf index ea3ce194647..534b37da8bd 100644 --- a/addons/map/XEH_postInitClient.sqf +++ b/addons/map/XEH_postInitClient.sqf @@ -8,7 +8,7 @@ LOG(MSG_INIT); // Calculate the maximum zoom allowed for this map call FUNC(determineZoom); -GVAR(flashlights) = [] call CBA_fnc_createNamespace; +GVAR(flashlights) = createHashMap; ["CBA_settingsInitialized", { if (isMultiplayer && {GVAR(DefaultChannel) != -1}) then { diff --git a/addons/map/functions/fnc_isFlashlight.sqf b/addons/map/functions/fnc_isFlashlight.sqf index e563d741145..ae26b41569d 100644 --- a/addons/map/functions/fnc_isFlashlight.sqf +++ b/addons/map/functions/fnc_isFlashlight.sqf @@ -17,14 +17,12 @@ params [["_class", "", [""]]]; -private _isFlashlight = GVAR(flashlights) getVariable _class; - -if (isNil "_isFlashlight") then { +GVAR(flashlights) getOrDefaultCall [_class, { private _items = ([_class] + (_class call CBA_fnc_switchableAttachments)); private _cfgWeapons = configFile >> "CfgWeapons"; // if this item or any of the switchable items is a flashlight - _isFlashlight = _items findIf { + _items findIf { private _weaponConfig = _cfgWeapons >> _x; [ @@ -34,10 +32,5 @@ if (isNil "_isFlashlight") then { isText (_x >> "ACE_Flashlight_Colour") || {!(getArray (_x >> "ambient") in [[], [0,0,0]]) && {getNumber (_x >> "irLight") == 0}} } != -1 // return - } != -1; - - // cache value - GVAR(flashlights) setVariable [_class, _isFlashlight]; -}; - -_isFlashlight // return + } != -1 // return +}, true] // return diff --git a/addons/map/initSettings.inc.sqf b/addons/map/initSettings.inc.sqf index 8de301eaa16..20665b5a71f 100644 --- a/addons/map/initSettings.inc.sqf +++ b/addons/map/initSettings.inc.sqf @@ -67,14 +67,11 @@ false, true, { - [QGVAR(BFT_Enabled), _this] call EFUNC(common,cbaSettings_settingChanged); - if (GVAR(BFT_Enabled) && {isNil QGVAR(BFT_markers)}) then { GVAR(BFT_markers) = []; [LINKFUNC(blueForceTrackingUpdate), GVAR(BFT_Interval), []] call CBA_fnc_addPerFrameHandler; }; - }, - false + } ] call CBA_fnc_addSetting; [ @@ -94,9 +91,7 @@ [localize LSTRING(BFT_ShowPlayerNames_DisplayName), localize LSTRING(BFT_ShowPlayerNames_Description)], [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize LSTRING(BFT_Module_DisplayName)], false, - true, - {[QGVAR(BFT_ShowPlayerNames), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false + true ] call CBA_fnc_addSetting; [ @@ -105,7 +100,5 @@ [localize LSTRING(BFT_HideAiGroups_DisplayName), localize LSTRING(BFT_HideAiGroups_Description)], [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize LSTRING(BFT_Module_DisplayName)], false, - true, - {[QGVAR(BFT_HideAiGroups), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false + true ] call CBA_fnc_addSetting; diff --git a/addons/map_gestures/XEH_preInit.sqf b/addons/map_gestures/XEH_preInit.sqf index e603e5398a1..42090ac7240 100644 --- a/addons/map_gestures/XEH_preInit.sqf +++ b/addons/map_gestures/XEH_preInit.sqf @@ -8,6 +8,6 @@ PREP_RECOMPILE_END; #include "initSettings.inc.sqf" -GVAR(GroupColorCfgMappingNew) = call CBA_fnc_createNamespace; +GVAR(GroupColorCfgMappingNew) = createHashMap; ADDON = true; diff --git a/addons/map_gestures/functions/fnc_addGroupColorMapping.sqf b/addons/map_gestures/functions/fnc_addGroupColorMapping.sqf index 17a8ffbb045..f533f9df345 100644 --- a/addons/map_gestures/functions/fnc_addGroupColorMapping.sqf +++ b/addons/map_gestures/functions/fnc_addGroupColorMapping.sqf @@ -25,7 +25,7 @@ TRACE_3("params",_group,_leadColor,_unitColor); if (_group isEqualType grpNull) then {_group = groupID _group}; if (_group == "") exitWith {ERROR("Group ID is blank, which is not valid.")}; -if (!([_leadColor] call FUNC(isValidColorArray))) exitWith {ERROR("leadColor is not a valid color array.")}; -if (!([_unitColor] call FUNC(isValidColorArray))) exitWith {ERROR("color is not a valid color array.")}; +if !([_leadColor] call FUNC(isValidColorArray)) exitWith {ERROR("leadColor is not a valid color array.")}; +if !([_unitColor] call FUNC(isValidColorArray)) exitWith {ERROR("color is not a valid color array.")}; -GVAR(GroupColorCfgMappingNew) setVariable [_group, [_leadColor, _unitColor]]; +GVAR(GroupColorCfgMappingNew) set [toLower _group, [_leadColor, _unitColor]]; diff --git a/addons/map_gestures/functions/fnc_drawMapGestures.sqf b/addons/map_gestures/functions/fnc_drawMapGestures.sqf index 2f0c80de3ea..0a69c1924b8 100644 --- a/addons/map_gestures/functions/fnc_drawMapGestures.sqf +++ b/addons/map_gestures/functions/fnc_drawMapGestures.sqf @@ -41,7 +41,7 @@ private _players = [_positions, FUNC(getProximityPlayers), missionNamespace, QGV }; // If color settings for the group exist, then use those, otherwise fall back to the default colors - private _colorMap = GVAR(GroupColorCfgMappingNew) getVariable [(groupID (group _x)), [GVAR(defaultLeadColor), GVAR(defaultColor)]]; + private _colorMap = GVAR(GroupColorCfgMappingNew) getOrDefault [toLower groupID (group _x), [GVAR(defaultLeadColor), GVAR(defaultColor)]]; private _color = _colorMap select (_x != leader _x); TRACE_2("",_colorMap,_color); diff --git a/addons/map_gestures/functions/fnc_isValidColorArray.sqf b/addons/map_gestures/functions/fnc_isValidColorArray.sqf index 7cc9335800b..bcd5fea38cd 100644 --- a/addons/map_gestures/functions/fnc_isValidColorArray.sqf +++ b/addons/map_gestures/functions/fnc_isValidColorArray.sqf @@ -20,7 +20,7 @@ scopeName "main"; params ["_colorArray"]; if (isNil "_colorArray") exitWith {false}; -if (!(_colorArray isEqualType [])) exitWith {false}; +if !(_colorArray isEqualType []) exitWith {false}; if (count _colorArray != 4) exitWith {false}; { diff --git a/addons/map_gestures/functions/fnc_moduleGroupSettings.sqf b/addons/map_gestures/functions/fnc_moduleGroupSettings.sqf index 07be21fc907..36bef695d51 100644 --- a/addons/map_gestures/functions/fnc_moduleGroupSettings.sqf +++ b/addons/map_gestures/functions/fnc_moduleGroupSettings.sqf @@ -24,9 +24,10 @@ if (!_activated) exitWith {}; // Transcode string setting into usable array. Example: "1,1,1,1" -> [1, 1, 1, 1] private _leadColor = call compile ("[" + (_logic getVariable ["leadColor", ""]) + "]"); -if (!([_leadColor] call FUNC(isValidColorArray))) exitWith {ERROR("leadColor is not a valid color array.")}; +if !([_leadColor] call FUNC(isValidColorArray)) exitWith {ERROR("leadColor is not a valid color array.")}; + private _color = call compile ("[" + (_logic getVariable ["color", ""]) + "]"); -if (!([_color] call FUNC(isValidColorArray))) exitWith {ERROR("color is not a valid color array.")}; +if !([_color] call FUNC(isValidColorArray)) exitWith {ERROR("color is not a valid color array.")}; // Add all synchronized groups and reference custom configuration for them { diff --git a/addons/map_gestures/functions/fnc_moduleSettings.sqf b/addons/map_gestures/functions/fnc_moduleSettings.sqf index b637997af75..22913dceef2 100644 --- a/addons/map_gestures/functions/fnc_moduleSettings.sqf +++ b/addons/map_gestures/functions/fnc_moduleSettings.sqf @@ -29,14 +29,14 @@ if (!_activated) exitWith {}; private _defaultLeadColor = _logic getVariable ["defaultLeadColor", ""]; if (_defaultLeadColor != "") then { _defaultLeadColor = call compile ("[" + _defaultLeadColor + "]"); - if (!([_defaultLeadColor] call FUNC(isValidColorArray))) exitWith {ERROR("defaultLeadColor is not a valid color array.")}; + if !([_defaultLeadColor] call FUNC(isValidColorArray)) exitWith {ERROR("defaultLeadColor is not a valid color array.")}; ["CBA_settings_setSettingMission", [QGVAR(defaultLeadColor), _defaultLeadColor, true]] call CBA_fnc_localEvent; }; private _defaultColor = _logic getVariable ["defaultColor", ""]; if (_defaultColor != "") then { _defaultColor = call compile ("[" + _defaultColor + "]"); - if (!([_defaultColor] call FUNC(isValidColorArray))) exitWith {ERROR("defaultColor is not a valid color array.")}; + if !([_defaultColor] call FUNC(isValidColorArray)) exitWith {ERROR("defaultColor is not a valid color array.")}; ["CBA_settings_setSettingMission", [QGVAR(defaultColor), _defaultColor, true]] call CBA_fnc_localEvent; }; diff --git a/addons/maptools/functions/fnc_canUseMapGPS.sqf b/addons/maptools/functions/fnc_canUseMapGPS.sqf index 0bdd0d0ea64..e9ca813288a 100644 --- a/addons/maptools/functions/fnc_canUseMapGPS.sqf +++ b/addons/maptools/functions/fnc_canUseMapGPS.sqf @@ -17,8 +17,7 @@ if (!visibleMap || {!alive ACE_player}) exitWith {false}; -private _gpsOpened = visibleGPS; -private _gpsAvailable = openGPS true; -if (!_gpsOpened) then {openGPS false}; +private _panels = flatten (ACE_player infoPanelComponents "left"); +private _index = _panels find "MinimapDisplayComponent"; -_gpsAvailable // return +_index != -1 && {_panels select (_index + 1)} diff --git a/addons/maptools/stringtable.xml b/addons/maptools/stringtable.xml index bb0782f22be..7e1d0cee97f 100644 --- a/addons/maptools/stringtable.xml +++ b/addons/maptools/stringtable.xml @@ -42,6 +42,8 @@ Tavola di calcolo Графическая доска Planche traçante + Wurfparabel Kartenwerkzeug + Tablero de Trazado The Plotting Board is a map tool designed for use in the directing of short range indirect fires. @@ -50,6 +52,8 @@ La tavola di calcolo è uno strumento utilizzato per dirigere fuoco di artiglieria a corto raggio. Графическая доска - это картографический инструмент, предназначенный для использования при ведении непрямого огня с малой дистанции. Une planche traçante est un outil cartographique conçu pour diriger des tirs indirects à courte distance. + Das Wurfparabel-Kartenwerkzeug ist ein Werkzeug, das für die Steuerung indirekten Feuers auf kurze Distanz entwickelt wurde. + El Tablero de Trazado es una herramienta de mapa utilizada para dirigir fuego indirecto de corto alcance. Map Tools @@ -275,6 +279,8 @@ Canali ammessi su tavola di calcolo Разрешить создание каналов на миллиметровой доске. Canaux autorisés sur la planche traçante + Wurfparabel Kartenwerkzeug erlaubte Kanäle + Permitir Canales de Dibujado de Tablero de Trazado Channels in which plotting board drawing is enabled. @@ -283,6 +289,8 @@ Canali in cui si può disegnare sulla tavola di calcolo. Каналы, в которых включено рисование на миллиметровой доске. Canaux dans lesquels vous pouvez dessiner sur le planche traçante + Kanäle, in denen das Zeichnen mit dem Wurfparabel-Kartenwerkzeug auf der Karte erlaubt ist. + Canales en los que el tablero de trazado está habilitado. Allow Direct Comms Only (Polylines Only) @@ -291,6 +299,8 @@ Comunicazioni Dirette (solo linee) Разрешать только прямую связь (только полилинии) Communications directes uniquement (lignes uniquement) + Nur direkte Kommunikation zulassen (nur Polylinien) + Permitir Sólo Comunicaciones Directas (Sólo Polylineas) Allow Direct/Group Comms (Polylines and Group Markers) @@ -299,6 +309,8 @@ Comunicazioni dirette/gruppo (linee e marker) Разрешить прямую/групповую связь (полилинии и групповые маркеры) Autoriser les communications directes/de groupe (polylignes et marqueurs de groupe) + Direkte/Gruppenkommunikation zulassen (Polylinien und Gruppenmarkierungen) + Permitir Comunicaciones Directas/Grupales (Polylineas y Marcadores de Grupo) Plotting Board @@ -307,6 +319,8 @@ Tavola di calcolo Миллиметровая доска Planche traçante + Wurfparabel Kartenwerkzeug + Tablero de Trazado Plotting Board Acrylic @@ -315,6 +329,8 @@ Acrilico tavola di calcolo Миллиметровая доска акрилловая Planche traçante Acrylique + Wurfparabel Kartenwerkzeug Acryl + Tablero de Trazado Acrílico Plotting Board Ruler @@ -323,6 +339,8 @@ Righello tavola di calcolo Линейка для миллиметровой доски Règle de la planche traçante + Wurfparabel Kartenwerkzeug Lineal + Regla de Tablero de Trazado To Plotting Board @@ -331,6 +349,8 @@ Su tavola di calcolo К миллиметровой доске. Sur la planche traçante + Zum Wurfparabel Kartenwerkzeug + A Tablero de Trazado To Plotting Board Acrylic @@ -339,6 +359,8 @@ Su acrilico tavola di calcolo К миллиметровой доске акрилловой Sur la planche traçante Acrylique + Zum Wurfparabel Kartenwerkzeug Acryl + A Tablero de Trazado Acrílico To Plotting Board Ruler @@ -347,6 +369,8 @@ Su righello tavola di calcolo К линейке миллиметровой доски. Sur la règle de la planche traçante + Zum Wurfparabel Kartenwerkzeug Lineal + A Regla de Tablero de Trazado Wipe all markers off Plotting Board @@ -355,6 +379,8 @@ Cancella tutti i disegni dalla tavola Сотрите все маркеры с миллиметровой доски. Effacer tous les dessins de la planche traçante + Alle Markierungen vom Wurfparabel Kartenwerkzeug entfernen + Borrar todas las marcas del Tablero de Trazado Show Plotting Board @@ -363,6 +389,8 @@ Mostra tavola di calcolo Показать миллиметровую доску. Afficher la planche traçante + Zeige Wurfparabel Kartenwerkzeug + Mostrar Tablero de Trazado Hide Plotting Board @@ -371,6 +399,8 @@ Nascondi tavola di calcolo Скрыть миллиметровую доску. Masquer la planche traçante + Verstecke Wurfparabel Kartenwerkzeug + Ocultar Tablero de Trazado Toggle Plotting Board Ruler @@ -379,6 +409,8 @@ Mostra/Nascondi Righello Переключить линейку миллиметровой доски. Afficher/masquer la règle + Schalte das Lineal des Wurfparabel-Kartenwerkzeuges um + Alternar Regla de Tablero de Trazado Align @@ -429,6 +461,8 @@ Su Вверх Monter + Nach oben + Arriba To Maptool @@ -437,6 +471,8 @@ Su strumento cartografico К инструментам карты Outil cartographique + Zum Kartenwerkzeug + A Herramienta de Mapa diff --git a/addons/markers/functions/fnc_removeTimestamp.sqf b/addons/markers/functions/fnc_removeTimestamp.sqf index 073d9ce6132..5d2c7c3c1f3 100644 --- a/addons/markers/functions/fnc_removeTimestamp.sqf +++ b/addons/markers/functions/fnc_removeTimestamp.sqf @@ -43,8 +43,8 @@ private _index = 1; private _keepCheckingDigits = true; private _validTimestamp = true; while {_keepCheckingDigits} do { - if (!(_string select [_index, 1] in DIGITS)) exitWith { _validTimestamp = false; }; - if (!(_string select [_index+1, 1] in DIGITS)) exitWith { _validTimestamp = false; }; + if !(_string select [_index, 1] in DIGITS) exitWith { _validTimestamp = false; }; + if !(_string select [_index+1, 1] in DIGITS) exitWith { _validTimestamp = false; }; switch (_string select [_index+2, 1]) do { case (":"): { _index = _index + 3; @@ -54,7 +54,7 @@ while {_keepCheckingDigits} do { }; case (" "): { _keepCheckingDigits = false; - if (!(_string select [_index+3, 3] in ["am]", "pm]"])) then {_validTimestamp = false; }; + if !(_string select [_index+3, 3] in ["am]", "pm]"]) then {_validTimestamp = false; }; }; default { _keepCheckingDigits = false; diff --git a/addons/markers/stringtable.xml b/addons/markers/stringtable.xml index a0c0be17f72..2c9dc1531ba 100644 --- a/addons/markers/stringtable.xml +++ b/addons/markers/stringtable.xml @@ -421,6 +421,7 @@ "MS" - 밀리초 (0부터 59까지) "MM" - ミリ秒 (0から59) "ММ" - миллисекунды (от 0 до 59) + "MM" - Milisegundos (de 0 a 59) "mmm" - Milliseconds (from 0 to 999) @@ -431,6 +432,7 @@ "mmm" - 밀리초 (0부터 999까지) "mmm" - ミリ秒 (0から599) "ммм" - миллисекунды (от 0 до 999) + "mmm" - Milisegundos (de 0 a 999) Timestamp Hour Format diff --git a/addons/medical/dev/test_hitpointConfigs.sqf b/addons/medical/dev/test_hitpointConfigs.sqf index 9de5c5e6868..7bdeb189c23 100644 --- a/addons/medical/dev/test_hitpointConfigs.sqf +++ b/addons/medical/dev/test_hitpointConfigs.sqf @@ -21,23 +21,16 @@ INFO_1("Checking uniforms for correct medical hitpoints [%1 units]",count _units private _testPass = true; { private _typeOf = configName _x; - private _hitpoints = (configProperties [_x >> "HitPoints", "isClass _x", true]) apply {configName _x}; - - // _typeOf createUnit [position player, group player, "z = this"]; - // deleteVehicle z; - - private _lastHitpoint = (_hitpoints param [(count _hitpoints) - 1, "#array"]); - if (_lastHitpoint != "ACE_HDBracket") then { - WARNING_2("%1 has bad last hitpoint: %2",_typeOf,_hitpoints); + private _hitpoints = (configProperties [_x >> "HitPoints", "isClass _x", true]) apply {toLowerANSI configName _x}; + private _expectedHitPoints = ["hitleftarm","hitrightarm","hitleftleg","hitrightleg","hithead","hitbody"]; + private _missingHitPoints = _expectedHitPoints select {!(_x in _hitpoints)}; + if (_missingHitPoints isNotEqualTo []) then { + WARNING_3("%1 missing ace hitpoints: %2 - class hitpoints: %3",_typeOf,_missingHitPoints,_hitpoints); _testPass = false; }; - if (((_hitpoints findIf {_x == "HitLeftArm"}) == -1) || {(_hitpoints findIf {_x == "HitRightArm"}) == -1} - || {(_hitpoints findIf {_x == "HitLeftLeg"}) == -1} || {(_hitpoints findIf {_x == "HitRightLeg"}) == -1} - || {(_hitpoints findIf {_x == "HitHead"}) == -1} || {(_hitpoints findIf {_x == "HitBody"}) == -1}) then { - WARNING_2("%1 missing ace hitpoints: %2",_typeOf,_hitpoints); - _testPass = false; - }; + // _typeOf createUnit [position player, group player, "z = this"]; + // deleteVehicle z; } forEach _units; _testPass diff --git a/addons/medical/dev/watchVariable.sqf b/addons/medical/dev/watchVariable.sqf index 05cb094ba8a..a0e064595ab 100644 --- a/addons/medical/dev/watchVariable.sqf +++ b/addons/medical/dev/watchVariable.sqf @@ -10,10 +10,10 @@ GVAR(dev_watchVariableRunning) = true; if (!isNull _display) exitWith {"Paused"}; private _unit = cursorTarget; - if (!(_unit isKindOf "CAManBase")) then {_unit = cursorObject}; - if (!(_unit isKindOf "CAManBase")) then {_unit = ACE_player}; + if !(_unit isKindOf "CAManBase") then {_unit = cursorObject}; + if !(_unit isKindOf "CAManBase") then {_unit = ACE_player}; if ((_unit != ACE_player) && {IS_UNCONSCIOUS(ACE_player)}) then {_unit = ACE_player}; - if (!(_unit isKindOf "CAManBase")) exitWith {"No Unit?"}; + if !(_unit isKindOf "CAManBase") exitWith {"No Unit?"}; private _return = []; diff --git a/addons/medical_ai/stringtable.xml b/addons/medical_ai/stringtable.xml index 5081a09d962..54f0c2714cc 100644 --- a/addons/medical_ai/stringtable.xml +++ b/addons/medical_ai/stringtable.xml @@ -58,6 +58,7 @@ Exigir Itens アイテムを要求 Требуемые предметы + Requerir Objetos AI will only perform medical treatment if they have the necessary items in their inventory. @@ -69,6 +70,7 @@ A IA só irá realizar tratamento médico se tiver os itens necessários em seu inventário. AIのインベントリに必要なアイテムがある場合にのみ治療を実行します。 Искусственный интеллект будет оказывать медицинскую помощь только в том случае, если в его инвентаре есть необходимые предметы. + La IA sólo realizará el tratamiento médico en caso de que dispongan de los objetos necesarios en su inventario. Auto Convert Items for AI @@ -80,6 +82,7 @@ Conversão automática de itens para IA AIのアイテムを自動変換 Автоматическое преобразование элементов для ИИ + Auto Convertir Objetos para la IA diff --git a/addons/medical_blood/XEH_postInit.sqf b/addons/medical_blood/XEH_postInit.sqf index daf45955843..b08921b441e 100644 --- a/addons/medical_blood/XEH_postInit.sqf +++ b/addons/medical_blood/XEH_postInit.sqf @@ -1,7 +1,5 @@ #include "script_component.hpp" -GVAR(useAceMedical) = ["ace_medical"] call EFUNC(common,isModLoaded); - // To support public API regardless of component settings [QGVAR(spurt), LINKFUNC(spurt)] call CBA_fnc_addEventHandler; diff --git a/addons/medical_blood/XEH_preInit.sqf b/addons/medical_blood/XEH_preInit.sqf index 852b4dbe73e..93da039be54 100644 --- a/addons/medical_blood/XEH_preInit.sqf +++ b/addons/medical_blood/XEH_preInit.sqf @@ -8,22 +8,8 @@ PREP_RECOMPILE_END; #include "initSettings.inc.sqf" -// Damage types which do not cause blood spurts -GVAR(noBloodDamageTypes) = createHashMapFromArray (call (uiNamespace getVariable QGVAR(noBloodDamageTypes))); - // blood object model namespace -GVAR(models) = [] call CBA_fnc_createNamespace; - -{ - _x params ["_name", "_model"]; - - // createSimpleObject expects a path without the leading slash - if ((_model select [0,1]) isEqualTo "\") then { - _model = _model select [1]; - }; - - GVAR(models) setVariable [_name, _model]; -} forEach [ +GVAR(models) = createHashMapFromArray [ // higher number means bigger model ["blooddrop_1", QPATHTOF(data\ace_drop_1.p3d)], ["blooddrop_2", QPATHTOF(data\ace_drop_2.p3d)], diff --git a/addons/medical_blood/XEH_preStart.sqf b/addons/medical_blood/XEH_preStart.sqf index d051879f3c7..e2683ff5867 100644 --- a/addons/medical_blood/XEH_preStart.sqf +++ b/addons/medical_blood/XEH_preStart.sqf @@ -4,7 +4,4 @@ // Damage types which do not cause blood spurts private _noBloodDamageTypes = "getNumber (_x >> 'noBlood') == 1" configClasses (configFile >> "ACE_Medical_Injuries" >> "damageTypes"); -uiNamespace setVariable [ - QGVAR(noBloodDamageTypes), - compileFinal str (_noBloodDamageTypes apply {[configName _x, nil]}) -]; +uiNamespace setVariable [QGVAR(noBloodDamageTypes), compileFinal (_noBloodDamageTypes createHashMapFromArray [])]; diff --git a/addons/medical_blood/functions/fnc_createBlood.sqf b/addons/medical_blood/functions/fnc_createBlood.sqf index e6740ef459e..fbff6cc3c66 100644 --- a/addons/medical_blood/functions/fnc_createBlood.sqf +++ b/addons/medical_blood/functions/fnc_createBlood.sqf @@ -21,7 +21,7 @@ params ["_type", "_position", "_source"]; TRACE_3("Creating blood",_type,_position,_source); -private _model = GVAR(models) getVariable _type; +private _model = GVAR(models) get _type; private _bloodDrop = createSimpleObject [_model, [0, 0, 0]]; _bloodDrop setDir random 360; diff --git a/addons/medical_blood/functions/fnc_handleWoundReceived.sqf b/addons/medical_blood/functions/fnc_handleWoundReceived.sqf index 8b46233af26..53d5d2361bf 100644 --- a/addons/medical_blood/functions/fnc_handleWoundReceived.sqf +++ b/addons/medical_blood/functions/fnc_handleWoundReceived.sqf @@ -22,7 +22,7 @@ params ["_unit", "_allDamages", "_shooter", "_damageType"]; (_allDamages select 0) params ["_damage"]; // Don't bleed if damage type does not cause bleeding -if (_damageType in GVAR(noBloodDamageTypes)) exitWith {}; +if (_damageType in (uiNamespace getVariable QGVAR(noBloodDamageTypes))) exitWith {}; // Don't bleed when players only and a non-player unit is wounded if (GVAR(enabledFor) == BLOOD_ONLY_PLAYERS && {!isPlayer _unit && {_unit != ACE_player}}) exitWith {}; diff --git a/addons/medical_blood/functions/fnc_isBleeding.sqf b/addons/medical_blood/functions/fnc_isBleeding.sqf index 2d57dcf73b3..a21a50913ae 100644 --- a/addons/medical_blood/functions/fnc_isBleeding.sqf +++ b/addons/medical_blood/functions/fnc_isBleeding.sqf @@ -17,7 +17,7 @@ params ["_unit"]; -if (GVAR(useAceMedical)) exitWith { +if (GETEGVAR(medical,enabled,false)) exitWith { IS_BLEEDING(_unit); }; diff --git a/addons/medical_blood/functions/fnc_onBleeding.sqf b/addons/medical_blood/functions/fnc_onBleeding.sqf index 02ddd93fd08..4963aaa21d4 100644 --- a/addons/medical_blood/functions/fnc_onBleeding.sqf +++ b/addons/medical_blood/functions/fnc_onBleeding.sqf @@ -25,7 +25,7 @@ if !(_unit call FUNC(isBleeding)) exitWith {}; if (!isNull objectParent _unit && {!(vehicle _unit isKindOf "StaticWeapon")}) exitWith {}; if (CBA_missionTime > (_unit getVariable [QGVAR(nextTime), -10])) then { - private _bloodLoss = (if (GVAR(useAceMedical)) then {GET_BLOOD_LOSS(_unit) * 2.5} else {getDammage _unit * 2}) min 6; + private _bloodLoss = ([damage _unit * 2, GET_BLOOD_LOSS(_unit) * 2.5] select GETEGVAR(medical,enabled,false)) min 6; _unit setVariable [QGVAR(nextTime), CBA_missionTime + 8 + random 2 - _bloodLoss]; TRACE_2("Creating blood drop for bleeding unit",_unit,_bloodLoss); diff --git a/addons/medical_damage/stringtable.xml b/addons/medical_damage/stringtable.xml index 626826117db..3f274dd37a4 100644 --- a/addons/medical_damage/stringtable.xml +++ b/addons/medical_damage/stringtable.xml @@ -803,6 +803,7 @@ Schmerz-Bewusstlosigkeit-Grenze 고통 기절 한계점 Limite de Dor Antes da Inconsciência + Umbral de Dolor de Inconsciencia Sets the threshold for severe pain, above which a person can fall unconscious upon receiving damage. @@ -814,6 +815,7 @@ Legt die Grenze für starke Schmerzen fest, oberhalb derer eine Person bei erlittenem Schaden bewusstlos werden kann. 사람이 데미지를 입었을 때 의식불명 상태가 될 수 있는 심각한 고통의 한계점을 설정합니다. Define o limite para dor severa, acima do qual uma pessoa pode ficar inconsciente ao receber dano. + Establece el umbral para dolor severo, sobre el cual una persona puede caer inconsciente una vez reciba daño. Fatal Injury Death Chance diff --git a/addons/medical_engine/XEH_postInit.sqf b/addons/medical_engine/XEH_postInit.sqf index 2514c62254f..ed660914984 100644 --- a/addons/medical_engine/XEH_postInit.sqf +++ b/addons/medical_engine/XEH_postInit.sqf @@ -6,27 +6,23 @@ [_new] call FUNC(updateDamageEffects); // Run on new controlled unit to update QGVAR(aimFracture) }, true] call CBA_fnc_addPlayerEventHandler; - ["CAManBase", "init", { params ["_unit"]; - // Check if last hit point is our dummy. - private _allHitPoints = getAllHitPointsDamage _unit param [0, []]; - reverse _allHitPoints; - while {(_allHitPoints param [0, ""]) select [0,1] == "#"} do { WARNING_1("Ignoring Reflector hitpoint %1",_allHitPoints deleteAt 0); }; + if (unitIsUAV _unit) exitWith {TRACE_1("ignore UAV AI",typeOf _unit);}; + if (getNumber (configOf _unit >> "isPlayableLogic") == 1) exitWith {TRACE_1("ignore logic unit",typeOf _unit);}; - if (_allHitPoints param [0, ""] != "ACE_HDBracket") then { - if (unitIsUAV _unit) exitWith {TRACE_1("ignore UAV AI",typeOf _unit);}; - if (getNumber ((configOf _unit) >> "isPlayableLogic") == 1) exitWith {TRACE_1("ignore logic unit",typeOf _unit)}; + private _allHitPoints = getAllHitPointsDamage _unit param [0, []]; + if ((GVAR(customHitpoints) arrayIntersect _allHitPoints) isNotEqualTo GVAR(customHitpoints)) exitWith { ERROR_1("Bad hitpoints for unit type ""%1""",typeOf _unit); - } else { - // Calling this function inside curly brackets allows the usage of - // "exitWith", which would be broken with "HandleDamage" otherwise. - _unit setVariable [ - QEGVAR(medical,HandleDamageEHID), - _unit addEventHandler ["HandleDamage", {_this call FUNC(handleDamage)}] - ]; }; + + // Calling this function inside curly brackets allows the usage of + // "exitWith", which would be broken with "HandleDamage" otherwise. + _unit setVariable [ + QEGVAR(medical,HandleDamageEHID), + _unit addEventHandler ["HandleDamage", {_this call FUNC(handleDamage)}] + ]; }, nil, [IGNORE_BASE_UAVPILOTS], true] call CBA_fnc_addClassEventHandler; #ifdef DEBUG_MODE_FULL @@ -88,7 +84,7 @@ }; }] call CBA_fnc_addEventHandler; -["CAManBase", "deleted", { +["CAManBase", "Deleted", { params ["_unit"]; TRACE_3("unit deleted",_unit,objectParent _unit,local _unit); if ((!isNull objectParent _unit) && {local objectParent _unit}) then { diff --git a/addons/medical_engine/XEH_preInit.sqf b/addons/medical_engine/XEH_preInit.sqf index b0304f167f1..035b9f4b052 100644 --- a/addons/medical_engine/XEH_preInit.sqf +++ b/addons/medical_engine/XEH_preInit.sqf @@ -40,11 +40,14 @@ GVAR(armorCache) = createHashMap; // with handle damage not returning full results. GVAR(fixedStatics) = []; -GVAR(animations) = [] call CBA_fnc_createNamespace; -GVAR(animations) setVariable [QUNCON_ANIM(faceUp), [QUNCON_ANIM(2),QUNCON_ANIM(2_1),QUNCON_ANIM(7_1),QUNCON_ANIM(8_1),QUNCON_ANIM(5_1),QUNCON_ANIM(6_1)]]; -GVAR(animations) setVariable [QUNCON_ANIM(faceDown), [QUNCON_ANIM(1),QUNCON_ANIM(3),QUNCON_ANIM(4),"unconscious",QUNCON_ANIM(9),QUNCON_ANIM(3_1),QUNCON_ANIM(4_1)]]; -GVAR(animations) setVariable [QUNCON_ANIM(faceLeft), [QUNCON_ANIM(7),QUNCON_ANIM(8),QUNCON_ANIM(1_1),QUNCON_ANIM(7_1),QUNCON_ANIM(8_1)]]; -GVAR(animations) setVariable [QUNCON_ANIM(faceRight), [QUNCON_ANIM(5),QUNCON_ANIM(6),QUNCON_ANIM(10),QUNCON_ANIM(5_1),QUNCON_ANIM(6_1)]]; +GVAR(animations) = createHashMapFromArray [ + [toLowerANSI QUNCON_ANIM(faceUp), [QUNCON_ANIM(2),QUNCON_ANIM(2_1),QUNCON_ANIM(7_1),QUNCON_ANIM(8_1),QUNCON_ANIM(5_1),QUNCON_ANIM(6_1)]], + [toLowerANSI QUNCON_ANIM(faceDown), [QUNCON_ANIM(1),QUNCON_ANIM(3),QUNCON_ANIM(4),"unconscious",QUNCON_ANIM(9),QUNCON_ANIM(3_1),QUNCON_ANIM(4_1)]], + [toLowerANSI QUNCON_ANIM(faceLeft), [QUNCON_ANIM(7),QUNCON_ANIM(8),QUNCON_ANIM(1_1),QUNCON_ANIM(7_1),QUNCON_ANIM(8_1)]], + [toLowerANSI QUNCON_ANIM(faceRight), [QUNCON_ANIM(5),QUNCON_ANIM(6),QUNCON_ANIM(10),QUNCON_ANIM(5_1),QUNCON_ANIM(6_1)]] +]; + +GVAR(customHitpoints) = ["hitleftarm", "hitrightarm", "hitleftleg", "hitrightleg"]; private _fnc_fixStatic = { params ["_vehicle"]; @@ -84,4 +87,7 @@ addMissionEventHandler ["Loaded", { [] call FUNC(disableThirdParty); +// Future-proofing +EGVAR(medical,enabled) = true; // TODO: remove when medical enable setting is implemented + ADDON = true; diff --git a/addons/medical_engine/functions/fnc_applyAnimAfterRagdoll.sqf b/addons/medical_engine/functions/fnc_applyAnimAfterRagdoll.sqf index db522b2bf72..726a606344a 100644 --- a/addons/medical_engine/functions/fnc_applyAnimAfterRagdoll.sqf +++ b/addons/medical_engine/functions/fnc_applyAnimAfterRagdoll.sqf @@ -23,7 +23,7 @@ if !(IS_UNCONSCIOUS(_unit) && // do not run if unit is conscio {alive _unit && // do not run if unit is dead {isNull objectParent _unit}}) exitWith {}; // do not run if unit in any vehicle -private _animsArray = GVAR(animations) getVariable [_anim, [""]]; +private _animsArray = GVAR(animations) getOrDefault [toLowerANSI _anim, [""]]; private _random = (toArray (hashValue _unit)) param [0, 0]; private _index = _random % (count _animsArray); private _unconsciousAnimation = _animsArray select _index; diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index a60816222fb..168203366c2 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -1,9 +1,9 @@ #include "..\script_component.hpp" /* - * Author: commy2, kymckay + * Author: commy2, kymckay, LinkIsGrim * HandleDamage EH where wound events are raised based on incoming damage. * Be aware that for each source of damage, the EH can fire multiple times (once for each hitpoint). - * We store these incoming damages and compare them on our final hitpoint: "ace_hdbracket". + * We store these incoming damages and compare them on last iteration of the event (_context == 2). * * Arguments: * Handle damage EH @@ -13,15 +13,16 @@ * * Public: No */ -params ["_unit", "_selection", "_damage", "_shooter", "_ammo", "_hitPointIndex", "_instigator", "_hitpoint"]; +params ["_unit", "_selection", "_damage", "_shooter", "_ammo", "_hitPointIndex", "_instigator", "_hitpoint", "_directHit", "_context"]; // HD sometimes triggers for remote units - ignore. if !(local _unit) exitWith {nil}; // Get missing meta info private _oldDamage = 0; +private _structuralDamage = _context == 0; -if (_hitPoint isEqualTo "") then { +if (_structuralDamage) then { _hitPoint = "#structural"; _oldDamage = damage _unit; } else { @@ -33,26 +34,29 @@ if !(isDamageAllowed _unit && {_unit getVariable [QEGVAR(medical,allowDamage), t private _newDamage = _damage - _oldDamage; -// Happens occasionally for vehiclehit events (see line 80 onwards) -// Just exit early to save some frametime -if (_newDamage == 0 && {_hitpoint isNotEqualTo "ace_hdbracket"}) exitWith {_oldDamage}; +// _newDamage == 0 happens occasionally for vehiclehit events (see line 80 onwards), just exit early to save some frametime +// context 4 is engine "bleeding". For us, it's just a duplicate event for #structural which we can ignore without any issues +if (_context != 2 && {_context == 4 || _newDamage == 0}) exitWith { + TRACE_4("Skipping engine bleeding or zero damage",_ammo,_newDamage,_directHit,_context); + _oldDamage +}; // Get scaled armor value of hitpoint and calculate damage before armor // We scale using passThrough to handle explosive-resistant armor properly (#9063) // We need realDamage to determine which limb was hit correctly [_unit, _hitpoint] call FUNC(getHitpointArmor) params ["_armor", "_armorScaled"]; private _realDamage = _newDamage * _armor; -if (_hitPoint isNotEqualTo "#structural") then { +if (!_structuralDamage) then { private _armorCoef = _armor/_armorScaled; private _damageCoef = linearConversion [0, 1, GVAR(damagePassThroughEffect), 1, _armorCoef]; _newDamage = _newDamage * _damageCoef; }; -TRACE_4("Received hit",_hitpoint,_ammo,_newDamage,_realDamage); +TRACE_6("Received hit",_hitpoint,_ammo,_newDamage,_realDamage,_directHit,_context); -// Drowning doesn't fire the EH for each hitpoint so the "ace_hdbracket" code never runs +// Drowning doesn't fire the EH for each hitpoint and never triggers _context=2 (LastHitPoint) // Damage occurs in consistent increments if ( - _hitPoint isEqualTo "#structural" && + _structuralDamage && {getOxygenRemaining _unit <= 0.5} && {_damage isEqualTo (_oldDamage + 0.005)} ) exitWith { @@ -64,14 +68,14 @@ if ( // Faster than (vehicle _unit), also handles dead units private _vehicle = objectParent _unit; +private _inVehicle = !isNull _vehicle; +private _environmentDamage = _ammo == ""; -// Crashing a vehicle doesn't fire the EH for each hitpoint so the "ace_hdbracket" code never runs +// Crashing a vehicle doesn't fire the EH for each hitpoint and never triggers _context=2 (LastHitPoint) // It does fire the EH multiple times, but this seems to scale with the intensity of the crash if ( EGVAR(medical,enableVehicleCrashes) && - {_hitPoint isEqualTo "#structural"} && - {_ammo isEqualTo ""} && - {!isNull _vehicle} && + {_environmentDamage && _inVehicle && _structuralDamage} && {vectorMagnitude (velocity _vehicle) > 5} // todo: no way to detect if stationary and another vehicle hits you ) exitWith { @@ -83,11 +87,8 @@ if ( // Receiving explosive damage inside a vehicle doesn't trigger for each hitpoint // This is the case for mines, explosives, artillery, and catasthrophic vehicle explosions -// Triggers twice, but that doesn't matter as damage is low if ( - _hitPoint isEqualTo "#structural" && - {!isNull _vehicle} && - {_ammo isNotEqualTo ""} && + (!_environmentDamage && _inVehicle && _structuralDamage) && { private _ammoCfg = configFile >> "CfgAmmo" >> _ammo; GET_NUMBER(_ammoCfg >> "explosive",0) > 0 || @@ -104,9 +105,13 @@ if ( 0 }; -// This hitpoint is set to trigger last, evaluate all the stored damage values -// to determine where wounds are applied -if (_hitPoint isEqualTo "ace_hdbracket") exitWith { +// Damages are stored for last iteration of the HandleDamage event (_context == 2) +_unit setVariable [format [QGVAR($%1), _hitPoint], [_realDamage, _newDamage]]; + +// Ref https://community.bistudio.com/wiki/Arma_3:_Event_Handlers#HandleDamage +// Context 2 means this is the last iteration of HandleDamage, so figure out which hitpoint took the most real damage and send wound event +// Don't exit, as the last iteration can be one of the hitpoints that we need to keep _oldDamage for +if (_context == 2) then { _unit setVariable [QEGVAR(medical,lastDamageSource), _shooter]; _unit setVariable [QEGVAR(medical,lastInstigator), _instigator]; @@ -157,7 +162,7 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { // Environmental damage sources all have empty ammo string // No explicit source given, we infer from differences between them - if (_ammo isEqualTo "") then { + if (_environmentDamage) then { // Any collision with terrain/vehicle/object has a shooter // Check this first because burning can happen at any velocity if !(isNull _shooter) then { @@ -199,16 +204,9 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { QGVAR($HitLeftArm),QGVAR($HitRightArm),QGVAR($HitLeftLeg),QGVAR($HitRightLeg), QGVAR($#structural) ]; - - 0 }; -// Damages are stored for "ace_hdbracket" event triggered last -_unit setVariable [format [QGVAR($%1), _hitPoint], [_realDamage, _newDamage]]; - // Engine damage to these hitpoints controls blood visuals, limping, weapon sway // Handled in fnc_damageBodyPart, persist here -if (_hitPoint in ["hithead", "hitbody", "hithands", "hitlegs"]) exitWith {_oldDamage}; - -// We store our own damage values so engine damage is unnecessary -0 +// For all other hitpoints, we store our own damage values, so engine damage is unnecessary +[0, _oldDamage] select (_hitPoint in ["hithead", "hitbody", "hithands", "hitlegs"]) diff --git a/addons/medical_engine/script_macros_config.hpp b/addons/medical_engine/script_macros_config.hpp index 611a8ad3569..4c276d7b186 100644 --- a/addons/medical_engine/script_macros_config.hpp +++ b/addons/medical_engine/script_macros_config.hpp @@ -20,13 +20,6 @@ // This used to take the armor values as parameters; it now inherits the values // of `armor`, `passThrough` and `explosionShielding` from the existing hitpoints // for vanilla consistency. -// "ACE_HDBracket" is a special hit point. It is designed in a way where the -// "HandleDamage" event handler will compute it at the end of every damage -// calculation step. This way we can figure out which hit point took the most -// damage from one projectile and should be receiving the ACE medical wound. -// the hit point itself should not take any damage -// It is important that the "ACE_HDBracket" hit point is the last in the config, -// but has the same selection as the first one (always "HitHead" for soldiers). #define ADD_ACE_HITPOINTS\ class HitLeftArm: HitHands {\ material = -1;\ @@ -47,15 +40,4 @@ };\ class HitRightLeg: HitLeftLeg {\ name = "leg_r";\ - };\ - class ACE_HDBracket {\ - armor = 1;\ - material = -1;\ - name = "head";\ - passThrough = 0;\ - radius = 1;\ - explosionShielding = 1;\ - visual = "";\ - minimalHit = 0;\ - depends = "HitHead";\ } diff --git a/addons/medical_engine/stringtable.xml b/addons/medical_engine/stringtable.xml index 1765df0d39d..cf197132029 100644 --- a/addons/medical_engine/stringtable.xml +++ b/addons/medical_engine/stringtable.xml @@ -37,6 +37,7 @@ Efeito de Penetração de Blindagem 装甲貫通効果 Эффект сквозного прохождения брони + Efecto de Atravesar Armadura Controls effect of armor 'passThrough' on final damage. Makes high armor values, like ones used in GL rigs, less effective.\nUse 0% for pre 3.16.0 armor behavior.\nOnly touch this if you know what you're doing! @@ -48,6 +49,7 @@ Controla o efeito de penetração (passThrough) da blindagem no dano final. Torna valores de blindagem altos, como os usados em coletes GL, menos eficazes.\nUse 0% para o comportamento de blindagem anterior à versão 3.16.0.\nSó mexa nisso se souber o que está fazendo! ボディアーマーの'passThrough'値が最終的な身体ダメージに与える影響を調整します。擲弾兵リグで使用されるような高い装甲値では効果が低くなります。\n3.16.0以前の挙動にするには0%にしてください。\nこれが何かわからない場合は変更しないことをお勧めします。 Контролирует эффект `passThrough` при нанесении конечного урона. Делает высокие значения брони, подобные тем, которые используются в GL rigs, менее эффективными.\nИспользуйте 0% для поведения брони до версии 3.16.0.n\Прикасайтесь к этому, только если знаете, что делаете! + Controla el efecto de 'passThrough' de armadura en el daño final. Hace que los valores altos de armadura, como los usados en los chalecos GL, sean menos efectivos.\nUsar 0% para comportamiento de armadura en versiones anteriores a 3.16.0.\nSólo modifica esto si sabes lo que estás haciendo! diff --git a/addons/medical_gui/XEH_postInit.sqf b/addons/medical_gui/XEH_postInit.sqf index 5ff49d21676..2b7fb8ce523 100644 --- a/addons/medical_gui/XEH_postInit.sqf +++ b/addons/medical_gui/XEH_postInit.sqf @@ -21,7 +21,7 @@ GVAR(selfInteractionActions) = []; [QEGVAR(interact_menu,newControllableObject), { params ["_type"]; // string of the object's classname - if (!(_type isKindOf "CAManBase")) exitWith {}; + if !(_type isKindOf "CAManBase") exitWith {}; { _x set [0, _type]; _x call EFUNC(interact_menu,addActionToClass); diff --git a/addons/medical_gui/stringtable.xml b/addons/medical_gui/stringtable.xml index 71388bfb41b..b88d9cbbf16 100644 --- a/addons/medical_gui/stringtable.xml +++ b/addons/medical_gui/stringtable.xml @@ -293,6 +293,7 @@ Medizinische Info anzeigen 医療情報一時表示 Просмотр медицинской информации + Ojear Información Médica Medical Peek Duration @@ -303,6 +304,7 @@ Dauer zum Anzeigen der medizinischen Info 医療情報一時表示の表示時間 Продолжительность медицинского осмотра + Duración del Ojear Información Médica How long the medical info peek remains open after releasing the key. @@ -313,6 +315,7 @@ Durata di visualizzazione delle Info Mediche dopo aver rilasciato il tasto. 医療情報一時表示キーを放してからどれだけ長く情報表示するか。 Как долго окно просмотра медицинской информации остается открытым после отпускания клавиши. + Durante cuánto tiempo la información médica ojeada permanece abierta una ves se deje de apretar la tecla. Load Patient @@ -566,6 +569,7 @@ Passa a te stesso 自分に切り替え Переключиться на себя + Cambiar a uno mismo Switch to target @@ -576,6 +580,7 @@ Passa al paziente 相手に切り替え Переключиться на цель + Cambiar al objetivo Head @@ -1002,6 +1007,7 @@ Nessuna emorragia 出血はしていない Кровотечения нет + Sin sangrado Slow bleeding @@ -1012,6 +1018,7 @@ Debole emorragia 出血は穏やか Медленное кровотечение + Sangrado lento Moderate bleeding @@ -1022,6 +1029,7 @@ Emorraggia moderata 出血はそこそこ速い Умеренное кровотечение + Sangrado moderado Severe bleeding @@ -1032,6 +1040,7 @@ Forte emorragia 出血は激しい Сильное кровотечение + Sangrado severo Massive bleeding @@ -1042,6 +1051,7 @@ Gravissima emorragia 出血は酷く多い Огромное кровотечение + Sangrado masivo in Pain @@ -1116,6 +1126,7 @@ Nessuna perdita di sangue 失血なし Потери крови нет + Sin pérdida de sangre @@ -1400,6 +1411,7 @@ Zeige medizinische Info beim Treffer an 被弾時の医療情報一時表示 Показать медицинскую информацию о попадании + Ojear Información Médica en Impacto Temporarily show medical info when injured. @@ -1411,6 +1423,7 @@ Bei Verletzungen vorübergehend medizinische Info anzeigen. 被弾時に医療情報を一時的に表示します。 Временно показывать медицинскую информацию при травме. + Temporalmente muestra la información médica cuando es herido. Medical Peek Duration on Hit @@ -1422,6 +1435,7 @@ Dauer der Anzeige bei einem Treffer. 被弾時の医療情報一時表示の表示時間 Продолжительность медицинского осмотра при попадании + Duración de Ojear la Información Médica cuando hay Impacto How long the medical info peek remains open after being injured. @@ -1433,6 +1447,7 @@ Wie lange die medizinische Info nach einer Verletzung angezeigt wird. 被弾時の医療情報の一時表示をどれだけ長く表示するか。 Как долго окно просмотра медицинской информации остается открытым после получения травмы. + Durante cuánto tiempo la información médica ojeada permanece abierta una tras haber sido herido. Show Trauma Sustained @@ -1445,6 +1460,7 @@ 显示遭受的创伤 Afficher les traumatismes subis Показать полученную травму + Mostrar Trauma Sostenido Show trauma sustained in the injury list. @@ -1457,6 +1473,7 @@ 在伤情表上显示创伤 Afficher les traumatismes subis dans la liste des blessures. Показать полученную травму в списке травм. + Mostrar trauma sostenido en la lista de heridas Body Part Outline Color @@ -1468,6 +1485,7 @@ Umrissfarbe des Körperteils 身体部位の輪郭表示の色 Цвет контура части тела + Color de Contorno de las Partes del Cuerpo Color of outline around selected body part. @@ -1479,6 +1497,7 @@ Farbe des Umrisses um das ausgewählten Körperteil. 選択した身体部位の輪郭表示の色。 Цвет контура вокруг выбранной части тела. + Color del contorno alrededor de la parte del cuerpo seleccionada. Minor Trauma @@ -1491,6 +1510,7 @@ 轻微创伤 Traumatisme mineur Незначительная травма + Trauma Menor Major Trauma @@ -1503,6 +1523,7 @@ 中度创伤 Traumatisme majeur Серьезная травма + Trauma mayor Severe Trauma @@ -1515,6 +1536,7 @@ 重度创伤 Traumatisme grave Тяжелая травма + Trauma Severo Chronic Trauma @@ -1527,6 +1549,7 @@ 慢性创伤 Traumatisme chronique Хроническая травма + Trauma Crónico L @@ -1538,6 +1561,7 @@ L Лево + I R @@ -1549,6 +1573,7 @@ R Право + D in your inventory @@ -1560,6 +1585,7 @@ im Inventar 個あなたが保有 в вашем инвентаре + en tu inventario in patient's inventory @@ -1571,6 +1597,7 @@ im Inventar des Patienten 個患者が保有 в инвентаре пациента + en el inventario del paciente in vehicle's inventory @@ -1582,6 +1609,7 @@ Nell'inventario del veicolo 個車両内に保有 в инвентаре транспорта + en el inventario del vehículo No effect until tourniquet removed @@ -1592,6 +1620,7 @@ Nessun effetto fino alla rimozione del laccio emostatico 止血帯を外すまで効果を発揮しません Никакого эффекта до тех пор, пока жгут не будет снят + Sin efecto hasta que se quita el torniquete Show Tourniquet Warning @@ -1602,6 +1631,7 @@ Mostra avviso di laccio emostatico 止血帯の警告を表示 Показать предупреждение о наложении жгута + Mostrar Advertencia de Torniquete Show a warning tooltip when a tourniquet will interfere with a medical action. @@ -1612,6 +1642,7 @@ Mostra un avviso se un laccio emostatico impedisce un trattamento medico. 止血帯が医療行為を妨げる場合には、警告ツールチップを表示します。 Показать всплывающую подсказку с предупреждением, когда жгут помешает медицинскому вмешательству. + Muestra un mensaje de advertencia cuando un torniquete interfiera con una acción médica. diff --git a/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf b/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf index 537c3566519..8be1d358df4 100644 --- a/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf +++ b/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf @@ -25,6 +25,7 @@ if (isNull _unit || {!isNil {_unit getVariable QEGVAR(medical,causeOfDeath)}}) e TRACE_4("enteredStateDeath",_this,_thisOrigin,_thisTransition,CBA_missionTime); private _causeOfDeath = format ["%1:%2", _thisOrigin, _thisTransition]; +private _source = _unit getVariable [QEGVAR(medical,lastDamageSource), objNull]; private _instigator = _unit getVariable [QEGVAR(medical,lastInstigator), objNull]; -[_unit, _causeOfDeath, _instigator] call EFUNC(medical_status,setDead); +[_unit, _causeOfDeath, _source, _instigator] call EFUNC(medical_status,setDead); diff --git a/addons/medical_status/functions/fnc_setDead.sqf b/addons/medical_status/functions/fnc_setDead.sqf index cb1e1f1d6f8..138948c0386 100644 --- a/addons/medical_status/functions/fnc_setDead.sqf +++ b/addons/medical_status/functions/fnc_setDead.sqf @@ -7,6 +7,7 @@ * 0: The unit * 1: Reason for death * 2: Killer + * 3: Instigator * * Return Value: * None @@ -14,9 +15,8 @@ * Public: No */ -params ["_unit", ["_reason", "#setDead"], ["_instigator", objNull]]; -TRACE_3("setDead",_unit,_reason,_instigator); - +params ["_unit", ["_reason", "#setDead"], ["_source", objNull], ["_instigator", objNull]]; +TRACE_4("setDead",_unit,_reason,_source,_instigator); // No heart rate or blood pressure to measure when dead _unit setVariable [VAR_HEART_RATE, 0, true]; @@ -38,7 +38,7 @@ if (_unitState isNotEqualTo "Dead") then { // (#8803) Reenable damage if disabled to prevent having live units in dead state // Keep this after death event for compatibility with third party hooks -if !(isDamageAllowed _unit) then { +if (!isDamageAllowed _unit) then { WARNING_1("setDead executed on unit with damage blocked - %1",_this); _unit allowDamage true; }; @@ -46,6 +46,6 @@ if !(isDamageAllowed _unit) then { // Kill the unit without changing visual apperance private _prevDamage = _unit getHitPointDamage "HitHead"; -_unit setHitPointDamage ["HitHead", 1, true, _instigator]; +_unit setHitPointDamage ["HitHead", 1, true, _source, _instigator]; -_unit setHitPointDamage ["HitHead", _prevDamage]; +_unit setHitPointDamage ["HitHead", _prevDamage, true, _source, _instigator]; diff --git a/addons/medical_status/stringtable.xml b/addons/medical_status/stringtable.xml index f6f51b55338..ea3f77429b2 100644 --- a/addons/medical_status/stringtable.xml +++ b/addons/medical_status/stringtable.xml @@ -126,6 +126,7 @@ Risque de perte d'arme 武器を落とす確率 Шанс выпадения оружия + Probabilidad de Soltar Arma Chance for a player to drop their weapon when going unconscious.\nHas no effect on AI. @@ -136,6 +137,7 @@ Pourcentage de chances pour un joueur de lâcher son arme lorsqu'il perd connaissance.\nAucun effet sur les IA. プレーヤーが意識を失ったときに武器を落とす可能性。\nAI には影響しません。 Шанс для игрока выронить свое оружие, когда он теряет сознание.\nНе влияет на ИИ + Probabilidad del jugador de soltar su arma cuando quedan inconscientes.\nNo tiene efecto sobre la IA. diff --git a/addons/medical_treatment/XEH_preInit.sqf b/addons/medical_treatment/XEH_preInit.sqf index bc01e267c1b..e6210a73729 100644 --- a/addons/medical_treatment/XEH_preInit.sqf +++ b/addons/medical_treatment/XEH_preInit.sqf @@ -14,27 +14,23 @@ PREP_RECOMPILE_END; // adjusting these is trail and error // if the animation is cut of ingame, increase these values // if the unit idles too much, decrease them -GVAR(animDurations) = [] call CBA_fnc_createNamespace; - -{ - GVAR(animDurations) setVariable _x; -} forEach [ - ["AinvPknlMstpSlayWnonDnon_medic", 7.5], - ["AinvPpneMstpSlayWnonDnon_medic", 7], - ["AinvPknlMstpSlayWrflDnon_medic", 7], - ["AinvPpneMstpSlayWrflDnon_medic", 9.5], - ["AinvPknlMstpSlayWlnrDnon_medic", 9], - ["AinvPknlMstpSlayWpstDnon_medic", 9.5], - ["AinvPpneMstpSlayWpstDnon_medic", 10], - ["AinvPknlMstpSlayWnonDnon_medicOther", 8.5], - ["AinvPpneMstpSlayWnonDnon_medicOther", 8.5], - ["AinvPknlMstpSlayWrflDnon_medicOther", 7], - ["AinvPpneMstpSlayWrflDnon_medicOther", 9], - ["AinvPknlMstpSlayWlnrDnon_medicOther", 9], - ["AinvPknlMstpSlayWpstDnon_medicOther", 10], - ["AinvPpneMstpSlayWpstDnon_medicOther", 8.5], - ["AinvPknlMstpSnonWnonDnon_medic1", 10], - ["AinvPknlMstpSnonWnonDr_medic0", 12] +GVAR(animDurations) = createHashMapFromArray [ + ["ainvpknlmstpslaywnondnon_medic", 7.5], + ["ainvppnemstpslaywnondnon_medic", 7], + ["ainvpknlmstpslaywrfldnon_medic", 7], + ["ainvppnemstpslaywrfldnon_medic", 9.5], + ["ainvpknlmstpslaywlnrdnon_medic", 9], + ["ainvpknlmstpslaywpstdnon_medic", 9.5], + ["ainvppnemstpslaywpstdnon_medic", 10], + ["ainvpknlmstpslaywnondnon_medicother", 8.5], + ["ainvppnemstpslaywnondnon_medicother", 8.5], + ["ainvpknlmstpslaywrfldnon_medicother", 7], + ["ainvppnemstpslaywrfldnon_medicother", 9], + ["ainvpknlmstpslaywlnrdnon_medicother", 9], + ["ainvpknlmstpslaywpstdnon_medicother", 10], + ["ainvppnemstpslaywpstdnon_medicother", 8.5], + ["ainvpknlmstpsnonwnondnon_medic1", 10], + ["ainvpknlmstpsnonwnondr_medic0", 12] ]; // class names of medical facilities (config case) diff --git a/addons/medical_treatment/functions/fnc_checkPulseLocal.sqf b/addons/medical_treatment/functions/fnc_checkPulseLocal.sqf index 3798e64eb4f..bb3efedc221 100644 --- a/addons/medical_treatment/functions/fnc_checkPulseLocal.sqf +++ b/addons/medical_treatment/functions/fnc_checkPulseLocal.sqf @@ -21,7 +21,7 @@ params ["_medic", "_patient", "_bodyPart"]; private _heartRate = 0; -if (!([_patient, _bodyPart] call FUNC(hasTourniquetAppliedTo))) then { +if !([_patient, _bodyPart] call FUNC(hasTourniquetAppliedTo)) then { _heartRate = switch (true) do { case (alive _patient): { GET_HEART_RATE(_patient) diff --git a/addons/medical_treatment/functions/fnc_checkResponse.sqf b/addons/medical_treatment/functions/fnc_checkResponse.sqf index dc76b1dbfbe..ca95fcb1d16 100644 --- a/addons/medical_treatment/functions/fnc_checkResponse.sqf +++ b/addons/medical_treatment/functions/fnc_checkResponse.sqf @@ -22,6 +22,11 @@ params ["_medic", "_patient"]; private _output = if (_patient call EFUNC(common,isAwake)) then { LSTRING(Check_Response_Responsive) } else { + if (GVAR(advancedDiagnose) == 3) exitWith { + if (IN_CRDC_ARRST(_patient)) exitWith { LSTRING(Check_Response_CardiacArrestDirect) }; + if (!alive _patient) exitWith { LSTRING(Check_Response_DeadDirect) }; + LSTRING(Check_Response_UnresponsiveDirect) + }; if ((GVAR(advancedDiagnose) == 2) && {IN_CRDC_ARRST(_patient)}) exitWith { LSTRING(Check_Response_CardiacArrest) }; if ((GVAR(advancedDiagnose) == 2) && {!alive _patient}) exitWith { LSTRING(Check_Response_Dead) }; LSTRING(Check_Response_Unresponsive) diff --git a/addons/medical_treatment/functions/fnc_cprLocal.sqf b/addons/medical_treatment/functions/fnc_cprLocal.sqf index 228774b2f63..e6b12990270 100644 --- a/addons/medical_treatment/functions/fnc_cprLocal.sqf +++ b/addons/medical_treatment/functions/fnc_cprLocal.sqf @@ -24,9 +24,14 @@ TRACE_2("cprLocal",_medic,_patient); private _bloodVolume = GET_BLOOD_VOLUME(_patient); private _successChance = linearConversion [BLOOD_VOLUME_CLASS_4_HEMORRHAGE, BLOOD_VOLUME_CLASS_2_HEMORRHAGE, _bloodVolume, GVAR(cprSuccessChanceMin), GVAR(cprSuccessChanceMax), true]; if ((random 1) < _successChance) then { + // If SpO2 is too low, it will make HR skyrocket to the point where patient goes back into CA + // Allow 3rd party mods to disable this mechanic + if (missionNamespace getVariable [QGVAR(setSpO2UponCPRSuccess), true] && {GET_SPO2(_patient) < DEFAULT_SPO2 / 2}) then { + _patient setVariable [VAR_SPO2, DEFAULT_SPO2 / 2, true]; + }; + TRACE_2("CPR random success",_bloodVolume,_successChance); [QEGVAR(medical,CPRSucceeded), _patient] call CBA_fnc_localEvent; } else { TRACE_2("CPR random fail",_bloodVolume,_successChance); }; - diff --git a/addons/medical_treatment/functions/fnc_fullHealLocal.sqf b/addons/medical_treatment/functions/fnc_fullHealLocal.sqf index dc95c44185a..42c5866a9af 100644 --- a/addons/medical_treatment/functions/fnc_fullHealLocal.sqf +++ b/addons/medical_treatment/functions/fnc_fullHealLocal.sqf @@ -77,12 +77,12 @@ _patient setVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0], true]; // wakeup needs to be done after achieving stable vitals, but before manually reseting unconc var if IS_UNCONSCIOUS(_patient) then { - if (!([_patient] call EFUNC(medical_status,hasStableVitals))) then { ERROR_2("fullheal [unit %1][state %2] did not restore stable vitals",_patient,_state); }; + if !([_patient] call EFUNC(medical_status,hasStableVitals)) then {ERROR_2("fullheal [unit %1][state %2] did not restore stable vitals",_patient,_state);}; TRACE_1("Waking up",_patient); [QEGVAR(medical,WakeUp), _patient] call CBA_fnc_localEvent; _state = GET_SM_STATE(_patient); TRACE_1("after WakeUp",_state); - if IS_UNCONSCIOUS(_patient) then { ERROR_2("fullheal [unit %1][state %2] failed to wake up patient",_patient,_state); }; + if IS_UNCONSCIOUS(_patient) then {ERROR_2("fullheal [unit %1][state %2] failed to wake up patient",_patient,_state);}; }; // Generic medical admin diff --git a/addons/medical_treatment/functions/fnc_treatment.sqf b/addons/medical_treatment/functions/fnc_treatment.sqf index c524fd7ebb1..5f6df40e31c 100644 --- a/addons/medical_treatment/functions/fnc_treatment.sqf +++ b/addons/medical_treatment/functions/fnc_treatment.sqf @@ -76,7 +76,7 @@ if (_medic isNotEqualTo player || {!_isInZeus}) then { }; // Determine the animation length - private _animDuration = GVAR(animDurations) getVariable _medicAnim; + private _animDuration = GVAR(animDurations) get toLowerANSI _medicAnim; if (isNil "_animDuration") then { WARNING_2("animation [%1] for [%2] has no duration defined",_medicAnim,_classname); _animDuration = 10; diff --git a/addons/medical_treatment/initSettings.inc.sqf b/addons/medical_treatment/initSettings.inc.sqf index fbb1b170c81..d080965eb9e 100644 --- a/addons/medical_treatment/initSettings.inc.sqf +++ b/addons/medical_treatment/initSettings.inc.sqf @@ -3,7 +3,7 @@ "LIST", [LSTRING(AdvancedDiagnose_DisplayName), LSTRING(AdvancedDiagnose_Description)], [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], - [[0, 1, 2], [ELSTRING(common,Disabled), ELSTRING(common,Enabled), LSTRING(AdvancedDiagnose_DiagnoseCardiacArrest)], 1], + [[0, 1, 2, 3], [ELSTRING(common,Disabled), ELSTRING(common,Enabled), LSTRING(AdvancedDiagnose_DiagnoseCardiacArrest), LSTRING(AdvancedDiagnose_DiagnoseCardiacArrestDirect)], 1], true ] call CBA_fnc_addSetting; diff --git a/addons/medical_treatment/stringtable.xml b/addons/medical_treatment/stringtable.xml index 29774efb3ca..8b8cc640ebf 100644 --- a/addons/medical_treatment/stringtable.xml +++ b/addons/medical_treatment/stringtable.xml @@ -77,6 +77,10 @@ Habilitado y poder diagnosticar Muerte/Parada cardíaca Abilitato e può diagnosticare Morte/Arresto Cardiaco + + Enabled & Can Diagnose Death/Cardiac Arrest [Directly] + 有効 & 死亡/心停止状態を診断可能 [直接的に] + Advanced Medication Erweiterte Medikation @@ -439,6 +443,7 @@ Tempo di scavo tomba 墓掘りの所要時間 Время рытья могилы + Tiempo de Cavado de Tumba Time, in seconds, required to dig a grave for a body. @@ -449,6 +454,7 @@ Tempo in secondi richiesto per seppellire un morto. 遺体の墓を掘るのに掛かる時間。 (秒単位) Время в секундах, необходимое для того, чтобы выкопать могилу для тела. + Tiempo, en segundos, requerido para cavar una tumba para un cuerpo. Allow Epinephrine @@ -3506,6 +3512,7 @@ Kein Schmerz 痛みはない Нет боли + Sin dolor In mild pain @@ -3627,6 +3634,7 @@ Kein IV IV なし Нет капельницы + Sin IV Blood Pressure @@ -4149,6 +4157,11 @@ %1 沒有反應 %1 tepki vermiyor + + %1 is unconscious + %1 は意識がない + %1 находится без сознания + %1 is not responsive, taking shallow gasps and convulsing %1 est inconscient, respire par intermittence et convulse. @@ -4161,6 +4174,11 @@ %1 не реагирует на раздражители, поверхностно дышит, в конвульсиях %1 no responde, dando pequeñas bocanadas y convulsionando + + %1 is in cardiac arrest + %1 は心停止している + У %1 произошла остановка сердца + %1 is not responsive, motionless and cold %1 est inconscient, inanimé et froid. @@ -4173,6 +4191,11 @@ %1 не реагирует на раздражители, не шевелится и холодный %1 no responde, sin movimiento y frío + + %1 is dead + %1 は死亡している + %1 мертв + You checked %1 Вы осмотрели раненого %1 @@ -4657,6 +4680,7 @@ Scava tomba per cadavere 墓を掘る Выкопать могилу для тела + Cavar tumba para cuerpo Digging grave for body... @@ -4667,6 +4691,7 @@ Scavando tomba per cadavere... 墓を掘っています Рытьё могилы для тела... + Cavando tumba para cuerpo... %1 has bandaged patient @@ -4919,6 +4944,7 @@ Controlla nome sulla lapide 墓石の名前を確認 Проверьте имя на надгробии + Comprobar nombre en la lápida Bandage Rollover @@ -4929,6 +4955,7 @@ Srotolamento Bendaggi 包帯の繰り越し Перевязка множественных ран + Vendaje múltiple If enabled, bandages can close different types of wounds on the same body part.\nBandaging multiple injuries will scale bandaging time accordingly. @@ -4939,6 +4966,7 @@ Se attivo, un singolo bendaggio potrà chiudere più ferite sulla stessa parte del corpo.\nBendare più ferite di conseguenza richiederà più tempo. 有効にすると、体の同じ部分にある別の種類の傷を一つの包帯で閉じることができます。\n複数の傷に包帯を巻くと、それに応じて包帯時間が変動します。 Если эта функция включена, бинты могут закрывать различные типы ран на одной и той же части тела.\nПри перевязке нескольких повреждений время перевязки будет увеличено соответствующим образом. + Si se habilita, las vendas pueden cerrar diferentes tipos de heridas en la misma parte del cuerpo.n\Vendar múltiples heridas escala el tiempo de vendado acorde. Bandage Effectiveness Coefficient @@ -4949,6 +4977,7 @@ Coefficiente di efficacia bendaggi 包帯有効性係数 Коэффициент эффективности повязки + Coeficiente de Efectividad de Vendado Determines how effective bandages are at closing wounds. @@ -4959,6 +4988,7 @@ Determina quanto i bendaggi sono efficaci nel chiudere le ferite. 包帯が傷をふさぐのにどれだけ効果的かを定義します。 Определяет, насколько эффективны бинты при закрытии ран. + Determina como de efectivos son los vendajes cerrando heridas. Medical Items @@ -4982,6 +5012,7 @@ 제우스 치료 시간 계수 Коэффициент времени обработки Zeus Coeff. de temps + Coeficiente de Tiempo del Tratamiento de Zeus Multiply all treatment times with this coefficient when in Zeus. @@ -4991,6 +5022,7 @@ 제우스일 때 모든 치료 시간에 이 계수를 곱합니다. Умножьте все время лечения на этот коэффициент, когда вы находитесь в Zeus. Coefficient de temps de traitement Zeus + Multiplica los tiempos de tratamientos por este coeficiente cuando se está en Zeus Painkillers @@ -5015,6 +5047,8 @@ 鎮痛剤を投与 진통제 투여 Administrer des analgésiques + Verabreiche Schmerztabletten + Administrar Analgésicos Administering Painkillers... @@ -5023,6 +5057,8 @@ 鎮痛剤を投与しています・・・ 진통제 투여 중... Administration d'analgésiques... + Verabreiche Schmerztablette... + Administrando Analgésicos... Over-the-counter analgesic used to combat light to moderate pain experiences. @@ -5031,6 +5067,8 @@ 軽度から中程度の痛みに対処するために使用される市販の鎮痛薬。 가벼운 통증부터 중간 정도의 통증을 퇴치하는 데 사용되는 일반의약품 진통제입니다. Analgésique sans ordonnance utilisé pour lutter contre les douleurs légères à modérées. + Rezeptfreies Analgetikum zur Bekämpfung leichter bis mittelschwerer Schmerzen. + Analgésico sin receta médica usado para aplacar dolores de ligeros a moderados. Over-the-counter analgesic used to combat light to moderate pain experiences. @@ -5039,6 +5077,8 @@ 軽度から中程度の痛みに対処するために使用される市販の鎮痛薬。 가벼운 통증부터 중간 정도의 통증을 퇴치하는 데 사용되는 일반의약품 진통제입니다. Analgésique sans ordonnance utilisé pour lutter contre les douleurs légères à modérées. + Rezeptfreies Analgetikum zur Bekämpfung leichter bis mittelschwerer Schmerzen. + Analgésico sin receta médica usado para aplacar dolores de ligeros a moderados. diff --git a/addons/medical_vitals/stringtable.xml b/addons/medical_vitals/stringtable.xml index eb0080bd078..2fe7336dc08 100644 --- a/addons/medical_vitals/stringtable.xml +++ b/addons/medical_vitals/stringtable.xml @@ -9,6 +9,8 @@ バイタル 생명 Paramètres vitaux + Vitalwerte + Vitales Enable SpO2 Simulation @@ -17,6 +19,8 @@ SpO2シミュレーションを有効化 산소포화도 시뮬레이션 활성화 Activer la simulation de la SpO2 + SpO2-Simulation aktivieren + Habilitar Simulación SpO2 Enables oxygen saturation simulation, providing variable heart rate and oxygen demand based on physical activity and altitude. Required for Airway Management. @@ -25,6 +29,8 @@ 酸素飽和度シミュレーションを有効にし、身体活動や標高に基づいて変動する心拍数と酸素要求量の機能を提供します。 気道管理に必要です。 산소포화도 시뮬레이션을 활성화하여 신체 활동과 고도에 따라 다양한 심박수와 산소 요구량을 제공합니다. 기도 관리에 필요합니다. Permet de simuler la saturation en oxygène, de modifier la fréquence cardiaque et la consommation d'oxygène en fonction de l'activité physique et de l'altitude. Nécessaire pour la gestion des voies respiratoires. + Aktiviert die Simulation der Sauerstoffsättigung und bietet variable Herzfrequenz und Sauerstoffbedarf basierend auf körperlicher Aktivität und Geländehöhe. Erforderlich für das Atemwegsmanagement. + Habilita la saturación de oxígeno, utilizando la demanda de oxígeno y ritmo cardíaco basado en la actividad física y la altitud. Requerido para el Manejo de las Vías Aéreas. diff --git a/addons/microdagr/initSettings.inc.sqf b/addons/microdagr/initSettings.inc.sqf index 8810939302d..aacc5fd24bc 100644 --- a/addons/microdagr/initSettings.inc.sqf +++ b/addons/microdagr/initSettings.inc.sqf @@ -15,7 +15,5 @@ private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(itemName) [LSTRING(WaypointPrecision_DisplayName), LSTRING(WaypointPrecision_Description)], _category, [[1, 2, 3], [LSTRING(WaypointPrecision_medium), LSTRING(WaypointPrecision_close), LSTRING(WaypointPrecision_exact)], 2], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(waypointPrecision), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // require mission restart + true // isGlobal ] call CBA_fnc_addSetting; diff --git a/addons/minedetector/XEH_postInit.sqf b/addons/minedetector/XEH_postInit.sqf index 77f2f6761c8..f5f5de0ca8a 100644 --- a/addons/minedetector/XEH_postInit.sqf +++ b/addons/minedetector/XEH_postInit.sqf @@ -1,16 +1,7 @@ #include "script_component.hpp" // Create a dictionary to store detector configs -GVAR(detectorConfigs) = call CBA_fnc_createNamespace; - -// Create a dictionary of detectable classnames -GVAR(detectableClasses) = call CBA_fnc_createNamespace; - -private _detectableClasses = call (uiNamespace getVariable [QGVAR(detectableClasses), {[]}]); //See XEH_preStart.sqf -{ - GVAR(detectableClasses) setVariable [_x, true]; -} forEach _detectableClasses; -TRACE_1("built cache",count allVariables GVAR(detectableClasses)); +GVAR(detectorConfigs) = createHashMap; [QGVAR(enableDetector), LINKFUNC(enableDetector)] call CBA_fnc_addEventHandler; [QGVAR(disableDetector), LINKFUNC(disableDetector)] call CBA_fnc_addEventHandler; diff --git a/addons/minedetector/XEH_preStart.sqf b/addons/minedetector/XEH_preStart.sqf index 48f003d08e3..046c0373640 100644 --- a/addons/minedetector/XEH_preStart.sqf +++ b/addons/minedetector/XEH_preStart.sqf @@ -15,5 +15,5 @@ private _detectableClasses = []; }; } forEach (configProperties [configFile >> "CfgAmmo", "isClass _x", true]); -TRACE_1("compiled",count _detectableClasses); -uiNamespace setVariable [QGVAR(detectableClasses), compileFinal str _detectableClasses]; +TRACE_1("built cache",count _detectableClasses); +uiNamespace setVariable [QGVAR(detectableClasses), compileFinal (_detectableClasses createHashMapFromArray [])]; diff --git a/addons/minedetector/functions/fnc_getDetectedObject.sqf b/addons/minedetector/functions/fnc_getDetectedObject.sqf index 810e4d4ff46..7811b3eaaa8 100644 --- a/addons/minedetector/functions/fnc_getDetectedObject.sqf +++ b/addons/minedetector/functions/fnc_getDetectedObject.sqf @@ -38,15 +38,13 @@ private _mine = objNull; private _distance = -1; { - private _objectType = typeOf _x; - - _isDetectable = GVAR(detectableClasses) getVariable _objectType; - if (isNil "_isDetectable" || {(getModelInfo _x) select 0 == "empty.p3d"}) then { - _isDetectable = false; + if ((getModelInfo _x) select 0 == "empty.p3d") then { + continue; }; - // If a nun-null object was detected exit the search - if (_isDetectable && {!isNull _x}) exitWith { + // If an object was detected, exit the search + if ((typeOf _x) in (uiNamespace getVariable QGVAR(detectableClasses))) exitWith { + _isDetectable = true; _distance = _detectorPointAGL distance _x; _mine = _x; TRACE_3("return",_isDetectable,_mine,_distance); diff --git a/addons/minedetector/functions/fnc_getDetectorConfig.sqf b/addons/minedetector/functions/fnc_getDetectorConfig.sqf index fe7a888ebf3..a5566cbfbfc 100644 --- a/addons/minedetector/functions/fnc_getDetectorConfig.sqf +++ b/addons/minedetector/functions/fnc_getDetectorConfig.sqf @@ -19,18 +19,15 @@ params ["_detectorType"]; if (_detectorType isEqualTo "") exitWith {[]}; -private _detectorConfig = GVAR(detectorConfigs) getVariable _detectorType; -if (isNil "_detectorConfig") then { +GVAR(detectorConfigs) getOrDefaultCall [_detectorType, { private _cfgEntry = (configFile >> "ACE_detector" >> "detectors" >> _detectorType); if (isClass _cfgEntry) then { - _detectorConfig = [ + [ _detectorType, getNumber (_cfgEntry >> "radius"), getArray (_cfgEntry >> "sounds") ]; } else { - _detectorConfig = []; + [] }; - GVAR(detectorConfigs) setVariable [_detectorType, _detectorConfig]; -}; -_detectorConfig +}, true] diff --git a/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf b/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf index d25d2bc2b78..2263716724a 100644 --- a/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf +++ b/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf @@ -18,7 +18,7 @@ TRACE_1("cycle fire mode",_this); if (!alive ACE_player) exitWith {}; -if (!([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith))) exitWith {}; +if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {}; private _currentShooter = objNull; diff --git a/addons/missileguidance/functions/fnc_onFired.sqf b/addons/missileguidance/functions/fnc_onFired.sqf index 18eaf2a7c70..1d63d120a9a 100644 --- a/addons/missileguidance/functions/fnc_onFired.sqf +++ b/addons/missileguidance/functions/fnc_onFired.sqf @@ -20,7 +20,7 @@ params ["_shooter","_weapon","","_mode","_ammo","","_projectile"]; // Bail on not missile -if (!(_ammo isKindOf "MissileBase")) exitWith {}; +if !(_ammo isKindOf "MissileBase") exitWith {}; // Bail if guidance is disabled for this ammo if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "enabled")) != 1) exitWith {}; diff --git a/addons/mk6mortar/functions/fnc_handleFired.sqf b/addons/mk6mortar/functions/fnc_handleFired.sqf index f2979d0e4e8..8ea2984b794 100644 --- a/addons/mk6mortar/functions/fnc_handleFired.sqf +++ b/addons/mk6mortar/functions/fnc_handleFired.sqf @@ -28,7 +28,7 @@ if (_vehicle distance ACE_player > 8000) exitWith {}; //AI will have no clue how to use: private _shooterMan = gunner _vehicle; -if (!([_shooterMan] call EFUNC(common,isPlayer))) exitWith {}; +if !([_shooterMan] call EFUNC(common,isPlayer)) exitWith {}; //Calculate air density: private _altitude = (getPosASL _vehicle) select 2; diff --git a/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf b/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf index 216bab43bc8..d721b0e4ae8 100644 --- a/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf +++ b/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf @@ -19,7 +19,7 @@ params ["_player", "_newVehicle"]; if (isNull _newVehicle) exitWith {}; -if (!(_newVehicle isKindOf "Mortar_01_base_F")) exitWith {}; +if !(_newVehicle isKindOf "Mortar_01_base_F") exitWith {}; private _tubeWeaponName = (weapons _newVehicle) select 0; private _fireModes = getArray (configFile >> "CfgWeapons" >> _tubeWeaponName >> "modes"); diff --git a/addons/mk6mortar/stringtable.xml b/addons/mk6mortar/stringtable.xml index a0d8612aa58..41955799988 100644 --- a/addons/mk6mortar/stringtable.xml +++ b/addons/mk6mortar/stringtable.xml @@ -163,7 +163,7 @@ A távmérő és számítógép megjelenítése (ezeket el KELL távolítani ha a légellenállás engedélyezve van) Показывает компьютер и дальномер (это НУЖНО отключить, если вы включаете сопротивление воздуха) Consenti l'utilizzo del Computer Balistico e del Telemetro (questi DEVONO essere disabilitati se vuoi abilitare la resistenza dell'aria) - 砲撃コンピュータと距離計を表示します (空気抵抗を仕様する場合は必ず無効化する必要があります) + 砲撃コンピュータと距離計を表示します (空気抵抗を有効化する場合はこれらを取り除く必要があります) 탄도계산컴퓨터와 거리측정기를 보여줍니다(공기저항을 활성화했을 경우 이 항목은 비활성화 되어야 합니다) 显示弹道计算机和测距仪(如果有启用空气阻力功能时,须停用此项功能) 顯示射控電腦和測距儀 (如果有啟用空氣阻力功能時,須停用此項功能) @@ -241,7 +241,7 @@ Rimuove i caricatori di colpi dal mortaio. Un operatore dovrà caricare proiettili singoli prima di poter fare fuoco. Non viene applicato su operatori IA. Elimina os carregadores do morteiro, requerendo que o atirador ou carregador utilize de forma individual a munição. Não afeta os morteiros controlados pela IA. Удаляет артиллерийские магазины, требует загрузку отдельных снарядов стрелком или заряжающим. Не влияет на артиллерию ИИ. - 迫撃砲から弾薬を除去します。射手か装填手により予め装填されている必要があります。AI迫撃砲へ影響を与えません。 + 迫撃砲から弾倉を除去します。一発ずつ射手か装填手によって装填される必要があります。AIの迫撃砲には影響を与えません。 박격포 탄창을 제거합니다, 사수나 장전수가 개별적으로 탄환을 넣어줘야 합니다. 인공지능은 영향을 받지 않습니다. 开启此功能时。迫击炮的弹药需由炮手与装填手共同合作来进行装填。此功能并不影响由 AI 射击的迫击炮 開啟此功能時。迫擊砲的彈藥需由砲手與裝填手共同合作來進行裝填。此功能並不影響由AI射擊的迫擊砲 @@ -257,7 +257,7 @@ Odstranit náboj Remover munição Извлечь снаряд - 弾薬を除去 + 砲弾を取り除く 탄약 제거 卸除弹头 卸除彈頭 @@ -273,7 +273,7 @@ Nabít minomet Carregar morteiro Зарядить миномет - 弾薬を装填 + 砲弾を装填 탄약 장전 装载弹头 裝載彈頭 @@ -288,7 +288,7 @@ Togliendo Proiettile Descarregar munição Извлечение снаряда - 弾薬を除去しています + 砲弾を取り除いています 탄약 제거 중 正在卸除弹头 卸除彈頭中 @@ -305,7 +305,7 @@ Připavuji náboj Preparar munição Подготовка снаряда - 砲弾を事前装填 + 砲弾を準備 탄약 준비 중 正在准备弹头 準備彈頭中 @@ -544,7 +544,7 @@ [ACE] Bedna se standardní 82mm municí [ACE] Caixa de Munição 82mm Padrão [ACE] Ящик снарядов 82мм (стандартный) - [ACE] 82mm 保管箱 + [ACE] 82mm 標準砲弾セット入り弾薬箱 [ACE] 82mm 기본 장비 상자 [ACE] 82 mm 预设弹药箱 [ACE] 82毫米預設彈藥箱 diff --git a/addons/nametags/XEH_postInit.sqf b/addons/nametags/XEH_postInit.sqf index 85115690b48..a3fb7307f2e 100644 --- a/addons/nametags/XEH_postInit.sqf +++ b/addons/nametags/XEH_postInit.sqf @@ -50,7 +50,7 @@ if (missionNamespace getVariable [QGVAR(useFactionIcons), true]) then { { if (isArray (_x >> QGVAR(rankIcons))) then { private _faction = configName _x; - if (!isNil {GVAR(factionRanks) getVariable _faction}) exitWith {}; // don't overwrite if already set + if (_faction in GVAR(factionRanks)) exitWith {}; // don't overwrite if already set private _icons = getArray (_x >> QGVAR(rankIcons)); [_faction, _icons] call FUNC(setFactionRankIcons); }; diff --git a/addons/nametags/functions/fnc_drawNameTagIcon.sqf b/addons/nametags/functions/fnc_drawNameTagIcon.sqf index 428cf037d5b..efe0c6bf157 100644 --- a/addons/nametags/functions/fnc_drawNameTagIcon.sqf +++ b/addons/nametags/functions/fnc_drawNameTagIcon.sqf @@ -42,7 +42,7 @@ _fnc_parameters = { default { private _targetFaction = _target getVariable [QGVAR(faction), faction _target]; - private _customRankIcons = GVAR(factionRanks) getVariable _targetFaction; + private _customRankIcons = GVAR(factionRanks) get _targetFaction; if (!isNil "_customRankIcons") then { _customRankIcons param [ALL_RANKS find rank _target, ""] // return diff --git a/addons/nametags/functions/fnc_setFactionRankIcons.sqf b/addons/nametags/functions/fnc_setFactionRankIcons.sqf index 88fd8808333..42d3ed40cbc 100644 --- a/addons/nametags/functions/fnc_setFactionRankIcons.sqf +++ b/addons/nametags/functions/fnc_setFactionRankIcons.sqf @@ -25,7 +25,7 @@ */ if (isNil QGVAR(factionRanks)) then { - GVAR(factionRanks) = [] call CBA_fnc_createNamespace; + GVAR(factionRanks) = createHashMap; }; params [["_faction", "", [""]], ["_icons", [], [[]], [7]]]; @@ -33,6 +33,11 @@ TRACE_2("setFactionRankIcons",_faction,_icons); if !(_faction != "" && {_icons isEqualTypeAll ""}) exitWith {false}; -GVAR(factionRanks) setVariable [_faction, _icons]; +_faction = configName (configFile >> "CfgFactionClasses" >> _faction); + +// Faction doesn't exist +if (_faction == "") exitWith {false}; + +GVAR(factionRanks) set [_faction, _icons]; true diff --git a/addons/nightvision/XEH_postInit.sqf b/addons/nightvision/XEH_postInit.sqf index 9bfee4d166c..5a1aa19b82e 100644 --- a/addons/nightvision/XEH_postInit.sqf +++ b/addons/nightvision/XEH_postInit.sqf @@ -61,7 +61,7 @@ if (!isNil QGVAR(serverPriorFog)) then {[] call FUNC(nonDedicatedFix);}; // If v if !([ACE_player, objNull, ["isNotEscorting", "isNotInside", "isNotSitting", "isNotRefueling"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if ((currentVisionMode ACE_player != 1)) exitWith {false}; - if (!(missionNamespace getVariable [QGVAR(allowBrightnessControl), true])) exitWith {false}; // just a mission setVar (not ace_setting) + if !(missionNamespace getVariable [QGVAR(allowBrightnessControl), true]) exitWith {false}; // just a mission setVar (not ace_setting) // Statement [ACE_player, 1] call FUNC(changeNVGBrightness); @@ -73,7 +73,7 @@ if (!isNil QGVAR(serverPriorFog)) then {[] call FUNC(nonDedicatedFix);}; // If v if !([ACE_player, objNull, ["isNotEscorting", "isNotInside", "isNotSitting", "isNotRefueling"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if ((currentVisionMode ACE_player != 1)) exitWith {false}; - if (!(missionNamespace getVariable [QGVAR(allowBrightnessControl), true])) exitWith {false}; // just a mission setVar (not ace_setting) + if !(missionNamespace getVariable [QGVAR(allowBrightnessControl), true]) exitWith {false}; // just a mission setVar (not ace_setting) // Statement [ACE_player, -1] call FUNC(changeNVGBrightness); diff --git a/addons/nightvision/stringtable.xml b/addons/nightvision/stringtable.xml index e1345ec44ec..1c1cd61ba7a 100644 --- a/addons/nightvision/stringtable.xml +++ b/addons/nightvision/stringtable.xml @@ -132,6 +132,7 @@ 야투경 (3세대, 갈색, 백색광) JVN (Gen3, marron, WP) ПНВ (Gen3, Коричневый, БФ) + Gafas de visión nocturna (Gen3, Marrón, FB) Night Vision Goggles, White Phosphor @@ -142,6 +143,7 @@ 백색광 야투경 Jumelles Vision Nocturne, Phosphore blanc Очки ночного видения, белый фосфор + Gafas de Visión Nocturna, Fósforo Blanco NV Goggles (Gen3, Green) @@ -169,6 +171,7 @@ 야투경 (3세대, 녹색, 백색광) JVN (Gen3, vertes, WP) ПНВ (Gen3, Зелёный, БФ) + Gafas de visión nocturna (Gen3, Verde, FB) NV Goggles (Gen3, Black) @@ -196,6 +199,7 @@ 야투경 (3세대, 검정, 백색광) JVN (Gen3, noires, WP) ПНВ (Gen3, Чёрный, БФ) + Gafas de visión nocturna (Gen3, Negro, FB) NV Goggles (Gen4, Brown) @@ -218,6 +222,7 @@ 야투경 (4세대, 갈색, 백색광) JVN (Gen4, marron, WP) ПНВ (Gen4, Коричневый, БФ) + Gafas de visión nocturna (Gen4, Marrón, FB) NV Goggles (Gen4, Black) @@ -240,6 +245,7 @@ 야투경 (4세대, 검정, 백색광) JVN (Gen4, noires, WP) ПНВ (Gen4, Чёрный, БФ) + Gafas de visión nocturna (Gen4, Negro, FB) NV Goggles (Gen4, Green) @@ -262,6 +268,7 @@ 야투경 (4세대, 녹색, 백색광) JVN (Gen4, vertes, WP) ПНВ (Gen4, Зелёный, БФ) + Gafas de visión nocturna (Gen4, Verde, FB) NV Goggles (Wide, Brown) @@ -284,6 +291,7 @@ 야투경 (넓음, 갈색, 백색광) JVN (Large, marron, WP) ПНВ (Широкий, Коричневый, БФ) + Gafas de visión nocturna (Panorámicas, Marrón, FB) NV Goggles (Wide, Black) @@ -306,6 +314,7 @@ 야투경 (넓음, 검정, 백색광) JVN (Large, noires, WP) ПНВ (Широкий, Чёрный, БФ) + Gafas de visión nocturna (Panorámicas, Negro, FB) NV Goggles (Wide, Green) @@ -328,6 +337,7 @@ 야투경 (넓음, 녹색, 백색광) JVN (Large, vertes, WP) ПНВ (Широкий, Зелёный, БФ) + Gafas de visión nocturna (Panorámicas, Verde, FB) Brightness: %1 @@ -587,6 +597,7 @@ 야투경 세대 Génération de jumelles de vision nocturne Генерация ночного видения + Generación de Visión Nocturna Gen %1 @@ -597,6 +608,7 @@ %1세대 Gen %1 Генерация %1 + Gen %1 diff --git a/addons/nlaw/functions/fnc_keyDown.sqf b/addons/nlaw/functions/fnc_keyDown.sqf index 60ac4bf3d8f..5b75c721406 100644 --- a/addons/nlaw/functions/fnc_keyDown.sqf +++ b/addons/nlaw/functions/fnc_keyDown.sqf @@ -19,8 +19,8 @@ TRACE_1("lock key down",GVAR(isLockKeyDown)); if (!alive ACE_player) exitWith {}; -if (!([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith))) exitWith {}; -if (!(ACE_player call CBA_fnc_canUseWeapon)) exitWith {}; +if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {}; +if !(ACE_player call CBA_fnc_canUseWeapon) exitWith {}; if ((getNumber (configFile >> "CfgWeapons" >> (currentWeapon ACE_player) >> QGVAR(enabled))) == 0) exitWith {}; if (GVAR(isLockKeyDown)) exitWith {ERROR("already running?");}; diff --git a/addons/overheating/stringtable.xml b/addons/overheating/stringtable.xml index 48399b443c3..ef20ae9e81d 100644 --- a/addons/overheating/stringtable.xml +++ b/addons/overheating/stringtable.xml @@ -882,6 +882,8 @@ 노리쇠 방식 Тип болта Type d'obturateur + Art des Verschlusses + Tipo de Cerrojo Open Bolt @@ -890,6 +892,8 @@ 오픈 볼트 Открыть болт Obturateur ouvert + Offener Verschluss + Cerrojo Abierto Closed Bolt @@ -898,6 +902,8 @@ 클로즈드 볼트 Закрыть болт Obturateur fermé + Geschlossener Verschluss + Cerrojo Cerrado Barrel Type @@ -906,6 +912,8 @@ 총열 방식 Тип ствола Type de canon + Lauftyp + Tipo de Cañón Non-Removeable @@ -914,6 +922,8 @@ 제거 불가 Несъемный Inamovible + Nicht entfernbar + No-Desmontable Quick Change @@ -922,6 +932,8 @@ 신속 교체 Быстросъемный Changement rapide + Schnellwechsel + Cambiado Rápido diff --git a/addons/overpressure/functions/fnc_firedEHBB.sqf b/addons/overpressure/functions/fnc_firedEHBB.sqf index 2ef48bf4d99..a0277859402 100644 --- a/addons/overpressure/functions/fnc_firedEHBB.sqf +++ b/addons/overpressure/functions/fnc_firedEHBB.sqf @@ -53,7 +53,7 @@ if (_distance < _backblastRange) then { [_damage * 100] call BIS_fnc_bloodEffect; - if (["ace_medical"] call EFUNC(common,isModLoaded)) then { + if (GETEGVAR(medical,enabled,false)) then { [_unit, _damage, "body", "backblast", _unit] call EFUNC(medical,addDamageToUnit); } else { _unit setDamage (damage _unit + _damage); diff --git a/addons/overpressure/functions/fnc_overpressureDamage.sqf b/addons/overpressure/functions/fnc_overpressureDamage.sqf index 812a2ab7ea2..12b7a820cab 100644 --- a/addons/overpressure/functions/fnc_overpressureDamage.sqf +++ b/addons/overpressure/functions/fnc_overpressureDamage.sqf @@ -57,7 +57,7 @@ TRACE_3("cache",_overpressureAngle,_overpressureRange,_overpressureDamage); [_damage * 100] call BIS_fnc_bloodEffect; }; - if (["ace_medical"] call EFUNC(common,isModLoaded)) then { + if (GETEGVAR(medical,enabled,false)) then { [_x, _damage, "body", "backblast", _firer] call EFUNC(medical,addDamageToUnit); } else { _x setDamage (damage _x + _damage); diff --git a/addons/parachute/CfgVehicles.hpp b/addons/parachute/CfgVehicles.hpp index f764494224d..545d9a37053 100644 --- a/addons/parachute/CfgVehicles.hpp +++ b/addons/parachute/CfgVehicles.hpp @@ -101,4 +101,36 @@ class CfgVehicles { class B_Soldier_05_f; class B_Pilot_F: B_Soldier_05_f {backpack = "ACE_NonSteerableParachute";}; class I_Soldier_04_F; class I_pilot_F: I_Soldier_04_F {backpack = "ACE_NonSteerableParachute";}; class O_helipilot_F; class O_Pilot_F: O_helipilot_F {backpack = "ACE_NonSteerableParachute";}; + + class Plane_Base_F; + class Plane_CAS_01_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_CAS_02_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_Fighter_01_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_Fighter_02_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_Fighter_03_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_Fighter_04_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; }; diff --git a/addons/parachute/initSettings.inc.sqf b/addons/parachute/initSettings.inc.sqf index 0cfc3f8ca05..0c6804cff79 100644 --- a/addons/parachute/initSettings.inc.sqf +++ b/addons/parachute/initSettings.inc.sqf @@ -5,9 +5,7 @@ private _category = [LELSTRING(common,categoryUncategorized), localize "str_dn_p "CHECKBOX", [LSTRING(HideAltimeter), LSTRING(HideAltimeter_tooltip)], _category, - true, - false, - {[QGVAR(hideAltimeter), _this, false] call EFUNC(common,cbaSettings_settingChanged)} + true ] call CBA_fnc_addSetting; [ diff --git a/addons/pylons/functions/fnc_showDialog.sqf b/addons/pylons/functions/fnc_showDialog.sqf index a06cb6f1142..9c0faab52d0 100644 --- a/addons/pylons/functions/fnc_showDialog.sqf +++ b/addons/pylons/functions/fnc_showDialog.sqf @@ -107,7 +107,7 @@ GVAR(comboBoxes) = []; private _mirroredIndex = getNumber (_x >> "mirroredMissilePos"); private _button = controlNull; - if (count allTurrets [_aircraft, false] > 0) then { + if ((allTurrets [_aircraft, false]) isNotEqualTo []) then { _button = _display ctrlCreate ["ctrlButtonPictureKeepAspect", -1]; private _turret = [_aircraft, _forEachIndex] call EFUNC(common,getPylonTurret); [_button, false, _turret] call FUNC(onButtonTurret); diff --git a/addons/realisticnames/Attachments.hpp b/addons/realisticnames/Attachments.hpp new file mode 100644 index 00000000000..a861bb4a043 --- /dev/null +++ b/addons/realisticnames/Attachments.hpp @@ -0,0 +1,174 @@ +//attachments + +class ItemCore; + +class acc_flashlight: ItemCore { + displayName = CSTRING(flashlight_Name); +}; + +class optic_MRD: ItemCore { + displayName = CSTRING(optic_mrd_Name); +}; +class optic_MRD_black: optic_MRD { + displayName = CSTRING(optic_mrd_black_Name); +}; + +class optic_Hamr: ItemCore { + displayName = CSTRING(optic_hamr); +}; +class optic_Hamr_khk_F: optic_Hamr { + displayName = CSTRING(optic_hamr_khk); +}; +class ACE_optic_Hamr_2D: optic_Hamr { + displayName = CSTRING(optic_hamr_2d); +}; +class ACE_optic_Hamr_PIP: ACE_optic_Hamr_2D { + displayName = CSTRING(optic_hamr_pip); +}; + +class optic_Arco: ItemCore { + displayName = CSTRING(optic_arco); +}; +class optic_Arco_blk_F: optic_Arco { + displayName = CSTRING(optic_arco_blk); +}; +class optic_Arco_ghex_F: optic_Arco { + displayName = CSTRING(optic_arco_ghex); +}; +class ACE_optic_Arco_2D: optic_Arco { + displayName = CSTRING(optic_arco_2d); +}; +class ACE_optic_Arco_PIP: ACE_optic_Arco_2D { + displayName = CSTRING(optic_arco_pip); +}; +class optic_Arco_lush_F: optic_Arco { + displayName = CSTRING(optic_arco_lush); +}; +class optic_Arco_arid_F: optic_Arco { + displayName = CSTRING(optic_arco_arid); +}; +class optic_Arco_AK_blk_F: optic_Arco_blk_F { + displayName = CSTRING(optic_arco_ak_blk); +}; +class optic_Arco_AK_lush_F: optic_Arco_lush_F { + displayName = CSTRING(optic_arco_ak_lush); +}; +class optic_Arco_AK_arid_F: optic_Arco_arid_F { + displayName = CSTRING(optic_arco_ak_arid); +}; + +class optic_ERCO_blk_f: optic_Arco { + displayName = CSTRING(optic_erco_blk); +}; +class optic_ERCO_khk_f: optic_ERCO_blk_f { + displayName = CSTRING(optic_erco_khk); +}; +class optic_ERCO_snd_f: optic_ERCO_blk_f { + displayName = CSTRING(optic_erco_snd); +}; + +class optic_LRPS: ItemCore { + displayName = CSTRING(optic_lrps); +}; +class optic_LRPS_ghex_F: optic_LRPS { + displayName = CSTRING(optic_lrps_ghex); +}; +class optic_LRPS_tna_F: optic_LRPS { + displayName = CSTRING(optic_lrps_tna); +}; +class ACE_optic_LRPS_2D: optic_LRPS { + displayName = CSTRING(optic_lrps_2d); +}; +class ACE_optic_LRPS_PIP: ACE_optic_LRPS_2D { + displayName = CSTRING(optic_lrps_pip); +}; + +class optic_AMS_base; +class optic_AMS: optic_AMS_base { + displayName = CSTRING(optic_ams); +}; +class optic_AMS_khk: optic_AMS { + displayName = CSTRING(optic_ams_khk); +}; +class optic_AMS_snd: optic_AMS { + displayName = CSTRING(optic_ams_snd); +}; + +class optic_KHS_base; +class optic_KHS_blk: optic_KHS_base { + displayName = CSTRING(optic_khs_blk); +}; +class optic_KHS_hex: optic_KHS_blk { + displayName = CSTRING(optic_khs_hex); +}; +class optic_KHS_old: ItemCore { + displayName = CSTRING(optic_khs_old); +}; +class optic_KHS_tan: optic_KHS_blk { + displayName = CSTRING(optic_khs_tan); +}; + +class optic_DMS: ItemCore { + displayName = CSTRING(optic_dms); +}; +class optic_DMS_ghex_F: optic_DMS { + displayName = CSTRING(optic_dms_ghex); +}; +class optic_DMS_weathered_F: optic_DMS { + displayName = CSTRING(optic_dms_weathered); +}; +class optic_DMS_weathered_Kir_F: optic_DMS_weathered_F { + displayName = CSTRING(optic_dms_weathered_kir); +}; + +class optic_holosight: ItemCore { + displayName = CSTRING(optic_holosight); +}; +class optic_Holosight_blk_F: optic_holosight { + displayName = CSTRING(optic_holosight_blk); +}; +class optic_Holosight_khk_F: optic_holosight { + displayName = CSTRING(optic_holosight_khk); +}; +class optic_Holosight_lush_F: optic_holosight { + displayName = CSTRING(optic_holosight_lush); +}; +class optic_Holosight_arid_F: optic_holosight { + displayName = CSTRING(optic_holosight_arid); +}; +class optic_Holosight_smg: ItemCore { + displayName = CSTRING(optic_holosight_smg); +}; +class optic_Holosight_smg_blk_F: optic_Holosight_smg { + displayName = CSTRING(optic_holosight_smg_blk); +}; +class optic_Holosight_smg_khk_F: optic_Holosight_smg { + displayName = CSTRING(optic_holosight_smg_khk); +}; + +class optic_MRCO: ItemCore { + displayName = CSTRING(optic_MRCO); +}; +class ACE_optic_MRCO_2D: optic_MRCO { + displayName = CSTRING(optic_MRCO_2d); +}; +class ACE_optic_MRCO_PIP: ACE_optic_MRCO_2D { + displayName = CSTRING(optic_MRCO_pip); +}; + +class optic_Yorris: ItemCore { + displayName = CSTRING(optic_Yorris); +}; + +class optic_ACO: ItemCore { + displayName = CSTRING(optic_ACO); +}; +class optic_ACO_grn: ItemCore { + displayName = CSTRING(optic_ACO_grn); +}; +class optic_ACO_smg: ItemCore { + displayName = CSTRING(optic_ACO_smg); +}; +class optic_ACO_grn_smg: ItemCore { + displayName = CSTRING(optic_ACO_grn_smg); +}; diff --git a/addons/realisticnames/CfgVehicles.hpp b/addons/realisticnames/CfgVehicles.hpp index 8d4d0c2f4a1..29ac412957f 100644 --- a/addons/realisticnames/CfgVehicles.hpp +++ b/addons/realisticnames/CfgVehicles.hpp @@ -249,6 +249,10 @@ class CfgVehicles { class O_Truck_02_medical_F: Truck_02_medical_base_F { displayName = CSTRING(Truck_02_medical_Name); }; + class Truck_02_water_base_F; + class C_IDAP_Truck_02_water_F: Truck_02_water_base_F { + displayName = CSTRING(Truck_02_water_Name); + }; class I_Truck_02_transport_F: Truck_02_transport_base_F { displayName = CSTRING(Truck_02_transport_Name); }; @@ -283,6 +287,12 @@ class CfgVehicles { class C_Truck_02_box_F: Truck_02_box_base_F { displayName = CSTRING(Truck_02_box_Name); }; + class C_IDAP_Truck_02_transport_F: Truck_02_transport_base_F { + displayName = CSTRING(Truck_02_transport_Name); + }; + class C_IDAP_Truck_02_F: Truck_02_base_F { + displayName = CSTRING(Truck_02_covered_Name); + }; class Truck_03_base_F; class O_Truck_03_transport_F: Truck_03_base_F { @@ -384,6 +394,9 @@ class CfgVehicles { class I_Heli_Transport_02_F: Heli_Transport_02_base_F { displayName = CSTRING(Heli_Transport_02_Name); }; + class C_IDAP_Heli_Transport_02_F: Heli_Transport_02_base_F { + displayName = CSTRING(Heli_Transport_02_Name); + }; // planes class Plane_CAS_01_base_F; diff --git a/addons/realisticnames/CfgWeapons.hpp b/addons/realisticnames/CfgWeapons.hpp index 953f981051e..5b0e33e98c9 100644 --- a/addons/realisticnames/CfgWeapons.hpp +++ b/addons/realisticnames/CfgWeapons.hpp @@ -2,6 +2,7 @@ class Mode_SemiAuto; class Mode_FullAuto; class CfgWeapons { + #include "Attachments.hpp" // assault rifles // MX @@ -707,175 +708,19 @@ class CfgWeapons { }; }; - //attachments - - class ItemCore; - - class acc_flashlight: ItemCore { - displayName = "UTG Defender 126"; - }; - - class optic_Hamr: ItemCore { - displayName = CSTRING(optic_hamr); - }; - class optic_Hamr_khk_F: optic_Hamr { - displayName = CSTRING(optic_hamr_khk); - }; - class ACE_optic_Hamr_2D: optic_Hamr { - displayName = CSTRING(optic_hamr_2d); - }; - class ACE_optic_Hamr_PIP: ACE_optic_Hamr_2D { - displayName = CSTRING(optic_hamr_pip); - }; - - class optic_Arco: ItemCore { - displayName = CSTRING(optic_arco); - }; - class optic_Arco_blk_F: optic_Arco { - displayName = CSTRING(optic_arco_blk); - }; - class optic_Arco_ghex_F: optic_Arco { - displayName = CSTRING(optic_arco_ghex); - }; - class ACE_optic_Arco_2D: optic_Arco { - displayName = CSTRING(optic_arco_2d); - }; - class ACE_optic_Arco_PIP: ACE_optic_Arco_2D { - displayName = CSTRING(optic_arco_pip); - }; - class optic_Arco_lush_F: optic_Arco { - displayName = CSTRING(optic_arco_lush); - }; - class optic_Arco_arid_F: optic_Arco { - displayName = CSTRING(optic_arco_arid); - }; - class optic_Arco_AK_blk_F: optic_Arco_blk_F { - displayName = CSTRING(optic_arco_ak_blk); - }; - class optic_Arco_AK_lush_F: optic_Arco_lush_F { - displayName = CSTRING(optic_arco_ak_lush); - }; - class optic_Arco_AK_arid_F: optic_Arco_arid_F { - displayName = CSTRING(optic_arco_ak_arid); - }; - - class optic_ERCO_blk_f: optic_Arco { - displayName = CSTRING(optic_erco_blk); - }; - class optic_ERCO_khk_f: optic_ERCO_blk_f { - displayName = CSTRING(optic_erco_khk); - }; - class optic_ERCO_snd_f: optic_ERCO_blk_f { - displayName = CSTRING(optic_erco_snd); - }; - - class optic_LRPS: ItemCore { - displayName = CSTRING(optic_lrps); - }; - class optic_LRPS_ghex_F: optic_LRPS { - displayName = CSTRING(optic_lrps_ghex); - }; - class optic_LRPS_tna_F: optic_LRPS { - displayName = CSTRING(optic_lrps_tna); - }; - class ACE_optic_LRPS_2D: optic_LRPS { - displayName = CSTRING(optic_lrps_2d); - }; - class ACE_optic_LRPS_PIP: ACE_optic_LRPS_2D { - displayName = CSTRING(optic_lrps_pip); - }; - - class optic_AMS_base; - class optic_AMS: optic_AMS_base { - displayName = CSTRING(optic_ams); - }; - class optic_AMS_khk: optic_AMS { - displayName = CSTRING(optic_ams_khk); - }; - class optic_AMS_snd: optic_AMS { - displayName = CSTRING(optic_ams_snd); - }; - - class optic_KHS_base; - class optic_KHS_blk: optic_KHS_base { - displayName = CSTRING(optic_khs_blk); - }; - class optic_KHS_hex: optic_KHS_blk { - displayName = CSTRING(optic_khs_hex); - }; - class optic_KHS_old: ItemCore { - displayName = CSTRING(optic_khs_old); - }; - class optic_KHS_tan: optic_KHS_blk { - displayName = CSTRING(optic_khs_tan); - }; - - class optic_DMS: ItemCore { - displayName = CSTRING(optic_dms); - }; - class optic_DMS_ghex_F: optic_DMS { - displayName = CSTRING(optic_dms_ghex); - }; - class optic_DMS_weathered_F: optic_DMS { - displayName = CSTRING(optic_dms_weathered); - }; - class optic_DMS_weathered_Kir_F: optic_DMS_weathered_F { - displayName = CSTRING(optic_dms_weathered_kir); - }; - - class optic_holosight: ItemCore { - displayName = CSTRING(optic_holosight); - }; - class optic_Holosight_blk_F: optic_holosight { - displayName = CSTRING(optic_holosight_blk); - }; - class optic_Holosight_khk_F: optic_holosight { - displayName = CSTRING(optic_holosight_khk); - }; - class optic_Holosight_lush_F: optic_holosight { - displayName = CSTRING(optic_holosight_lush); - }; - class optic_Holosight_arid_F: optic_holosight { - displayName = CSTRING(optic_holosight_arid); - }; - class optic_Holosight_smg: ItemCore { - displayName = CSTRING(optic_holosight_smg); - }; - class optic_Holosight_smg_blk_F: optic_Holosight_smg { - displayName = CSTRING(optic_holosight_smg_blk); - }; - class optic_Holosight_smg_khk_F: optic_Holosight_smg { - displayName = CSTRING(optic_holosight_smg_khk); - }; - - class optic_MRCO: ItemCore { - displayName = CSTRING(optic_MRCO); - }; - class ACE_optic_MRCO_2D: optic_MRCO { - displayName = CSTRING(optic_MRCO_2d); - }; - class ACE_optic_MRCO_PIP: ACE_optic_MRCO_2D { - displayName = CSTRING(optic_MRCO_pip); - }; - - class optic_Yorris: ItemCore { - displayName = CSTRING(optic_Yorris); - }; + // APEX/Tanoa - class optic_ACO: ItemCore { - displayName = CSTRING(optic_ACO); + // Type 115 + class arifle_ARX_base_F; + class arifle_ARX_blk_F: arifle_ARX_base_F { + displayName = CSTRING(arifle_arx_blk_Name); }; - class optic_ACO_grn: ItemCore { - displayName = CSTRING(optic_ACO_grn); + class arifle_ARX_ghex_F: arifle_ARX_base_F { + displayName = CSTRING(arifle_arx_ghex_Name); }; - class optic_ACO_smg: ItemCore { - displayName = CSTRING(optic_ACO_smg); + class arifle_ARX_hex_F: arifle_ARX_base_F { + displayName = CSTRING(arifle_arx_hex_Name); }; - class optic_ACO_grn_smg: ItemCore { - displayName = CSTRING(optic_ACO_grn_smg); - }; - - // APEX/Tanoa // QBZ-95 and variants class arifle_CTAR_base_F; @@ -1018,6 +863,16 @@ class CfgWeapons { // Contact/Livonia + // CZ 581 Shotgun + class sgun_HunterShotgun_01_base_F; + class sgun_HunterShotgun_01_F: sgun_HunterShotgun_01_base_F { + displayName = CSTRING(sgun_huntershotgun_01_Name); + }; + class sgun_HunterShotgun_01_sawedoff_base_F; + class sgun_HunterShotgun_01_sawedoff_F: sgun_HunterShotgun_01_sawedoff_base_F { + displayName = CSTRING(sgun_huntershotgun_sawedoff_01_Name); + }; + // FNX-45 (Green) class hgun_Pistol_heavy_01_green_F: hgun_Pistol_heavy_01_F { displayName = CSTRING(hgun_Pistol_heavy_01_green_Name); diff --git a/addons/realisticnames/stringtable.xml b/addons/realisticnames/stringtable.xml index 6130f6aaf4e..833c83db946 100644 --- a/addons/realisticnames/stringtable.xml +++ b/addons/realisticnames/stringtable.xml @@ -46,7 +46,7 @@ XM312 (Alta) XM312 (Magasított) XM312 (Alto) - XM312 (高) + XM312 (ハイマウント) XM312 (높음) XM312重機槍 (高射腳架) XM312(高) @@ -97,7 +97,7 @@ XM307 (Alta) XM307 (Magasított) XM307 (Alto) - XM307 (高) + XM307 (ハイマウント) XM307 (높음) XM307榴彈機槍 (高射腳架) XM307(高) @@ -556,7 +556,7 @@ Leopard 2SG Leopard 2SG Leopard 2SG - レオパルト 2SG + レオパルト2SG 레오파르트 2SG "豹2型新加坡版"主戰坦克 "豹"2 新加坡版 @@ -698,6 +698,12 @@ "卡玛兹"(医疗) KamAZ Medikal + + KamAZ Water + KamAZ Água + KamAZ 給水 + КамАЗ (водоноситель) + KamAZ MRL KamAS MRL @@ -1655,6 +1661,18 @@ FNX-45戰術型手槍 FNX-45 战术型 + + CZ 581 + CZ 581 + CZ 581 + CZ 581 + + + CZ 581 (Sawed-Off) + CZ 581 (Cano serrado) + CZ 581 (ソードオフ) + CZ 581 (Sawed-Off) + FNX-45 Tactical (Green) FNX-45 Tactical (Grün) @@ -2321,7 +2339,7 @@ Scorpion Evo 3 A1 Scorpion Evo 3 A1 Scorpion Evo 3 A1 - スコーピオン エボ 3 A1 + スコーピオン Evo 3 A1 스콜피온 에보 3 A1 "蠍式"Evo 3 A1衝鋒槍 Evo 3 A1 "蝎" @@ -2372,7 +2390,7 @@ Stoner 99 LMG Stoner 99 LMG Stoner 99 LMG - ストーナー 99 LMG + ストーナー99 LMG 스토너 99 LMG 斯通納99輕機槍 斯通纳 99 @@ -3056,6 +3074,24 @@ "柏拉格" 战斗无人机 Burraq UCAV + + Type 115 (Black) + Type 115 (Preto) + Type 115 (ブラック) + Type 115 (чёрный) + + + Type 115 (Green Hex) + Type 115 (Verde Hex) + Type 115 (緑六角形迷彩) + Type 115 (зелёный гекс) + + + Type 115 (Hex) + Type 115 (Hex) + Type 115 (六角形迷彩) + Type 115 (гекс) + QBZ-95-1 (Black) QBZ-95-1 (Černá) @@ -3651,7 +3687,7 @@ Polaris DAGOR (light) Polaris DAGOR (leicht) - ポラリス DAGOR (軽) + ポラリス DAGOR (軽装) "北極星"先進佈署越野車 (輕型) "北极星"(轻型) Polaris DAGOR (leggero) @@ -3840,6 +3876,24 @@ Wiesel 2 RFCV (Radar) 비젤 2 RFCV (레이더) + + UTG Defender 126 + UTG Defender 126 + UTG ディフェンダー 126 + UTG Defender 126 + + + EOTech MRDS + EOTech MRDS + EOTech MRDS + EOTech MRDS + + + EOTech MRDS (Black) + EOTech MRDS (Preto) + EOTech MRDS (ブラック) + EOTech MRDS (чёрный) + Leupold Mark 4 HAMR Leupold Mark 4 HAMR @@ -4272,7 +4326,7 @@ KAHLES Helia (Tan) KAHLES Helia (Tan) KAHLES Helia(沙色) - KAHLES Helia (タン) + KAHLES ヘリア (タン) KAHLES Helia (Tan) KAHLES Helia (Marroncino) KAHLES Helia (пустынный) diff --git a/addons/rearm/XEH_postInit.sqf b/addons/rearm/XEH_postInit.sqf index f156fb71d64..61ec35b8dec 100644 --- a/addons/rearm/XEH_postInit.sqf +++ b/addons/rearm/XEH_postInit.sqf @@ -1,9 +1,8 @@ #include "script_component.hpp" -GVAR(hardpointGroupsCache) = [] call CBA_fnc_createNamespace; GVAR(configTypesAdded) = []; -GVAR(magazineNameCache) = [] call CBA_fnc_createNamespace; -GVAR(originalMagazineNames) = []; +GVAR(magazineNameCache) = createHashMap; +GVAR(usedMagazineNames) = createHashMap; [QGVAR(initSupplyVehicle), { TRACE_1("initSupplyVehicle EH",_this); // Warning: this can run before settings are init diff --git a/addons/rearm/XEH_preStart.sqf b/addons/rearm/XEH_preStart.sqf index b092699f9b9..b013b04b860 100644 --- a/addons/rearm/XEH_preStart.sqf +++ b/addons/rearm/XEH_preStart.sqf @@ -4,6 +4,6 @@ // Test binarization one time at startup - ref https://github.com/acemod/ACE3/pull/8093 private _test = getText (configFile >> "Cfg3DEN" >> "Object" >> "AttributeCategories" >> "ace_attributes" >> "Attributes" >> "ace_rearm_rearmCargo" >> "defaultValue"); -if (!("else {" in _test)) then { +if !("else {" in _test) then { ERROR("3den attribute has ERROR [check binarization]"); }; diff --git a/addons/rearm/functions/fnc_getMagazineName.sqf b/addons/rearm/functions/fnc_getMagazineName.sqf index 2ee4a988ed9..e961831c8c4 100644 --- a/addons/rearm/functions/fnc_getMagazineName.sqf +++ b/addons/rearm/functions/fnc_getMagazineName.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* - * Author: PabstMirror - * Gets a non-ambigious display name for a magazine using displayNameShort (AP/HE) + * Author: PabstMirror, johnb43 + * Gets a non-ambigious display name for a magazine using displayNameShort (AP/HE). * * Arguments: * 0: Magazine Classname @@ -10,7 +10,7 @@ * Display Name * * Example: - * ["B_20mm_AP"] call ace_rearm_fnc_getMagazineName + * "60Rnd_20mm_AP_shells" call ace_rearm_fnc_getMagazineName * * Public: No */ @@ -18,31 +18,31 @@ params ["_className"]; TRACE_1("getMagazineName",_className); -private _magName = GVAR(magazineNameCache) getVariable _className; -if (isNil "_magName") then { - private _displayName = getText(configFile >> "CfgMagazines" >> _className >> "displayName"); +GVAR(magazineNameCache) getOrDefaultCall [_className, { + private _cfgMagazines = configFile >> "CfgMagazines"; + private _displayName = getText (_cfgMagazines >> _className >> "displayName"); + if (_displayName == "") then { _displayName = _className; WARNING_1("Magazine is missing display name [%1]",_className); }; - if ((_displayName select [0,6]) == "[CSW] ") then { _displayName = _displayName select [6]; }; + // [CSW] prefix is localised + if (["ace_csw"] call EFUNC(common,isModLoaded)) then { + _displayName = trim (_displayName regexReplace [LELSTRING(csw,regex), ""]); + }; - GVAR(magazineNameCache) setVariable [_className, _displayName]; - GVAR(originalMagazineNames) pushBack _displayName; - TRACE_2("Adding to cache",_className,_displayName); + // If the display name exists already, add displayNameShort to the existing entry + private _existingClassname = GVAR(usedMagazineNames) get _displayName; - // go through all existing cache entries and update if there now are duplicates - { - private _xMagName = GVAR(magazineNameCache) getVariable _x; - if ((_xMagName == _displayName) && {({_xMagName == _x} count GVAR(originalMagazineNames)) > 1}) then { - private _xMagName = format ["%1: %2", _displayName, getText(configFile >> "CfgMagazines" >> _x >> "displayNameShort")]; - GVAR(magazineNameCache) setVariable [_x, _xMagName]; - TRACE_2("Using unique name",_x,_xMagName); - }; - } forEach (allVariables GVAR(magazineNameCache)); + if (!isNil "_existingClassname") then { + GVAR(magazineNameCache) set [_existingClassname, format ["%1: %2", _displayName, getText (_cfgMagazines >> _existingClassname >> "displayNameShort")]]; - _magName = GVAR(magazineNameCache) getVariable _className; -}; + _displayName = format ["%1: %2", _displayName, getText (_cfgMagazines >> _className >> "displayNameShort")]; + }; + + GVAR(usedMagazineNames) set [_displayName, _className]; + TRACE_2("Adding to cache",_className,_displayName); -_magName + _displayName +}, true] // return diff --git a/addons/rearm/initSettings.inc.sqf b/addons/rearm/initSettings.inc.sqf index 37535d8d90e..6489bd9326c 100644 --- a/addons/rearm/initSettings.inc.sqf +++ b/addons/rearm/initSettings.inc.sqf @@ -7,7 +7,7 @@ private _category = [ELSTRING(main,Category_Logistics), LLSTRING(DisplayName)]; true, true, {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -15,8 +15,7 @@ private _category = [ELSTRING(main,Category_Logistics), LLSTRING(DisplayName)]; [LSTRING(RearmSettings_level_DisplayName), LSTRING(RearmSettings_level_Description)], _category, [[0,1,2],[LSTRING(RearmSettings_vehicle), LSTRING(RearmSettings_magazine), LSTRING(RearmSettings_caliber)],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(level), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -24,8 +23,7 @@ private _category = [ELSTRING(main,Category_Logistics), LLSTRING(DisplayName)]; [LSTRING(RearmSettings_supply_DisplayName), LSTRING(RearmSettings_supply_Description)], _category, [[0,1,2],[LSTRING(RearmSettings_unlimited), LSTRING(RearmSettings_limited), LSTRING(RearmSettings_magazineSupply)],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(supply), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -33,6 +31,5 @@ private _category = [ELSTRING(main,Category_Logistics), LLSTRING(DisplayName)]; [LLSTRING(RearmSettings_distance_DisplayName), LLSTRING(RearmSettings_distance_Description)], _category, [10, 50, 20, 0], - true, // isGlobal - {[QGVAR(supply), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; diff --git a/addons/refuel/ACE_Refuel_Positions.hpp b/addons/refuel/ACE_Refuel_Positions.hpp new file mode 100644 index 00000000000..78af5b6d48d --- /dev/null +++ b/addons/refuel/ACE_Refuel_Positions.hpp @@ -0,0 +1,96 @@ +class GVAR(positions) { + Altis[] = { /* Altis */ {"Land_fs_feed_F", {{3757,13478,0},{4001,12592,0},{5023,14430,0},{5769,20086,0},{6199,15081,0},{6798,15561,0},{8482,18261,0},{9026,15729,0},{9206,12112,0},{11832,14156,0},{12025,15830,0},{14173,16542,0},{14221,18303,0},{15297,17566,0},{15781,17453,0},{16751,12513,0},{16875,15469,0},{17417,13937,0},{19961,11454,0},{20785,16666,0},{21231,7117,0},{23379,19799,0},{25701,21373,0}}}}; + Stratis[] = { /* Stratis */ {"Land_FuelStation_Feed_F", {{2708,5788,0}}}}; + VR[] = {}; + Malden[] = { /* Malden 2035 */ + {"Land_fs_feed_F", {{3227,6291,0},{5111,9062,0},{5504,3500,0},{6633,8807,0},{7047,7052,0}}}, + {"Land_FuelStation_01_pump_malevil_F", {{7224,7772,0},{8047,4023,0}}}, + {"Land_FuelStation_Feed_F", {{10063,3988,0},{11600,4477,0}}} + }; + Tanoa[] = { /* Tanoa */ + {"Land_fs_feed_F", {{2132,3360,0},{2452,7435,0},{3030,11316,0},{5174,8806,0},{5380,4093,0},{5594,12508,0},{7978,7419,0},{8319,9709,0},{8494,12432,0},{8954,13678,0},{8970,10332,0},{10827,6490,0},{10941,9855,0},{11146,5152,0},{11631,2999,0},{14261,11513,0},{14365,8743,0}}}, + {"Land_FuelStation_01_pump_F", {{1865,12128,0},{5409,9905,0},{5682,10165,0},{5776,4222,0},{5793,10825,0},{6592,13080,0},{6887,7491,0},{7359,7998,0},{9954,13467,0},{11635,13047,0},{11694,2271,0},{12613,7583,0}}} + }; + Enoch[] = { /* Livonia */ + {"Land_FuelStation_03_pump_F", {{2008,7365,0},{6259,3949,0}}}, + {"Land_FuelStation_Feed_F", {{10208,2173,0}}} + }; + + Bootcamp_ACR[] = { /* CUP Bukovina */ {"Land_A_FuelStation_Feed", {{652,473,0},{2849,1612,0}}}}; + Woodland_ACR[] = { /* CUP Bystrica */ {"Land_A_FuelStation_Feed", {{447,1381,0},{1302,2185,0},{1855,6852,0},{4102,1195,0},{4755,4499,0}}}}; + chernarus[] = { /* CUP Chernarus (Autumn) */ {"Land_A_FuelStation_Feed", {{2021,2242,0},{2692,5602,0},{2997,7471,0},{3648,8968,0},{4733,6381,0},{5847,2191,0},{5849,10112,0},{6705,2996,0},{7255,7662,0},{9502,2005,0},{10154,5300,0},{10446,8866,0},{10726,10786,0},{12988,10076,0},{13385,6603,0}}}}; + chernarus_summer[] = { /* CUP Chernarus (Summer) */ {"Land_A_FuelStation_Feed", {{2021,2242,0},{2685,5606,0},{2998,7473,0},{3652,8973,0},{4733,6381,0},{5854,2193,0},{5849,10112,0},{6702,2995,0},{7255,7662,0},{9502,2005,0},{10154,5300,0},{10452,8869,0},{10726,10786,0},{13001,10074,0},{13398,6606,0}}}}; + Chernarus_Winter[] = { /* CUP Chernarus (Winter) */ {"Land_A_FuelStation_Feed", {{2021,2242,0},{2685,5604,0},{2997,7471,0},{3657,8979,0},{4733,6381,0},{5854,2193,0},{5849,10112,0},{6702,2995,0},{7255,7662,0},{9503,2019,0},{10155,5309,0},{10452,8869,0},{10726,10786,0},{12994,10075,0},{13385,6603,0}}}}; + cup_chernarus_A3[] = { /* CUP Chernarus 2020 */ + {"Land_fs_feed_F", {{2511,5279,0}}}, + {"Land_FuelStation_03_pump_F", {{313,9385,0},{1129,2400,0},{2021,2242,0},{2692,5602,0},{2991,7471,1},{3007,12654,0},{3648,8968,0},{4328,13081,0},{4733,6381,0},{5847,2191,0},{5849,10112,0},{6699,3001,0},{7255,7662,0},{7494,12662,0},{9502,2005,0},{10155,5309,0},{10452,8869,0},{10726,10786,0},{13001,10074,0},{13398,6606,0},{13569,13329,0}}} + }; + Desert_E[] = { /* CUP Desert */ }; + porto[] = { /* CUP Porto */ }; + ProvingGrounds_PMC[] = { /* CUP Proving Grounds */ {"Land_FuelStation_Feed_PMC", {{698,1208,0}}}}; + intro[] = { /* CUP Rahmadi */ }; + sara[] = { /* CUP Sahrani */ + {"Land_Benzina_schnell", {{8473,9423,0},{9227,5840,0},{9433,5187,0},{10168,6423,0},{10932,9475,0},{11233,6114,0},{11756,10227,0},{12289,6833,0}}}, + {"Land_Fuelstation_army", {{9568,9819,0},{19294,13879,0}}} + }; + sara_dbe1[] = { /* CUP United Sahrani */ + {"Land_Benzina_schnell", {{8473,9423,0},{9227,5840,0},{9433,5187,0},{10168,6423,0},{10932,9475,0},{11233,6114,0},{11756,10227,0},{12289,6833,0}}}, + {"Land_Fuelstation_army", {{9568,9819,0},{19294,13879,0}}} + }; + saralite[] = { /* CUP Southern Sahrani */ + {"Land_Benzina_schnell", {{3593,6663,0},{4347,3080,0},{4553,2427,0},{5288,3663,0},{6052,6715,0},{6353,3354,0},{6876,7467,0},{7409,4073,0}}}, + {"Land_Fuelstation_army", {{4688,7059,0}}} + }; + Shapur_BAF[] = { /* CUP Shapur */ {"Land_Ind_FuelStation_Feed_EP1", {{1512,1298,0}}}}; + takistan[] = { /* CUP Takistan */ {"Land_Ind_FuelStation_Feed_EP1", {{2004,11720,0},{3081,9848,0},{3549,4197,0},{5538,9284,0},{5836,5771,0},{7497,1818,0},{8248,7800,0},{10422,6328,0},{10647,11021,0}}}}; + Mountains_ACR[] = { /* CUP Takistan Mountains */ {"Land_Ind_FuelStation_Feed_EP1", {{2962,4197,0},{5249,5771,0}}}}; + utes[] = { /* CUP Utes */ }; + zargabad[] = { /* CUP Zargabad */ {"Land_Ind_FuelStation_Feed_EP1", {{3736,2784,0},{3867,4208,0},{3871,5980,0},{5027,1906,0}}}}; + + pja310[] = { /* G.O.S Al Rayak */ {"Land_Ind_FuelStation_Feed_EP1", {{887,18588,0},{964,18356,0},{1196,18463,0},{1872,8754,0},{2051,8437,0},{2125,8238,0},{2240,8584,0},{2310,8566,0},{2366,3901,0},{2879,13142,0},{3880,10361,0},{4056,13261,0},{4122,13487,0},{4302,13628,0},{4475,13377,0},{4556,13742,0},{6461,3372,0},{7216,6059,0},{7228,6344,0},{7416,6099,0},{7472,6838,0},{7591,6081,0},{11650,3536,0},{14863,7292,0},{16466,18897,0},{16476,19116,0},{16642,18994,0},{16676,19199,0},{16858,10558,0},{16908,9959,0},{17120,3706,0},{17100,4375,0},{18056,4133,0},{18229,4066,0},{18235,4571,0},{18814,5010,0}}}}; + australia[] = { /* Aussie Australia v5.09 */ + {"Land_fs_feed_F", {{4614,16978,0},{5509,19273,0},{5487,19276,0},{5508,19330,0},{5540,19357,0},{5564,19377,0},{5623,19376,0},{5643,19352,0},{6355,17860,0},{12811,27772,0},{15837,33438,0},{16335,33436,0},{16367,33436,0},{17127,33902,0},{20754,12737,0},{20874,12793,0},{20901,12793,1},{22127,25635,0},{22127,25666,0},{22162,25712,0},{22194,25712,0},{22213,25630,0},{22315,19235,0},{22595,24757,0},{24909,13855,0},{25050,12786,0},{25071,12786,0},{26085,11260,1},{26212,11174,0},{26824,28005,0},{27719,17108,0},{27757,12033,0},{28473,35132,0},{30707,11879,0},{31091,5370,0},{31096,10918,0},{31096,10945,0},{31165,10914,0},{31165,10958,0},{31313,16763,0},{31515,9673,0},{31515,9652,0},{31758,4861,0},{32224,2736,0},{33919,13364,0},{33936,13350,0},{34789,26383,0},{35274,26021,2},{35786,12148,0},{35765,12170,0},{35835,12145,0},{35833,12188,0},{35812,12210,0},{36199,16479,0},{36399,13140,0},{36593,12065,0},{36574,13089,0},{36595,13089,0},{36597,13282,0},{38153,14544,0},{38520,18891,0},{38515,20173,0},{38535,20198,0},{38565,20198,0}}}, + {"Land_FuelStation_01_pump_F", {{5495,18693,0},{32067,29608,0},{32087,29611,0},{33215,4147,0},{37293,13172,0},{37293,13193,0}}}, + {"Land_FuelStation_Feed_F", {{19303,16449,0},{31064,20116,0}}} + }; + Farabad[] = { /* Farabad */ + {"Land_Benzina_schnell", {{592,7505,0},{804,1445,0},{3132,3129,0}}}, + {"Land_fs_feed_F", {{1920,4960,0},{5052,4703,1},{9456,9277,0}}}, + {"Land_FuelStation_01_pump_F", {{2378,6248,0},{7092,534,0}}}, + {"Land_Ind_FuelStation_Feed_EP1", {{4788,5525,0}}} + }; + IslaPera[] = { /* Isla Pera */ + {"Land_fs_feed_F", {{1855,2866,0}}}, + {"Land_FuelStation_01_pump_malevil_F", {{3981,2065,0},{5306,8796,0},{9236,4287,0}}} + }; + VTF_Lybor[] = { /* Lybor */ + {"Land_FuelStation_03_pump_F", {{3879,3823,0}}}, + {"Land_FuelStation_Feed_F", {{1831,2694,0},{2175,3323,0},{3304,2981,0},{4271,3024,0}}} + }; + rof_mok[] = { /* Mull of Kintyre, Scotland */ + {"Land_A_FuelStation_Feed", {{12837,5124,1},{15271,17533,0},{19453,21896,0}}}, + {"Land_fs_feed_F", {{7492,17369,0}}}, + {"Land_Fuelstation", {{10284,18679,0}}}, + {"Land_Ind_FuelStation_Feed_EP1", {{9762,16325,0}}} + }; + pulau[] = { /* Pulau */ + {"Land_fs_feed_F", {{2368,3128,0},{4891,7168,0},{7358,7368,0}}}, + {"Land_FuelStation_Feed_F", {{5994,5789,0}}} + }; + WL_Rosche[] = { /* Rosche, Germany (2.0) */ + {"Land_fs_feed_F", {{693,4803,0},{12059,6700,0},{13320,14822,0}}}, + {"Land_FuelStation_01_pump_F", {{447,6859,0}}}, + {"Land_Ind_FuelStation_Feed_EP1", {{1437,5455,0}}} + }; + Kapaulio[] = { /* Saint Kapaulio */ + {"Land_fs_feed_F", {{931,7647,0},{958,6796,0},{2034,9426,0},{2563,9427,0},{3500,8110,0},{3602,6082,0},{4222,6308,0},{4561,693,0},{8077,5906,0},{8434,13145,0},{8525,17299,0},{9265,7155,0},{10527,18267,0},{12078,1846,0},{12833,6464,0},{13433,6327,0},{14084,6308,0},{14172,7786,0},{14831,4649,0},{16080,14743,0},{17356,2312,0},{18047,5254,0},{18318,5042,0}}}, + {"Land_FuelStation_01_pump_malevil_F", {{18039,18139,0}}}, + {"Land_FuelStation_Feed_F", {{756,12133,0},{1239,7346,0},{1726,17469,0},{3113,10070,0},{3828,8362,0},{5668,16967,0},{7435,14185,0},{7543,12107,0},{8366,6086,0},{9672,9586,0},{11749,12255,0},{12802,10022,0},{13989,3591,0},{15198,10900,0},{19063,1654,0},{19378,18517,0}}} + }; + pabst_yellowstone[] = { /* Yellowstone */ + {"Land_fs_feed_F", {{3075,7426,0},{7060,3626,0},{7950,4060,0},{7974,4072,0}}}, + {"Land_FuelStation_01_pump_F", {{4565,1953,0}}}, + {"Land_FuelStation_01_pump_malevil_F", {{7072,3676,0}}}, + {"Land_FuelStation_Feed_F", {{4678,3971,0},{6391,5174,0}}} + }; +}; diff --git a/addons/refuel/Cfg3DEN.hpp b/addons/refuel/Cfg3DEN.hpp index 33831079955..00d5453d955 100644 --- a/addons/refuel/Cfg3DEN.hpp +++ b/addons/refuel/Cfg3DEN.hpp @@ -1,7 +1,4 @@ -#define GET_NUMBER(config,default) (if (isNumber (config)) then {getNumber (config)} else {default}) #define GET_1ST_ARRAY(config) (if (isArray (config)) then {getArray (config) select 0} else {[ARR_3(0,0,0)]}) - -#define DEFAULT_FUELCARGO GET_NUMBER(configOf _this >> QQGVAR(fuelCargo),REFUEL_DISABLED_FUEL) #define DEFAULT_HOOKS GET_1ST_ARRAY(configOf _this >> QQGVAR(hooks)) class Cfg3DEN { @@ -14,8 +11,8 @@ class Cfg3DEN { tooltip = CSTRING(fuelCargo_edenDesc); property = QGVAR(fuelCargo); control = "EditShort"; - expression = QUOTE(if (_value != DEFAULT_FUELCARGO) then {[ARR_2(_this,_value)] call DFUNC(makeSource)}); - defaultValue = QUOTE(DEFAULT_FUELCARGO); + expression = QUOTE(if (_value != (_this call FUNC(getFuelCargo))) then {[ARR_2(_this,_value)] call FUNC(makeSource)}); + defaultValue = QUOTE(_this call FUNC(getFuelCargo)); validate = "number"; condition = "(1-objectBrain)*(1-objectAgent)"; typeName = "NUMBER"; diff --git a/addons/refuel/CfgVehicles.hpp b/addons/refuel/CfgVehicles.hpp index 5fba3369434..44575a141d7 100644 --- a/addons/refuel/CfgVehicles.hpp +++ b/addons/refuel/CfgVehicles.hpp @@ -1,3 +1,5 @@ +#define XEH_INHERITED class EventHandlers {class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {};} + class CBA_Extended_EventHandlers; class CfgNonAIVehicles { @@ -45,9 +47,7 @@ class CfgVehicles { class ThingX; class GVAR(fuelNozzle): ThingX { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; + XEH_INHERITED; displayName = QGVAR(fuelNozzle); scope = 1; @@ -275,12 +275,6 @@ class CfgVehicles { GVAR(hooks)[] = {{0.38,-3.17,-0.7},{-0.41,-3.17,-0.7}}; GVAR(fuelCargo) = 2000; }; - class C_Van_01_fuel_F: Van_01_fuel_base_F { - transportFuel = 0; //1k - }; - class I_G_Van_01_fuel_F: Van_01_fuel_base_F { - transportFuel = 0; //1k - }; class Tank_F: Tank { GVAR(fuelCapacity) = 1200; @@ -295,7 +289,6 @@ class CfgVehicles { class B_APC_Tracked_01_base_F: APC_Tracked_01_base_F {}; class B_APC_Tracked_01_CRV_F: B_APC_Tracked_01_base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{-1.08,-4.81,-0.8}}; GVAR(fuelCargo) = 1000; }; @@ -407,7 +400,6 @@ class CfgVehicles { // Vanilla fuel vehicles class Truck_02_fuel_base_F: Truck_02_base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{0.99,-3.47,-0.67},{-1.04,-3.47,-0.67}}; GVAR(fuelCargo) = 10000; }; @@ -416,13 +408,11 @@ class CfgVehicles { }; class B_Truck_01_fuel_F: B_Truck_01_mover_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{0.28,-4.99,-0.3},{-0.25,-4.99,-0.3}}; GVAR(fuelCargo) = 10000; }; class O_Truck_03_fuel_F: Truck_03_base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{1.3,-1.59,-0.62},{-1.16,-1.59,-0.62}}; GVAR(fuelCargo) = 10000; }; @@ -436,20 +426,17 @@ class CfgVehicles { class Pod_Heli_Transport_04_base_F: Slingload_base_F {}; class Land_Pod_Heli_Transport_04_fuel_F: Pod_Heli_Transport_04_base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{-1.49,1.41,-0.3}}; GVAR(fuelCargo) = 10000; }; class Slingload_01_Base_F: Slingload_base_F {}; class B_Slingload_01_Fuel_F: Slingload_01_Base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{0.55,3.02,-0.5},{-0.52,3.02,-0.5}}; GVAR(fuelCargo) = 10000; }; class O_Heli_Transport_04_fuel_F: Heli_Transport_04_base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{-1.52,1.14,-1.18}}; GVAR(fuelCargo) = 10000; }; @@ -466,11 +453,7 @@ class CfgVehicles { }; }; class Land_StorageBladder_01_F: StorageBladder_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - - transportFuel = 0; //60k + XEH_INHERITED; GVAR(hooks)[] = {{-3.35,2.45,0.17}}; GVAR(fuelCargo) = 60000; }; @@ -486,36 +469,35 @@ class CfgVehicles { }; }; class Land_FlexibleTank_01_F: FlexibleTank_base_F { - transportFuel = 0; //300 GVAR(hooks)[] = {{0, 0, 0.5}}; GVAR(fuelCargo) = 300; }; // Vanilla buildings class Land_Fuelstation_Feed_F: House_Small_F { - transportFuel = 0; //50k + XEH_INHERITED; GVAR(hooks)[] = {{0,0,-0.5}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_fs_feed_F: House_Small_F { - transportFuel = 0; //50k + XEH_INHERITED; GVAR(hooks)[] = {{-0.4,0.022,-0.23}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_FuelStation_01_pump_F: House_F { - transportFuel = 0; //50k + XEH_INHERITED; GVAR(hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_FuelStation_01_pump_malevil_F: House_F { - transportFuel = 0; //50k + XEH_INHERITED; GVAR(hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_FuelStation_03_pump_F: House_F { // Enoch - transportFuel = 0; //50k + XEH_INHERITED; GVAR(hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; diff --git a/addons/refuel/XEH_PREP.hpp b/addons/refuel/XEH_PREP.hpp index 077c8f1aed7..cb9279500bc 100644 --- a/addons/refuel/XEH_PREP.hpp +++ b/addons/refuel/XEH_PREP.hpp @@ -11,6 +11,7 @@ PREP(disconnect); PREP(dropNozzle); PREP(getCapacity); PREP(getFuel); +PREP(getFuelCargo); PREP(handleDisconnect); PREP(handleRespawn); PREP(initSource); diff --git a/addons/refuel/XEH_postInit.sqf b/addons/refuel/XEH_postInit.sqf index c826efd3d45..f6f5a7d7b36 100644 --- a/addons/refuel/XEH_postInit.sqf +++ b/addons/refuel/XEH_postInit.sqf @@ -1,95 +1,151 @@ #include "script_component.hpp" -if (isServer) then { - addMissionEventHandler ["HandleDisconnect", {call FUNC(handleDisconnect)}]; -}; +["CBA_settingsInitialized", { + if (!GVAR(enabled)) exitWith {}; -[QGVAR(initSource), LINKFUNC(initSource)] call CBA_fnc_addEventHandler; + ["All", "InitPost", { + params ["_vehicle"]; + if (getFuelCargo _vehicle <= 0) exitWith {}; + TRACE_1("initPost",_vehicle); -if (!hasInterface) exitWith {}; + if (local _vehicle) then { + _vehicle setFuelCargo 0; + LOG("initPost setFuelCargo"); + }; + }, true, ["Man"], true] call CBA_fnc_addClassEventHandler; -["isNotRefueling", {!((_this select 0) getVariable [QGVAR(isRefueling), false])}] call EFUNC(common,addCanInteractWithCondition); + if (isServer) then { + addMissionEventHandler ["HandleDisconnect", {call FUNC(handleDisconnect)}]; + }; -["MouseButtonDown", LINKFUNC(onMouseButtonDown)] call CBA_fnc_addDisplayHandler; + private _cfgPositions = configFile >> QGVAR(positions) >> worldName; + if (isArray _cfgPositions) then { + { + _x params ["_class", "_positions"]; + { + private _objects = _x nearObjects [_class, 30]; + if (_objects isEqualTo []) then { + WARNING_3("no pumps %1 found near %2 %3",_class,worldName,_x); + } else { + { + // terrain fuel pumps don't trigger init and must setFuelCargo on each client + _x setFuelCargo 0; + } forEach _objects; + }; + } forEach _positions; + } forEach getArray _cfgPositions; -GVAR(mainAction) = [ - QGVAR(Refuel), - localize LSTRING(Refuel), - QPATHTOF(ui\icon_refuel_interact.paa), - {}, - { - alive _target - && {[_player, _target, [INTERACT_EXCEPTIONS]] call EFUNC(common,canInteractWith)} - && {REFUEL_DISABLED_FUEL != ([_target] call FUNC(getCapacity))} - }, - {}, [], [0,0,0], - REFUEL_ACTION_DISTANCE -] call EFUNC(interact_menu,createAction); - -GVAR(actions) = [ - [QGVAR(TakeNozzle), - localize LSTRING(TakeNozzle), - QPATHTOF(ui\icon_refuel_interact.paa), - {[_player, _target] call FUNC(TakeNozzle)}, - {[_player, _target] call FUNC(canTakeNozzle)}, - {}, [], [0,0,0], - REFUEL_ACTION_DISTANCE - ] call EFUNC(interact_menu,createAction), - [QGVAR(CheckFuelCounter), - localize LSTRING(CheckFuelCounter), - QPATHTOF(ui\icon_refuel_interact.paa), - {[_player, _target] call FUNC(readFuelCounter)}, - {true}, - {}, [], [0,0,0], - REFUEL_ACTION_DISTANCE - ] call EFUNC(interact_menu,createAction), - [QGVAR(CheckFuel), - localize LSTRING(CheckFuel), - QPATHTOF(ui\icon_refuel_interact.paa), - {[_player, _target] call FUNC(checkFuel)}, - {[_player, _target] call FUNC(canCheckFuel)}, - {}, [], [0,0,0], - REFUEL_ACTION_DISTANCE - ] call EFUNC(interact_menu,createAction), - [QGVAR(Return), - localize LSTRING(Return), + // placed in editor static objects don't trigger init but synchronize fuel cargo + // placed in editor vehicles both trigger init and synchronize fuel cargo + { + if (getFuelCargo _x > 0 && {local _x}) then { + TRACE_1("allMissionObjects",_x); + _x setFuelCargo 0; + }; + } forEach allMissionObjects ""; + } else { + // here are both terrain and editor static objects + WARNING_2("World %1: %2 is not configured; can load slower",worldName,QGVAR(positions)); + private _halfWorldSize = worldSize / 2; + private _worldCenter = [_halfWorldSize, _halfWorldSize]; + _halfWorldSize = _halfWorldSize * sqrt 2; + private _refuelMissionObjects = allMissionObjects "" select {getFuelCargo _x > 0}; + private _baseStaticClasses = keys (uiNamespace getVariable QGVAR(cacheRefuelClassesBaseStatic)); + + { + { + _x setFuelCargo 0; + } forEach (_worldCenter nearObjects [_x, _halfWorldSize]); + } forEach _baseStaticClasses; + }; + + [QGVAR(initSource), LINKFUNC(initSource)] call CBA_fnc_addEventHandler; + + if (!hasInterface) exitWith {}; + + ["isNotRefueling", {!((_this select 0) getVariable [QGVAR(isRefueling), false])}] call EFUNC(common,addCanInteractWithCondition); + + ["MouseButtonDown", LINKFUNC(onMouseButtonDown)] call CBA_fnc_addDisplayHandler; + + GVAR(mainAction) = [ + QGVAR(Refuel), + localize LSTRING(Refuel), QPATHTOF(ui\icon_refuel_interact.paa), - {[_player, _target] call FUNC(returnNozzle)}, - {[_player, _target] call FUNC(canReturnNozzle)}, + {}, + { + alive _target + && {[_player, _target, [INTERACT_EXCEPTIONS]] call EFUNC(common,canInteractWith)} + && {REFUEL_DISABLED_FUEL != ([_target] call FUNC(getCapacity))} + }, {}, [], [0,0,0], REFUEL_ACTION_DISTANCE - ] call EFUNC(interact_menu,createAction) -]; + ] call EFUNC(interact_menu,createAction); -// init menu for config refuel vehicles -private _cacheRefuelClasses = call (uiNamespace getVariable [QGVAR(cacheRefuelClasses), {[[],[]]}]); -_cacheRefuelClasses params [["_staticClasses", [], [[]]], ["_dynamicClasses", [], [[]]]]; + GVAR(actions) = [ + [QGVAR(TakeNozzle), + localize LSTRING(TakeNozzle), + QPATHTOF(ui\icon_refuel_interact.paa), + {[_player, _target] call FUNC(TakeNozzle)}, + {[_player, _target] call FUNC(canTakeNozzle)}, + {}, [], [0,0,0], + REFUEL_ACTION_DISTANCE + ] call EFUNC(interact_menu,createAction), + [QGVAR(CheckFuelCounter), + localize LSTRING(CheckFuelCounter), + QPATHTOF(ui\icon_refuel_interact.paa), + {[_player, _target] call FUNC(readFuelCounter)}, + {true}, + {}, [], [0,0,0], + REFUEL_ACTION_DISTANCE + ] call EFUNC(interact_menu,createAction), + [QGVAR(CheckFuel), + localize LSTRING(CheckFuel), + QPATHTOF(ui\icon_refuel_interact.paa), + {[_player, _target] call FUNC(checkFuel)}, + {[_player, _target] call FUNC(canCheckFuel)}, + {}, [], [0,0,0], + REFUEL_ACTION_DISTANCE + ] call EFUNC(interact_menu,createAction), + [QGVAR(Return), + localize LSTRING(Return), + QPATHTOF(ui\icon_refuel_interact.paa), + {[_player, _target] call FUNC(returnNozzle)}, + {[_player, _target] call FUNC(canReturnNozzle)}, + {}, [], [0,0,0], + REFUEL_ACTION_DISTANCE + ] call EFUNC(interact_menu,createAction) + ]; -{ - private _className = _x; - [_className, 0, ["ACE_MainActions"], GVAR(mainAction)] call EFUNC(interact_menu,addActionToClass); - { - [_className, 0, ["ACE_MainActions", QGVAR(Refuel)], _x] call EFUNC(interact_menu,addActionToClass); - } forEach GVAR(actions); - TRACE_1("add menu to static",_x); -} forEach _staticClasses; - -{ - private _className = _x; - [_className, 0, ["ACE_MainActions"], GVAR(mainAction), true] call EFUNC(interact_menu,addActionToClass); + private _staticClasses = keys (uiNamespace getVariable QGVAR(cacheRefuelClassesStatic)); + private _baseDynamicClasses = keys (uiNamespace getVariable QGVAR(cacheRefuelClassesBaseDynamic)); + + // init menu for config refuel vehicles { - [_className, 0, ["ACE_MainActions", QGVAR(Refuel)], _x, true] call EFUNC(interact_menu,addActionToClass); - } forEach GVAR(actions); - TRACE_1("add menu to dynamic",_x); -} forEach _dynamicClasses; - -#ifdef DRAW_HOOKS_POS -addMissionEventHandler ["Draw3D", { - private _source = cursorObject; - private _cfgPos = getArray (configOf _source >> QGVAR(hooks)); - private _dynPos = _source getVariable [QGVAR(hooks), []]; + private _className = _x; + [_className, 0, ["ACE_MainActions"], GVAR(mainAction)] call EFUNC(interact_menu,addActionToClass); + { + [_className, 0, ["ACE_MainActions", QGVAR(Refuel)], _x] call EFUNC(interact_menu,addActionToClass); + } forEach GVAR(actions); + TRACE_1("add menu to static",_x); + } forEach _staticClasses; + { - drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", [1,1,1,1], _source modelToWorldVisual _x, 1, 1, 0, format ["Hook %1", _forEachIndex]]; - } forEach ([_dynPos, _cfgPos] select (_dynPos isEqualTo [])); -}]; -#endif + private _className = _x; + [_className, 0, ["ACE_MainActions"], GVAR(mainAction), true] call EFUNC(interact_menu,addActionToClass); + { + [_className, 0, ["ACE_MainActions", QGVAR(Refuel)], _x, true] call EFUNC(interact_menu,addActionToClass); + } forEach GVAR(actions); + TRACE_1("add menu to dynamic",_x); + } forEach _baseDynamicClasses; + + #ifdef DRAW_HOOKS_POS + addMissionEventHandler ["Draw3D", { + private _source = cursorObject; + private _cfgPos = getArray (configOf _source >> QGVAR(hooks)); + private _dynPos = _source getVariable [QGVAR(hooks), _cfgPos]; + { + drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", [1,1,1,1], _source modelToWorldVisual _x, 1, 1, 0, format ["Hook %1", _forEachIndex]]; + } forEach _dynPos; + }]; + #endif +}] call CBA_fnc_addEventHandler; diff --git a/addons/refuel/XEH_preStart.sqf b/addons/refuel/XEH_preStart.sqf index fa5fe4acda1..308ca30a9b9 100644 --- a/addons/refuel/XEH_preStart.sqf +++ b/addons/refuel/XEH_preStart.sqf @@ -4,27 +4,44 @@ // cache refuel vehicles, see XEH_postInit.sqf private _staticClasses = []; -private _dynamicClasses = []; +private _baseStaticClasses = []; +private _baseDynamicClasses = []; +private _cacheRefuelCargo = createHashMap; { - private _fuelCargo = getNumber (_x >> QGVAR(fuelCargo)); + private _transportFuel = getNumber (_x >> "transportFuel"); + private _fuelCargo = [_x >> QGVAR(fuelCargo), "NUMBER", _transportFuel] call CBA_fnc_getConfigEntry; if (_fuelCargo > 0 || {_fuelCargo == REFUEL_INFINITE_FUEL}) then { private _sourceClass = configName _x; + private _noXEH = !isText (_x >> "EventHandlers" >> "CBA_Extended_EventHandlers" >> "init"); + private _isPublic = getNumber (_x >> "scope") == 2; // check if we can use actions with inheritance if ( - !isText (_x >> "EventHandlers" >> "CBA_Extended_EventHandlers" >> "init") // addActionToClass relies on XEH init - || {configName _x isKindOf "Static"} // CBA_fnc_addClassEventHandler doesn't support "Static" class + _noXEH // addActionToClass relies on XEH init + || {_sourceClass isKindOf "Static"} // CBA_fnc_addClassEventHandler doesn't support "Static" class ) then { - if (2 == getNumber (_x >> "scope")) then { - _staticClasses pushBackUnique _sourceClass; + if (_isPublic) then { + if (_noXEH) then { + WARNING_3("Class %1: %2 [%3] needs XEH",_sourceClass,configName inheritsFrom _x,configSourceMod _x); + }; + _staticClasses pushBack _sourceClass; + if (_baseStaticClasses findIf {_sourceClass isKindOf _x} == -1) then { + _baseStaticClasses pushBack _sourceClass; + }; }; } else { - if (-1 == _dynamicClasses findIf {_sourceClass isKindOf _x}) then { - _dynamicClasses pushBackUnique _sourceClass; + if (_baseDynamicClasses findIf {_sourceClass isKindOf _x} == -1) then { + _baseDynamicClasses pushBack _sourceClass; }; }; + if (_isPublic) then { + _cacheRefuelCargo set [_sourceClass, _fuelCargo]; + }; }; -} forEach ('true' configClasses (configFile >> "CfgVehicles")); +} forEach ("true" configClasses (configFile >> "CfgVehicles")); -TRACE_2("compiled",count _staticClasses,count _dynamicClasses); -uiNamespace setVariable [QGVAR(cacheRefuelClasses), compileFinal str [_staticClasses, _dynamicClasses]]; +TRACE_3("found",count _staticClasses,count _baseStaticClasses,count _baseDynamicClasses); +uiNamespace setVariable [QGVAR(cacheRefuelClassesStatic), compileFinal (_staticClasses createHashMapFromArray [])]; +uiNamespace setVariable [QGVAR(cacheRefuelClassesBaseStatic), compileFinal (_baseStaticClasses createHashMapFromArray [])]; +uiNamespace setVariable [QGVAR(cacheRefuelClassesBaseDynamic), compileFinal (_baseDynamicClasses createHashMapFromArray [])]; +uiNamespace setVariable [QGVAR(cacheRefuelCargo), compileFinal _cacheRefuelCargo]; diff --git a/addons/refuel/config.cpp b/addons/refuel/config.cpp index b39b6650594..79b97994f17 100644 --- a/addons/refuel/config.cpp +++ b/addons/refuel/config.cpp @@ -14,6 +14,7 @@ class CfgPatches { }; }; +#include "ACE_Refuel_Positions.hpp" #include "ACE_Settings.hpp" #include "Cfg3DEN.hpp" #include "CfgEventHandlers.hpp" diff --git a/addons/refuel/dev/exportTerrainRefuelPositions.sqf b/addons/refuel/dev/exportTerrainRefuelPositions.sqf new file mode 100644 index 00000000000..c7f9abfb2fd --- /dev/null +++ b/addons/refuel/dev/exportTerrainRefuelPositions.sqf @@ -0,0 +1,95 @@ +// call compileScript ["z\ace\addons\refuel\dev\exportTerrainRefuelPositions.sqf"] +// can be run in Eden Editor console + +#include "\z\ace\addons\refuel\script_component.hpp" + +{ + if (!isArray (configFile >> QGVAR(positions) >> configName _x)) then { + WARNING_1("need configs on [%1]",configName _x); + }; +} forEach ("true" configClasses (configFile >> "CfgWorldList")); + + + +private _basePumps = []; +private _totalCount = 0; +private _posCount = 0; +private _message = ""; +private _halfWorldSize = worldSize / 2; +private _worldCenter = [_halfWorldSize, _halfWorldSize]; +_halfWorldSize = _halfWorldSize * sqrt 2; + +private _baseStaticClasses = keys (uiNamespace getVariable QGVAR(cacheRefuelClassesBaseStatic)); +private _class = ""; +private _objects = []; +private _positions = []; +private _object = objNull; +private _pos = []; + +{ + _class = _x; + _objects = _worldCenter nearObjects [_class, _halfWorldSize]; + if (_objects isEqualTo []) then { + continue; + }; + ADD(_totalCount,count _objects); + _positions = []; + { + _object = _x; + _pos = ASLToAGL getPosASL _object; + if (-1 < _positions findIf {60 > _x distance _pos && {20 < _x distance _pos}}) then { + _message = "INCREASE DISTANCE " + str _pos; + }; + if (-1 == _positions findIf {20 > _x distance _pos}) then { + _positions pushBack (_pos apply {round _x}); + INC(_posCount); + }; + } forEach _objects; + _positions sort true; // sort positions by smallest first + _basePumps pushBack [_class, _positions]; +} forEach _baseStaticClasses; + +_basePumps sort true; // sort pump classes alphabetically + +// check final array as it's calculated in postInit +private _checkCount = 0; +{ + _x params ["_class", "_positions"]; + private _pumps = []; + { + _pumps append (_x nearObjects [_class, 30]); + } forEach _positions; + _pumps = _pumps arrayIntersect _pumps; + _checkCount = _checkCount + count _pumps; +} forEach _basePumps; +if (_checkCount != _totalCount) then { + _message = "WRONG COUNT " + str _checkCount; +}; + +// export text +private _nl = toString [10]; +private _multipleBasePumps = 1 < count _basePumps; +private _output = [format [" %1[] = { /* %2 */", worldName, getText (configfile >> "CfgWorlds" >> worldName >> "description")]]; +{ + if (_forEachIndex > 0) then {_output pushBack ","}; + _x params ["_class", "_positions"]; + if (_multipleBasePumps) then { + _output pushBack (_nl + " "); + } else { + _output pushBack " "; + }; + _output pushBack format ["{""%1"", {", _class]; + { + if (_forEachIndex > 0) then {_output pushBack ","}; + _output pushBack format ["{%1,%2,%3}", _x#0, _x#1, _x#2]; + } forEach _positions; + _output pushBack "}}"; +} forEach _basePumps; +if (_multipleBasePumps) then {_output pushBack (_nl + " ")}; +if (_basePumps isEqualTo []) then {_output pushBack " "}; +_output pushBack ("};" + _nl); + +_output = _output joinString ""; + +copyToClipboard _output; +[_totalCount, _posCount, _message, _output] diff --git a/addons/refuel/dev/test_debugConfigs.sqf b/addons/refuel/dev/test_debugConfigs.sqf index f427f07d28c..52ff8a962ae 100644 --- a/addons/refuel/dev/test_debugConfigs.sqf +++ b/addons/refuel/dev/test_debugConfigs.sqf @@ -5,14 +5,14 @@ private _testPass = true; -diag_log text format ["[ACE-refuel] Showing CfgVehicles with vanilla transportFuel"]; -private _fuelTrucks = configProperties [configFile >> "CfgVehicles", "(isClass _x) && {(getNumber (_x >> 'transportFuel')) > 0}", true]; +INFO("Showing CfgVehicles with transportFuel and without XEH"); +private _badCfgVehicles = ' + 2 == getNumber (_x >> "scope") + && {0 < getNumber (_x >> "transportFuel")} + && {!isText (_x >> "EventHandlers" >> "CBA_Extended_EventHandlers" >> "init")} +' configClasses (configFile >> "CfgVehicles"); { - if ((configName _x) isKindOf "Car") then { - diag_log text format ["Car [%1] needs config [transportFuel: %2]", configName _x, getNumber (_x >> 'transportFuel')]; - } else { - diag_log text format ["Non-car? [%1] needs config [transportFuel: %2]", configName _x, getNumber (_x >> 'transportFuel')]; - }; -} forEach _fuelTrucks; + diag_log text format ["Class %1: %2 [%3] needs XEH", configName _x, configName inheritsFrom _x, configSourceMod _x]; +} forEach _badCfgVehicles; _testPass diff --git a/addons/refuel/functions/fnc_getFuelCargo.sqf b/addons/refuel/functions/fnc_getFuelCargo.sqf new file mode 100644 index 00000000000..360679013e4 --- /dev/null +++ b/addons/refuel/functions/fnc_getFuelCargo.sqf @@ -0,0 +1,20 @@ +#include "..\script_component.hpp" +/* + * Author: Dystopian + * Returns vehicle fuel amount from config (cached). + * + * Arguments: + * 0: Fuel Source + * + * Return Value: + * Fuel amount from config + * + * Example: + * cursorObject call ace_refuel_fnc_getFuelCargo + * + * Public: No + */ + +params ["_source"]; + +(uiNamespace getVariable QGVAR(cacheRefuelCargo)) getOrDefault [typeOf _source, REFUEL_DISABLED_FUEL] diff --git a/addons/refuel/functions/fnc_makeJerryCan.sqf b/addons/refuel/functions/fnc_makeJerryCan.sqf index 4b807756c9e..31a91a30d7b 100644 --- a/addons/refuel/functions/fnc_makeJerryCan.sqf +++ b/addons/refuel/functions/fnc_makeJerryCan.sqf @@ -16,6 +16,13 @@ * Public: Yes */ +// Only run this after the settings are initialized +if !(EGVAR(common,settingsInitFinished)) exitWith { + EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(makeJerryCan), _this]; +}; + +if (!GVAR(enabled)) exitWith {}; + params [["_target", objNull, [objNull]], ["_fuelAmount", 20, [0]]]; if (isNull _target || diff --git a/addons/refuel/functions/fnc_makeSource.sqf b/addons/refuel/functions/fnc_makeSource.sqf index 38b2d8a2618..9d76635849f 100644 --- a/addons/refuel/functions/fnc_makeSource.sqf +++ b/addons/refuel/functions/fnc_makeSource.sqf @@ -25,21 +25,39 @@ if !(EGVAR(common,settingsInitFinished)) exitWith { EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(makeSource), _this]; }; +if (!GVAR(enabled)) exitWith {}; + params [ ["_source", objNull, [objNull]], ["_fuelCargo", 0, [0]], ["_hooks", nil, [[]]] ]; -TRACE_3("makeSource",_source,_fuelCargo,_hooks); -private _fuelCargoConfig = getNumber (configOf _source >> QGVAR(fuelCargo)); +private _fuelCargoConfig = _source call FUNC(getFuelCargo); + +TRACE_4("makeSource",_source,_fuelCargo,_hooks,_fuelCargoConfig); if ( isNull _source || {_fuelCargo < 0 && {!(_fuelCargo in [REFUEL_INFINITE_FUEL, REFUEL_DISABLED_FUEL])}} - || {_fuelCargo != 0 && {_fuelCargo == _fuelCargoConfig}} ) exitWith {}; +// We might be removing fuel from an object that in config doesn't have fuel, but was given fuel via this function prior +if (_fuelCargo == REFUEL_DISABLED_FUEL && {_fuelCargoConfig == REFUEL_DISABLED_FUEL}) exitWith { + if (isNil {_source getVariable QGVAR(currentFuelCargo)}) exitWith {}; + + _source setVariable [QGVAR(currentFuelCargo), nil, true]; + _source setVariable [QGVAR(capacity), REFUEL_DISABLED_FUEL, true]; + + private _jipID = _source getVariable QGVAR(initSource_jipID); + + if (isNil "_jipID") exitWith {}; + + _jipID call CBA_fnc_removeGlobalEventJIP; + + _source setVariable [QGVAR(initSource_jipID), nil]; +}; + private _capacity = if (_fuelCargo < 0) then {_fuelCargo} else {_fuelCargoConfig max _fuelCargo}; _source setVariable [QGVAR(capacity), _capacity, true]; @@ -57,10 +75,10 @@ if ( }; // only add if menu doesn't already exist -if (!(_fuelCargoConfig != 0 && {!isNil {_source getVariable QGVAR(initSource_jipID)}})) then { - private _jipID = [QGVAR(initSource), [_source]] call CBA_fnc_globalEventJIP; - [_jipID, _source] call CBA_fnc_removeGlobalEventJIP; - _source setVariable [QGVAR(initSource_jipID), _jipID]; -}; +if (_fuelCargoConfig != REFUEL_DISABLED_FUEL || {!isNil {_source getVariable QGVAR(initSource_jipID)}}) exitWith {}; + +private _jipID = [QGVAR(initSource), [_source]] call CBA_fnc_globalEventJIP; +[_jipID, _source] call CBA_fnc_removeGlobalEventJIP; +_source setVariable [QGVAR(initSource_jipID), _jipID]; [QGVAR(sourceInitialized), [_source]] call CBA_fnc_globalEvent; diff --git a/addons/refuel/initSettings.inc.sqf b/addons/refuel/initSettings.inc.sqf index f3744697a44..2888ad190ce 100644 --- a/addons/refuel/initSettings.inc.sqf +++ b/addons/refuel/initSettings.inc.sqf @@ -1,12 +1,21 @@ private _category = [ELSTRING(main,Category_Logistics), "str_state_refuel"]; +[ + QGVAR(enabled), "CHECKBOX", + ELSTRING(common,Enabled), + _category, + true, + 1, + {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + [ QGVAR(rate), "SLIDER", [LSTRING(RefuelSettings_speed_DisplayName), LSTRING(RefuelSettings_speed_Description)], _category, [0,25,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(rate), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -14,8 +23,7 @@ private _category = [ELSTRING(main,Category_Logistics), "str_state_refuel"]; [LSTRING(RefuelSettings_speedCargo_DisplayName), LSTRING(RefuelSettings_speedCargo_Description)], _category, [0,250,10,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(cargoRate), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -23,8 +31,7 @@ private _category = [ELSTRING(main,Category_Logistics), "str_state_refuel"]; [LSTRING(RefuelSettings_hoseLength_DisplayName)], _category, [0,50,12,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(hoseLength), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -32,6 +39,5 @@ private _category = [ELSTRING(main,Category_Logistics), "str_state_refuel"]; [LSTRING(RefuelSettings_progressDuration_DisplayName), LSTRING(RefuelSettings_progressDuration_Description)], _category, [0, 10, 2], // [min, max, default value] - true, // isGlobal - {[QGVAR(progressDuration), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; diff --git a/addons/refuel/stringtable.xml b/addons/refuel/stringtable.xml index 909a3f4587e..648ee38c6da 100644 --- a/addons/refuel/stringtable.xml +++ b/addons/refuel/stringtable.xml @@ -506,6 +506,7 @@ 연료통 집어들기 Взять канистру с топливом Ramasser le réservoir de carburant + Coger garrafa de combustible Picking fuel canister up... @@ -515,6 +516,7 @@ 연료통 집어드는 중... Поднимаю канистру с топливом... Ramasser les bidons de carburant... + Cogiendo garrafa de combustible... Connect fuel canister @@ -524,6 +526,7 @@ 연료통 꽂기 Подсоединить канистру с топливом Raccorder le réservoir de carburant + Conectar garrafa de combustible Connecting fuel canister... @@ -533,6 +536,7 @@ 연료통 꽂는 중... Подсоединение топливной канистры... Raccorder le réservoir de carburant... + Conectando garrafa de combustible... Disconnect fuel canister @@ -542,6 +546,7 @@ 연료통 빼기 Отсоединить канистру с топливом Débrancher le réservoir de carburant + Desconectar garrafa de combustible Refuel hose length diff --git a/addons/reload/stringtable.xml b/addons/reload/stringtable.xml index e081834e29b..2c4bbcab769 100644 --- a/addons/reload/stringtable.xml +++ b/addons/reload/stringtable.xml @@ -138,6 +138,7 @@ Taśma została połączona 탄띠가 연결되었습니다 Ремень был пристегнут + Cinta enganchada Belt could not be linked @@ -148,6 +149,7 @@ Taśma nie mogła być połączona 탄띠를 연결할 수 없습니다 Ремень не удалось пристегнуть + La cinta no ha podido ser enganchada diff --git a/addons/reloadlaunchers/stringtable.xml b/addons/reloadlaunchers/stringtable.xml index ac42ef4d99e..b55ccde1705 100644 --- a/addons/reloadlaunchers/stringtable.xml +++ b/addons/reloadlaunchers/stringtable.xml @@ -10,6 +10,7 @@ 동료의 장전에 대한 알림 표시 Affichage de notifications lors d'une rechargement par un ami Отображает уведомления о загрузке помощника + Mostrar notificaciones para recarga de compañero Displays notifications when an assistant loads a gunner's launcher. @@ -20,6 +21,7 @@ 부사수가 사수의 발사기를 장전할 때 알림을 표시합니다. Affiche une notofication lorsqu'un assistant recharge l'arme du tireur. Отображает уведомления, когда помощник загружает пусковую установку стрелка. + Mostrar notificaciones cuando un asistente recarga el lanzador del tirador. Load launcher @@ -47,6 +49,7 @@ %1 ładuje twoją wyrzutnię %1이(가) 당신의 발사기를 장전했습니다. %1 загружает Вашу установку + %1 está cargando tu lanzador %1 stopped loading your launcher @@ -57,6 +60,7 @@ %1 przestał ładować twoją wyrzutnię %1이(가) 당신의 발사기 장전을 멈췄습니다. %1 прекратил загружать Вашу установку + %1 paró de cargar tu lanzador Loading launcher... @@ -118,6 +122,7 @@ Wyrzutnia nie mogła być załadowana 발사기를 장전할 수 없습니다. Не удалось загрузить пусковую установку + El lanzador no ha podido ser cargado Buddy Loading @@ -128,6 +133,7 @@ Nachladen durch Kamerad バディローディング Перезарядка помощником + Cargado de Compañero diff --git a/addons/repair/XEH_PREP.hpp b/addons/repair/XEH_PREP.hpp index 186ec0b310f..16e11b7476e 100644 --- a/addons/repair/XEH_PREP.hpp +++ b/addons/repair/XEH_PREP.hpp @@ -25,7 +25,6 @@ PREP(getSelectionsToIgnore); PREP(getPatchWheelTime); PREP(getPostRepairDamage); PREP(getRepairItems); -PREP(getWheelHitPointsWithSelections); PREP(hasItems); PREP(isEngineer); PREP(isInRepairFacility); diff --git a/addons/repair/dev/draw_showRepairInfo.sqf b/addons/repair/dev/draw_showRepairInfo.sqf index 20bf748e7fd..182b2f7a088 100644 --- a/addons/repair/dev/draw_showRepairInfo.sqf +++ b/addons/repair/dev/draw_showRepairInfo.sqf @@ -4,6 +4,7 @@ #include "..\script_component.hpp" addMissionEventHandler ["Draw3D", { + if (isGamePaused) exitWith {}; if !((cursorObject isKindOf "Car") || (cursorObject isKindOf "Tank") || (cursorObject isKindOf "Air")) exitWith {}; private _config = configOf cursorObject; @@ -11,7 +12,7 @@ addMissionEventHandler ["Draw3D", { private _hitpointGroups = getArray (_config >> QGVAR(hitpointGroups)); (getAllHitPointsDamage cursorObject) params [["_hitPoints", []], ["_hitSelections", []]]; - ([cursorObject] call FUNC(getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; + ([cursorObject] call EFUNC(common,getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; private _output = []; @@ -28,7 +29,7 @@ addMissionEventHandler ["Draw3D", { _info = _info + "[Wheel]"; _color = [0,1,0,1]; }; - if (!((getText (_config>> "HitPoints" >> _hitpoint >> "depends")) in ["", "0"])) then { + if !((getText (_config>> "HitPoints" >> _hitpoint >> "depends")) in ["", "0"]) then { _info = _info + format ["[depends: %1]", getText (_config>> "HitPoints" >> _hitpoint >> "depends")]; _color = [0,0,1,1] }; diff --git a/addons/repair/functions/fnc_addRepairActions.sqf b/addons/repair/functions/fnc_addRepairActions.sqf index 9dad1ecc311..16711d7b8a1 100644 --- a/addons/repair/functions/fnc_addRepairActions.sqf +++ b/addons/repair/functions/fnc_addRepairActions.sqf @@ -37,7 +37,7 @@ private _selectionsToIgnore = _vehicle call FUNC(getSelectionsToIgnore); (getAllHitPointsDamage _vehicle) params [["_hitPoints", []], ["_hitSelections", []]]; // Since 1.82 these are all lower case // get hitpoints of wheels with their selections -([_vehicle] call FUNC(getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; +([_vehicle] call EFUNC(common,getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; private _hitPointsAddedNames = []; private _hitPointsAddedStrings = []; diff --git a/addons/repair/functions/fnc_canRepair.sqf b/addons/repair/functions/fnc_canRepair.sqf index f1f4aa7b7c8..ff61450b12b 100644 --- a/addons/repair/functions/fnc_canRepair.sqf +++ b/addons/repair/functions/fnc_canRepair.sqf @@ -65,7 +65,7 @@ if (!_return) exitWith {false}; // if (_vehicleStateCondition == 1 && {!([_target] call FUNC(isInStableCondition))}) exitWith {false}; private _repairLocations = getArray (_config >> "repairLocations"); -if (!("All" in _repairLocations)) then { +if !("All" in _repairLocations) then { private _repairFacility = {([_caller] call FUNC(isInRepairFacility)) || ([_target] call FUNC(isInRepairFacility))}; private _repairVeh = {([_caller] call FUNC(isNearRepairVehicle)) || ([_target] call FUNC(isNearRepairVehicle))}; { diff --git a/addons/repair/functions/fnc_getSelectionsToIgnore.sqf b/addons/repair/functions/fnc_getSelectionsToIgnore.sqf index 08ca639a209..455b58c0405 100644 --- a/addons/repair/functions/fnc_getSelectionsToIgnore.sqf +++ b/addons/repair/functions/fnc_getSelectionsToIgnore.sqf @@ -28,7 +28,7 @@ private _turretPaths = ((fullCrew [_vehicle, "gunner", true]) + (fullCrew [_vehi (getAllHitPointsDamage _vehicle) params [["_hitPoints", []], ["_hitSelections", []]]; // get hitpoints of wheels with their selections -([_vehicle] call FUNC(getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; +([_vehicle] call EFUNC(common,getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; private _indexesToIgnore = []; private _processedSelections = []; @@ -117,7 +117,7 @@ private _processedSelections = []; continue }; - if (!(getText (_vehCfg >> "HitPoints" >> _hitpoint >> "depends") in ["", "0"])) then { // skip depends hitpoints, should be normalized by engine + if !(getText (_vehCfg >> "HitPoints" >> _hitpoint >> "depends") in ["", "0"]) then { // skip depends hitpoints, should be normalized by engine TRACE_3("Skipping depends hitpoint",_hitpoint,_forEachIndex,_selection); /*#ifdef DEBUG_MODE_FULL systemChat format ["Skipping depends hitpoint, hitpoint %1, index %2, selection %3", _hitpoint, _forEachIndex, _selection]; diff --git a/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf b/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf deleted file mode 100644 index 5d655887c65..00000000000 --- a/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf +++ /dev/null @@ -1,97 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: commy2 - * Returns the wheel hitpoints and their selections. - * - * Arguments: - * 0: Vehicle - * - * Return Value: - * 0: Wheel hitpoints - * 1: Wheel hitpoint selections in model coordinates - * - * Example: - * [car1] call ace_repair_fnc_getWheelHitPointsWithSelections - * - * Public: No - */ - -params ["_vehicle"]; -TRACE_1("params",_vehicle); - -// get the vehicles wheel config -private _wheels = configOf _vehicle >> "Wheels"; - -// exit with nothing if the vehicle has no wheels class -if !(isClass _wheels) exitWith {TRACE_1("No Wheels",_wheels); [[],[]]}; - -// get all hitpoints and selections -(getAllHitPointsDamage _vehicle) params ["_hitPoints", "_hitPointSelections"]; - -// get all wheels and read selections from config -_wheels = "true" configClasses _wheels; - -private _wheelHitPoints = []; -private _wheelHitPointSelections = []; - -{ - private _wheelName = configName _x; - private _wheelCenter = getText (_x >> "center"); - private _wheelBone = getText (_x >> "boneName"); - private _wheelBoneNameResized = _wheelBone select [0, 9]; //ount "wheel_X_Y"; // this is a requirement for physx. Should work for all addon vehicles. - - TRACE_4("",_wheelName,_wheelCenter,_wheelBone,_wheelBoneNameResized); - - private _wheelHitPoint = ""; - private _wheelHitPointSelection = ""; - - //Commy's orginal method - { - if ((_wheelBoneNameResized != "") && {_x find _wheelBoneNameResized == 0}) exitWith { // same as above. Requirement for physx. - _wheelHitPoint = _hitPoints select _forEachIndex; - _wheelHitPointSelection = _hitPointSelections select _forEachIndex; - TRACE_2("wheel found [Orginal]",_wheelName,_wheelHitPoint); - }; - } forEach _hitPointSelections; - - - if (_vehicle isKindOf "Car") then { - //Backup method, search for the closest hitpoint to the wheel's center selection pos. - //Ref #2742 - RHS's HMMWV - if (_wheelHitPoint == "") then { - private _wheelCenterPos = _vehicle selectionPosition _wheelCenter; - if (_wheelCenterPos isEqualTo [0,0,0]) exitWith {TRACE_1("no center?",_wheelCenter);}; - - - private _bestDist = 99; - private _bestIndex = -1; - { - if (_x != "") then { - //Filter out things that definitly aren't wheeels (#3759) - if ((toLowerANSI (_hitPoints select _forEachIndex)) in ["hitengine", "hitfuel", "hitbody"]) exitWith {TRACE_1("filter",_x)}; - private _xPos = _vehicle selectionPosition _x; - if (_xPos isEqualTo [0,0,0]) exitWith {}; - private _xDist = _wheelCenterPos distance _xPos; - if (_xDist < _bestDist) then { - _bestIndex = _forEachIndex; - _bestDist = _xDist; - }; - }; - } forEach _hitPointSelections; - - TRACE_2("closestPoint",_bestDist,_bestIndex); - if (_bestIndex != -1) then { - _wheelHitPoint = _hitPoints select _bestIndex; - _wheelHitPointSelection = _hitPointSelections select _bestIndex; - TRACE_2("wheel found [Backup]",_wheelName,_wheelHitPoint); - }; - }; - }; - - if ((_wheelHitPoint != "") && {_wheelHitPointSelection != ""}) then { - _wheelHitPoints pushBack _wheelHitPoint; - _wheelHitPointSelections pushBack _wheelHitPointSelection; - }; -} forEach _wheels; - -[_wheelHitPoints, _wheelHitPointSelections] diff --git a/addons/repair/functions/fnc_normalizeHitPoints.sqf b/addons/repair/functions/fnc_normalizeHitPoints.sqf index 5e61ef8c88a..97f34c22db6 100644 --- a/addons/repair/functions/fnc_normalizeHitPoints.sqf +++ b/addons/repair/functions/fnc_normalizeHitPoints.sqf @@ -33,7 +33,7 @@ private _dependentHitPointScripts = []; { if ((_x != "") && {isClass (_config >> _x)} && {!(_x in _realHitPoints)}) then { _realHitPoints pushBack _x; - if (!((getText (_config >> _x >> "depends")) in ["", "0"])) then { + if !((getText (_config >> _x >> "depends")) in ["", "0"]) then { _dependentHitPoints pushBack _x; _dependentHitPointScripts pushBack compile getText (_config >> _x >> "depends"); }; diff --git a/addons/repair/functions/fnc_repair.sqf b/addons/repair/functions/fnc_repair.sqf index 86ff191000a..526b2d506b6 100644 --- a/addons/repair/functions/fnc_repair.sqf +++ b/addons/repair/functions/fnc_repair.sqf @@ -70,7 +70,7 @@ if (!_return) exitWith {false}; // if (_vehicleStateCondition == 1 && {!([_target] call FUNC(isInStableCondition))}) exitWith {false}; private _repairLocations = getArray (_config >> "repairLocations"); -if (!("All" in _repairLocations)) then { +if !("All" in _repairLocations) then { private _repairFacility = {([_caller] call FUNC(isInRepairFacility)) || ([_target] call FUNC(isInRepairFacility))}; private _repairVeh = {([_caller] call FUNC(isNearRepairVehicle)) || ([_target] call FUNC(isNearRepairVehicle))}; { diff --git a/addons/repair/functions/fnc_repair_failure.sqf b/addons/repair/functions/fnc_repair_failure.sqf index c305c90b6bf..f9de2a8ae6e 100644 --- a/addons/repair/functions/fnc_repair_failure.sqf +++ b/addons/repair/functions/fnc_repair_failure.sqf @@ -65,7 +65,7 @@ if (isNil _callback) then { } else { _callback = missionNamespace getVariable _callback; }; -if (!(_callback isEqualType {})) then {_callback = {TRACE_1("callback was NOT code",_callback)};}; +if !(_callback isEqualType {}) then {_callback = {TRACE_1("callback was NOT code",_callback)};}; _args call _callback; diff --git a/addons/repair/functions/fnc_repair_success.sqf b/addons/repair/functions/fnc_repair_success.sqf index 271d662cd49..62480827791 100644 --- a/addons/repair/functions/fnc_repair_success.sqf +++ b/addons/repair/functions/fnc_repair_success.sqf @@ -60,7 +60,7 @@ if (isNil _callback) then { } else { _callback = missionNamespace getVariable _callback; }; -if (!(_callback isEqualType {})) then {_callback = {TRACE_1("callback was NOT code",_callback)};}; +if !(_callback isEqualType {}) then {_callback = {TRACE_1("callback was NOT code",_callback)};}; _args call _callback; diff --git a/addons/repair/initSettings.inc.sqf b/addons/repair/initSettings.inc.sqf index 26d502e757a..e39bb93a764 100644 --- a/addons/repair/initSettings.inc.sqf +++ b/addons/repair/initSettings.inc.sqf @@ -8,16 +8,14 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; true, true, {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ QGVAR(displayTextOnRepair), "CHECKBOX", [LSTRING(SettingDisplayTextName), LSTRING(SettingDisplayTextDesc)], _category, - true, // default value - false, // isGlobal - {[QGVAR(displayTextOnRepair), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // default value ] call CBA_fnc_addSetting; [ @@ -25,8 +23,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(engineerSetting_Repair_name), LSTRING(engineerSetting_Repair_description)], _category, [[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],1], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(engineerSetting_repair), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -34,8 +31,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(engineerSetting_Wheel_name), LSTRING(engineerSetting_Wheel_description)], _category, [[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(engineerSetting_wheel), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -69,8 +65,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(repairDamageThreshold_name), LSTRING(repairDamageThreshold_description)], _category, [0, 1, 0.6, 1, true], - true, // isGlobal - {[QGVAR(repairDamageThreshold), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -78,8 +73,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(repairDamageThreshold_Engineer_name), LSTRING(repairDamageThreshold_Engineer_description)], _category, [0, 1, 0.4, 1, true], - true, // isGlobal - {[QGVAR(repairDamageThreshold_engineer), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -87,8 +81,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(consumeItem_ToolKit_name), LSTRING(consumeItem_ToolKit_description)], _category, [[0,1],[ELSTRING(common,No), ELSTRING(common,Yes)],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(consumeItem_toolKit), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -105,8 +98,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(fullRepairLocation), LSTRING(fullRepairLocation_description)], _catFullRepair, [[0,1,2,3,4],[LSTRING(useAnywhere), LSTRING(repairVehicleOnly), LSTRING(repairFacilityOnly), LSTRING(vehicleAndFacility), ELSTRING(common,Disabled)],2], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(fullRepairLocation), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -114,8 +106,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(engineerSetting_fullRepair_name), LSTRING(engineerSetting_fullRepair_description)], _catFullRepair, [[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],2], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(engineerSetting_fullRepair), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -168,8 +159,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(autoShutOffEngineWhenStartingRepair_name), LSTRING(autoShutOffEngineWhenStartingRepair_description)], _category, false, // default value - true, // isGlobal - {[QGVAR(autoShutOffEngineWhenStartingRepair), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ diff --git a/addons/repair/stringtable.xml b/addons/repair/stringtable.xml index 775202ed3a6..850f9dee7f3 100644 --- a/addons/repair/stringtable.xml +++ b/addons/repair/stringtable.xml @@ -281,6 +281,7 @@ 전체 수리 시간 계수 Coefficient du temps de réparation complète Коэффициент времени полного ремонта + Coeficiente de Tiempo de Reparación Completa Modifies how long it takes to perform a Full Repair.\nThe repair time is based on the amount of repairs needed for each part, including those normally inaccessible. @@ -291,6 +292,7 @@ 전체적인 수리를 수행하는 데 걸리는 시간을 수정합니다.\n수리 시간은 일반적으로 접근할 수 없는 부품을 포함하여 각 부품에 필요한 수리 시간을 기준으로 합니다. Modifie la durée que prend une réparation complète.\nLe temps de réparation est basé sur la quantité de réparations requises pour chaque partie, incluant celles qui sont normalement inaccessibles. Изменяет время, необходимое для выполнения полного ремонта.\nВремя ремонта зависит от объема ремонтных работ, необходимых для каждой детали, включая те, которые обычно недоступны. + Modifica cuánto tiempo lleva realizar una Reparación Completa.\nEl tiempo de reparación está basado en la cantidad de reparaciones necesarias para cada parte, incluyendo aquellas que normalmente no son accesibles. Boost engineer training when in repair vehicles or facilities. Untrained becomes engineer, engineer becomes advanced engineer. @@ -1262,6 +1264,7 @@ タイヤ交換の許可 바퀴 교체 허용 Autoriser le remplacement des roues + Permitir Recambio de Rueda Who can remove and replace wheels? @@ -1287,6 +1290,7 @@ 바퀴 수리 허용 Autoriser le rafistolage des roues Разрешить починить колесо + Permitir Parcheo de Rueda Who can patch wheels? @@ -1297,6 +1301,7 @@ 누가 바퀴를 수리할 수 있습니까? Qui peut rafistoler les roues ? Кто может починить колеса? + Quién puede parchear ruedas? Allow Repair @@ -1957,6 +1962,7 @@ 바퀴 수리 아이템 필요 Exigences pour rafistoler une roue Требования для починки колеса + Requerimientos de Parcheo de Ruedas Items required to patch a wheel. @@ -1967,6 +1973,7 @@ 바퀴를 수리하기 위해 아이템이 필요합니다. Equipements requis pour rafistoler une roue. Предметы, необходимые для починки колеса. + Objetos requeridos para parchear una rueda. Misc Repair Requirements @@ -2142,6 +2149,7 @@ 부품 수리 시간 Temps de réparation des pièces Время ремонта детали + Tiempo de Reparación de Pieza Time in seconds to complete a repair. @@ -2152,6 +2160,7 @@ 수리를 완료하는 시간(초 단위) Durée en secondes pour terminer une réparation. Время завершения ремонта в секундах. + Tiempo en segundos para completar una reparación. Wheel Change Time @@ -2162,6 +2171,7 @@ 바퀴 교체 시간 Temps de changement d'une roue Время замены колеса + Tiempo de Cambio de Rueda Time in seconds to remove or change a wheel. @@ -2172,6 +2182,7 @@ 바퀴를 제거하거나 교체하는 데 걸리는 시간(초 단위) Durée en seconde pour enlever ou changer une roue. Время в секундах на снятие или замену колеса. + Tiempo en segundos para quitar o cambiar una rueda. Patch Wheel @@ -2182,6 +2193,7 @@ 바퀴 수리 Rafistoler la roue Чинить колесо + Parchear Rueda Patching Wheel... @@ -2192,6 +2204,7 @@ 바퀴 수리 중... Rafistolage de la roue... Починка колеса... + Parcheando Rueda... Wheel Patch Time @@ -2202,6 +2215,7 @@ 바퀴 수리 시간 Temps de rafistolage d'une roue Время починки полеса + Tiempo de Parcheo de Rueda Time it takes to patch a wheel by 5%. @@ -2212,6 +2226,7 @@ 바퀴를 5% 수리하는 데 걸리는 시간(초 단위) Durée pour rafistoler une roue de 5%. Время, необходимое для починки колеса, сокращается на 5%. + Tiempo que lleva parchear una rueda por cada 5%. Patch Wheel Threshold @@ -2222,6 +2237,7 @@ 바퀴 수리 한계점 Seuil de rafistolage d'une roue Порог починки колеса + Umbral de Parcheo de Rueda Maximum damage to which a wheel can be patched.\n0% means all damage can be repaired. @@ -2232,6 +2248,7 @@ 바퀴를 수리할 수 있는 최대 레벨입니다. Niveau maximum de dégâts jusqu'à laquelle une roue peut être réparée.\n0% signifie que la roue peut être reparée entièrement. Максимальный уровень, до которого колесо может быть починено. + Máximo daño que permite a una rueda ser parcheada.\n0% significa que todo el daño puede ser reparado. Wheel Patch Location @@ -2242,6 +2259,7 @@ 바퀴 수리 장소 Lieu de rafistolage des roues Место починки колеса + Localización para el Parcheo de Rueda Where the wheel can be patched. @@ -2252,6 +2270,7 @@ 바퀴를 수리할 수 있는 곳입니다. Lieu où les roues peuvent être rafistolées. Где колесо можно починить. + Dónde puede ser parcheada la rueda. On the ground @@ -2262,6 +2281,7 @@ 지면 위 Sur le terrain На земле + En el suelo On a vehicle @@ -2272,6 +2292,7 @@ 차량 Sur un véhicule На транспорте + En un vehículo diff --git a/addons/scopes/functions/fnc_adjustScope.sqf b/addons/scopes/functions/fnc_adjustScope.sqf index 0a9d7bd089b..a760065cdec 100644 --- a/addons/scopes/functions/fnc_adjustScope.sqf +++ b/addons/scopes/functions/fnc_adjustScope.sqf @@ -22,7 +22,7 @@ if (!GVAR(enabled)) exitWith {false}; params ["_unit", "_turretAndDirection", "_majorStep"]; TRACE_3("adjustScope",_unit,_turretAndDirection,_majorStep); -if (!(_unit isKindOf "Man")) exitWith {false}; +if !(_unit isKindOf "Man") exitWith {false}; if (currentMuzzle _unit != currentWeapon _unit) exitWith {false}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); diff --git a/addons/scopes/functions/fnc_canAdjustZero.sqf b/addons/scopes/functions/fnc_canAdjustZero.sqf index ca03ab41236..1461d91d204 100644 --- a/addons/scopes/functions/fnc_canAdjustZero.sqf +++ b/addons/scopes/functions/fnc_canAdjustZero.sqf @@ -20,7 +20,7 @@ params ["_unit"]; if (cameraView == "GUNNER") exitWith {false}; if (!isNull objectParent _unit) exitWith {false}; if (GVAR(simplifiedZeroing)) exitWith {false}; -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {false}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {false}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith {false}; diff --git a/addons/scopes/functions/fnc_canResetZero.sqf b/addons/scopes/functions/fnc_canResetZero.sqf index 79dae44be95..92bbda1a4dd 100644 --- a/addons/scopes/functions/fnc_canResetZero.sqf +++ b/addons/scopes/functions/fnc_canResetZero.sqf @@ -19,7 +19,7 @@ params ["_unit"]; if (cameraView == "GUNNER") exitWith {false}; if (!isNull objectParent _unit) exitWith {false}; -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {false}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {false}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith {false}; diff --git a/addons/scopes/functions/fnc_firedEH.sqf b/addons/scopes/functions/fnc_firedEH.sqf index f1b8e91bf4e..5ff78a44b70 100644 --- a/addons/scopes/functions/fnc_firedEH.sqf +++ b/addons/scopes/functions/fnc_firedEH.sqf @@ -18,7 +18,7 @@ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); -if (!(_ammo isKindOf "BulletBase")) exitWith {}; +if !(_ammo isKindOf "BulletBase") exitWith {}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith {}; diff --git a/addons/scopes/functions/fnc_getCurrentZeroRange.sqf b/addons/scopes/functions/fnc_getCurrentZeroRange.sqf index 001e5e8b79e..d1bc3b7790d 100644 --- a/addons/scopes/functions/fnc_getCurrentZeroRange.sqf +++ b/addons/scopes/functions/fnc_getCurrentZeroRange.sqf @@ -17,12 +17,12 @@ params ["_unit"]; -if (!GVAR(enabled)) exitWith { currentZeroing _unit }; +if (!GVAR(enabled)) exitWith {currentZeroing _unit}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith { currentZeroing _unit }; if (GVAR(simplifiedZeroing)) exitWith { - if (!(GVAR(canAdjustElevation) select _weaponIndex)) exitWith { currentZeroing _unit }; + if !(GVAR(canAdjustElevation) select _weaponIndex) exitWith {currentZeroing _unit}; private _adjustment = _unit getVariable [QGVAR(Adjustment), [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]; ((_adjustment select _weaponIndex) select 0) }; diff --git a/addons/scopes/functions/fnc_getOptics.sqf b/addons/scopes/functions/fnc_getOptics.sqf index 6be1952b6f8..d419d8d7f05 100644 --- a/addons/scopes/functions/fnc_getOptics.sqf +++ b/addons/scopes/functions/fnc_getOptics.sqf @@ -21,7 +21,7 @@ params ["_unit"]; private _optics = ["", "", ""]; -if (!(_unit isKindOf "CAManBase")) exitWith {_optics}; +if !(_unit isKindOf "CAManBase") exitWith {_optics}; { if (count _x >= 2) then { diff --git a/addons/scopes/initKeybinds.inc.sqf b/addons/scopes/initKeybinds.inc.sqf index a147b1b2157..0e8db972381 100644 --- a/addons/scopes/initKeybinds.inc.sqf +++ b/addons/scopes/initKeybinds.inc.sqf @@ -2,7 +2,7 @@ // Conditions: canInteract if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; [ACE_player] call FUNC(inventoryCheck); @@ -14,7 +14,7 @@ // Conditions: canInteract if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; [ACE_player] call FUNC(inventoryCheck); @@ -26,7 +26,7 @@ // Conditions: canInteract if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; [ACE_player] call FUNC(inventoryCheck); @@ -38,7 +38,7 @@ // Conditions: canInteract if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; [ACE_player] call FUNC(inventoryCheck); @@ -50,7 +50,7 @@ // Conditions: canInteract if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; [ACE_player] call FUNC(inventoryCheck); @@ -62,7 +62,7 @@ // Conditions: canInteract if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; [ACE_player] call FUNC(inventoryCheck); @@ -74,7 +74,7 @@ // Conditions: canInteract if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; [ACE_player] call FUNC(inventoryCheck); @@ -86,7 +86,7 @@ // Conditions: canInteract if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; [ACE_player] call FUNC(inventoryCheck); diff --git a/addons/sitting/functions/fnc_sit.sqf b/addons/sitting/functions/fnc_sit.sqf index 2d7cc999daa..70e028719b8 100644 --- a/addons/sitting/functions/fnc_sit.sqf +++ b/addons/sitting/functions/fnc_sit.sqf @@ -78,7 +78,7 @@ if (_seatsClaimed isEqualTo []) then { _seat setVariable [QGVAR(seatsClaimed), _seatsClaimed, true]; // Also prevent dragging/carrying -if (!([_seat] call EFUNC(common,owned))) then { +if !([_seat] call EFUNC(common,owned)) then { [_player, _seat] call EFUNC(common,claim); }; diff --git a/addons/sitting/initSettings.inc.sqf b/addons/sitting/initSettings.inc.sqf index 744c188e9fd..ee1af1ec8ef 100644 --- a/addons/sitting/initSettings.inc.sqf +++ b/addons/sitting/initSettings.inc.sqf @@ -6,5 +6,5 @@ true, true, {[QGVAR(enable), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; diff --git a/addons/slideshow/functions/fnc_mapImage_init.sqf b/addons/slideshow/functions/fnc_mapImage_init.sqf index 5235315bd0f..3fb6e4c7f89 100644 --- a/addons/slideshow/functions/fnc_mapImage_init.sqf +++ b/addons/slideshow/functions/fnc_mapImage_init.sqf @@ -50,7 +50,7 @@ ctrlMapAnimCommit _map; // add drawEH to draw markers next update (they will get drawn 3 times total) _map setVariable ["markers", _markers]; -_map ctrlAddEventHandler ["draw", { +_map ctrlAddEventHandler ["Draw", { params ["_map"]; private _markers = _map getVariable ["markers", []]; TRACE_2("drawing markers",_map,count _markers); diff --git a/addons/switchunits/functions/fnc_switchUnit.sqf b/addons/switchunits/functions/fnc_switchUnit.sqf index 135088d2430..9ce074eecbb 100644 --- a/addons/switchunits/functions/fnc_switchUnit.sqf +++ b/addons/switchunits/functions/fnc_switchUnit.sqf @@ -18,7 +18,7 @@ params ["_unit"]; // don't switch to original player units -if (!([_unit] call FUNC(isValidAi))) exitWith {}; +if !([_unit] call FUNC(isValidAi)) exitWith {}; // exit var private _leave = false; diff --git a/addons/tagging/XEH_postInit.sqf b/addons/tagging/XEH_postInit.sqf index dd46b7fb988..02e082648a7 100644 --- a/addons/tagging/XEH_postInit.sqf +++ b/addons/tagging/XEH_postInit.sqf @@ -1,14 +1,6 @@ // by esteldunedain #include "script_component.hpp" - -// Cache for static objects -GVAR(cacheStaticModels) = [false] call CBA_fnc_createNamespace; -private _cacheStaticModels = call (uiNamespace getVariable [QGVAR(cacheStaticModels), {[]}]); -{ - GVAR(cacheStaticModels) setVariable [_x, true]; -} forEach _cacheStaticModels; - if (hasInterface) then { // Compile and cache config tags call FUNC(compileConfigTags); diff --git a/addons/tagging/XEH_preStart.sqf b/addons/tagging/XEH_preStart.sqf index e1ac396c48f..eb8f7ab767a 100644 --- a/addons/tagging/XEH_preStart.sqf +++ b/addons/tagging/XEH_preStart.sqf @@ -26,9 +26,9 @@ private _cfgBase = configFile >> "CfgNonAIVehicles"; private _array = _model splitString "\"; _cacheStaticModels pushBackUnique toLowerANSI (_array select -1); }; -} forEach (_nonaivehicleClasses select {(configName _x) isKindOf ["Bridge_base_F", _cfgBase]}); +} forEach (_nonAIVehicleClasses select {(configName _x) isKindOf ["Bridge_base_F", _cfgBase]}); -uiNamespace setVariable [QGVAR(cacheStaticModels), compileFinal str _cacheStaticModels]; +uiNamespace setVariable [QGVAR(cacheStaticModels), compileFinal (_cacheStaticModels createHashMapFromArray [])]; TRACE_1("compiled",count _cacheStaticModels); // force preload of stencil texture to avoid error popup diff --git a/addons/tagging/functions/fnc_checkTaggable.sqf b/addons/tagging/functions/fnc_checkTaggable.sqf index 7eab60c1ba5..ef20062a32d 100644 --- a/addons/tagging/functions/fnc_checkTaggable.sqf +++ b/addons/tagging/functions/fnc_checkTaggable.sqf @@ -43,14 +43,14 @@ if (_object isKindOf "Static") exitWith {false}; // Taggable vehicle, do not exit - if (((_object getVariable [QGVAR(canTag), getNumber (configOf _object >> QGVAR(canTag))]) in [1, true]) + if (((_object getVariable [QGVAR(canTag), getNumber (configOf _object >> QGVAR(canTag))]) in [1, true]) && {getText (configOf _object >> "selectionClan") in selectionNames _object}) exitWith { false }; // If the class is not categorized correctly search the cache - private _modelName = (getModelInfo _object) select 0; - private _isStatic = GVAR(cacheStaticModels) getVariable [_modelName, false]; + private _modelName = toLowerANSI ((getModelInfo _object) select 0); + private _isStatic = _modelName in (uiNamespace getVariable QGVAR(cacheStaticModels)); TRACE_2("Object:",_modelName,_isStatic); // If the class in not on the cache, exit (!_isStatic) diff --git a/addons/tagging/functions/fnc_generateStencilTexture.sqf b/addons/tagging/functions/fnc_generateStencilTexture.sqf index 1870d671141..6d8dffdc551 100644 --- a/addons/tagging/functions/fnc_generateStencilTexture.sqf +++ b/addons/tagging/functions/fnc_generateStencilTexture.sqf @@ -29,10 +29,10 @@ params [ ["_dimension", 512, [0]] ]; -if (_textColor select [0, 1] == "#") then { _textColor = _textColor select [1]; }; -if (_backgroundColor select [0, 1] == "#") then { _backgroundColor = _backgroundColor select [1]; }; -if (!((count _textColor) in [6,8])) exitWith { ERROR_1("bad Tcolor %1",_textColor); "" }; -if (!((count _backgroundColor) in [6,8])) exitWith { ERROR_1("bad Bcolor %1",_textColor); "" }; +if (_textColor select [0, 1] == "#") then {_textColor = _textColor select [1];}; +if (_backgroundColor select [0, 1] == "#") then {_backgroundColor = _backgroundColor select [1];}; +if !((count _textColor) in [6,8]) exitWith {ERROR_1("bad Tcolor %1",_textColor); ""}; +if !((count _backgroundColor) in [6,8]) exitWith {ERROR_1("bad Bcolor %1",_textColor); ""}; if (_autoMultiline) then { private _magicWidth = 0.75; diff --git a/addons/tagging/functions/fnc_stencilVehicle.sqf b/addons/tagging/functions/fnc_stencilVehicle.sqf index b2ee99c2413..1dfd86a2f95 100644 --- a/addons/tagging/functions/fnc_stencilVehicle.sqf +++ b/addons/tagging/functions/fnc_stencilVehicle.sqf @@ -29,7 +29,7 @@ TRACE_2("",_vehicle,_text); if (!isServer) exitWith {}; if (_text == "") exitWith {}; private _clanSel = getText (configOf _vehicle >> "selectionClan"); -if (!(_clanSel in selectionNames _vehicle)) exitWith { TRACE_1("no tag",_clanSel); }; +if !(_clanSel in selectionNames _vehicle) exitWith {TRACE_1("no tag",_clanSel);}; private _texture = [_text, _textSize, _textColor, "00000000", true] call FUNC(generateStencilTexture); TRACE_1("",_texture); diff --git a/addons/tagging/functions/fnc_tag.sqf b/addons/tagging/functions/fnc_tag.sqf index aa0ba9fac97..f130e1322b3 100644 --- a/addons/tagging/functions/fnc_tag.sqf +++ b/addons/tagging/functions/fnc_tag.sqf @@ -60,8 +60,8 @@ if ((!isNull _object) && { }; // If the class is not categorized correctly search the cache - private _modelName = (getModelInfo _object) select 0; - private _isStatic = GVAR(cacheStaticModels) getVariable [_modelName, false]; + private _modelName = toLowerANSI ((getModelInfo _object) select 0); + private _isStatic = _modelName in (uiNamespace getVariable QGVAR(cacheStaticModels)); TRACE_2("Object:",_modelName,_isStatic); // If the class in not on the cache, exit (!_isStatic) diff --git a/addons/tagging/initSettings.inc.sqf b/addons/tagging/initSettings.inc.sqf index 4fc35b83d1b..e05146c0819 100644 --- a/addons/tagging/initSettings.inc.sqf +++ b/addons/tagging/initSettings.inc.sqf @@ -4,8 +4,5 @@ private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(Tagging)] QGVAR(quickTag), "LIST", [LLSTRING(QuickTag), LLSTRING(QuickTagDesc)], _category, - [[0,1,2,3], [LELSTRING(Common,Disabled), LLSTRING(LastUsed), LLSTRING(RandomX), LLSTRING(Random)], 1], // [values, titles, defaultIndex] - false, // isGlobal - {[QGVAR(quickTag), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart + [[0,1,2,3], [LELSTRING(Common,Disabled), LLSTRING(LastUsed), LLSTRING(RandomX), LLSTRING(Random)], 1] // [values, titles, defaultIndex] ] call CBA_fnc_addSetting; diff --git a/addons/tagging/stringtable.xml b/addons/tagging/stringtable.xml index 4d32fac6d66..fa54b56b542 100644 --- a/addons/tagging/stringtable.xml +++ b/addons/tagging/stringtable.xml @@ -384,6 +384,7 @@ 차량 ID 마킹 Marquage ID des véhicules Идентификационная маркировка транспортного средства + Marcado Identificativo de Vehículo Replaces clan tag with stenciled text @@ -394,6 +395,7 @@ 클랜 태그를 스텐실 텍스트로 바꿉니다. Remplace le tag du clan par un texte au pochoir Заменяет тег клана трафаретным текстом + Reemplaza marca del clan con un texto serigrafiado diff --git a/addons/ui/XEH_PREP.hpp b/addons/ui/XEH_PREP.hpp index f7edabcc3fa..436e59361c5 100644 --- a/addons/ui/XEH_PREP.hpp +++ b/addons/ui/XEH_PREP.hpp @@ -1,5 +1,4 @@ PREP(compileConfigUI); -PREP(handlePlayerChanged); PREP(handleSpeedIndicator); PREP(moduleInit); PREP(onAnimChanged); diff --git a/addons/ui/XEH_clientInit.sqf b/addons/ui/XEH_clientInit.sqf index 1ef328b1769..2c8cd3e4b49 100644 --- a/addons/ui/XEH_clientInit.sqf +++ b/addons/ui/XEH_clientInit.sqf @@ -4,11 +4,11 @@ if (!hasInterface) exitWith {}; // Compile and cache config UI -GVAR(configCache) = call CBA_fnc_createNamespace; +GVAR(configCache) = createHashMap; call FUNC(compileConfigUI); // Scripted API namespace -GVAR(elementsSet) = call CBA_fnc_createNamespace; +GVAR(elementsSet) = createHashMap; // Attach all event handlers where UI has to be updated ["CBA_settingsInitialized", { @@ -21,7 +21,7 @@ GVAR(elementsSet) = call CBA_fnc_createNamespace; // Defaults must be set in this EH to make sure controls are activated and advanced settings can be modified { [_x, missionNamespace getVariable (format [QGVAR(%1), _x]), false, !GVAR(allowSelectiveUI)] call FUNC(setAdvancedElement); - } forEach (allVariables GVAR(configCache)); + } forEach (keys GVAR(configCache)); // Execute local event for when it's safe to modify UI through this API // infoDisplayChanged can execute multiple times, make sure it only happens once @@ -40,12 +40,11 @@ GVAR(elementsSet) = call CBA_fnc_createNamespace; [true] call FUNC(setElements); } else { private _nameNoPrefix = toLowerANSI (_name select [7]); - private _cachedElement = GVAR(configCache) getVariable _nameNoPrefix; - if (!isNil "_cachedElement") then { + if (_nameNoPrefix in GVAR(configCache)) then { [_nameNoPrefix, _value, true] call FUNC(setAdvancedElement); }; }; }] call CBA_fnc_addEventHandler; }] call CBA_fnc_addEventHandler; -["unit", LINKFUNC(handlePlayerChanged), true] call CBA_fnc_addPlayerEventHandler; +[QUOTE(ADDON), "AnimChanged", LINKFUNC(onAnimChanged)] call EFUNC(common,addPlayerEH); diff --git a/addons/ui/functions/fnc_compileConfigUI.sqf b/addons/ui/functions/fnc_compileConfigUI.sqf index ef6ec1026a4..960db9aed45 100644 --- a/addons/ui/functions/fnc_compileConfigUI.sqf +++ b/addons/ui/functions/fnc_compileConfigUI.sqf @@ -40,6 +40,6 @@ TRACE_1("Caching Condition",_x); } forEach (configProperties [_x >> "conditions"]); - GVAR(configCache) setVariable [_class, [_idd, _elements, _location, _conditions]]; + GVAR(configCache) set [_class, [_idd, _elements, _location, _conditions]]; }; } forEach ("true" configClasses (configFile >> "ACE_UI")); diff --git a/addons/ui/functions/fnc_handlePlayerChanged.sqf b/addons/ui/functions/fnc_handlePlayerChanged.sqf deleted file mode 100644 index 94f317a18cd..00000000000 --- a/addons/ui/functions/fnc_handlePlayerChanged.sqf +++ /dev/null @@ -1,32 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: veteran29 - * Handles switching units. - * - * Arguments: - * 0: New Unit - * 1: Old Unit - * - * Return Value: - * None - * - * Example: - * [newbob, oldbob] call ace_ui_fnc_handlePlayerChanged - * - * Public: No - */ -params ["_newUnit", "_oldUnit"]; -TRACE_2("unit changed",_newUnit,_oldUnit); - -if (!isNull _oldUnit) then { - _oldUnit removeEventHandler ["AnimChanged", _oldUnit getVariable [QGVAR(animHandler), -1]]; - _oldUnit setVariable [QGVAR(animHandler), nil]; - TRACE_1("remove old",_oldUnit getVariable QGVAR(animHandler)); -}; - -// Don't add a new EH if the unit respawned -if (_newUnit getVariable [QGVAR(animHandler), -1] == -1) then { - private _animHandler = _newUnit addEventHandler ["AnimChanged", LINKFUNC(onAnimChanged)]; - TRACE_1("add new",_animHandler); - _newUnit setVariable [QGVAR(animHandler), _animHandler]; -}; diff --git a/addons/ui/functions/fnc_setAdvancedElement.sqf b/addons/ui/functions/fnc_setAdvancedElement.sqf index 6751d9700c3..86a11348020 100644 --- a/addons/ui/functions/fnc_setAdvancedElement.sqf +++ b/addons/ui/functions/fnc_setAdvancedElement.sqf @@ -20,7 +20,9 @@ params ["_element", "_show", ["_showHint", false, [true]], ["_force", false, [true]]]; -private _cachedElement = GVAR(configCache) getVariable _element; +_element = toLowerANSI _element; + +private _cachedElement = GVAR(configCache) get _element; if (isNil "_cachedElement") exitWith {TRACE_1("nil element",_this)}; if (!_force && {!GVAR(allowSelectiveUI)}) exitWith { @@ -56,7 +58,7 @@ if ( // Get setting from scripted API if (!_force) then { - private _setElement = GVAR(elementsSet) getVariable _element; + private _setElement = GVAR(elementsSet) get _element; if (!isNil "_setElement") then { _setElement params ["_sourceSet", "_showSet"]; if (_showHint) then { diff --git a/addons/ui/functions/fnc_setElementVisibility.sqf b/addons/ui/functions/fnc_setElementVisibility.sqf index f7f8dccd0c8..938fb2da7de 100644 --- a/addons/ui/functions/fnc_setElementVisibility.sqf +++ b/addons/ui/functions/fnc_setElementVisibility.sqf @@ -32,12 +32,11 @@ if (_source == "" || {_element == ""}) exitWith { _element = toLowerANSI _element; // Verify element is bound -private _cachedElement = GVAR(configCache) getVariable _element; -if (isNil "_cachedElement") exitWith { +if !(_element in GVAR(configCache)) exitWith { WARNING_2("Element '%1' does not exist - modification by '%2' failed.",_element,_source); }; -private _setElement = GVAR(elementsSet) getVariable _element; +private _setElement = GVAR(elementsSet) get _element; private _return = false; if (isNil "_setElement") then { @@ -45,7 +44,7 @@ if (isNil "_setElement") then { private _success = [_element, _show, false, true] call FUNC(setAdvancedElement); if (_success) then { - GVAR(elementsSet) setVariable [_element, [_source, _show]]; + GVAR(elementsSet) set [_element, [_source, _show]]; _return = true; }; } else { @@ -57,7 +56,7 @@ if (isNil "_setElement") then { }; } else { TRACE_3("Unsetting element",_sourceSet,_element,_show); - GVAR(elementsSet) setVariable [_element, nil]; + GVAR(elementsSet) set [_element, nil]; [_element, _show, false, true] call FUNC(setAdvancedElement); _return = true; diff --git a/addons/vector/functions/fnc_onKeyHold.sqf b/addons/vector/functions/fnc_onKeyHold.sqf index 60a38ba96da..f19039851b6 100644 --- a/addons/vector/functions/fnc_onKeyHold.sqf +++ b/addons/vector/functions/fnc_onKeyHold.sqf @@ -16,7 +16,7 @@ * Public: No */ -if (!((currentWeapon ACE_player) isKindOf ["ACE_Vector", configFile >> "CfgWeapons"])) exitWith { +if !((currentWeapon ACE_player) isKindOf ["ACE_Vector", configFile >> "CfgWeapons"]) exitWith { [_this select 1] call CBA_fnc_removePerFrameHandler; GVAR(currentMode) = ""; diff --git a/addons/vehicle_damage/XEH_PREP.hpp b/addons/vehicle_damage/XEH_PREP.hpp index 524fe6ea9dd..a7eb5198811 100644 --- a/addons/vehicle_damage/XEH_PREP.hpp +++ b/addons/vehicle_damage/XEH_PREP.hpp @@ -11,3 +11,4 @@ PREP(knockOut); PREP(addDamage); PREP(handleDamageEjectIfDestroyed); PREP(blowOffTurret); +PREP(medicalDamage); diff --git a/addons/vehicle_damage/XEH_postInit.sqf b/addons/vehicle_damage/XEH_postInit.sqf index ce563302e3d..43050086d81 100644 --- a/addons/vehicle_damage/XEH_postInit.sqf +++ b/addons/vehicle_damage/XEH_postInit.sqf @@ -3,12 +3,14 @@ ["ace_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 (isPlayer _crewman) exitWith {}; - if (!alive _crewman || { !( [_crewman] call EFUNC(common,isAwake))} ) exitWith {}; + if (!alive _crewman || {!([_crewman] call EFUNC(common,isAwake))}) exitWith {}; unassignVehicle _crewman; _crewman leaveVehicle _vehicle; diff --git a/addons/vehicle_damage/functions/fnc_abandon.sqf b/addons/vehicle_damage/functions/fnc_abandon.sqf index 6a9d4eeb296..83b06a80df1 100644 --- a/addons/vehicle_damage/functions/fnc_abandon.sqf +++ b/addons/vehicle_damage/functions/fnc_abandon.sqf @@ -18,6 +18,8 @@ params ["_vehicle"]; TRACE_2("abandon",_vehicle,(crew _vehicle) select {alive _x}); +if (_vehicle getVariable [QGVAR(allowCrewInImmobile), false]) exitWith {}; // check for API + [{ params ["_vehicle"]; _vehicle allowCrewInImmobile false; diff --git a/addons/vehicle_damage/functions/fnc_addDamage.sqf b/addons/vehicle_damage/functions/fnc_addDamage.sqf index 75d72da3406..35475bd36cb 100644 --- a/addons/vehicle_damage/functions/fnc_addDamage.sqf +++ b/addons/vehicle_damage/functions/fnc_addDamage.sqf @@ -37,6 +37,6 @@ if (_hitIndex >= 0) then { _vehicle setHitPointDamage [_hitPoint, _damage, true]; }; -if (_hitPoint isEqualTo "hitengine" && { _damage > 0.9 }) then { - _vehicle call EFUNC(cookoff,engineFire); +if (_hitPoint == "hitengine" && {_damage > 0.9}) then { + [QEGVAR(cookoff,engineFireServer), _vehicle] call CBA_fnc_serverEvent; }; diff --git a/addons/vehicle_damage/functions/fnc_detonate.sqf b/addons/vehicle_damage/functions/fnc_detonate.sqf index 67d64da442b..7f0dce28c93 100644 --- a/addons/vehicle_damage/functions/fnc_detonate.sqf +++ b/addons/vehicle_damage/functions/fnc_detonate.sqf @@ -6,7 +6,6 @@ * Arguments: * 0: The vehicle * 1: Person who caused detonation (default: objNull) - * 2: An array of vehicle ammo in vehicle (default: []) * * Return Value: * None @@ -17,19 +16,12 @@ * Public: No */ -params ["_vehicle", ["_injurer", objNull], ["_vehicleAmmo", []]]; +params ["_vehicle", ["_injurer", objNull]]; -if (_vehicleAmmo isEqualTo []) then { - _vehicleAmmo = [_vehicle] call EFUNC(cookoff,getVehicleAmmo); -}; - -([_vehicle] + _vehicleAmmo) call EFUNC(cookoff,detonateAmmunition); - -if ((_vehicleAmmo select 1) > 0) then { +if (((_vehicle call EFUNC(cookoff,getVehicleAmmo)) select 1) > 0) then { { - // random amount of injuries - for "_i" from 0 to random 5 do { - [_x, random 1 , selectRandom ["Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg"], selectRandom ["bullet", "shell", "explosive"], _injurer] call EFUNC(medical,addDamageToUnit); - }; - } forEach crew _vehicle; + [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_handleCookoff.sqf b/addons/vehicle_damage/functions/fnc_handleCookoff.sqf index 7cf63377960..3e7b83ebb61 100644 --- a/addons/vehicle_damage/functions/fnc_handleCookoff.sqf +++ b/addons/vehicle_damage/functions/fnc_handleCookoff.sqf @@ -23,9 +23,12 @@ params ["_vehicle", "_chanceOfFire", "_intensity", ["_injurer", objNull], ["_hitPart", ""], ["_canRing", false], ["_canJet", true]]; -private _alreadyCookingOff = _vehicle getVariable [QGVAR(cookingOff), false]; +// Ignore if the vehicle is already cooking off +if (_vehicle getVariable [QEGVAR(cookoff,isCookingOff), false]) exitWith {true}; -if (!_alreadyCookingOff && { _chanceOfFire >= random 1 }) exitWith { +_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 { @@ -44,28 +47,13 @@ if (!_alreadyCookingOff && { _chanceOfFire >= random 1 }) exitWith { _source = ["hit_engine_point", "HitPoints"]; }; - // sending nil for _maxIntensity (9th param) to use default value in ace_cookoff_fnc_cookOff - [QEGVAR(cookOff,cookOff), [_vehicle, _intensity, _injurer, _delayWithSmoke, _fireDetonateChance, _detonateAfterCookoff, _source, _canRing, nil, _canJet]] call CBA_fnc_localEvent; - _vehicle setVariable [QGVAR(cookingOff), true]; + [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); - // cant setVehicleAmmo 0 here because it removes FFV unit's ammo - if (GVAR(removeAmmoDuringCookoff)) then { - private _ammo = [_vehicle] call EFUNC(cookoff,getVehicleAmmo); - _ammo params ["_magazines"]; - TRACE_1("removing magazines",_magazines); - { - _x params ["_magazine"]; - _vehicle removeMagazines _magazine; - } forEach _magazines; - }; true }; -// Avoid RPT spam -if (_alreadyCookingOff) exitWith { true }; - LOG_2("[%1] No Cook-off - Chance of fire [%2]",_vehicle,_chanceOfFire); false diff --git a/addons/vehicle_damage/functions/fnc_handleDetonation.sqf b/addons/vehicle_damage/functions/fnc_handleDetonation.sqf index 9556cea424d..8f317323fa7 100644 --- a/addons/vehicle_damage/functions/fnc_handleDetonation.sqf +++ b/addons/vehicle_damage/functions/fnc_handleDetonation.sqf @@ -21,18 +21,17 @@ */ params ["_vehicle", "_chanceOfDetonate", "_vehicleAmmo", "_explosiveAmmoCount", "_nonExplosiveAmmoCount", ["_injurer", objNull]]; -private _alreadyDetonating = _vehicle getVariable [QGVAR(detonating), false]; + private _isKnockedOut = _explosiveAmmoCount > 0; -if (!_alreadyDetonating && { _chanceOfDetonate >= random 1 }) exitWith { +// Ignore if the vehicle is already detonating ammo +if (_vehicle getVariable [QEGVAR(cookoff,isAmmoDetonating), false]) exitWith {_isKnockedOut}; + +if (_chanceOfDetonate >= random 1) exitWith { [_vehicle, _injurer, _vehicleAmmo] call FUNC(detonate); LOG_2("Detonating [%1] with a chance-to-detonate [%2]",_vehicle,_chanceOfDetonate); - _vehicle setVariable [QGVAR(detonating), true]; _isKnockedOut }; -// Avoid RPT spam -if (_alreadyDetonating) exitWith { _isKnockedOut }; - LOG_2("[%1] No Detonation - Chance of detonation [%2]",_vehicle,_chanceOfDetonate); false diff --git a/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf b/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf index e18d8a38149..02033b83be7 100644 --- a/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf +++ b/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf @@ -28,7 +28,7 @@ TRACE_6("handleVehicleDamage",_vehicle,_hitPoint,_hitIndex,_injurer,_oldDamage,_ if !(alive _vehicle) exitWith { private _eventHandler = _vehicle getVariable[QGVAR(handleDamage), nil]; if !(isNil "_eventHandler") then { - _vehicle removeEventHandler ["handleDamage", _eventHandler]; + _vehicle removeEventHandler ["HandleDamage", _eventHandler]; }; LOG_1("Vehicle [%1] no longer alive",_vehicle); true diff --git a/addons/vehicle_damage/functions/fnc_medicalDamage.sqf b/addons/vehicle_damage/functions/fnc_medicalDamage.sqf new file mode 100644 index 00000000000..c5234cf1c12 --- /dev/null +++ b/addons/vehicle_damage/functions/fnc_medicalDamage.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Applies medical damage to a unit. + * + * Arguments: + * 0: Target + * 1: Source + * 2: Instigator + * 3: Guarantee death? (default: false) + * + * Return Value: + * None + * + * Example: + * [cursorObject, player, player] call ace_vehicle_damage_fnc_medicalDamage; + * + * Public: No + */ + +params ["_unit", "_source", "_instigator", ["_guaranteeDeath", false]]; + +// Check if unit is invulnerable +if !(isDamageAllowed _unit && {_unit getVariable [QEGVAR(medical,allowDamage), true]}) exitWith {}; + +if (GETEGVAR(medical,enabled,false)) then { + for "_i" from 0 to floor (4 + random 3) do { + [_unit, random [0, 0.66, 1], selectRandom ["Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg"], selectRandom ["bullet", "shell", "explosive"], _instigator] call EFUNC(medical,addDamageToUnit); + }; +} else { + { + _unit setHitPointDamage [_x, (_unit getHitPointDamage _x) + random [0, 0.66, 1], true, _source, _instigator]; + } forEach ["HitFace", "HitNeck", "HitHead", "HitPelvis", "HitAbdomen", "HitDiaphragm", "HitChest", "HitBody", "HitArms", "HitHands", "HitLegs"]; +}; + +// If guaranteed death is wished +if (_guaranteeDeath && {alive _unit}) then { + [_unit, QGVAR(medicalDamage), _source, _instigator] call EFUNC(common,setDead); +}; diff --git a/addons/vehicle_damage/functions/fnc_processHit.sqf b/addons/vehicle_damage/functions/fnc_processHit.sqf index 73e70bbf577..2402df7fc25 100644 --- a/addons/vehicle_damage/functions/fnc_processHit.sqf +++ b/addons/vehicle_damage/functions/fnc_processHit.sqf @@ -37,12 +37,10 @@ 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 + // Kill everyone inside for very insane damage { - _x setDamage 1; - _x setVariable [QEGVAR(medical,lastDamageSource), _injurer]; - _x setVariable [QEGVAR(medical,lastInstigator), _injurer]; - } forEach crew _vehicle; + [QGVAR(medicalDamage), [_x, _injurer, _injurer, true], _x] call CBA_fnc_targetEvent; + } forEach (crew _vehicle); _vehicle setDamage 1; _return = false; _return @@ -119,7 +117,7 @@ if (_isCar) then { _ammoEffectiveness = (_ammoEffectiveness + (_ammoEffectiveness * 0.5)) min 1; }; -private _currentVehicleAmmo = [_vehicle] call EFUNC(cookoff,getVehicleAmmo); +private _currentVehicleAmmo = _vehicle call EFUNC(cookoff,getVehicleAmmo); private _chanceOfDetonation = 0; private _explosiveAmmoCount = 0; private _nonExplosiveAmmoCount = 0; @@ -163,7 +161,7 @@ switch (_hitArea) do { _chanceOfFire = 0; // no cookoff for cars }; - if ([_vehicle, _chanceToDetonate, _currentVehicleAmmo, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { + if ([_vehicle, _chanceToDetonate, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { [_vehicle] call FUNC(knockOut); }; @@ -191,7 +189,7 @@ switch (_hitArea) do { _chanceOfFire = 0; // no cookoff for cars }; - if ([_vehicle, _chanceToDetonate, _currentVehicleAmmo, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { + if ([_vehicle, _chanceToDetonate, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { [_vehicle, _hitIndex, _hitpointName, 0.89 * _penChance] call FUNC(addDamage); [_vehicle] call FUNC(knockOut); }; @@ -265,7 +263,7 @@ switch (_hitArea) do { _chanceOfFire = 0; // no cookoff for cars }; - if ([_vehicle, _chanceToDetonate, _currentVehicleAmmo, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { + if ([_vehicle, _chanceToDetonate, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { [_vehicle] call FUNC(knockOut); }; diff --git a/addons/vehicle_damage/initSettings.inc.sqf b/addons/vehicle_damage/initSettings.inc.sqf index ae322a6fd88..0d3f324af2f 100644 --- a/addons/vehicle_damage/initSettings.inc.sqf +++ b/addons/vehicle_damage/initSettings.inc.sqf @@ -8,16 +8,6 @@ true // Needs mission restart ] call CBA_settings_fnc_init; -[ - QGVAR(removeAmmoDuringCookoff), "CHECKBOX", - [LSTRING(removeAmmoAfterCookoff_setting_enable), LSTRING(removeAmmoAfterCookoff_setting_description)], - LSTRING(category_displayName), - true, // default value - true, // isGlobal - {[QGVAR(removeAmmoDuringCookoff), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart -] call CBA_settings_fnc_init; - [ QGVAR(enableCarDamage), "CHECKBOX", [LSTRING(carDamage_setting_enable), LSTRING(carDamage_setting_description)], diff --git a/addons/vehicle_damage/stringtable.xml b/addons/vehicle_damage/stringtable.xml index 5581408f745..4a8fdb42643 100644 --- a/addons/vehicle_damage/stringtable.xml +++ b/addons/vehicle_damage/stringtable.xml @@ -49,30 +49,6 @@ Продвинутое повреждение машин Habilitar/Deshabilitar daño avanzado de coche (Experimental) - - Removes all vehicle ammo after cook-off - 誘爆後に車両から全ての弾薬を削除 - Retire toutes les munitions des véhicules après une auto-inflammation. - Entfernt die gesamte Munition nach dem Durchzünden der Munition eines Fahrzeuges. - Rimuove tutte le munizioni dal veicolo dopo l'esplosione delle stesse - Usuwa całą amunicję z pojazdu po samozapłonie - 殉爆后移除所有车辆弹药 - 쿡오프 현상 후 차량에서 모든 탄약을 제거합니다. - Удалять все боеприпасы из техники после их детонации - Elimina toda la munición del vehículo despues ser inducida a detonar por calor - - - Enable/Disable Ammo Removal During Cook-Off - 誘爆中の弾薬除去を有効/無効にする - Retirer les munitions durant l'auto-inflammation - Aktiviert/Deaktiviert Entfernung der Munition beim Durchzünden - Abilita rimozione munizioni dopo l'esplosione - Włącz/Wyłącz usuwanie amunicji podczas samozapłonu - 启用/禁用殉爆过程中的弹药移除功能 - 쿡오프시 탄약 제거 활성화/비활성화 - Удалять боеприпасы из-за детонации - Habilita/Deshabilita ka eliminación de munición durante la detonación inducida por calor - Wreck (Turret) Épave (tourelle) diff --git a/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf b/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf index 6461e7fca28..4d0f065c06a 100644 --- a/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf +++ b/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf @@ -23,8 +23,12 @@ if (!params [["_unit", objNull, [objNull]], ["_veh", objNull, [objNull]], ["_use }; TRACE_3("params",_unit,_veh,_useCustom); -if (isNull _unit) exitWith {ERROR("null unit");}; -if (isNull _veh) exitWith {ERROR("null vehicle");}; +if (isNull _unit) exitWith { + ERROR("null unit"); +}; +if (isNull _veh) exitWith { + ERROR("null vehicle"); +}; if (_useCustom) then { private _previousMags = magazinesDetail _unit; diff --git a/addons/vehiclelock/functions/fnc_lockpick.sqf b/addons/vehiclelock/functions/fnc_lockpick.sqf index 4ef3289b458..7bb29395f0e 100644 --- a/addons/vehiclelock/functions/fnc_lockpick.sqf +++ b/addons/vehiclelock/functions/fnc_lockpick.sqf @@ -33,7 +33,10 @@ if ((locked _veh) == 0) exitWith {false}; if !("ACE_key_lockpick" in (_unit call EFUNC(common,uniqueItems))) exitWith {false}; private _vehLockpickStrength = _veh getVariable[QGVAR(lockpickStrength), GVAR(DefaultLockpickStrength)]; -if (!(_vehLockpickStrength isEqualType 0)) exitWith {ERROR("ACE_vehicleLock_LockpickStrength invalid"); false}; +if !(_vehLockpickStrength isEqualType 0) exitWith { + ERROR("ACE_vehicleLock_LockpickStrength invalid"); + false +}; //-1 indicates unpickable lock if (_vehLockpickStrength < 0) exitWith {false}; @@ -45,7 +48,7 @@ private _condition = { ((_unit distance _veh) < 5) && {(speed _veh) < 0.1} }; -if (!([[_unit, _veh]] call _condition)) exitWith {false}; +if !([[_unit, _veh]] call _condition) exitWith {false}; private _returnValue = _funcType in ["canLockpick", "startLockpick", "finishLockpick"]; switch (_funcType) do { diff --git a/addons/vehiclelock/functions/fnc_moduleSync.sqf b/addons/vehiclelock/functions/fnc_moduleSync.sqf index c29c7a06d29..a269fbd6e54 100644 --- a/addons/vehiclelock/functions/fnc_moduleSync.sqf +++ b/addons/vehiclelock/functions/fnc_moduleSync.sqf @@ -22,7 +22,7 @@ if (!isServer) exitWith {}; params ["_logic", "_syncedObjects", "_activated"]; TRACE_3("params",_logic,_syncedObjects,_activated); -if !(_activated) exitWith {WARNING("Vehicle Lock Sync Module - placed but not active");}; +if (!_activated) exitWith {WARNING("Vehicle Lock Sync Module - placed but not active");}; [{ params ["_syncedObjects"]; diff --git a/addons/vehiclelock/initSettings.inc.sqf b/addons/vehiclelock/initSettings.inc.sqf index 9f68c77e7c3..dcb520e7e21 100644 --- a/addons/vehiclelock/initSettings.inc.sqf +++ b/addons/vehiclelock/initSettings.inc.sqf @@ -3,8 +3,7 @@ [LSTRING(DefaultLockpickStrength_DisplayName), LSTRING(DefaultLockpickStrength_Description)], LSTRING(DisplayName), [-1,60,10,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(defaultLockpickStrength), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ diff --git a/addons/viewports/functions/fnc_eachFrame.sqf b/addons/viewports/functions/fnc_eachFrame.sqf index 068a5edcf5c..21f2f09dc8d 100644 --- a/addons/viewports/functions/fnc_eachFrame.sqf +++ b/addons/viewports/functions/fnc_eachFrame.sqf @@ -27,7 +27,7 @@ private _newIndex = -1; if (cba_events_control) then { if (cameraView != "INTERNAL") exitWith {}; if (isTurnedOut _player) exitWith {}; - if (!([_player, _vehicle, []] call EFUNC(common,canInteractWith))) exitWith {}; + if !([_player, _vehicle, []] call EFUNC(common,canInteractWith)) exitWith {}; BEGIN_COUNTER(newIndex); if ((_shownIndex > -1) && {currentVisionMode _player != _lastVisionMode}) then { diff --git a/addons/viewports/functions/fnc_getSeatInfo.sqf b/addons/viewports/functions/fnc_getSeatInfo.sqf index 86dccebdd19..01c71c3cfeb 100644 --- a/addons/viewports/functions/fnc_getSeatInfo.sqf +++ b/addons/viewports/functions/fnc_getSeatInfo.sqf @@ -41,6 +41,6 @@ private _compartment = switch (_role) do { }; }; -if (!(_compartment isEqualType "")) then { _compartment = format ["Compartment%1",_compartment] }; +if !(_compartment isEqualType "") then {_compartment = format ["Compartment%1",_compartment]}; [_role, _cargoIndex, _turretPath, _compartment] diff --git a/addons/viewrestriction/functions/fnc_changeCamera.sqf b/addons/viewrestriction/functions/fnc_changeCamera.sqf index 6a1f7d03ff6..eb6907386a4 100644 --- a/addons/viewrestriction/functions/fnc_changeCamera.sqf +++ b/addons/viewrestriction/functions/fnc_changeCamera.sqf @@ -18,7 +18,7 @@ params ["_newCameraView", "_cameraOn"]; -if (! ([_newCameraView, _cameraOn] call FUNC(canChangeCamera))) exitWith {}; +if !([_newCameraView, _cameraOn] call FUNC(canChangeCamera)) exitWith {}; TRACE_1("View Restricted",XGVAR(mode)); diff --git a/addons/viewrestriction/initSettings.inc.sqf b/addons/viewrestriction/initSettings.inc.sqf index 3ed47c10efb..80382f5b198 100644 --- a/addons/viewrestriction/initSettings.inc.sqf +++ b/addons/viewrestriction/initSettings.inc.sqf @@ -6,7 +6,7 @@ [[0, 1, 2, 3], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson), LSTRING(Selective)], 0], true, {[QGVAR(mode), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -17,7 +17,7 @@ [[0, 1, 2], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson)], 0], true, {[QGVAR(modeSelectiveFoot), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -28,7 +28,7 @@ [[0, 1, 2], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson)], 0], true, {[QGVAR(modeSelectiveLand), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -39,7 +39,7 @@ [[0, 1, 2], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson)], 0], true, {[QGVAR(modeSelectiveAir), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -50,7 +50,7 @@ [[0, 1, 2], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson)], 0], true, {[QGVAR(modeSelectiveSea), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ diff --git a/addons/volume/initSettings.inc.sqf b/addons/volume/initSettings.inc.sqf index 8735f81527f..44bb464a1ee 100644 --- a/addons/volume/initSettings.inc.sqf +++ b/addons/volume/initSettings.inc.sqf @@ -3,9 +3,6 @@ "CHECKBOX", [ELSTRING(common,Enabled), LSTRING(KeybindDescription)], format ["ACE %1", LLSTRING(Name)], - false, - false, - {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, false ] call CBA_fnc_addSetting; @@ -14,10 +11,7 @@ "LIST", [LSTRING(Reduction), LSTRING(ReductionDescription)], format ["ACE %1", LLSTRING(Name)], - [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ["0%", "10%", "20%", "30%", "40%", "50%", "60%", "70%", "80%", "90%", "100%"], 5], - false, - {[QGVAR(reduction), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false + [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ["0%", "10%", "20%", "30%", "40%", "50%", "60%", "70%", "80%", "90%", "100%"], 5] ] call CBA_fnc_addSetting; [ @@ -25,10 +19,7 @@ "LIST", [LSTRING(FadeDelay), LSTRING(FadeDelayDescription)], format ["ACE %1", LLSTRING(Name)], - [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ["0s", "1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s", "10s"], 1], - false, - {[QGVAR(fadeDelay), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false + [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ["0s", "1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s", "10s"], 1] ] call CBA_fnc_addSetting; [ @@ -36,9 +27,6 @@ "CHECKBOX", [LSTRING(LowerInVehicles), LSTRING(LowerInVehiclesDescription)], format ["ACE %1", LLSTRING(Name)], - false, - false, - {[QGVAR(lowerInVehicles), _this] call EFUNC(common,cbaSettings_settingChanged)}, false ] call CBA_fnc_addSetting; @@ -47,10 +35,7 @@ "CHECKBOX", [LSTRING(ShowNotification), LSTRING(ShowNotificationDescription)], format ["ACE %1", LLSTRING(Name)], - true, - false, - {[QGVAR(showNotification), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false + true ] call CBA_fnc_addSetting; [ @@ -58,8 +43,5 @@ "CHECKBOX", [LSTRING(RemindIfLowered), LSTRING(RemindIfLoweredDescription)], format ["ACE %1", LLSTRING(Name)], - false, - false, - {[QGVAR(remindIfLowered), _this] call EFUNC(common,cbaSettings_settingChanged)}, false ] call CBA_fnc_addSetting; diff --git a/addons/weaponselect/XEH_postInit.sqf b/addons/weaponselect/XEH_postInit.sqf index 77a2fc673b0..e9f05de8bbd 100644 --- a/addons/weaponselect/XEH_postInit.sqf +++ b/addons/weaponselect/XEH_postInit.sqf @@ -198,7 +198,7 @@ if (!hasInterface) exitWith {}; ["ACE3 Vehicles", QGVAR(CollisionLights), localize LSTRING(CollisionLights), { // Conditions: canInteract - if (!([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith))) exitWith {false}; + if !([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if ((ACE_player isEqualTo (vehicle ACE_player)) || {ACE_player != (driver (vehicle ACE_player))}) exitWith {false}; diff --git a/addons/weaponselect/XEH_preInit.sqf b/addons/weaponselect/XEH_preInit.sqf index 92ba1b06a60..e699f3d2f38 100644 --- a/addons/weaponselect/XEH_preInit.sqf +++ b/addons/weaponselect/XEH_preInit.sqf @@ -11,18 +11,22 @@ GVAR(GrenadesAll) = []; GVAR(GrenadesFrag) = []; GVAR(GrenadesNonFrag) = []; +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgAmmo = configFile >> "CfgAmmo"; +private _cfgThrow = configFile >> "CfgWeapons" >> "Throw"; + { - private _magazines = getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines"); + private _magazines = getArray (_cfgThrow >> _x >> "magazines"); GVAR(GrenadesAll) append _magazines; { - private _ammo = getText (configFile >> "CfgMagazines" >> _x >> "ammo"); - private _explosive = getNumber (configFile >> "CfgAmmo" >> _ammo >> "explosive"); + private _ammo = getText (_cfgMagazines >> _x >> "ammo"); + private _explosive = getNumber (_cfgAmmo >> _ammo >> "explosive"); ([GVAR(GrenadesFrag), GVAR(GrenadesNonFrag)] select (_explosive == 0)) pushBack _x; } forEach _magazines; -} forEach getArray (configFile >> "CfgWeapons" >> "Throw" >> "muzzles"); +} forEach getArray (_cfgThrow >> "muzzles"); #include "initSettings.inc.sqf" diff --git a/addons/weaponselect/functions/fnc_selectNextGrenade.sqf b/addons/weaponselect/functions/fnc_selectNextGrenade.sqf index ff111a93f6d..ad17c7f18d9 100644 --- a/addons/weaponselect/functions/fnc_selectNextGrenade.sqf +++ b/addons/weaponselect/functions/fnc_selectNextGrenade.sqf @@ -61,14 +61,14 @@ private _vestGrenades = vestItems _unit select {_x in GVAR(GrenadesAll) private _backpackGrenades = backpackItems _unit select {_x in GVAR(GrenadesAll) && {_x != _nextGrenade}}; // remove all grenades except those we are switching to --> this breaks the selector -{_unit removeItemFromUniform _x; false} count _uniformGrenades; -{_unit removeItemFromVest _x; false} count _vestGrenades; -{_unit removeItemFromBackpack _x; false} count _backpackGrenades; +{_unit removeItemFromUniform _x} forEach _uniformGrenades; +{_unit removeItemFromVest _x} forEach _vestGrenades; +{_unit removeItemFromBackpack _x} forEach _backpackGrenades; // readd grenades -{_unit addItemToUniform _x; false} count _uniformGrenades; -{_unit addItemToVest _x; false} count _vestGrenades; -{_unit addItemToBackpack _x; false} count _backpackGrenades; +{_unit addItemToUniform _x} forEach _uniformGrenades; +{_unit addItemToVest _x} forEach _vestGrenades; +{_unit addItemToBackpack _x} forEach _backpackGrenades; [_nextGrenade, {_x == _nextGrenade} count _magazines] call FUNC(displayGrenadeTypeAndNumber); diff --git a/addons/weaponselect/initSettings.inc.sqf b/addons/weaponselect/initSettings.inc.sqf index 029c5201cb6..f5695748b40 100644 --- a/addons/weaponselect/initSettings.inc.sqf +++ b/addons/weaponselect/initSettings.inc.sqf @@ -2,7 +2,5 @@ QGVAR(displayText), "CHECKBOX", [LSTRING(SettingDisplayTextName), LSTRING(SettingDisplayTextDesc)], ELSTRING(common,ACEKeybindCategoryWeapons), - true, // default value - false, // isGlobal - {[QGVAR(displayText), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // default value ] call CBA_fnc_addSetting; diff --git a/addons/weather/functions/fnc_calculateWindSpeed.sqf b/addons/weather/functions/fnc_calculateWindSpeed.sqf index cd73fac3588..d24322bef09 100644 --- a/addons/weather/functions/fnc_calculateWindSpeed.sqf +++ b/addons/weather/functions/fnc_calculateWindSpeed.sqf @@ -47,15 +47,15 @@ if (_terrainEffectEnabled) then { private _newWindSpeed = 0; { private _windSource = [100, _windDirAdjusted, _x] call _fnc_polar2vect; - if (!(terrainIntersectASL [_position, _position vectorAdd _windSource])) exitWith { + if !(terrainIntersectASL [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 9) * _windSpeed; }; _windSource = [100, _windDirAdjusted + _x, 0] call _fnc_polar2vect; - if (!(terrainIntersectASL [_position, _position vectorAdd _windSource])) exitWith { + if !(terrainIntersectASL [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 9) * _windSpeed; }; _windSource = [100, _windDirAdjusted - _x, 0] call _fnc_polar2vect; - if (!(terrainIntersectASL [_position, _position vectorAdd _windSource])) exitWith { + if !(terrainIntersectASL [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 9) * _windSpeed; }; } forEach [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; @@ -69,15 +69,15 @@ if (_obstacleEffectEnabled) then { private _newWindSpeed = 0; { private _windSource = [20, _windDirAdjusted, _x] call _fnc_polar2vect; - if (!(lineIntersects [_position, _position vectorAdd _windSource])) exitWith { + if !(lineIntersects [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 2) * _windSpeed; }; _windSource = [20, _windDirAdjusted + _x, 0] call _fnc_polar2vect; - if (!(lineIntersects [_position, _position vectorAdd _windSource])) exitWith { + if !(lineIntersects [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 2) * _windSpeed; }; _windSource = [20, _windDirAdjusted - _x, 0] call _fnc_polar2vect; - if (!(lineIntersects [_position, _position vectorAdd _windSource])) exitWith { + if !(lineIntersects [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 2) * _windSpeed; }; } forEach [0, 5, 10, 15, 20, 25, 30, 35, 40, 45]; diff --git a/addons/weather/init3DEN.sqf b/addons/weather/init3DEN.sqf index 34b7dc2d5bc..74af5fbaf1b 100644 --- a/addons/weather/init3DEN.sqf +++ b/addons/weather/init3DEN.sqf @@ -5,7 +5,7 @@ // cannot create checkboxes which have the default value "true" // 3den uses inverted checkboxes instead, but those only change in appearence // we have to auto set these settings manually - on mission creation -add3DENEventHandler ["onMissionNew", { +add3DENEventHandler ["OnMissionNew", { set3DENMissionAttributes [ ["Intel", "IntelWavesIsForced", true], ["Intel", "IntelWindIsForced", true] diff --git a/addons/weather/initSettings.inc.sqf b/addons/weather/initSettings.inc.sqf index fb11e31e753..26f44420840 100644 --- a/addons/weather/initSettings.inc.sqf +++ b/addons/weather/initSettings.inc.sqf @@ -34,6 +34,5 @@ private _category = [format ["ACE %1", LLSTRING(Module_DisplayName)]]; QGVAR(showCheckAirTemperature), "CHECKBOX", [LSTRING(showCheckAirTemperature_DisplayName), LELSTRING(common,showActionInSelfInteraction)], _category, - true, // default value - false // isGlobal + true // default value ] call CBA_fnc_addSetting; diff --git a/addons/xm157/functions/fnc_keyPress.sqf b/addons/xm157/functions/fnc_keyPress.sqf index c5e4760563e..3a9dd53a269 100644 --- a/addons/xm157/functions/fnc_keyPress.sqf +++ b/addons/xm157/functions/fnc_keyPress.sqf @@ -19,8 +19,8 @@ params ["_func", "_keyDown"]; if (!GVAR(shown)) exitWith { false }; // fast exit if not shown -if (!([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith))) exitWith { false }; -if (!(ACE_player call CBA_fnc_canUseWeapon)) exitWith { false }; +if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith { false }; +if !(ACE_player call CBA_fnc_canUseWeapon) exitWith { false }; if (currentMuzzle ACE_player != currentWeapon ACE_player) exitWith { false }; private _display = uinamespace getVariable [QGVAR(display), displayNull]; diff --git a/addons/zeus/CfgVehicles.hpp b/addons/zeus/CfgVehicles.hpp index 2a1f2611256..5fb4a4f61a5 100644 --- a/addons/zeus/CfgVehicles.hpp +++ b/addons/zeus/CfgVehicles.hpp @@ -256,6 +256,12 @@ class CfgVehicles { displayName = CSTRING(ModuleSimulation_DisplayName); function = QFUNC(moduleSimulation); }; + class GVAR(moduleSpectator): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(Utility); + displayName = ECSTRING(spectator,Module_DisplayName); + curatorInfoType = QGVAR(RscSpectator); + }; class GVAR(moduleSuicideBomber): GVAR(moduleBase) { curatorCanAttach = 1; category = QGVAR(AI); diff --git a/addons/zeus/XEH_PREP.hpp b/addons/zeus/XEH_PREP.hpp index 8de15147bd5..69dd7b18a63 100644 --- a/addons/zeus/XEH_PREP.hpp +++ b/addons/zeus/XEH_PREP.hpp @@ -34,6 +34,7 @@ PREP(moduleSetMedicalVehicle); PREP(moduleSetRepairFacility); PREP(moduleSetRepairVehicle); PREP(moduleSimulation); +PREP(moduleSpectator); PREP(moduleSuicideBomber); PREP(moduleSuppressiveFire); PREP(moduleSuppressiveFireLocal); @@ -56,6 +57,7 @@ PREP(ui_groupSide); PREP(ui_patrolArea); PREP(ui_searchArea); PREP(ui_setEngineer); +PREP(ui_spectator); PREP(ui_suicideBomber); PREP(ui_teleportPlayers); PREP(ui_toggleFlashlight); diff --git a/addons/zeus/XEH_postInit.sqf b/addons/zeus/XEH_postInit.sqf index b4d1302ab5b..15b4c15f769 100644 --- a/addons/zeus/XEH_postInit.sqf +++ b/addons/zeus/XEH_postInit.sqf @@ -11,6 +11,7 @@ QGVAR(GlobalSkillAI) addPublicVariableEventHandler FUNC(moduleGlobalSetSkill); [QGVAR(moduleSearchNearby), CBA_fnc_searchNearby] call CBA_fnc_addEventHandler; [QGVAR(moduleSearchArea), CBA_fnc_taskSearchArea] call CBA_fnc_addEventHandler; [QGVAR(suppressiveFire), LINKFUNC(moduleSuppressiveFireLocal)] call CBA_fnc_addEventHandler; +[QGVAR(moduleSpectator), LINKFUNC(moduleSpectator)] call CBA_fnc_addEventHandler; // Editable object commands must be ran on server, this events are used in the respective module if (isServer) then { diff --git a/addons/zeus/config.cpp b/addons/zeus/config.cpp index 2714c247b05..d90c9062949 100644 --- a/addons/zeus/config.cpp +++ b/addons/zeus/config.cpp @@ -99,6 +99,11 @@ class CfgPatches { QGVAR(moduleLayTrench) }; }; + class GVAR(spectator): ADDON { + units[] = { + QGVAR(moduleSpectator) + }; + }; }; class ACE_Curator { @@ -112,6 +117,7 @@ class ACE_Curator { GVAR(arsenal) = "ace_arsenal"; GVAR(fire) = "ace_fire"; GVAR(trenches) = "ace_trenches"; + GVAR(spectator) = "ace_spectator"; }; #include "CfgFactionClasses.hpp" diff --git a/addons/zeus/functions/fnc_addObjectToCurator.sqf b/addons/zeus/functions/fnc_addObjectToCurator.sqf index 9651630ccce..4b87904d0f6 100644 --- a/addons/zeus/functions/fnc_addObjectToCurator.sqf +++ b/addons/zeus/functions/fnc_addObjectToCurator.sqf @@ -17,7 +17,7 @@ params ["_object"]; -if (!(_object getVariable [QGVAR(addObject), GVAR(autoAddObjects)])) exitWith {}; +if !(_object getVariable [QGVAR(addObject), GVAR(autoAddObjects)]) exitWith {}; [{ TRACE_1("Delayed addCuratorEditableObjects",_this); diff --git a/addons/zeus/functions/fnc_bi_moduleCurator.sqf b/addons/zeus/functions/fnc_bi_moduleCurator.sqf index ec04a12d241..cdc4d35b648 100644 --- a/addons/zeus/functions/fnc_bi_moduleCurator.sqf +++ b/addons/zeus/functions/fnc_bi_moduleCurator.sqf @@ -23,13 +23,13 @@ params ["_logic", "_units", "_activated"]; if (_activated) then { - //--- Terminate when not created on the server - if (!isserver && local _logic && isnull (getassignedcuratorunit _logic)) exitwith { + // Terminate when not created on the server + if (!isServer && local _logic && isnull (getassignedcuratorunit _logic)) exitwith { [format ["%1 is trying to create curator logic ModuleCurator_F",profilename],"bis_fnc_error",false] call bis_fnc_mp; deletevehicle _logic; }; - //--- Get curator owner + // Get curator owner _ownerVar = _logic getvariable ["owner",""]; _ownerUID = parsenumber _ownerVar; if (cheatsenabled) then { @@ -46,13 +46,13 @@ if (_activated) then { }; _isAdmin = _ownerVar == "#adminLogged" || _ownerVar == "#adminVoted"; - //--- Wipe out the variable so clients can't access it + // Wipe out the variable so clients can't access it _logic setvariable ["owner",nil]; - //--- Server + // Server if (isserver) then { - //--- Prepare admin variable + // Prepare admin variable _adminVar = ""; if (_isAdmin) then { _letters = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]; @@ -61,12 +61,12 @@ if (_activated) then { _logic setvariable ["adminVar",_adminVar,true]; }; - //--- Get allowed addons + // Get allowed addons _addonsType = _logic getvariable ["Addons",2]; _addons = []; switch _addonsType do { - //--- All (including unofficial ones) + // All (including unofficial ones) case 3: { _cfgPatches = configfile >> "cfgpatches"; for "_i" from 0 to (count _cfgPatches - 1) do { @@ -79,10 +79,10 @@ if (_activated) then { _logic addcuratoraddons _addons; }; - //--- All active + // All active case 2: {}; - //--- All mission + // All mission case 1: { _addonsList = []; { @@ -92,13 +92,13 @@ if (_activated) then { _logic addcuratoraddons _addonsList; }; - //--- None + // None case 0: { removeallcuratoraddons _logic; }; }; - //--- Handle ownership + // Handle ownership [_logic,_ownerVar,_ownerUID,_adminVar] spawn { scriptname "BIS_fnc_moduleCurator: Owner"; @@ -110,16 +110,16 @@ if (_activated) then { _name = _logic getvariable ["name",""]; if (_name == "") then {_name = localize "STR_A3_curator";}; - //--- Wait until mission starts + // Wait until mission starts waitUntil {time > 0}; // NOTE: DO NOT CHANGE TO CBA_missionTime, IT BREAKS THE MODULE - //--- Refresh addon list, so it's broadcasted to clients + // Refresh addon list, so it's broadcasted to clients _addons = curatoraddons _logic; removeAllCuratorAddons _logic; _logic addcuratoraddons _addons; while {true} do { - //--- Wait for player to become Zeus + // Wait for player to become Zeus switch true do { case (_ownerUID > 0): { waituntil { @@ -133,7 +133,7 @@ if (_activated) then { }; if (isnull _logic) exitwith {}; - //--- Assign + // Assign _player = objnull; switch true do { case (_ownerUID > 0): { @@ -150,7 +150,7 @@ if (_activated) then { waituntil {_player assignCurator _logic; getassignedcuratorunit _logic == _player || isnull _logic}; if (isnull _logic) exitwith {}; - //--- Add radio channels + // Add radio channels { _x radiochanneladd [_player]; } foreach (_logic getvariable ["channels",[]]); @@ -159,7 +159,7 @@ if (_activated) then { private _msgCode = { params ["_logic","_player"]; - //--- Sent notification to all assigned players + // Sent notification to all assigned players if ((_logic getVariable ["showNotification",true]) && GVAR(zeusAscension)) then { { if (isplayer _x) then { @@ -181,7 +181,7 @@ if (_activated) then { // Added by ace_zeus [QGVAR(zeusUnitAssigned), [_logic,_player]] call CBA_fnc_globalEvent; - //--- Wait for player to stop being Zeus + // Wait for player to stop being Zeus switch true do { case (_ownerUID > 0): { waituntil { @@ -195,12 +195,12 @@ if (_activated) then { }; if (isnull _logic) exitwith {}; - //--- Add radio channels + // Add radio channels { _x radiochannelremove [_player]; } foreach (_logic getvariable ["channels",[]]); - //--- Unassign + // Unassign waituntil {unassigncurator _logic; isnull (getassignedcuratorunit _logic) || isnull _logic}; if (isnull _logic) exitwith {}; }; @@ -211,14 +211,14 @@ if (_activated) then { params ["_logic"]; if (GVAR(zeusBird)) then { - //--- Create bird + // Create bird _birdType = _logic getVariable ["birdType","eagle_f"]; if (_birdType != "") then { _bird = createvehicle [_birdType,[100,100,100],[],0,"none"]; _logic setVariable ["bird",_bird,true]; }; - //--- Locality changed + // Locality changed _logic addeventhandler [ "local", { @@ -237,7 +237,7 @@ if (_activated) then { [_logic] call _birdCode; }; - //--- Activated all future addons + // Activated all future addons _addons = []; { if (typeof _x == "ModuleCuratorAddAddons_F") then { @@ -254,12 +254,12 @@ if (_activated) then { if (time <= 0) then { _addons call bis_fnc_activateaddons; }; }; - //--- Player + // Player if (hasinterface) then { waituntil {local player}; _serverCommand = ["#kick", "#shutdown"] select (_ownerVar == "#adminLogged"); - //--- Black effect until the interface is open + // Black effect until the interface is open _forced = _logic getvariable ["forced",0] > 0; if (_forced) then { _isCurator = switch true do { @@ -279,15 +279,15 @@ if (_activated) then { }; }; - //--- Check if player is server admin + // Check if player is server admin if (_isAdmin) then { _adminVar = _logic getvariable ["adminVar",""]; _logic setvariable ["adminVar",nil]; if (isserver) then { - //--- Host + // Host missionnamespace setvariable [_adminVar,player]; } else { - //--- Client + // Client [_logic,_adminVar,_serverCommand] spawn { scriptname "BIS_fnc_moduleCurator: Admin check"; @@ -314,7 +314,7 @@ if (_activated) then { sleep 1; waituntil {alive player}; - //--- Show warning when Zeus key is not assigned + // Show warning when Zeus key is not assigned if (count (actionkeys "curatorInterface") == 0) then { [ format [ @@ -324,7 +324,7 @@ if (_activated) then { ] call bis_fnc_guiMessage; }; - //--- Show hint about pinging for players + // Show hint about pinging for players if ( isnil {profilenamespace getvariable "bis_fnc_curatorPinged_done"} && @@ -339,7 +339,7 @@ if (_activated) then { }; }; - //--- Add local event handlers + // Add local event handlers _logic addeventhandler ["curatorFeedbackMessage",{_this call bis_fnc_showCuratorFeedbackMessage;}]; _logic addeventhandler ["curatorPinged",{_this call bis_fnc_curatorPinged;}]; _logic addeventhandler ["curatorObjectPlaced",{_this call bis_fnc_curatorObjectPlaced;}]; diff --git a/addons/zeus/functions/fnc_getModuleDestination.sqf b/addons/zeus/functions/fnc_getModuleDestination.sqf index b328201d6ce..10d7acae9e0 100644 --- a/addons/zeus/functions/fnc_getModuleDestination.sqf +++ b/addons/zeus/functions/fnc_getModuleDestination.sqf @@ -113,9 +113,9 @@ GVAR(moduleDestination_mapDrawEH) = [((findDisplay 312) displayCtrl 50), "draw", } else { TRACE_4("cleaning up",_this select 1,GVAR(moduleDestination_displayEHMouse),GVAR(moduleDestination_displayEHKeyboard),GVAR(moduleDestination_mapDrawEH)); (_this select 1) call CBA_fnc_removePerFrameHandler; - (findDisplay 312) displayRemoveEventHandler ["mouseButtonDown", GVAR(moduleDestination_displayEHMouse)]; + (findDisplay 312) displayRemoveEventHandler ["MouseButtonDown", GVAR(moduleDestination_displayEHMouse)]; (findDisplay 312) displayRemoveEventHandler ["KeyDown", GVAR(moduleDestination_displayEHKeyboard)]; - ((findDisplay 312) displayCtrl 50) ctrlRemoveEventHandler ["draw", GVAR(moduleDestination_mapDrawEH)]; + ((findDisplay 312) displayCtrl 50) ctrlRemoveEventHandler ["Draw", GVAR(moduleDestination_mapDrawEH)]; GVAR(moduleDestination_displayEHMouse) = nil; GVAR(moduleDestination_displayEHKeyboard) = nil; GVAR(moduleDestination_mapDrawEH) = nil; diff --git a/addons/zeus/functions/fnc_moduleCargoParadrop.sqf b/addons/zeus/functions/fnc_moduleCargoParadrop.sqf index 69d90d310d6..2aaffb37964 100644 --- a/addons/zeus/functions/fnc_moduleCargoParadrop.sqf +++ b/addons/zeus/functions/fnc_moduleCargoParadrop.sqf @@ -30,13 +30,13 @@ TRACE_4("moduleCargoParadrop placed",_logic,typeOf _vehicle,_pilot,typeOf _pilot deleteVehicle _logic; // cleanup logic now, we just needed it to get the attached vehicle -if (!(missionNamespace getVariable [QEGVAR(cargo,enable), false])) exitWith { +if !(missionNamespace getVariable [QEGVAR(cargo,enable), false]) exitWith { [LSTRING(RequiresAddon)] call FUNC(showMessage); }; if (isNull _vehicle) exitWith { [LSTRING(NothingSelected)] call FUNC(showMessage); }; -if (!(_vehicle isKindOf "Air")) exitWith { +if !(_vehicle isKindOf "Air") exitWith { [format ["%1 %2", localize "str_dn_aircraft", localize "str_msg_no_veh_select"]] call FUNC(showMessage); }; if ((!alive _vehicle) || {!alive _pilot}) exitWith { diff --git a/addons/zeus/functions/fnc_moduleCargoParadropWaypoint.sqf b/addons/zeus/functions/fnc_moduleCargoParadropWaypoint.sqf index dded460710b..65706484999 100644 --- a/addons/zeus/functions/fnc_moduleCargoParadropWaypoint.sqf +++ b/addons/zeus/functions/fnc_moduleCargoParadropWaypoint.sqf @@ -22,7 +22,7 @@ TRACE_2("moduleCargoParadropWaypoint",_vehicleGroup,_wpPos); private _vehicle = vehicle leader _vehicleGroup; private _commander = driver _vehicle; private _cargo = _vehicle getVariable [QEGVAR(cargo,loaded), []]; -if (!(_vehicle isKindOf "Air")) exitWith {WARNING_1("not in a air vehicle",typeOf _vehicle); true}; +if !(_vehicle isKindOf "Air") exitWith {WARNING_1("not in a air vehicle",typeOf _vehicle); true}; if (_cargo isEqualTo []) exitWith {WARNING_1("no cargo",_cargo); true}; private _previousSpeedMode = speedMode _vehicleGroup; diff --git a/addons/zeus/functions/fnc_moduleHeal.sqf b/addons/zeus/functions/fnc_moduleHeal.sqf index 9a49375003d..4bf0525ea75 100644 --- a/addons/zeus/functions/fnc_moduleHeal.sqf +++ b/addons/zeus/functions/fnc_moduleHeal.sqf @@ -43,7 +43,7 @@ switch (false) do { }; // Heal validated target -if (["ace_medical"] call EFUNC(common,isModLoaded)) then { +if (GETEGVAR(medical,enabled,false)) then { TRACE_1("healing with ace_medical",_unit); [QEGVAR(medical_treatment,fullHealLocal), [_unit], _unit] call CBA_fnc_targetEvent; } else { diff --git a/addons/zeus/functions/fnc_moduleSetMedic.sqf b/addons/zeus/functions/fnc_moduleSetMedic.sqf index f66ca9132da..d44dd56e593 100644 --- a/addons/zeus/functions/fnc_moduleSetMedic.sqf +++ b/addons/zeus/functions/fnc_moduleSetMedic.sqf @@ -21,7 +21,7 @@ params ["_logic"]; if !(local _logic) exitWith {}; -if !(["ace_medical"] call EFUNC(common,isModLoaded)) then { +if !(GETEGVAR(medical,enabled,false)) then { [LSTRING(RequiresAddon)] call FUNC(showMessage); } else { private _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); diff --git a/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf b/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf index 1f982129357..b6742a25a44 100644 --- a/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf +++ b/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf @@ -21,7 +21,7 @@ params ["_logic"]; if !(local _logic) exitWith {}; -if !(["ace_medical"] call EFUNC(common,isModLoaded)) then { +if !(GETEGVAR(medical,enabled,false)) then { [LSTRING(RequiresAddon)] call FUNC(showMessage); } else { private _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); @@ -40,7 +40,7 @@ if !(["ace_medical"] call EFUNC(common,isModLoaded)) then { if (GETVAR(_unit,EGVAR(captives,isHandcuffed),false)) then { [LSTRING(OnlyNonCaptive)] call FUNC(showMessage); } else { - if (!(GETVAR(_unit,EGVAR(medical,isMedicalFacility),false))) then { + if !(GETVAR(_unit,EGVAR(medical,isMedicalFacility),false)) then { _unit setVariable [QEGVAR(medical,isMedicalFacility), true, true]; }; }; diff --git a/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf b/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf index e8189b377e6..26bb3fcfe95 100644 --- a/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf +++ b/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf @@ -21,7 +21,7 @@ params ["_logic"]; if !(local _logic) exitWith {}; -if !(["ace_medical"] call EFUNC(common,isModLoaded)) then { +if !(GETEGVAR(medical,enabled,false)) then { [LSTRING(RequiresAddon)] call FUNC(showMessage); } else { private _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); diff --git a/addons/zeus/functions/fnc_moduleSpectator.sqf b/addons/zeus/functions/fnc_moduleSpectator.sqf new file mode 100644 index 00000000000..fb9ca2a63b1 --- /dev/null +++ b/addons/zeus/functions/fnc_moduleSpectator.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Zeus module function to make the local player an ACE Spectator. + * + * Arguments: + * 0: Force interface + * 1: Hide player + * 2: Sides available to spectate + * 3: Camera modes available + * 4: Vision modes available + * + * Return Value: + * None + * + * Example: + * [true, true, [west], [0, 1, 2], [-2, -1, 0, 1]] call ace_zeus_fnc_moduleSpectator + * + * Public: No + */ + +params ["_force", "_hide", "_sides", "_modes", "_visions"]; +TRACE_1("params",_this); + +// Update sides available to spectate +[_sides, [west, east, independent, civilian] - _sides] call EFUNC(spectator,updateSides); + +// Update available camera modes +[_modes, [0, 1, 2] - _modes] call EFUNC(spectator,updateCameraModes); + +// Update available vision modes +[_visions, [-2, -1, 0, 1, 2, 3, 4, 5, 6, 7] - _visions] call EFUNC(spectator,updateVisionModes); + +// Make unit spectator (close Zeus camera if open) +if (!isNull curatorCamera) then { + (findDisplay 312) closeDisplay 2; +}; + +[true, _force, _hide] call EFUNC(spectator,setSpectator); diff --git a/addons/zeus/functions/fnc_moduleSuicideBomber.sqf b/addons/zeus/functions/fnc_moduleSuicideBomber.sqf index 8346eb42665..8425ff15485 100644 --- a/addons/zeus/functions/fnc_moduleSuicideBomber.sqf +++ b/addons/zeus/functions/fnc_moduleSuicideBomber.sqf @@ -57,7 +57,7 @@ if (_autoSeek) then { LOG("Unit deleted or killed, PFH removed"); }; - if (!([_unit] call EFUNC(common,isAwake))) exitWith {}; + if !([_unit] call EFUNC(common,isAwake)) exitWith {}; // Detonation private _nearObjects = (_unit nearObjects _activationRadius) select {side _x == _activationSide && {_x != _unit} && {alive _x}}; diff --git a/addons/zeus/functions/fnc_showMessage.sqf b/addons/zeus/functions/fnc_showMessage.sqf index 8bbd7d510dc..53094dbfb3f 100644 --- a/addons/zeus/functions/fnc_showMessage.sqf +++ b/addons/zeus/functions/fnc_showMessage.sqf @@ -18,7 +18,7 @@ * Public: Yes */ -if (!(_this isEqualTypeParams [""])) exitWith {ERROR_1("First arg must be string [%1]",_this);}; +if !(_this isEqualTypeParams [""]) exitWith {ERROR_1("First arg must be string [%1]",_this);}; private _message = _this apply {if ((_x isEqualType "") && {isLocalized _x}) then {localize _x} else {_x}}; [objNull, format _message] call BIS_fnc_showCuratorFeedbackMessage; diff --git a/addons/zeus/functions/fnc_ui_globalSetSkill.sqf b/addons/zeus/functions/fnc_ui_globalSetSkill.sqf index 31f41d76c6b..5a7c5fc5e03 100644 --- a/addons/zeus/functions/fnc_ui_globalSetSkill.sqf +++ b/addons/zeus/functions/fnc_ui_globalSetSkill.sqf @@ -24,7 +24,7 @@ private _ctrlButtonOK = _display displayCtrl 1; //IDC_OK private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); TRACE_1("logicObject",_logic); -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; //Specific on-load stuff: private _fnc_sliderMove = { @@ -74,5 +74,5 @@ private _fnc_onConfirm = { [QGVAR(GlobalSkillAI),GVAR(GlobalSkillAI)] call FUNC(moduleGlobalSetSkill); }; -_display displayAddEventHandler ["unload", _fnc_onUnload]; -_ctrlButtonOK ctrlAddEventHandler ["buttonclick", _fnc_onConfirm]; +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_groupSide.sqf b/addons/zeus/functions/fnc_ui_groupSide.sqf index 4dff592f621..110e2e302da 100644 --- a/addons/zeus/functions/fnc_ui_groupSide.sqf +++ b/addons/zeus/functions/fnc_ui_groupSide.sqf @@ -24,7 +24,7 @@ private _ctrlButtonOK = _display displayCtrl 1; //IDC_OK private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); TRACE_1("logicObject",_logic); -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; //Validate the module target: private _unit = effectiveCommander (attachedTo _logic); @@ -101,7 +101,7 @@ private _fnc_onSelection = { _ctrl ctrlSetTextColor _color; - _ctrl ctrlAddEventHandler ["buttonclick", _fnc_onSelection]; + _ctrl ctrlAddEventHandler ["ButtonClick", _fnc_onSelection]; } forEach IDCs; private _fnc_onUnload = { @@ -129,5 +129,5 @@ private _fnc_onConfirm = { deleteVehicle _logic; }; -_display displayAddEventHandler ["unload", _fnc_onUnload]; -_ctrlButtonOK ctrlAddEventHandler ["buttonClick", _fnc_onConfirm]; +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_setEngineer.sqf b/addons/zeus/functions/fnc_ui_setEngineer.sqf index b2515c311dd..3f008403cc7 100644 --- a/addons/zeus/functions/fnc_ui_setEngineer.sqf +++ b/addons/zeus/functions/fnc_ui_setEngineer.sqf @@ -23,7 +23,7 @@ private _ctrlButtonOK = _display displayCtrl 1; // IDC_OK private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); TRACE_1("logicObject",_logic); -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; // Validate module target private _unit = attachedTo _logic; diff --git a/addons/zeus/functions/fnc_ui_spectator.sqf b/addons/zeus/functions/fnc_ui_spectator.sqf new file mode 100644 index 00000000000..fe9b4a36687 --- /dev/null +++ b/addons/zeus/functions/fnc_ui_spectator.sqf @@ -0,0 +1,265 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Initializes the "Spectator" Zeus module display. + * + * Arguments: + * 0: spectator controls group + * + * Return Value: + * None + * + * Example: + * [CONTROL] call ace_zeus_fnc_ui_spectator + * + * Public: No + */ + +#define SIDE_IDCs [92540, 92541, 92542, 92543] +#define CAMERA_IDCs [92550, 92551, 92552] +#define VISION_IDCs [92558, 92559, 92560, 92561] + +params ["_control"]; + +private _display = ctrlParent _control; +private _ctrlButtonOK = _display displayCtrl 1; // IDC_OK +private _logic = missionNamespace getVariable ["BIS_fnc_initCuratorAttributes_target", objNull]; +TRACE_1("Logic Object",_logic); + +_control ctrlRemoveAllEventHandlers "SetFocus"; + +// Validate module target +private _unit = attachedTo _logic; +TRACE_1("Unit",_unit); + +scopeName "Main"; +private _fnc_errorAndClose = { + params ["_msg"]; + _display closeDisplay 0; + deleteVehicle _logic; + [_msg] call FUNC(showMessage); + breakOut "Main"; +}; + +switch (false) do { + case (["ace_spectator"] call EFUNC(common,isModLoaded)): { + [LSTRING(RequiresAddon)] call _fnc_errorAndClose; + }; + case (!isNull _unit): { + [LSTRING(NothingSelected)] call _fnc_errorAndClose; + }; + case (_unit isKindOf "CAManBase"): { + [LSTRING(OnlyInfantry)] call _fnc_errorAndClose; + }; + case (alive _unit): { + [LSTRING(OnlyAlive)] call _fnc_errorAndClose; + }; + case ([_unit, true] call EFUNC(common,isPlayer)): { + [LSTRING(OnlyPlayers)] call _fnc_errorAndClose; + }; +}; + +// Specific onLoad stuff +private _side = side _unit; + +// Spectate sides +private _fnc_onSideSelection = { + params ["_ctrl"]; + + private _display = ctrlParent _ctrl; + if (isNull _display) exitWith {}; + + private _color = _ctrl getVariable "color"; + private _scale = 1; + + private _sides = _display getVariable [QGVAR(spectateSides), []]; + private _selectedSide = (ctrlIDC _ctrl) - 92540; + + // Add or remove from spectatable sides and update color and scale + if (_selectedSide in _sides) then { + _display setVariable [QGVAR(spectateSides), _sides - [_selectedSide]]; + _color set [3, 0.5]; + } else { + _display setVariable [QGVAR(spectateSides), _sides + [_selectedSide]]; + _color set [3, 1]; + _scale = 1.2; + }; + + _ctrl ctrlSetTextColor _color; + [_ctrl, _scale, 0.1] call BIS_fnc_ctrlSetScale; +}; + +// Use the unit's side as default +private _activeSide = [east, west, independent, civilian] find _side; + +// Handle sides other than default four (sideEnemy) +if (_activeSide != -1) then { + _display setVariable [QGVAR(spectateSides), [_activeSide]]; +}; + +{ + private _ctrl = _display displayCtrl _x; + private _side = _x - 92540; + private _color = [_side] call BIS_fnc_sideColor; + _ctrl setVariable ["color", _color]; + _ctrl ctrlSetActiveColor _color; + _color set [3, 0.5]; + + if (_side == _activeSide) then { + [_ctrl, 1.2, 0] call BIS_fnc_ctrlSetScale; + _color set [3, 1]; + }; + + _ctrl ctrlSetTextColor _color; + + _ctrl ctrlAddEventHandler ["ButtonClick", _fnc_onSideSelection]; +} forEach SIDE_IDCs; + +// Camera modes +private _fnc_onModesSelection = { + params ["_ctrl"]; + + private _display = ctrlParent _ctrl; + if (isNull _display) exitWith {}; + + private _color = [1, 1, 1, 0.5]; + private _scale = 1; + + private _modes = _display getVariable [QGVAR(cameraModes), []]; + private _selectedMode = (ctrlIDC _ctrl) - 92550; + + // Add or remove from camera modes and update color and scale + if (_selectedMode in _modes) then { + _display setVariable [QGVAR(cameraModes), _modes - [_selectedMode]]; + } else { + _display setVariable [QGVAR(cameraModes), _modes + [_selectedMode]]; + _color set [3, 1]; + _scale = 1.2; + }; + + _ctrl ctrlSetTextColor _color; + [_ctrl, _scale, 0.1] call BIS_fnc_ctrlSetScale; +}; + +// Use setting as default since global variable will change +private _availableModes = [[0, 1, 2], [1, 2], [0], [1], [2]] select EGVAR(spectator,restrictModes); +_display setVariable [QGVAR(cameraModes), _availableModes]; + +{ + private _ctrl = _display displayCtrl _x; + private _color = [1, 1, 1, 0.5]; + + if ((_x - 92550) in _availableModes) then { + [_ctrl, 1.2, 0] call BIS_fnc_ctrlSetScale; + _color set [3, 1]; + }; + + _ctrl ctrlSetTextColor _color; + + _ctrl ctrlAddEventHandler ["ButtonClick", _fnc_onModesSelection]; +} forEach CAMERA_IDCs; + +// Vision Modes +private _fnc_onVisionSelection = { + params ["_ctrl", "_state"]; + + private _display = ctrlParent _ctrl; + if (isNull _display) exitwith {}; + + // Convert to boolean since EH returns state as 0 or 1 + private _state = [false, true] select _state; + + private _visions = _display getVariable [QGVAR(visionModes), []]; + private _selectedVision = (ctrlIDC _ctrl) - 92560; + + // Add or remove from vision modes + if (_state) then { + _display setVariable [QGVAR(visionModes), _visions + [_selectedVision]]; + } else { + _display setVariable [QGVAR(visionModes), _visions - [_selectedVision]]; + }; + + // Handle all checked/unchecked + private _allCheckboxes = VISION_IDCs apply {cbChecked (_display displayCtrl _x)}; + + if (_allCheckboxes isEqualTo [_state, _state, _state, _state]) then { + (_display displayCtrl 92557) cbSetChecked _state; + }; +}; + +// Use setting as default since global variable will change +private _availableVisions = [[-2,-1,0,1], [-2,-1], [-2,0,1], [-2]] select EGVAR(spectator,restrictVisions); +_display setVariable [QGVAR(visionModes), _availableVisions]; + +{ + private _ctrl = _display displayCtrl _x; + + if ((_x - 92560) in _availableVisions) then { + _ctrl cbSetChecked true; + }; + + _ctrl ctrlAddEventHandler ["CheckedChanged", _fnc_onVisionSelection]; +} forEach VISION_IDCs; + +// Init all visions checkbox +private _fnc_onVisionsAll = { + params ["_ctrl", "_state"]; + + private _display = ctrlParent _ctrl; + if (isNull _display) exitWith {}; + + // Convert to boolean since EH returns state as 0 or 1 + _state = _state == 1; + + // Set state of all checkboxes + { + (_display displayCtrl _x) cbSetChecked _state; + } forEach VISION_IDCs; + + // Store new visions mode setting + private _setting = [[], [-2, -1, 0, 1]] select _state; + _display setVariable [QGVAR(visionModes), _setting]; +}; + +private _allCheckbox = _display displayCtrl 92557; + +// Set to checked by default if setting is all vision modes +if (_availableVisions isEqualTo [-2, -1, 0, 1]) then { + _allCheckbox cbSetChecked true; +}; + +_allCheckbox ctrlAddEventHandler ["CheckedChanged", _fnc_onVisionsAll]; + +// Confirm and Cancel +private _fnc_onUnload = { + private _logic = missionNamespace getVariable ["BIS_fnc_initCuratorAttributes_target", objNull]; + if (isNull _logic) exitWith {}; + + deleteVehicle _logic; +}; + +private _fnc_onConfirm = { + params [["_ctrlButtonOK", controlNull, [controlNull]]]; + + private _display = ctrlParent _ctrlButtonOK; + if (isNull _display) exitWith {}; + + private _logic = missionNamespace getVariable ["BIS_fnc_initCuratorAttributes_target", objNull]; + if (isNull _logic) exitWith {}; + + private _unit = attachedTo _logic; + if (isNull _unit) exitWith {}; + + private _force = lbCurSel (_display displayCtrl 92531) > 0; + private _hide = lbCurSel (_display displayCtrl 92532) > 0; + private _sides = (_display getVariable [QGVAR(spectateSides), []]) apply {_x call BIS_fnc_sideType}; + private _modes = _display getVariable [QGVAR(cameraModes), []]; + private _visions = _display getVariable [QGVAR(visionModes), []]; + + [QGVAR(moduleSpectator), [_force, _hide, _sides, _modes, _visions], _unit] call CBA_fnc_targetEvent; + + deleteVehicle _logic; +}; + +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_teleportPlayers.sqf b/addons/zeus/functions/fnc_ui_teleportPlayers.sqf index 1becc040048..b7aab411268 100644 --- a/addons/zeus/functions/fnc_ui_teleportPlayers.sqf +++ b/addons/zeus/functions/fnc_ui_teleportPlayers.sqf @@ -23,7 +23,7 @@ private _ctrlButtonOK = _display displayCtrl 1; //IDC_OK private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); TRACE_1("logicObject",_logic); -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; //Specific on-load stuff: private _listbox = _display displayCtrl 16189; @@ -91,5 +91,5 @@ private _fnc_onConfirm = { }; _display displayAddEventHandler ["KeyUp", _fnc_onKeyUp]; -_display displayAddEventHandler ["unload", _fnc_onUnload]; -_ctrlButtonOK ctrlAddEventHandler ["buttonclick", _fnc_onConfirm]; +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/stringtable.xml b/addons/zeus/stringtable.xml index 8b3aaed92ca..e871ef85eff 100644 --- a/addons/zeus/stringtable.xml +++ b/addons/zeus/stringtable.xml @@ -1097,6 +1097,22 @@ 需要一個不存在的插件 현재 없는 애드온을 필요로 합니다 + + Only Players + プレイヤーのみ + Nur Spieler + 오직 플레이어만 + Tylko gracze + Joueurs seulement + Solo Giocatori + 仅玩家 + 只有玩家 + Только игроки + Apenas Jogadores + Pouze hráči + Solo jugadores + Sadece Oyuncular + None Keiner @@ -1322,6 +1338,7 @@ 화물 내리기 Выгрузить из отсека Décharger de la cargaison + Descargar de la carga Toggle NVGs @@ -1483,7 +1500,7 @@ Fill from top to bottom Von oben nach unten befüllen Remplir de haut en bas - 上から下まで占拠 + 上から下へと占拠 Riempi dall'alto al basso 由上而下進行填滿 由上而下进行填满 @@ -1968,6 +1985,7 @@ 의료 메뉴가 비활성화되었습니다 Медицинское меню отключено Le Menu médical est désactivé + El menú médico está deshabilitado Lay Trenchline @@ -1978,6 +1996,7 @@ Piazza Trincea 塹壕溝線を敷設 Проложить траншею + Poner una Trinchera +SHIFT to force (Can only lay N/S or E/W) @@ -1988,6 +2007,42 @@ +SHIFT per forzare (Può piazzare solo N/S o E/O +SHIFTキー で強制的に敷設 (北/南または東/西方向にのみ配置可能) +SHIFT на принудительное (может укладываться только на Север/Юг или Восток/Запад) + +SHIFT para forzar (Puede solo colocar en N/S or E/O) + + + Forces the spectator interface preventing the player from closing it with the Escape key + 観戦インターフェイスを強制し、ユーザーがEscキーでも閉じられないようにします。 + Активирует интерфейс spectator, не позволяя игроку закрыть его с помощью клавиши Escape. + + + Hide player + プレイヤーを隠す + Скрыть игрока + + + Hides the player by making them invisible, invulnerable, muted, and removing them from their group + 透明化、無敵化、ミュート、グループからの除外を行いプレーヤーを隠します + Скрывает игрока, делая его невидимым, неуязвимым, отключая звук и удаляя из группы. + + + Sets the sides that are available to spectate + 指定の陣営を観戦可能に設定します + Устанавливает стороны, доступные для режима spectator + + + White Hot + 白=熱源 + Белый + + + Black Hot + 黒=熱源 + Чёрный + + + Toggle All + 全てを切り替え + Выключить все diff --git a/addons/zeus/ui/RscAttributes.hpp b/addons/zeus/ui/RscAttributes.hpp index 0ff21b145f6..da3f53364fb 100644 --- a/addons/zeus/ui/RscAttributes.hpp +++ b/addons/zeus/ui/RscAttributes.hpp @@ -915,3 +915,231 @@ class GVAR(RscSuicideBomber): RscDisplayAttributes { class ButtonCancel: ButtonCancel {}; }; }; + +class GVAR(RscSpectator): RscDisplayAttributes { + onLoad = QUOTE([ARR_3('onLoad',_this,QQGVAR(RscSpectator))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload',_this,QQGVAR(RscSpectator))] call FUNC(zeusAttributes)); + class Controls: Controls { + class Background: Background {}; + class Title: Title {}; + class Content: Content { + class Controls { + class spectator: RscControlsGroupNoScrollbars { + onSetFocus = QUOTE(_this call FUNC(ui_spectator)); + idc = 92530; + x = 0; + y = 0; + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(10.7)); + class controls { + class ForceInterfaceLabel: RscText { + idc = -1; + text = "$STR_a3_cfgvehicles_modulecurator_f_arguments_forced"; + tooltip = CSTRING(ModuleSpectator_ForceInterface_Tooltip); + x = 0; + y = 0; + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(1)); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class ForceInterface: ctrlToolbox { + idc = 92531; + x = QUOTE(W_PART(10.1)); + y = 0; + w = QUOTE(W_PART(15.9)); + h = QUOTE(H_PART(1)); + rows = 1; + columns = 2; + strings[] = {ECSTRING(common,No), ECSTRING(common,Yes)}; + }; + class HidePlayerLabel: ForceInterfaceLabel { + text = CSTRING(ModuleSpectator_HidePlayer); + tooltip = CSTRING(ModuleSpectator_HidePlayer_Tooltip); + y = QUOTE(H_PART(1.1)); + }; + class HidePlayer: ForceInterface { + idc = 92532; + y = QUOTE(H_PART(1.1)); + }; + class SpectateSides: RscControlsGroupNoScrollbars { + idc = 92533; + x = 0; + y = QUOTE(H_PART(2.2)); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(2.5)); + class controls { + class Label: RscText { + idc = -1; + text = "$STR_A3_Spectator_Eden_WhitelistedSides_Name"; + tooltip = CSTRING(ModuleSpectator_SpectableSides_Tooltip); + x = 0; + y = 0; + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(2.5)); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class Background: RscText { + idc = -1; + x = QUOTE(W_PART(10)); + y = 0; + w = QUOTE(W_PART(16)); + h = QUOTE(H_PART(2.5)); + colorBackground[] = {1, 1, 1, 0.1}; + }; + class BLUFOR: RscActivePicture { + idc = 92541; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_west_ca.paa"; + x = QUOTE(W_PART(12.5)); + y = QUOTE(H_PART(0.25)); + w = QUOTE(W_PART(2)); + h = QUOTE(H_PART(2)); + tooltip = "$STR_WEST"; + }; + class OPFOR: BLUFOR { + idc = 92540; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_east_ca.paa"; + x = QUOTE(W_PART(15.5)); + tooltip = "$STR_EAST"; + }; + class Independent: BLUFOR { + idc = 92542; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_guer_ca.paa"; + x = QUOTE(W_PART(18.5)); + tooltip = "$STR_guerrila"; + }; + class Civilian: BLUFOR { + idc = 92543; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_civ_ca.paa"; + x = QUOTE(W_PART(21.5)); + tooltip = "$STR_Civilian"; + }; + }; + }; + class CameraModes: RscControlsGroupNoScrollbars { + idc = 92534; + x = 0; + y = QUOTE(H_PART(4.8)); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(2.5)); + class controls { + class Label: RscText { + idc = -1; + text = ECSTRING(spectator,modes_DisplayName); + tooltip = ECSTRING(spectator,modes_Description); + x = 0; + y = 0; + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(2.5)); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class Background: RscText { + idc = -1; + x =QUOTE(W_PART(10)); + y = 0; + w = QUOTE(W_PART(16)); + h = QUOTE(H_PART(2.5)); + colorBackground[] = {1, 1, 1, 0.1}; + }; + class Free: RscActivePicture { + idc = 92550; + text = "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\Free.paa"; + x = QUOTE(W_PART(13.375)); + y = QUOTE(H_PART(0.375)); + w = QUOTE(W_PART(1.75)); + h = QUOTE(H_PART(1.75)); + tooltip = "$STR_A3_Spectator_free_camera_tooltip"; + }; + class Follow: Free { + idc = 92552; + text = "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\Follow.paa"; + x = QUOTE(W_PART(17.125)); + tooltip = "$STR_A3_Spectator_3pp_camera_tooltip"; + }; + class FirstPerson: Free { + idc = 92551; + text = "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\Fps.paa"; + x = QUOTE(W_PART(20.875)); + tooltip = "$STR_A3_Spectator_1pp_camera_tooltip"; + }; + }; + }; + class VisionModes: RscControlsGroupNoScrollbars { + idc = 92535; + x = 0; + y = QUOTE(H_PART(7.4)); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(3.3)); + class controls { + class Label: RscText { + idc = -1; + text = ECSTRING(spectator,visions_DisplayName); + tooltip = ECSTRING(spectator,visions_Description); + x = 0; + y = 0; + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(1)); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class Background: RscText { + idc = -1; + x = 0; + y = QUOTE(H_PART(1)); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(2.3)); + colorBackground[] = {1, 1, 1, 0.1}; + }; + class AllCheckBox: RscCheckBox { + idc = 92557; + tooltip = CSTRING(ToggleAll); + x = QUOTE(W_PART(25)); + y = 0; + w = QUOTE(W_PART(1)); + h = QUOTE(H_PART(1)); + }; + class NormalLabel: Label { + text = "$STR_speed_normal"; + tooltip = ""; + x = QUOTE(W_PART(1)); + y = QUOTE(H_PART(1.1)); + w = QUOTE(W_PART(10.8)); + colorBackground[] = {0, 0, 0, 0.6}; + }; + class Normal: AllCheckBox { + idc = 92558; + x = QUOTE(W_PART(11.9)); + y = QUOTE(H_PART(1.1)); + }; + class NightVisionLabel: NormalLabel { + text = "$STR_usract_night_vision"; + y = QUOTE(H_PART(2.2)); + }; + class NightVision: Normal { + idc = 92559; + y = QUOTE(H_PART(2.2)); + }; + class WhiteHotLabel: NormalLabel { + text = CSTRING(ModuleSpectator_WhiteHot); + x = QUOTE(W_PART(13.1)); + }; + class WhiteHot: Normal { + idc = 92560; + x = QUOTE(W_PART(24)); + }; + class BlackHotLabel: WhiteHotLabel { + text = CSTRING(ModuleSpectator_BlackHot); + y = QUOTE(Y_PART(2.2)); + }; + class BlackHot: WhiteHot { + idc = 92561; + y = QUOTE(H_PART(2.2)); + }; + }; + }; + }; + }; + }; + }; + class ButtonOK: ButtonOK {}; + class ButtonCancel: ButtonCancel {}; + }; +}; diff --git a/docs/_config.yml b/docs/_config.yml index 66cd1141f7b..ee7822969d6 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -9,8 +9,8 @@ ace: version: major: 3 minor: 17 - patch: 0 - build: 82 + patch: 1 + build: 86 markdown: kramdown diff --git a/docs/_config_dev.yml b/docs/_config_dev.yml index e3c042e9c70..348e1aee441 100644 --- a/docs/_config_dev.yml +++ b/docs/_config_dev.yml @@ -9,8 +9,8 @@ ace: version: major: 3 minor: 17 - patch: 0 - build: 82 + patch: 1 + build: 86 markdown: kramdown diff --git a/docs/wiki/development/coding-guidelines.md b/docs/wiki/development/coding-guidelines.md index 786a5d74e89..fe9f0bfdf09 100644 --- a/docs/wiki/development/coding-guidelines.md +++ b/docs/wiki/development/coding-guidelines.md @@ -381,11 +381,19 @@ However the following is allowed: _value = (_array select 0) select 1; ``` -Any conditions in statements shall always be wrapped around brackets. +Any conditions in statements shall always be wrapped around brackets. Both uses of the `!` operator below are allowed. ```sqf -if (!_value) then {}; if (_value) then {}; +if (!_value) then {}; +if !(_value) then {}; +``` + +Use of the `!` operator on the lefthand-side of brackets can be more readable, particularly for more complex conditions or macros: + +```sqf +if !(_value && _otherValue && {_thirdValue call _something}) then {}; +if !(GETEGVAR(addon,globalVariableName,defaultValue)) then {}; ``` ### 5.6 Magic Numbers @@ -632,81 +640,6 @@ player addEventHandler ["Fired", FUNC(handleFired)]; // bad player addEventHandler ["Fired", {call FUNC(handleFired)}]; // good ``` -### 7.4 Hashes - -When a key value pair is required, make use of the hash implementation from ACE3. - -Hashes are a variable type that store key value pairs. They are not implemented natively in SQF, so there are a number of macros and functions for their usage in ACE3. If you are unfamiliar with the idea, they are similar in function to `setVariable`/`getVariable` but do not require an object to use. - -The following example is a simple usage using our macros which will be explained further below. - -```sqf -_hash = HASHCREATE; -HASH_SET(_hash,"key","value"); -if (HASH_HASKEY(_hash,"key")) then { - player sideChat format ["val: %1", HASH_GET(_hash,"key"); // will print out "val: value" -}; -HASH_REM(_hash,"key"); -if (HASH_HASKEY(_hash,"key")) then { - // this will never execute because we removed the hash key/val pair "key" -}; -``` - -A description of the above macros is below. - -| Macro | Use | -| ------|-------| -|`HASHCREATE` | Used to create an empty hash. | -|`HASH_SET(hash,key,val)` | Will set the hash key to that value, a key can be anything, even objects. | -|`HASH_GET(hash,key)` | Will return the value of that key (or nil if it doesn't exist). | -|`HASH_HASKEY(hash,key)` | Will return true/false if that key exists in the hash. | -|`HASH_REM(hash,key)` | Will remove that hash key. | - -#### 7.4.1 Hashlists - -A hashlist is an extension of a hash. It is a list of hashes! The reason for having this special type of storage container rather than using a normal array is that an array of normal hashes that are similar will duplicate a large amount of data in their storage of keys. A hashlist on the other hand uses a common list of keys and an array of unique value containers. The following will demonstrate its usage. - -```sqf -_defaultKeys = ["key1", "key2", "key3"]; -// create a new hashlist using the above keys as default -_hashList = HASHLIST_CREATELIST(_defaultKeys); - -//lets get a blank hash template out of this hashlist -_hash = HASHLIST_CREATEHASH(_hashList); - -//_hash is now a standard hash... -HASH_SET(_hash,"key1","1"); - -//to store it to the list we need to push it to the list -HASHLIST_PUSH(_hashList, _hash); - -//now lets get it out and store it in something else for fun -//it was pushed to an empty list, so it's index is 0 -_anotherHash = HASHLIST_SELECT(_hashList,0); - -// this should print "val: 1" -player sideChat format["val: %1", HASH_GET(_anotherHash,"key1")]; - -//Say we need to add a new key to the hashlist -//that we didn't initialize it with? We can simply -//set a new key using the standard HASH_SET macro -HASH_SET(_anotherHash,"anotherKey","another value"); -``` - -As you can see above working with hashlists are fairly simple, a more in depth explanation of the macros is below. - -| Macro | Use | -| -------|---------| -|`HASHLIST_CREATELIST(keys)` | Creates a new hashlist with the default keys, pass [] for no default keys. | -|`HASHLIST_CREATEHASH(hashlist)` | Returns a blank hash template from a hashlist. | -|`HASHLIST_PUSH(hashList, hash)` | Pushes a new hash onto the end of the list. | -|`HASHLIST_SELECT(hashlist, index)` | Returns the hash at that index in the list. | -|`HASHLIST_SET(hashlist, index, hash)` | Sets a specific index to that hash. | - -##### 7.4.1.1 A note on pass by reference and hashes - -Hashes and hashlists are implemented with SQF arrays, and as such they are passed by reference to other functions. Remember to make copies (using the `+` operator) if you intend for the hash or hashlist to be modified with out the need for changing the original value. - ## 8. Performance Considerations ### 8.1 Adding Elements to Arrays diff --git a/docs/wiki/feature/grenades.md b/docs/wiki/feature/grenades.md index 679b309b1ec..2b60c08d4ec 100644 --- a/docs/wiki/feature/grenades.md +++ b/docs/wiki/feature/grenades.md @@ -23,6 +23,8 @@ version: ### 1.1 Throw modes Provides different modes for throwing grenades (high throw, precision throw and drop mode). +A grenade is only rollable if the fuse time (`explosionTime`) is >= 1 second and the player isn't in a vehicle. + ### 1.2 Hand flares Adds throwable hand flares in the colors white, red, green and yellow. Additionally buffs existing flares by making them brighter and last longer. diff --git a/docs/wiki/feature/hitreactions.md b/docs/wiki/feature/hitreactions.md index 7d12c1cb12d..a84d1c0b78b 100644 --- a/docs/wiki/feature/hitreactions.md +++ b/docs/wiki/feature/hitreactions.md @@ -18,3 +18,6 @@ version: ### 1.1 Falling under fire If a unit is shot while running it falls to the ground in a prone position, the area where the shot lands does not matters. Note that the shot needs to inflict a certain amount of damage to make the unit fall, a small cut won't make the unit stumble. + +### 1.2 Weapon dropping +If a unit's arm is shot it will cause the gun to be dropped based on the chance set. The default is 0. diff --git a/docs/wiki/framework/cargo-framework.md b/docs/wiki/framework/cargo-framework.md index 68b28f7fa70..a1d810ce9c4 100644 --- a/docs/wiki/framework/cargo-framework.md +++ b/docs/wiki/framework/cargo-framework.md @@ -47,6 +47,24 @@ class CfgVehicles {

ace_cargo_hasCargo and ace_cargo_canLoad are only needed if you aren't inheriting from any of BI base classes or if you are trying to disable loading for a specific vehicle / object.

+### 1.3 Adding predefined cargo via config + +```cpp +class CfgVehicles { + class yourVehicleClass { + ace_cargo_space = 4; // Add if necessary + ace_cargo_hasCargo = 1; // Add if necessary + class ace_cargo { + class cargo { + class ACE_medicalSupplyCrate { // Doesn't have to have the same name as the item you're adding + type = "ACE_medicalSupplyCrate"; + amount = 1; + }; + }; + }; + }; +}; +``` ## 2. Events diff --git a/docs/wiki/framework/cookoff-framework.md b/docs/wiki/framework/cookoff-framework.md index b53fea2049c..81296991540 100644 --- a/docs/wiki/framework/cookoff-framework.md +++ b/docs/wiki/framework/cookoff-framework.md @@ -12,43 +12,22 @@ version: patch: 0 --- -## 1. Disabling / Enabling Cook off for individual vehicles +## 1. Disabling cook-off fire for individual vehicles -You can dynamically enable and/or disable vehicle cook off for individual vehicles by using `setVariable`: +Cook-off fire can be disabled for a specific vehicle (does not affect ammo cook-off): ``` -VEHICLE setVariable ["ace_cookoff_enable", true, true]; +_vehicle setVariable ["ace_cookoff_enable", false, true]; ``` -The above will enable cook off for that specific vehicle, no matter the mission settings. +Mission settings will always apply however, so you can't enable cook-off on a vehicle if the mission settings have cook-off for vehicles disabled. -Likewise, cook off can also be disabled for a specific vehicle: +## 2. Disabling ammunition cook-off for individual vehicles and boxes -``` -VEHICLE setVariable ["ace_cookoff_enable", false, true]; -``` - -## 2. Cook off probability - -You can set the probability of cook off for individual vehicle types by changing the `ace_cookoff_probability` value in the vehicle's config: +Ammunition cook-off can be disabled for a specific vehicle or box (does not affect cook-off fire): ``` -class MyVehicle { - ace_cookoff_probability = 0.6; -}; +_vehicleOrBox setVariable ["ace_cookoff_enableAmmoCookoff", false, true]; ``` -Global cook off probability can also be adjusted with the `ace_cookoff_probabilityCoef` mission setting. - -Higher values will make cook-off more probable, whilst lower values will make cook-off less probable. - -## 3. Ignore damage to turret - -For use on vehicles when damage to the main turret would not cause a vehicle cookoff. -e.g. RCWS turrets - -``` -class MyVehicle { - ace_vehicle_damage_turretFireProb = 0; -}; -``` +Mission settings will always apply however, so you can't enable ammunition cook-off on a vehicle or box if the mission settings have ammunition cook-off disabled. diff --git a/docs/wiki/framework/events-framework.md b/docs/wiki/framework/events-framework.md index bec6492c968..860cd900684 100644 --- a/docs/wiki/framework/events-framework.md +++ b/docs/wiki/framework/events-framework.md @@ -103,18 +103,17 @@ MenuType: 0 = Interaction, 1 = Self Interaction | Event Key | Parameters | Locality | Type | Description | |----------|---------|---------|---------|---------| -|`ace_refuel_started` | [_source, _target] | Local | Listen | Refueling has started | +|`ace_refuel_started` | [_source, _target] | Local | Listen | Refuelling has started | |`ace_refuel_tick` | [_source, _target, _amount] | Local | Listen | Amount of fuel transferred in a tick | -|`ace_refuel_stopped` | [_source, _target] | Local | Listen | Refueling has stopped | +|`ace_refuel_stopped` | [_source, _target] | Local | Listen | Refuelling has stopped | ### 2.10 Cook Off (`ace_cookoff`) | Event Key | Parameters | Locality | Type | Description | -|----------|---------|---------|---------|---------| -|`ace_cookoff_cookOff` | _vehicle | Global | Listen | Vehicle cook off has started -|`ace_cookoff_cookOffBox` | _box | Global | Listen | Ammo box cook off has started | -|`ace_cookoff_engineFire` | _vehicle | Global | Listen | Engine fire has started | - +|----------|---------|---------|---------|---------|---------| +|`ace_cookoff_cookOff` | [_vehicle, _intensity, _instigator, _smokeDelayEnabled, _ammoDetonationChance, _detonateAfterCookoff, _fireSource, _canRing, _maxIntensity, _canJet] | Global | Listen | Vehicle cook-off has started | +|`ace_cookoff_cookOffBox` | [_box, _source, _instigator, _delay] | Global | Listen | Ammo box cook-off has started | +|`ace_cookoff_engineFire` | [_vehicle] | Global | Listen | Engine fire has started | ### 2.11 Attach (`ace_attach`) @@ -156,9 +155,15 @@ MenuType: 0 = Interaction, 1 = Self Interaction | Event Key | Parameters | Locality | Type | Description | |---------- |------------|----------|------|-------------| -|---------- |------------|----------|------|-------------| | `ace_interaction_doorOpeningStarted` | [_house, _door, _animations] | Local | Listen | Called when local unit starts interacting with doors -| `ace_interaction_doorOpeningStopped` | [_house, _door, _animations] | Local | Listen | Called when local unit stopps interacting with doors +| `ace_interaction_doorOpeningStopped` | [_house, _door, _animations] | Local | Listen | Called when local unit stops interacting with doors + +### 2.17 Headless (`ace_headless`) + +| Event Key | Parameters | Locality | Type | Description | +|---------- |------------|----------|------|-------------| +| `ace_headless_groupTransferPre` | [_group, _HC (OBJECT), _previousOwner, _idHC] | Target | Listen | Called just before a group is transferred from any machine to a HC. Called where group currently is local and on the HC, where group is going to be local. +| `ace_headless_groupTransferPost` | [_group, _HC (OBJECT), _previousOwner, _idHC, _transferredSuccessfully] | Target | Listen | Called just after a group is transferred from a machine to a HC. Called where group was local and on the HC, where group is now local. `_transferredSuccessfully` is passed so mods can actually check if the locality was properly transferred, as ownership transfer is not guaranteed. ## 3. Usage Also Reference [CBA Events System](https://github.com/CBATeam/CBA_A3/wiki/Custom-Events-System){:target="_blank"} documentation. diff --git a/docs/wiki/framework/grenades-framework.md b/docs/wiki/framework/grenades-framework.md index fce3b480c2d..755773c1710 100644 --- a/docs/wiki/framework/grenades-framework.md +++ b/docs/wiki/framework/grenades-framework.md @@ -50,6 +50,10 @@ class CfgAmmo { ace_grenades_flashbangBangs = 6; // 6 bangs ace_grenades_flashbangInterval = 0.25; // 0.25 seconds between each subsequent bang ace_grenades_flashbangIntervalMaxDeviation = 0.05; // Deviation of up to ± 0.05 seconds on each fuse + ace_grenades_flashbangExplodeSound[] = { // Sound that is played upon detonation + {"A3\Sounds_F\arsenal\explosives\grenades\Explosion_HE_grenade_01.wss", 5, 1.2, 400}, // file path, volume, pitch, max distance + {"A3\Sounds_F\arsenal\explosives\grenades\Explosion_HE_grenade_02.wss", 5, 1.2, 400} + }; }; }; ``` @@ -70,6 +74,11 @@ The average amount of time in seconds, after `explosionTime` has passed, between The amount of randomness in the fuse time. +### 2.1.5 ace_grenades_flashbangExplodeSound + +The sounds that can be used when the flashbang detonates. It randomly selects an entry from this array (equal chances, there are no weights involved). +If not defined, `[format ["A3\Sounds_F\arsenal\explosives\grenades\Explosion_HE_grenade_0%1.wss", floor (random 4) + 1], 5, 1.2, 400]` is used as a default instead (4 sounds total). + ### 2.2 Incendiary Config Values ```cpp @@ -103,6 +112,12 @@ If set to zero or left undefined, the grenade is not treated as a flare. If it i Sets the color of the emitted light. The first 3 values of the array of the color, the last is the light intensity. +### 2.4 Grenade Rolling + +#### 2.4.1 ace_grenades_rollVectorDirAndUp + +Sets the `setVectorDirAndUp` of the grenade when the grenade is rolled. + ## 3. Events ### 3.1 Listenable diff --git a/docs/wiki/framework/headless-framework.md b/docs/wiki/framework/headless-framework.md index 6dbc83c5123..7a2a5a08221 100644 --- a/docs/wiki/framework/headless-framework.md +++ b/docs/wiki/framework/headless-framework.md @@ -30,14 +30,29 @@ As of ACEX v3.2.0 _(before merge into ACE3)_ this feature can also be enabled wi ## 2. Scripting -### 2.1 Disable Transferring for a Group +### 2.1 Manipulating HC Transfers of Groups via function -To prevent a group from transferring to a Headless Client use the following line on a group leader (or every unit in a group in case group leader may not spawn): +`ace_headless_fnc_blacklist` + + | Arguments | Type | Optional (default value) +---| --------- | ---- | ------------------------ +0 | Units | Object, Group or Array of both | Required +1 | Add (true) or remove (false) from blacklist | Bool | Optional (default: `true`) +2 | Owner to transfer units to | Number | Optional (default: `-1`) +3 | Rebalance (0 = no rebalance, 1 = rebalance, 2 = force rebalance) | Number | (default: `0`) +**R** | None | None | Return value + +`Force rebalance` means that all units, including the ones that are on the HCs, are rebalanced amongst the HCs, whereas `rebalance` means that newly spawned units are going to be evenly distributed amongst HCs. Therefore, `rebalance` does not guarantee that the HCs will have an equal amount of groups, whereas `force rebalance` does. + +### 2.2 Disable Transferring for a Group via variable + +To prevent a group from transferring to a Headless Client use the following line on a unit within a group: ```sqf this setVariable ["acex_headless_blacklist", true]; ``` +This variable can also be set on vehicles, disabling transferal of any groups having units in said vehicles. ## 3. Limitations @@ -48,3 +63,7 @@ Some Arma 3 features are incompatible, this is up to BI to add support. Disable Additionally, groups will not be transferred due to lack of support if they: - Have waypoints with synchronized triggers (waypoint would not change status based on trigger condition) (added in ACEX v3.2.0 - _before merge into ACE3_) + +Groups will not be transferred to avoid issues: +- If a player is within the group. +- If they contain UAVs. diff --git a/docs/wiki/framework/hitreactions-framework.md b/docs/wiki/framework/hitreactions-framework.md new file mode 100644 index 00000000000..ca3ff93f5bf --- /dev/null +++ b/docs/wiki/framework/hitreactions-framework.md @@ -0,0 +1,32 @@ +--- +layout: wiki +title: Hit Reactions Framework +description: Explains how to set-up weapons with ACE3 hit reactions system. +group: framework +order: 5 +parent: wiki +mod: ace +version: + major: 3 + minor: 18 + patch: 0 +--- + +## 1. Config Values + +```cpp +class CfgWeapons { + class MyWeapon { + ace_hitreactions_undroppable = 1; // Prevents weapon from being dropped + }; +}; +``` + +## 2. Mission Variables + +### 2.1 Safe pickup distance for AI + +Allows 3rd party mods to set the distance between AI and the nearest hostile that is considered safe to go pickup a dropped weapon. +```sqf +ace_hitreactions_safePickupDistance = 10; // default is 8 +``` diff --git a/docs/wiki/framework/medical-treatment-framework.md b/docs/wiki/framework/medical-treatment-framework.md index 736295804ae..52e661a516d 100644 --- a/docs/wiki/framework/medical-treatment-framework.md +++ b/docs/wiki/framework/medical-treatment-framework.md @@ -128,3 +128,10 @@ If a mission maker wishes to disable Zeus access to the medical menu, they can s ```sqf ace_medical_gui_enableZeusModule = false; // default is true ``` + +### 3.3 SpO2 Configuration + +If 3rd party mods want to disable SpO2 being set to a minimum upon successful CPR, they can set the variable below: +```sqf +ace_medical_treatment_setSpO2UponCPRSuccess = false; // default is true +``` diff --git a/docs/wiki/framework/nametags-framework.md b/docs/wiki/framework/nametags-framework.md new file mode 100644 index 00000000000..d27a358b170 --- /dev/null +++ b/docs/wiki/framework/nametags-framework.md @@ -0,0 +1,45 @@ +--- +layout: wiki +title: Nametags Framework +description: Explains how to implement rank icons for factions. +group: framework +order: 5 +parent: wiki +mod: ace +version: + major: 3 + minor: 13 + patch: 0 +--- + +## 1. Config Values + +### 1.1 Faction rank icons + +Defines the rank icons used by a faction. + +```cpp +class CfgFactionClasses { + class MyFaction { + ace_nametags_rankIcons[] = { + "\z\ace\addons\nametags\UI\icons_germany\private_gs.paa", // path to private rank icon + "\z\ace\addons\nametags\UI\icons_germany\corporal_gs.paa", // path to corporal rank icon + "\z\ace\addons\nametags\UI\icons_germany\sergeant_gs.paa", // path to sergeant rank icon + "\z\ace\addons\nametags\UI\icons_germany\lieutenant_gs.paa", // path to lieutenant rank icon + "\z\ace\addons\nametags\UI\icons_germany\captain_gs.paa", // path to captain rank icon + "\z\ace\addons\nametags\UI\icons_germany\major_gs.paa", // path to major rank icon + "\z\ace\addons\nametags\UI\icons_germany\colonel_gs.paa" // path to colonel rank icon + }; + }; +}; +``` + +## 2. Mission Variables + +### 2.1 Faction rank icon usage + +If disabled, it won't use the faction icons defined via the config entry listed above. +Needs to be set before postInit. +```sqf +ace_nametags_useFactionIcons = false; // by default true +``` diff --git a/docs/wiki/framework/refuel-framework.md b/docs/wiki/framework/refuel-framework.md index 325606a9707..3cf10d72053 100644 --- a/docs/wiki/framework/refuel-framework.md +++ b/docs/wiki/framework/refuel-framework.md @@ -134,5 +134,5 @@ The jerry can will now have a volume of 200 liters. | Name | Arguments | Global? | Added in | | ------------- | ------------- | ----- | ------------- | -| ace_refuel_sourceInitialized | Fuel source (OBJECT), items (BOOL or ARRAY) | Yes | 3.16.0 | +| ace_refuel_sourceInitialized | Fuel source (OBJECT) | Yes | 3.16.0 | | ace_refuel_jerryCanInitalized | Jerry can (OBJECT) | Yes | 3.16.0 | diff --git a/docs/wiki/framework/vehicledamage-framework.md b/docs/wiki/framework/vehicledamage-framework.md index 7e22bccf5db..0d4268bf5e8 100644 --- a/docs/wiki/framework/vehicledamage-framework.md +++ b/docs/wiki/framework/vehicledamage-framework.md @@ -47,7 +47,7 @@ Default: 0.5 #### 1.1.5 `ace_vehicle_damage_turretFireProb` -The probabilitiy for the vehicle to catch on fire upon its turret being penetrated +The probability for the vehicle to catch on fire upon its turret being penetrated Default: 0.2 @@ -126,3 +126,11 @@ Default ARMA config value. We assume that the warheads are vanilla strings, so o - `TandemHEAT` If no `ace_vehicle_damage_incendiary` defined, this value will be used to assume a default based on above table of common values (excluding `Incendiary Bullet` which is 0). + +## 3. Disabling crew bailing for individual vehicles + +Crew bailing when their vehicle is disabled (immobile or can't shoot) can be disabled for a specific vehicle: + +``` +_vehicle setVariable ["ace_vehicle_damage_allowCrewInImmobile", true, true]; +``` From eedbb0b5bca9f9a890d7b14838cf6c421404c316 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 20 Jun 2024 00:04:34 -0500 Subject: [PATCH 266/282] Revert to 60a0dae, merge conflict wasn't resolved properly --- .../functions/fnc_handleFired.sqf | 2 +- .../functions/fnc_readAmmoDataFromConfig.sqf | 2 +- addons/advanced_fatigue/XEH_postInit.sqf | 2 +- addons/advanced_fatigue/XEH_preInit.sqf | 1 - .../functions/fnc_mainLoop.sqf | 2 +- addons/advanced_throwing/XEH_postInit.sqf | 12 +- addons/advanced_throwing/XEH_preStart.sqf | 18 + .../functions/fnc_drawThrowable.sqf | 11 +- .../functions/fnc_prepare.sqf | 16 +- .../advanced_throwing/functions/fnc_throw.sqf | 2 +- addons/advanced_throwing/stringtable.xml | 2 + addons/ai/stringtable.xml | 2 + .../arsenal/functions/fnc_onArsenalClose.sqf | 2 +- .../arsenal/functions/fnc_onArsenalOpen.sqf | 2 +- .../functions/fnc_onSelChangedLeft.sqf | 6 + .../functions/fnc_onSelChangedRight.sqf | 9 +- addons/arsenal/functions/fnc_showItem.sqf | 2 +- .../missions/Arsenal.VR/fnc_createTarget.sqf | 2 +- addons/arsenal/stringtable.xml | 14 + .../artillerytables/functions/fnc_firedEH.sqf | 2 +- .../functions/fnc_interactMenuOpened.sqf | 2 +- addons/artillerytables/initSettings.inc.sqf | 4 +- addons/atragmx/functions/fnc_initGunList.sqf | 2 +- .../fnc_read_gun_list_entries_from_config.sqf | 2 +- .../fnc_target_speed_assist_timer.sqf | 2 +- ...c_toggle_c1_ballistic_coefficient_data.sqf | 2 +- .../fnc_toggle_muzzle_velocity_data.sqf | 2 +- .../functions/fnc_toggle_truing_drop.sqf | 2 +- .../functions/fnc_update_zero_range.sqf | 2 +- addons/attach/functions/fnc_handleKilled.sqf | 2 +- addons/ballistics/stringtable.xml | 7 + addons/captives/XEH_postInit.sqf | 2 +- .../functions/fnc_doEscortCaptive.sqf | 2 +- .../captives/functions/fnc_setHandcuffed.sqf | 2 +- .../captives/functions/fnc_setSurrendered.sqf | 2 +- addons/captives/stringtable.xml | 2 + addons/cargo/CfgVehicles.hpp | 13 +- addons/cargo/functions/fnc_addCargoItem.sqf | 21 +- addons/cargo/functions/fnc_initVehicle.sqf | 11 +- addons/cargo/initSettings.inc.sqf | 24 +- addons/cargo/stringtable.xml | 10 + addons/common/XEH_PREP.hpp | 3 + addons/common/XEH_postInit.sqf | 6 +- addons/common/XEH_preInit.sqf | 1 + addons/common/dev/test_cfgPatches.sqf | 4 +- .../fnc_actionKeysNamesConverted.sqf | 10 +- addons/common/functions/fnc_addPlayerEH.sqf | 61 +++ addons/common/functions/fnc_addWeapon.sqf | 48 +- .../fnc_cbaSettings_settingChanged.sqf | 8 +- .../common/functions/fnc_defineVariable.sqf | 2 +- .../common/functions/fnc_disableUserInput.sqf | 6 +- addons/common/functions/fnc_errorMessage.sqf | 8 +- .../common/functions/fnc_getSettingData.sqf | 3 +- .../fnc_getWheelHitPointsWithSelections.sqf | 104 ++++ .../functions/fnc_registerItemReplacement.sqf | 15 +- .../functions/fnc_replaceRegisteredItems.sqf | 6 +- addons/common/functions/fnc_setDead.sqf | 44 ++ addons/common/functions/fnc_showHud.sqf | 2 +- addons/common/stringtable.xml | 13 + addons/compat_cup_terrains/CfgVehicles.hpp | 18 +- addons/compat_cup_units/CfgGlasses.hpp | 492 ++++++++++++++++++ addons/compat_cup_units/config.cpp | 1 + .../CfgVehicles.hpp | 5 - .../compat_cup_weapons_csw/stringtable.xml | 34 ++ .../stringtable.xml | 11 + .../compat_gm_refuel/CfgVehicles.hpp | 6 - addons/compat_gm/compat_gm_refuel/config.cpp | 1 - addons/compat_rf/$PBOPREFIX$ | 1 + addons/compat_rf/CfgWeapons.hpp | 42 ++ .../CfgVehicles.hpp | 12 + .../config.cpp | 21 + .../script_component.hpp | 3 + .../compat_rf_realisticnames/Attachments.hpp | 41 ++ .../compat_rf_realisticnames/CfgMagazines.hpp | 24 + .../compat_rf_realisticnames/CfgVehicles.hpp | 134 +++++ .../compat_rf_realisticnames/CfgWeapons.hpp | 111 ++++ .../compat_rf_realisticnames/config.cpp | 23 + .../script_component.hpp | 3 + .../compat_rf_realisticnames/stringtable.xml | 297 +++++++++++ addons/compat_rf/config.cpp | 18 + addons/compat_rf/script_component.hpp | 6 + addons/compat_rhs_afrf3/CfgAmmo.hpp | 4 + .../compat_rhs_afrf3_refuel/CfgVehicles.hpp | 10 - .../compat_rhs_afrf3_refuel/config.cpp | 2 +- .../compat_rhs_usf3_refuel/CfgVehicles.hpp | 15 - .../compat_rhs_usf3_refuel/config.cpp | 1 - addons/compat_sog/CfgAmmo/grenades.hpp | 7 + addons/compat_sog/CfgEventHandlers.hpp | 10 + addons/compat_sog/CfgVehicles/land.hpp | 49 +- addons/compat_sog/CfgVehicles/wheeled.hpp | 2 - addons/compat_sog/config.cpp | 3 +- .../functions/fnc_handlePunjiTrapTrigger.sqf | 4 +- .../compat_spe_refuel/CfgVehicles.hpp | 2 - addons/compat_ws/CfgWeapons.hpp | 5 + .../compat_ws_realisticnames/Attachments.hpp | 75 +++ .../compat_ws_realisticnames/CfgVehicles.hpp | 60 +++ .../compat_ws_realisticnames/CfgWeapons.hpp | 20 + .../compat_ws_realisticnames/config.cpp | 1 + .../compat_ws_realisticnames/stringtable.xml | 215 +++++++- .../functions/fnc_handleDamage.sqf | 2 +- addons/cookoff/ACE_Settings.hpp | 6 +- addons/cookoff/CfgCloudlets.hpp | 1 - addons/cookoff/CfgEden.hpp | 17 +- addons/cookoff/CfgEventHandlers.hpp | 1 - addons/cookoff/CfgSFX.hpp | 1 - addons/cookoff/CfgVehicles.hpp | 37 +- addons/cookoff/XEH_PREP.hpp | 18 +- addons/cookoff/XEH_postInit.sqf | 95 ++-- addons/cookoff/functions/fnc_cookOff.sqf | 129 ----- addons/cookoff/functions/fnc_cookOffBox.sqf | 74 --- .../cookoff/functions/fnc_cookOffBoxLocal.sqf | 52 ++ .../functions/fnc_cookOffBoxServer.sqf | 50 ++ .../cookoff/functions/fnc_cookOffEffect.sqf | 200 ------- addons/cookoff/functions/fnc_cookOffLocal.sqf | 229 ++++++++ .../cookoff/functions/fnc_cookOffServer.sqf | 202 +++++++ .../functions/fnc_detonateAmmunition.sqf | 132 ----- .../fnc_detonateAmmunitionServer.sqf | 54 ++ .../fnc_detonateAmmunitionServerLoop.sqf | 181 +++++++ addons/cookoff/functions/fnc_engineFire.sqf | 51 -- .../cookoff/functions/fnc_engineFireLocal.sqf | 81 +++ .../functions/fnc_engineFireServer.sqf | 34 ++ .../cookoff/functions/fnc_getVehicleAmmo.sqf | 71 +-- .../cookoff/functions/fnc_handleDamageBox.sqf | 80 ++- .../cookoff/functions/fnc_isMagazineFlare.sqf | 12 +- addons/cookoff/functions/fnc_smoke.sqf | 19 +- addons/cookoff/initSettings.inc.sqf | 78 +-- addons/cookoff/script_component.hpp | 13 +- addons/cookoff/stringtable.xml | 252 +++------ .../fnc_reload_handleAddTurretMag.sqf | 2 +- .../fnc_reload_handleRemoveTurretMag.sqf | 2 +- .../functions/fnc_reload_handleReturnAmmo.sqf | 2 +- addons/csw/initSettings.inc.sqf | 9 +- addons/csw/stringtable.xml | 17 + addons/dagr/XEH_postInit.sqf | 2 +- .../functions/fnc_disarmDropItems.sqf | 7 +- .../functions/fnc_eventTargetStart.sqf | 2 +- .../functions/fnc_openDisarmDialog.sqf | 11 +- addons/dogtags/XEH_postInit.sqf | 8 +- addons/dogtags/XEH_preInit.sqf | 2 +- .../dogtags/functions/fnc_canCheckDogtag.sqf | 2 +- .../dogtags/functions/fnc_canTakeDogtag.sqf | 2 +- .../functions/fnc_disableFactionDogtags.sqf | 7 +- .../functions/fnc_dropObject_carry.sqf | 2 +- addons/dragging/stringtable.xml | 6 + addons/dragon/XEH_postInit.sqf | 4 +- addons/dragon/functions/fnc_sightAttach.sqf | 2 +- addons/dragon/functions/fnc_sightDetach.sqf | 2 +- .../explosives/functions/fnc_addClacker.sqf | 2 +- .../functions/fnc_addDetonateActions.sqf | 4 +- .../functions/fnc_onIncapacitated.sqf | 2 +- addons/explosives/stringtable.xml | 4 + addons/fastroping/XEH_postInit.sqf | 6 +- addons/fastroping/initSettings.inc.sqf | 4 +- addons/fastroping/stringtable.xml | 2 + addons/field_rations/XEH_postInit.sqf | 2 +- .../functions/fnc_handleEffects.sqf | 17 +- addons/fieldmanual/stringtable.xml | 90 ++++ addons/fire/XEH_PREP.hpp | 1 - addons/fire/XEH_preInit.sqf | 2 - addons/fire/functions/fnc_burnIndicator.sqf | 2 +- addons/fire/functions/fnc_isBurning.sqf | 5 +- addons/fire/functions/fnc_isPlant.sqf | 20 - addons/fortify/functions/fnc_setupModule.sqf | 4 +- addons/frag/CfgAmmoFragSpawner.hpp | 14 +- addons/frag/functions/fnc_findReflections.sqf | 2 +- addons/frag/script_component.hpp | 2 +- .../functions/fnc_pfhUpdateGForces.sqf | 2 +- addons/grenades/CfgAmmo.hpp | 3 +- addons/grenades/CfgEventHandlers.hpp | 1 - addons/grenades/CfgMagazines.hpp | 1 - addons/grenades/CfgVehicles.hpp | 1 - addons/grenades/CfgWeapons.hpp | 1 - addons/grenades/Effects.hpp | 1 - addons/grenades/XEH_PREP.hpp | 4 +- addons/grenades/XEH_postInit.sqf | 39 +- addons/grenades/XEH_preInit.sqf | 3 + ...nc_addChangeFuseItemContextMenuOptions.sqf | 41 +- .../functions/fnc_damageEngineAndWheels.sqf | 44 ++ addons/grenades/functions/fnc_flare.sqf | 3 +- .../functions/fnc_flashbangExplosionEH.sqf | 252 +++++---- .../functions/fnc_flashbangThrownFuze.sqf | 19 +- addons/grenades/functions/fnc_incendiary.sqf | 133 ++--- addons/grenades/functions/fnc_nextMode.sqf | 57 +- .../grenades/functions/fnc_throwGrenade.sqf | 99 ++-- addons/grenades/initSettings.inc.sqf | 9 +- addons/grenades/script_component.hpp | 7 +- addons/grenades/stringtable.xml | 5 + .../functions/fnc_offGunbagCallback.sqf | 31 +- .../functions/fnc_swapGunbagCallback.sqf | 63 +-- .../gunbag/functions/fnc_toGunbagCallback.sqf | 26 +- addons/headless/XEH_PREP.hpp | 1 + addons/headless/XEH_postInit.sqf | 34 ++ addons/headless/functions/fnc_blacklist.sqf | 51 ++ .../headless/functions/fnc_transferGroups.sqf | 184 +++++-- addons/headless/initSettings.inc.sqf | 18 +- addons/headless/script_component.hpp | 4 + addons/hearing/CfgEventHandlers.hpp | 1 - addons/hearing/CfgVehicles.hpp | 4 +- addons/hearing/CfgWeapons.hpp | 2 +- addons/hearing/XEH_PREP.hpp | 2 +- addons/hearing/XEH_postInit.sqf | 26 +- addons/hearing/XEH_preInit.sqf | 7 +- addons/hearing/functions/fnc_addEarPlugs.sqf | 60 ++- addons/hearing/functions/fnc_earRinging.sqf | 9 +- .../hearing/functions/fnc_explosionNear.sqf | 9 +- addons/hearing/functions/fnc_firedNear.sqf | 101 ++-- .../hearing/functions/fnc_getAmmoLoudness.sqf | 44 ++ .../hearing/functions/fnc_handleRespawn.sqf | 20 +- .../hearing/functions/fnc_hasEarPlugsIn.sqf | 7 +- .../hearing/functions/fnc_moduleHearing.sqf | 4 +- .../hearing/functions/fnc_putInEarplugs.sqf | 25 +- .../hearing/functions/fnc_removeEarplugs.sqf | 27 +- .../functions/fnc_updateHearingProtection.sqf | 32 +- .../fnc_updatePlayerVehAttenuation.sqf | 14 +- addons/hearing/functions/fnc_updateVolume.sqf | 34 +- addons/hearing/initKeybinds.inc.sqf | 15 +- addons/hearing/initSettings.inc.sqf | 23 +- addons/hearing/stringtable.xml | 5 + .../hellfire/functions/fnc_setupVehicle.sqf | 2 +- addons/hitreactions/ACE_Settings.hpp | 1 - addons/hitreactions/CfgEventHandlers.hpp | 7 +- addons/hitreactions/XEH_PREP.hpp | 2 +- addons/hitreactions/XEH_postInit.sqf | 94 ++++ addons/hitreactions/XEH_preInit.sqf | 12 + .../functions/fnc_checkWeaponDrop.sqf | 33 ++ addons/hitreactions/initSettings.inc.sqf | 23 +- addons/hitreactions/script_component.hpp | 2 + addons/hitreactions/stringtable.xml | 12 +- addons/interact_menu/XEH_clientInit.sqf | 9 +- addons/interact_menu/XEH_preInit.sqf | 6 +- .../functions/fnc_addActionToClass.sqf | 10 +- .../functions/fnc_addMainAction.sqf | 8 +- .../functions/fnc_compileMenu.sqf | 16 +- .../functions/fnc_compileMenuSelfAction.sqf | 13 +- .../functions/fnc_initMenuReorder.sqf | 2 +- .../interact_menu/functions/fnc_keyDown.sqf | 2 +- .../functions/fnc_removeActionFromClass.sqf | 9 +- .../functions/fnc_renderActionPoints.sqf | 7 +- .../interact_menu/functions/fnc_splitPath.sqf | 12 +- .../fnc_userActions_getHouseActions.sqf | 9 +- addons/interact_menu/initSettings.inc.sqf | 4 +- .../functions/fnc_addPassengerActions.sqf | 6 +- .../functions/fnc_canPullOutBody.sqf | 2 +- addons/interaction/initSettings.inc.sqf | 2 +- addons/irlight/stringtable.xml | 14 + addons/killtracker/XEH_postInit.sqf | 50 +- addons/killtracker/initSettings.inc.sqf | 9 + addons/killtracker/stringtable.xml | 14 +- .../functions/fnc_seekerFindLaserSpot.sqf | 4 +- addons/laser/stringtable.xml | 2 + .../functions/fnc_refuelUAV.sqf | 2 +- .../functions/fnc_magazineRepackFinish.sqf | 2 +- addons/main/script_version.hpp | 4 +- addons/map/XEH_postInitClient.sqf | 2 +- addons/map/functions/fnc_isFlashlight.sqf | 15 +- addons/map/initSettings.inc.sqf | 13 +- addons/map_gestures/XEH_preInit.sqf | 2 +- .../functions/fnc_addGroupColorMapping.sqf | 6 +- .../functions/fnc_drawMapGestures.sqf | 2 +- .../functions/fnc_isValidColorArray.sqf | 2 +- .../functions/fnc_moduleGroupSettings.sqf | 5 +- .../functions/fnc_moduleSettings.sqf | 4 +- .../maptools/functions/fnc_canUseMapGPS.sqf | 7 +- addons/maptools/stringtable.xml | 36 ++ .../markers/functions/fnc_removeTimestamp.sqf | 6 +- addons/markers/stringtable.xml | 2 + addons/medical/dev/test_hitpointConfigs.sqf | 21 +- addons/medical/dev/watchVariable.sqf | 6 +- addons/medical_ai/stringtable.xml | 3 + addons/medical_blood/XEH_postInit.sqf | 2 - addons/medical_blood/XEH_preInit.sqf | 16 +- addons/medical_blood/XEH_preStart.sqf | 5 +- .../functions/fnc_createBlood.sqf | 2 +- .../functions/fnc_handleWoundReceived.sqf | 2 +- .../functions/fnc_isBleeding.sqf | 2 +- .../functions/fnc_onBleeding.sqf | 2 +- addons/medical_damage/stringtable.xml | 2 + addons/medical_engine/XEH_postInit.sqf | 28 +- addons/medical_engine/XEH_preInit.sqf | 16 +- .../functions/fnc_applyAnimAfterRagdoll.sqf | 2 +- .../functions/fnc_handleDamage.sqf | 62 ++- .../medical_engine/script_macros_config.hpp | 18 - addons/medical_engine/stringtable.xml | 2 + addons/medical_gui/XEH_postInit.sqf | 2 +- addons/medical_gui/stringtable.xml | 31 ++ .../functions/fnc_enteredStateDeath.sqf | 3 +- .../medical_status/functions/fnc_setDead.sqf | 12 +- addons/medical_status/stringtable.xml | 2 + addons/medical_treatment/XEH_preInit.sqf | 38 +- .../functions/fnc_checkPulseLocal.sqf | 2 +- .../functions/fnc_checkResponse.sqf | 5 + .../functions/fnc_cprLocal.sqf | 7 +- .../functions/fnc_fullHealLocal.sqf | 4 +- .../functions/fnc_treatment.sqf | 2 +- addons/medical_treatment/initSettings.inc.sqf | 2 +- addons/medical_treatment/stringtable.xml | 40 ++ addons/medical_vitals/stringtable.xml | 6 + addons/microdagr/initSettings.inc.sqf | 4 +- addons/minedetector/XEH_postInit.sqf | 11 +- addons/minedetector/XEH_preStart.sqf | 4 +- .../functions/fnc_getDetectedObject.sqf | 12 +- .../functions/fnc_getDetectorConfig.sqf | 11 +- .../fnc_cycleAttackProfileKeyDown.sqf | 2 +- .../missileguidance/functions/fnc_onFired.sqf | 2 +- .../mk6mortar/functions/fnc_handleFired.sqf | 2 +- .../fnc_handlePlayerVehicleChanged.sqf | 2 +- addons/mk6mortar/stringtable.xml | 14 +- addons/nametags/XEH_postInit.sqf | 2 +- .../functions/fnc_drawNameTagIcon.sqf | 2 +- .../functions/fnc_setFactionRankIcons.sqf | 9 +- addons/nightvision/XEH_postInit.sqf | 4 +- addons/nightvision/stringtable.xml | 12 + addons/nlaw/functions/fnc_keyDown.sqf | 4 +- addons/overheating/stringtable.xml | 12 + .../overpressure/functions/fnc_firedEHBB.sqf | 2 +- .../functions/fnc_overpressureDamage.sqf | 2 +- addons/parachute/CfgVehicles.hpp | 32 ++ addons/parachute/initSettings.inc.sqf | 4 +- addons/pylons/functions/fnc_showDialog.sqf | 2 +- addons/realisticnames/Attachments.hpp | 174 +++++++ addons/realisticnames/CfgVehicles.hpp | 13 + addons/realisticnames/CfgWeapons.hpp | 185 +------ addons/realisticnames/stringtable.xml | 68 ++- addons/rearm/XEH_postInit.sqf | 5 +- addons/rearm/XEH_preStart.sqf | 2 +- .../rearm/functions/fnc_getMagazineName.sqf | 44 +- addons/rearm/initSettings.inc.sqf | 11 +- addons/refuel/ACE_Refuel_Positions.hpp | 96 ++++ addons/refuel/Cfg3DEN.hpp | 7 +- addons/refuel/CfgVehicles.hpp | 36 +- addons/refuel/XEH_PREP.hpp | 1 + addons/refuel/XEH_postInit.sqf | 218 +++++--- addons/refuel/XEH_preStart.sqf | 39 +- addons/refuel/config.cpp | 1 + .../dev/exportTerrainRefuelPositions.sqf | 95 ++++ addons/refuel/dev/test_debugConfigs.sqf | 16 +- addons/refuel/functions/fnc_getFuelCargo.sqf | 20 + addons/refuel/functions/fnc_makeJerryCan.sqf | 7 + addons/refuel/functions/fnc_makeSource.sqf | 34 +- addons/refuel/initSettings.inc.sqf | 22 +- addons/refuel/stringtable.xml | 5 + addons/reload/stringtable.xml | 2 + addons/reloadlaunchers/stringtable.xml | 6 + addons/repair/XEH_PREP.hpp | 1 - addons/repair/dev/draw_showRepairInfo.sqf | 5 +- .../repair/functions/fnc_addRepairActions.sqf | 2 +- addons/repair/functions/fnc_canRepair.sqf | 2 +- .../functions/fnc_getSelectionsToIgnore.sqf | 4 +- .../fnc_getWheelHitPointsWithSelections.sqf | 97 ---- .../functions/fnc_normalizeHitPoints.sqf | 2 +- addons/repair/functions/fnc_repair.sqf | 2 +- .../repair/functions/fnc_repair_failure.sqf | 2 +- .../repair/functions/fnc_repair_success.sqf | 2 +- addons/repair/initSettings.inc.sqf | 30 +- addons/repair/stringtable.xml | 21 + addons/scopes/functions/fnc_adjustScope.sqf | 2 +- addons/scopes/functions/fnc_canAdjustZero.sqf | 2 +- addons/scopes/functions/fnc_canResetZero.sqf | 2 +- addons/scopes/functions/fnc_firedEH.sqf | 2 +- .../functions/fnc_getCurrentZeroRange.sqf | 4 +- addons/scopes/functions/fnc_getOptics.sqf | 2 +- addons/scopes/initKeybinds.inc.sqf | 16 +- addons/sitting/functions/fnc_sit.sqf | 2 +- addons/sitting/initSettings.inc.sqf | 2 +- .../slideshow/functions/fnc_mapImage_init.sqf | 2 +- .../switchunits/functions/fnc_switchUnit.sqf | 2 +- addons/tagging/XEH_postInit.sqf | 8 - addons/tagging/XEH_preStart.sqf | 4 +- .../tagging/functions/fnc_checkTaggable.sqf | 6 +- .../functions/fnc_generateStencilTexture.sqf | 8 +- .../tagging/functions/fnc_stencilVehicle.sqf | 2 +- addons/tagging/functions/fnc_tag.sqf | 4 +- addons/tagging/initSettings.inc.sqf | 5 +- addons/tagging/stringtable.xml | 2 + addons/ui/XEH_PREP.hpp | 1 - addons/ui/XEH_clientInit.sqf | 11 +- addons/ui/functions/fnc_compileConfigUI.sqf | 2 +- .../ui/functions/fnc_handlePlayerChanged.sqf | 32 -- .../ui/functions/fnc_setAdvancedElement.sqf | 6 +- .../ui/functions/fnc_setElementVisibility.sqf | 9 +- addons/vector/functions/fnc_onKeyHold.sqf | 2 +- addons/vehicle_damage/XEH_PREP.hpp | 1 + addons/vehicle_damage/XEH_postInit.sqf | 4 +- .../vehicle_damage/functions/fnc_abandon.sqf | 2 + .../functions/fnc_addDamage.sqf | 4 +- .../vehicle_damage/functions/fnc_detonate.sqf | 20 +- .../functions/fnc_handleCookoff.sqf | 24 +- .../functions/fnc_handleDetonation.sqf | 11 +- .../functions/fnc_handleVehicleDamage.sqf | 2 +- .../functions/fnc_medicalDamage.sqf | 39 ++ .../functions/fnc_processHit.sqf | 16 +- addons/vehicle_damage/initSettings.inc.sqf | 10 - addons/vehicle_damage/stringtable.xml | 24 - .../functions/fnc_addKeyForVehicle.sqf | 8 +- addons/vehiclelock/functions/fnc_lockpick.sqf | 7 +- .../vehiclelock/functions/fnc_moduleSync.sqf | 2 +- addons/vehiclelock/initSettings.inc.sqf | 3 +- addons/viewports/functions/fnc_eachFrame.sqf | 2 +- .../viewports/functions/fnc_getSeatInfo.sqf | 2 +- .../functions/fnc_changeCamera.sqf | 2 +- addons/viewrestriction/initSettings.inc.sqf | 10 +- addons/volume/initSettings.inc.sqf | 24 +- addons/weaponselect/XEH_postInit.sqf | 2 +- addons/weaponselect/XEH_preInit.sqf | 12 +- .../functions/fnc_selectNextGrenade.sqf | 12 +- addons/weaponselect/initSettings.inc.sqf | 4 +- .../functions/fnc_calculateWindSpeed.sqf | 12 +- addons/weather/init3DEN.sqf | 2 +- addons/weather/initSettings.inc.sqf | 3 +- addons/xm157/functions/fnc_keyPress.sqf | 4 +- addons/zeus/CfgVehicles.hpp | 6 + addons/zeus/XEH_PREP.hpp | 2 + addons/zeus/XEH_postInit.sqf | 1 + addons/zeus/config.cpp | 6 + .../zeus/functions/fnc_addObjectToCurator.sqf | 2 +- .../zeus/functions/fnc_bi_moduleCurator.sqf | 64 +-- .../functions/fnc_getModuleDestination.sqf | 4 +- .../functions/fnc_moduleCargoParadrop.sqf | 4 +- .../fnc_moduleCargoParadropWaypoint.sqf | 2 +- addons/zeus/functions/fnc_moduleHeal.sqf | 2 +- addons/zeus/functions/fnc_moduleSetMedic.sqf | 2 +- .../fnc_moduleSetMedicalFacility.sqf | 4 +- .../functions/fnc_moduleSetMedicalVehicle.sqf | 2 +- addons/zeus/functions/fnc_moduleSpectator.sqf | 39 ++ .../functions/fnc_moduleSuicideBomber.sqf | 2 +- addons/zeus/functions/fnc_showMessage.sqf | 2 +- .../zeus/functions/fnc_ui_globalSetSkill.sqf | 6 +- addons/zeus/functions/fnc_ui_groupSide.sqf | 8 +- addons/zeus/functions/fnc_ui_setEngineer.sqf | 2 +- addons/zeus/functions/fnc_ui_spectator.sqf | 265 ++++++++++ .../zeus/functions/fnc_ui_teleportPlayers.sqf | 6 +- addons/zeus/stringtable.xml | 57 +- addons/zeus/ui/RscAttributes.hpp | 228 ++++++++ docs/_config.yml | 4 +- docs/_config_dev.yml | 4 +- docs/wiki/development/coding-guidelines.md | 87 +--- docs/wiki/feature/grenades.md | 2 + docs/wiki/feature/hitreactions.md | 3 + docs/wiki/framework/cargo-framework.md | 18 + docs/wiki/framework/cookoff-framework.md | 37 +- docs/wiki/framework/events-framework.md | 23 +- docs/wiki/framework/grenades-framework.md | 15 + docs/wiki/framework/headless-framework.md | 23 +- docs/wiki/framework/hitreactions-framework.md | 32 ++ .../framework/medical-treatment-framework.md | 7 + docs/wiki/framework/nametags-framework.md | 45 ++ docs/wiki/framework/refuel-framework.md | 2 +- .../wiki/framework/vehicledamage-framework.md | 10 +- 448 files changed, 6942 insertions(+), 3195 deletions(-) create mode 100644 addons/common/functions/fnc_addPlayerEH.sqf create mode 100644 addons/common/functions/fnc_getWheelHitPointsWithSelections.sqf create mode 100644 addons/common/functions/fnc_setDead.sqf create mode 100644 addons/compat_cup_units/CfgGlasses.hpp delete mode 100644 addons/compat_gm/compat_gm_refuel/CfgVehicles.hpp create mode 100644 addons/compat_rf/$PBOPREFIX$ create mode 100644 addons/compat_rf/CfgWeapons.hpp create mode 100644 addons/compat_rf/compat_rf_nouniformrestrictions/CfgVehicles.hpp create mode 100644 addons/compat_rf/compat_rf_nouniformrestrictions/config.cpp create mode 100644 addons/compat_rf/compat_rf_nouniformrestrictions/script_component.hpp create mode 100644 addons/compat_rf/compat_rf_realisticnames/Attachments.hpp create mode 100644 addons/compat_rf/compat_rf_realisticnames/CfgMagazines.hpp create mode 100644 addons/compat_rf/compat_rf_realisticnames/CfgVehicles.hpp create mode 100644 addons/compat_rf/compat_rf_realisticnames/CfgWeapons.hpp create mode 100644 addons/compat_rf/compat_rf_realisticnames/config.cpp create mode 100644 addons/compat_rf/compat_rf_realisticnames/script_component.hpp create mode 100644 addons/compat_rf/compat_rf_realisticnames/stringtable.xml create mode 100644 addons/compat_rf/config.cpp create mode 100644 addons/compat_rf/script_component.hpp delete mode 100644 addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/CfgVehicles.hpp delete mode 100644 addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgVehicles.hpp create mode 100644 addons/compat_ws/compat_ws_realisticnames/Attachments.hpp create mode 100644 addons/compat_ws/compat_ws_realisticnames/CfgVehicles.hpp delete mode 100644 addons/cookoff/functions/fnc_cookOff.sqf delete mode 100644 addons/cookoff/functions/fnc_cookOffBox.sqf create mode 100644 addons/cookoff/functions/fnc_cookOffBoxLocal.sqf create mode 100644 addons/cookoff/functions/fnc_cookOffBoxServer.sqf delete mode 100644 addons/cookoff/functions/fnc_cookOffEffect.sqf create mode 100644 addons/cookoff/functions/fnc_cookOffLocal.sqf create mode 100644 addons/cookoff/functions/fnc_cookOffServer.sqf delete mode 100644 addons/cookoff/functions/fnc_detonateAmmunition.sqf create mode 100644 addons/cookoff/functions/fnc_detonateAmmunitionServer.sqf create mode 100644 addons/cookoff/functions/fnc_detonateAmmunitionServerLoop.sqf delete mode 100644 addons/cookoff/functions/fnc_engineFire.sqf create mode 100644 addons/cookoff/functions/fnc_engineFireLocal.sqf create mode 100644 addons/cookoff/functions/fnc_engineFireServer.sqf delete mode 100644 addons/fire/functions/fnc_isPlant.sqf create mode 100644 addons/grenades/functions/fnc_damageEngineAndWheels.sqf create mode 100644 addons/headless/functions/fnc_blacklist.sqf create mode 100644 addons/hearing/functions/fnc_getAmmoLoudness.sqf create mode 100644 addons/hitreactions/XEH_postInit.sqf create mode 100644 addons/hitreactions/functions/fnc_checkWeaponDrop.sqf create mode 100644 addons/realisticnames/Attachments.hpp create mode 100644 addons/refuel/ACE_Refuel_Positions.hpp create mode 100644 addons/refuel/dev/exportTerrainRefuelPositions.sqf create mode 100644 addons/refuel/functions/fnc_getFuelCargo.sqf delete mode 100644 addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf delete mode 100644 addons/ui/functions/fnc_handlePlayerChanged.sqf create mode 100644 addons/vehicle_damage/functions/fnc_medicalDamage.sqf create mode 100644 addons/zeus/functions/fnc_moduleSpectator.sqf create mode 100644 addons/zeus/functions/fnc_ui_spectator.sqf create mode 100644 docs/wiki/framework/hitreactions-framework.md create mode 100644 docs/wiki/framework/nametags-framework.md diff --git a/addons/advanced_ballistics/functions/fnc_handleFired.sqf b/addons/advanced_ballistics/functions/fnc_handleFired.sqf index b41fd7a7c01..ff2fe85ae4f 100644 --- a/addons/advanced_ballistics/functions/fnc_handleFired.sqf +++ b/addons/advanced_ballistics/functions/fnc_handleFired.sqf @@ -19,7 +19,7 @@ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); -if (!(_ammo isKindOf "BulletBase")) exitWith {}; +if !(_ammo isKindOf "BulletBase") exitWith {}; if (!alive _projectile) exitWith {}; if (underwater _unit) exitWith {}; diff --git a/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf b/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf index 125c3677b88..51907869241 100644 --- a/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf +++ b/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf @@ -40,7 +40,7 @@ if (_transonicStabilityCoef == 0) then { _transonicStabilityCoef = 0.5; }; private _dragModel = getNumber(_ammoConfig >> "ACE_dragModel"); -if (!(_dragModel in [1, 2, 5, 6, 7, 8])) then { +if !(_dragModel in [1, 2, 5, 6, 7, 8]) then { _dragModel = 1; }; private _ballisticCoefficients = getArray(_ammoConfig >> "ACE_ballisticCoefficients"); diff --git a/addons/advanced_fatigue/XEH_postInit.sqf b/addons/advanced_fatigue/XEH_postInit.sqf index f5aa7432f01..08fd827d588 100644 --- a/addons/advanced_fatigue/XEH_postInit.sqf +++ b/addons/advanced_fatigue/XEH_postInit.sqf @@ -46,7 +46,7 @@ if (!hasInterface) exitWith {}; }, true] call CBA_fnc_addPlayerEventHandler; // - Duty factors ------------------------------------------------------------- - if (GVAR(medicalLoaded)) then { + if (GETEGVAR(medical,enabled,false)) then { [QEGVAR(medical,pain), { // 0->1.0, 0.5->1.05, 1->1.1 linearConversion [0, 1, (_this getVariable [QEGVAR(medical,pain), 0]), 1, 1.1, true]; }] call FUNC(addDutyFactor); diff --git a/addons/advanced_fatigue/XEH_preInit.sqf b/addons/advanced_fatigue/XEH_preInit.sqf index 9f58e44fdf2..643b7b0be00 100644 --- a/addons/advanced_fatigue/XEH_preInit.sqf +++ b/addons/advanced_fatigue/XEH_preInit.sqf @@ -13,6 +13,5 @@ GVAR(dutyList) = createHashMap; GVAR(setAnimExclusions) = []; GVAR(inertia) = 0; GVAR(inertiaCache) = createHashMap; -GVAR(medicalLoaded) = ["ace_medical"] call EFUNC(common,isModLoaded); ADDON = true; diff --git a/addons/advanced_fatigue/functions/fnc_mainLoop.sqf b/addons/advanced_fatigue/functions/fnc_mainLoop.sqf index da469b6d218..add9b6e5d81 100644 --- a/addons/advanced_fatigue/functions/fnc_mainLoop.sqf +++ b/addons/advanced_fatigue/functions/fnc_mainLoop.sqf @@ -25,7 +25,7 @@ if (!alive ACE_player) exitWith { private _oxygen = 0.9; // Default AF oxygen saturation -if (GVAR(medicalLoaded) && {EGVAR(medical_vitals,simulateSpo2)}) then { +if (GETEGVAR(medical,enabled,false) && {EGVAR(medical_vitals,simulateSpo2)}) then { _oxygen = (ACE_player getVariable [QEGVAR(medical,spo2), 97]) / 100; }; diff --git a/addons/advanced_throwing/XEH_postInit.sqf b/addons/advanced_throwing/XEH_postInit.sqf index 774c99b3e65..d91129b0250 100644 --- a/addons/advanced_throwing/XEH_postInit.sqf +++ b/addons/advanced_throwing/XEH_postInit.sqf @@ -10,20 +10,10 @@ if (!hasInterface) exitWith {}; // Temporary Wind Info indication GVAR(tempWindInfo) = false; -// Ammo/Magazines look-up hash for correctness of initSpeed -GVAR(ammoMagLookup) = call CBA_fnc_createNamespace; -{ - { - private _ammo = getText (configFile >> "CfgMagazines" >> _x >> "ammo"); - if (_ammo != "") then { GVAR(ammoMagLookup) setVariable [_ammo, _x]; }; - } forEach (getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines")); -} forEach getArray (configFile >> "CfgWeapons" >> "Throw" >> "muzzles"); - - // Add keybinds ["ACE3 Weapons", QGVAR(prepare), localize LSTRING(Prepare), { // Condition - if (!([ACE_player] call FUNC(canPrepare))) exitWith {false}; + if !([ACE_player] call FUNC(canPrepare)) exitWith {false}; if (EGVAR(common,isReloading)) exitWith {true}; // Statement diff --git a/addons/advanced_throwing/XEH_preStart.sqf b/addons/advanced_throwing/XEH_preStart.sqf index 022888575ed..efd2ca1f7eb 100644 --- a/addons/advanced_throwing/XEH_preStart.sqf +++ b/addons/advanced_throwing/XEH_preStart.sqf @@ -1,3 +1,21 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" + +// Ammo/Magazines look-up hash for correctness of initSpeed +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgAmmo = configFile >> "CfgAmmo"; +private _cfgThrow = configFile >> "CfgWeapons" >> "Throw"; + +private _ammoMagLookup = createHashMap; + +{ + { + private _ammo = getText (_cfgMagazines >> _x >> "ammo"); + if (_ammo != "") then { + _ammoMagLookup set [configName (_cfgAmmo >> _ammo), _x]; + }; + } forEach (getArray (_cfgThrow >> _x >> "magazines")); +} forEach (getArray (_cfgThrow >> "muzzles")); + +uiNamespace setVariable [QGVAR(ammoMagLookup), compileFinal _ammoMagLookup]; diff --git a/addons/advanced_throwing/functions/fnc_drawThrowable.sqf b/addons/advanced_throwing/functions/fnc_drawThrowable.sqf index 5bc3f22b571..f85c33dbde2 100644 --- a/addons/advanced_throwing/functions/fnc_drawThrowable.sqf +++ b/addons/advanced_throwing/functions/fnc_drawThrowable.sqf @@ -43,13 +43,10 @@ if ((!_primed) && {!((_throwableMag in (uniformItems ACE_player)) || {_throwable // Get correct throw power for primed grenade if (_primed) then { - private _ammoType = typeOf _activeThrowable; - _throwableMag = GVAR(ammoMagLookup) getVariable _ammoType; - if (isNil "_throwableMag") then { - // What we're trying to throw must not be a normal throwable because it is not in our lookup hash (e.g. 40mm smoke) - // Just use HandGrenade as it has an average initSpeed value - _throwableMag = "HandGrenade"; - }; + // If ammo type is not found: + // What we're trying to throw must not be a normal throwable because it is not in our lookup hash (e.g. 40mm smoke) + // Just use HandGrenade as it has an average initSpeed value + _throwableMag = (uiNamespace getVariable QGVAR(ammoMagLookup)) getOrDefault [typeOf _activeThrowable, "HandGrenade"]; }; // Some throwables have different classname for magazine and ammo diff --git a/addons/advanced_throwing/functions/fnc_prepare.sqf b/addons/advanced_throwing/functions/fnc_prepare.sqf index 7926c2c8649..c158ad51502 100644 --- a/addons/advanced_throwing/functions/fnc_prepare.sqf +++ b/addons/advanced_throwing/functions/fnc_prepare.sqf @@ -18,19 +18,10 @@ params ["_unit"]; TRACE_1("params",_unit); -// Temporarily enable wind info, to aid in throwing smoke grenades effectively -if ( - GVAR(enableTempWindInfo) && - {!(missionNamespace getVariable [QEGVAR(weather,WindInfo), false])} -) then { - [] call EFUNC(weather,displayWindInfo); - GVAR(tempWindInfo) = true; -}; - // Select next throwable if one already in hand if (_unit getVariable [QGVAR(inHand), false]) exitWith { TRACE_1("inHand",_unit); - if (!(_unit getVariable [QGVAR(primed), false])) then { + if !(_unit getVariable [QGVAR(primed), false]) then { TRACE_1("not primed",_unit); // Restore muzzle ammo (setAmmo 1 has no impact if no appliccable throwable in inventory) // selectNextGrenade relies on muzzles array (setAmmo 0 removes the muzzle from the array and current can't be found, cycles between 0 and 1 muzzles) @@ -44,6 +35,11 @@ if (isNull (_unit getVariable [QGVAR(activeThrowable), objNull]) && {(currentThr TRACE_1("no throwables",_unit); }; +// Temporarily enable wind info, to aid in throwing smoke grenades effectively +if (GVAR(enableTempWindInfo) && {!(missionNamespace getVariable [QEGVAR(weather,WindInfo), false])}) then { + [] call EFUNC(weather,displayWindInfo); + GVAR(tempWindInfo) = true; +}; _unit setVariable [QGVAR(inHand), true]; diff --git a/addons/advanced_throwing/functions/fnc_throw.sqf b/addons/advanced_throwing/functions/fnc_throw.sqf index 797f18d7730..d6b38a6a0c7 100644 --- a/addons/advanced_throwing/functions/fnc_throw.sqf +++ b/addons/advanced_throwing/functions/fnc_throw.sqf @@ -20,7 +20,7 @@ TRACE_1("params",_unit); // Prime the throwable if it hasn't been cooking already // Next to proper simulation this also has to happen before delay for orientation of the throwable to be set -if (!(_unit getVariable [QGVAR(primed), false])) then { +if !(_unit getVariable [QGVAR(primed), false]) then { [_unit] call FUNC(prime); }; diff --git a/addons/advanced_throwing/stringtable.xml b/addons/advanced_throwing/stringtable.xml index 1e0b5ae23f7..e0e526e12e7 100644 --- a/addons/advanced_throwing/stringtable.xml +++ b/addons/advanced_throwing/stringtable.xml @@ -193,6 +193,7 @@ 바람 정보 임시로 표시 Afficher temporairement les informations sur le vent Временно показать информацию о ветре + Mostrar información del viento temporalmente Temporarily display Wind Info while throwing, to aid in placing smoke grenades effectively. @@ -202,6 +203,7 @@ 연막탄을 효과적으로 배치하는 데 도움이 되도록 투척하는 동안 일시적으로 바람 정보를 표시합니다. Affiche les informations sur le vent pendant le lancement pour placer les grenades fumigènes plus efficacement. Временно отображайте информацию о ветре во время броска, чтобы помочь эффективно разместить дымовые шашки. + Mostrar información del viento temporalmente mientras se lanza, para ayudar a lanzar las granadas de humo de forma efectiva. Prepare/Change Throwable diff --git a/addons/ai/stringtable.xml b/addons/ai/stringtable.xml index 11a686f6b2e..b9df8bb35a1 100644 --- a/addons/ai/stringtable.xml +++ b/addons/ai/stringtable.xml @@ -91,6 +91,7 @@ Equipar NVGs automaticamente 暗視装置の自動装備 Автоматическое оснащение ПНВ + Auto equipar gafas de visión nocturna Equips NVG in inventory during night time and unequips it during day time.\nDoes not add NVGs to inventory! @@ -102,6 +103,7 @@ Equipa o NVG do inventário durante a noite e desequipa durante o dia.\nNão adiciona NVGs ao inventário! インベントリ内の暗視装置を夜間に装備し、日中は解除し収納します。\nこれはNVGをインベントリに追加しません。 Экипирует ПНВ в ночное время и отключает его в дневное время.\nНе добавляет ПНВ в инвентарь! + Equipa las gafas de visión nocturna en el inventario cuando es de noche, y las desequipa cuando es de día.\nNo añade las gafas al inventario! diff --git a/addons/arsenal/functions/fnc_onArsenalClose.sqf b/addons/arsenal/functions/fnc_onArsenalClose.sqf index f2316bc9d5b..6803d2d5de5 100644 --- a/addons/arsenal/functions/fnc_onArsenalClose.sqf +++ b/addons/arsenal/functions/fnc_onArsenalClose.sqf @@ -18,7 +18,7 @@ (_this select 1) params ["", "_exitCode"]; [QGVAR(displayClosed), []] call CBA_fnc_localEvent; -removeMissionEventHandler ["draw3D", GVAR(camPosUpdateHandle)]; +removeMissionEventHandler ["Draw3D", GVAR(camPosUpdateHandle)]; if (is3DEN) then { private _centerOriginParent = objectParent GVAR(centerOrigin); diff --git a/addons/arsenal/functions/fnc_onArsenalOpen.sqf b/addons/arsenal/functions/fnc_onArsenalOpen.sqf index f307c932b13..0f0a5817c6e 100644 --- a/addons/arsenal/functions/fnc_onArsenalOpen.sqf +++ b/addons/arsenal/functions/fnc_onArsenalOpen.sqf @@ -278,4 +278,4 @@ showCinemaBorder false; //--------------- Reset camera pos [nil, [controlNull, 0, 0]] call FUNC(handleMouse); -GVAR(camPosUpdateHandle) = addMissionEventHandler ["draw3D", {call FUNC(updateCamPos)}]; +GVAR(camPosUpdateHandle) = addMissionEventHandler ["Draw3D", {call FUNC(updateCamPos)}]; diff --git a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf index 5bf08245c88..e25016b303d 100644 --- a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf @@ -382,6 +382,9 @@ switch (GVAR(currentLeftPanel)) do { }; GVAR(currentItems) set [IDX_CURR_VEST, _item]; + + [GVAR(center), ""] call BIS_fnc_setUnitInsignia; + [GVAR(center), GVAR(currentInsignia)] call BIS_fnc_setUnitInsignia; }; TOGGLE_RIGHT_PANEL_CONTAINER @@ -420,6 +423,9 @@ switch (GVAR(currentLeftPanel)) do { }; GVAR(currentItems) set [IDX_CURR_BACKPACK, _item]; + + [GVAR(center), ""] call BIS_fnc_setUnitInsignia; + [GVAR(center), GVAR(currentInsignia)] call BIS_fnc_setUnitInsignia; }; TOGGLE_RIGHT_PANEL_CONTAINER diff --git a/addons/arsenal/functions/fnc_onSelChangedRight.sqf b/addons/arsenal/functions/fnc_onSelChangedRight.sqf index ccb29887651..abec68ceeef 100644 --- a/addons/arsenal/functions/fnc_onSelChangedRight.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedRight.sqf @@ -69,7 +69,14 @@ switch (_currentItemsIndex) do { // Secondary weapon case IDX_CURR_SECONDARY_WEAPON_ITEMS: { private _currentItemInSlot = (GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON_ITEMS) select _itemIndex; - private _isDisposable = CBA_disposable_replaceDisposableLauncher && {!isNil {CBA_disposable_loadedLaunchers getVariable (secondaryWeapon GVAR(center))}}; + private _isDisposable = CBA_disposable_replaceDisposableLauncher && {!isNil "CBA_disposable_loadedLaunchers"} && + { + if (CBA_disposable_loadedLaunchers isEqualType createHashMap) then { // after CBA 3.18 + (secondaryWeapon GVAR(center)) in CBA_disposable_loadedLaunchers + } else { + !isNil {CBA_disposable_loadedLaunchers getVariable (secondaryWeapon player)} + } + }; // If removal if (_item == "") then { diff --git a/addons/arsenal/functions/fnc_showItem.sqf b/addons/arsenal/functions/fnc_showItem.sqf index 7ceda5f0d54..f47f12d2bf4 100644 --- a/addons/arsenal/functions/fnc_showItem.sqf +++ b/addons/arsenal/functions/fnc_showItem.sqf @@ -72,6 +72,6 @@ if (_nextAction != GVAR(currentAction)) then { GVAR(currentAction) = _nextAction; }; -if (!(GVAR(currentAction) in ["Civil", "Salute"])) then { +if !(GVAR(currentAction) in ["Civil", "Salute"]) then { GVAR(center) selectWeapon ([primaryWeapon GVAR(center), secondaryWeapon GVAR(center), handgunWeapon GVAR(center), binocular GVAR(center)] select GVAR(selectedWeaponType)); // select correct weapon, prevents floating weapons }; diff --git a/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf b/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf index a93611d3291..502f7b888dc 100644 --- a/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf +++ b/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf @@ -63,7 +63,7 @@ _target switchMove "amovpercmstpslowwrfldnon"; _target setVariable ["origin", _position]; // When killed, respawn AI -_target addEventHandler ["killed", { +_target addEventHandler ["Killed", { params ["_target"]; // Killed may fire twice, 2nd will be null - https://github.com/acemod/ACE3/pull/7561 diff --git a/addons/arsenal/stringtable.xml b/addons/arsenal/stringtable.xml index 02c35266db9..cf858ec24d8 100644 --- a/addons/arsenal/stringtable.xml +++ b/addons/arsenal/stringtable.xml @@ -1245,6 +1245,8 @@ Интегрирован тепловизор. 열화상 내장 Thermique intégrée + Thermal integriert + Térmica integrada Thermal & Primary integrated @@ -1253,6 +1255,8 @@ Интегрирован тепловизор и осн.прицел. 열화상과 주무기 내장 Thermique et primaire intégrés + Thermal und in Primärwaffe integriert + Térmica y Primaria integrada Not Supported @@ -1609,6 +1613,7 @@ Décroissant Decrescente Нисходящий + Descendiente Ascending @@ -1620,6 +1625,7 @@ Croissant Crescente Восходящий + Ascendiente Tools @@ -1647,6 +1653,7 @@ Nombre de munitions Quantidade de munição Количество боеприпасов + Cantidad de munición Illuminators @@ -1657,6 +1664,7 @@ Iluminadores イルミネーター Осветители + Iluminadores Default to Favorites @@ -1668,6 +1676,7 @@ Favoris par défaut Favoritos por padrão По умолчанию - Избранное + Favoritos por defecto Controls whether the ACE Arsenal defaults to showing all items or favorites. @@ -1679,6 +1688,7 @@ Contrôle si l'arsenal ACE affiche par défaut tous les éléments ou les favoris. Controla se o Arsenal ACE exibe por padrão todos os itens ou favoritos. Определяет, будет ли в арсенале ACE по умолчанию отображаться все предметы или избранное. + Controla si el Arsenal de ACE muestra por defecto todos los objetos o sólo los favoritos Favorites Color @@ -1690,6 +1700,7 @@ Couleurs favorites Cor dos favoritos Избранный цвет + Color de Favoritos Highlight color for favorited items. @@ -1701,6 +1712,7 @@ Met en surbrillance les éléments favoris. Cor de destaque para itens favoritados. Выделите цветом любимые предметы. + Color de marcado para los objetos favoritos Switch between displaying all items or your favorites.\nDouble click while holding Shift to add or remove an item. @@ -1712,6 +1724,7 @@ Change entre l'affichage de tous les éléments ou de vos favoris.\nDouble-cliquez en maintenant la touche Maj enfoncée pour ajouter ou supprimer un élément. Alterna entre a exibição de todos os itens ou seus favoritos.\nClique duas vezes enquanto mantém pressionada a tecla Shift para adicionar ou remover um item. Переключайтесь между отображением всех элементов или ваших избранных.\nДважды щелкните, удерживая Shift, чтобы добавить или удалить элемент. + Alterna entre mostrar todos los objetos o sólo los favoritos.\nDoble click mientras se pulsa Shift para añadir o quitar un objeto. Search\nCTRL + Click to enable live results @@ -1721,6 +1734,7 @@ 검색\nCtrl + 클릭으로 실시간 검색 결과를 활성화 Поиск\nCtrl + Click для включения результатов в реальном времени Recherche\nCTRL + clic pour modifier les résultats tout en écrivant + Buscar\nCTRL + Click habilita los objetos en directo diff --git a/addons/artillerytables/functions/fnc_firedEH.sqf b/addons/artillerytables/functions/fnc_firedEH.sqf index 01947b4ebe0..f735c4c9615 100644 --- a/addons/artillerytables/functions/fnc_firedEH.sqf +++ b/addons/artillerytables/functions/fnc_firedEH.sqf @@ -25,7 +25,7 @@ params ["_vehicle", "", "", "", "", "_magazine", "_projectile", "_gunner"]; TRACE_4("firedEH",_vehicle,_magazine,_projectile,_gunner); -if (!([_gunner] call EFUNC(common,isPlayer))) exitWith {}; // AI don't know how to use (this does give them more range than a player) +if !([_gunner] call EFUNC(common,isPlayer)) exitWith {}; // AI don't know how to use (this does give them more range than a player) if ((gunner _vehicle) != _gunner) exitWith {}; // check if primaryGunner diff --git a/addons/artillerytables/functions/fnc_interactMenuOpened.sqf b/addons/artillerytables/functions/fnc_interactMenuOpened.sqf index b7d6371339e..4ba6342fc83 100644 --- a/addons/artillerytables/functions/fnc_interactMenuOpened.sqf +++ b/addons/artillerytables/functions/fnc_interactMenuOpened.sqf @@ -19,7 +19,7 @@ params ["_menuType"]; TRACE_1("interactMenuOpened",_menuType); if (_menuType != 1) exitWith {}; -if (!("ACE_artilleryTable" in (ace_player call EFUNC(common,uniqueItems)))) exitWith {}; +if !("ACE_artilleryTable" in (ace_player call EFUNC(common,uniqueItems))) exitWith {}; private _vehicleAdded = ace_player getVariable [QGVAR(vehiclesAdded), []]; private _rangeTablesShown = ace_player getVariable [QGVAR(rangeTablesShown), []]; diff --git a/addons/artillerytables/initSettings.inc.sqf b/addons/artillerytables/initSettings.inc.sqf index 762010b2caa..f34190f910a 100644 --- a/addons/artillerytables/initSettings.inc.sqf +++ b/addons/artillerytables/initSettings.inc.sqf @@ -15,7 +15,5 @@ private _categoryName = [format ["ACE %1", localize "str_a3_cfgmarkers_nato_art" [LSTRING(disableArtilleryComputer_displayName), LSTRING(disableArtilleryComputer_description)], _categoryName, false, // default value - true, // isGlobal - {[QGVAR(disableArtilleryComputer), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart + true // isGlobal ] call CBA_fnc_addSetting; diff --git a/addons/atragmx/functions/fnc_initGunList.sqf b/addons/atragmx/functions/fnc_initGunList.sqf index 2ae67bb78df..515bc9013eb 100644 --- a/addons/atragmx/functions/fnc_initGunList.sqf +++ b/addons/atragmx/functions/fnc_initGunList.sqf @@ -23,7 +23,7 @@ if ((profileNamespace getVariable ["ACE_ATragMX_profileNamespaceVersion", 0]) == _resetGunList = false; { // Verify each gun has correct param type - if (!(_x isEqualTypeArray ["", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", [], [], false])) exitWith { + if !(_x isEqualTypeArray ["", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", [], [], false]) exitWith { _resetGunList = true; }; } forEach GVAR(gunList); diff --git a/addons/atragmx/functions/fnc_read_gun_list_entries_from_config.sqf b/addons/atragmx/functions/fnc_read_gun_list_entries_from_config.sqf index 31451c7ff81..cbbb4603e34 100644 --- a/addons/atragmx/functions/fnc_read_gun_list_entries_from_config.sqf +++ b/addons/atragmx/functions/fnc_read_gun_list_entries_from_config.sqf @@ -74,7 +74,7 @@ private _validate_preset = { ERROR(_errorMsg); _valid = false; }; - if (!((_this select 17) in ["ASM", "ICAO"])) then { + if !((_this select 17) in ["ASM", "ICAO"]) then { private _errorMsg = format ["Invalid atmosphere model: %1", _this select 17]; ERROR(_errorMsg); _valid = false; diff --git a/addons/atragmx/functions/fnc_target_speed_assist_timer.sqf b/addons/atragmx/functions/fnc_target_speed_assist_timer.sqf index b34dd666f22..5408edee3af 100644 --- a/addons/atragmx/functions/fnc_target_speed_assist_timer.sqf +++ b/addons/atragmx/functions/fnc_target_speed_assist_timer.sqf @@ -26,7 +26,7 @@ if !(ctrlVisible 9000) then { params ["_args"]; _args params ["_startTime"]; - if (!(GVAR(speedAssistTimer))) exitWith { + if !(GVAR(speedAssistTimer)) exitWith { GVAR(speedAssistTimer) = true; ctrlSetText [8006, Str(Round((CBA_missionTime - _startTime) * 10) / 10)]; diff --git a/addons/atragmx/functions/fnc_toggle_c1_ballistic_coefficient_data.sqf b/addons/atragmx/functions/fnc_toggle_c1_ballistic_coefficient_data.sqf index bb581ad6ea7..a8cd7ce52ae 100644 --- a/addons/atragmx/functions/fnc_toggle_c1_ballistic_coefficient_data.sqf +++ b/addons/atragmx/functions/fnc_toggle_c1_ballistic_coefficient_data.sqf @@ -15,7 +15,7 @@ * Public: No */ -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {}; if (ctrlVisible 17000) then { false call FUNC(show_c1_ballistic_coefficient_data); diff --git a/addons/atragmx/functions/fnc_toggle_muzzle_velocity_data.sqf b/addons/atragmx/functions/fnc_toggle_muzzle_velocity_data.sqf index 562ef305537..34326b251da 100644 --- a/addons/atragmx/functions/fnc_toggle_muzzle_velocity_data.sqf +++ b/addons/atragmx/functions/fnc_toggle_muzzle_velocity_data.sqf @@ -15,7 +15,7 @@ * Public: No */ -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {}; if (ctrlVisible 16000) then { false call FUNC(show_muzzle_velocity_data); diff --git a/addons/atragmx/functions/fnc_toggle_truing_drop.sqf b/addons/atragmx/functions/fnc_toggle_truing_drop.sqf index 2c61b1776ba..2d13619de08 100644 --- a/addons/atragmx/functions/fnc_toggle_truing_drop.sqf +++ b/addons/atragmx/functions/fnc_toggle_truing_drop.sqf @@ -15,7 +15,7 @@ * Public: No */ -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {}; if (ctrlVisible 18000) then { false call FUNC(show_truing_drop); diff --git a/addons/atragmx/functions/fnc_update_zero_range.sqf b/addons/atragmx/functions/fnc_update_zero_range.sqf index 023a5a7ee29..8a3eca13448 100644 --- a/addons/atragmx/functions/fnc_update_zero_range.sqf +++ b/addons/atragmx/functions/fnc_update_zero_range.sqf @@ -35,7 +35,7 @@ if (!GVAR(atmosphereModeTBH)) then { _relativeHumidity = 0.5; }; -private _scopeBaseAngle = if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) then { +private _scopeBaseAngle = if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZero:%1:%2:%3:%4", _zeroRange, _muzzleVelocity, _airFriction, _boreHeight]; (parseNumber _zeroAngle) } else { diff --git a/addons/attach/functions/fnc_handleKilled.sqf b/addons/attach/functions/fnc_handleKilled.sqf index ef08aff3058..2183b05b426 100644 --- a/addons/attach/functions/fnc_handleKilled.sqf +++ b/addons/attach/functions/fnc_handleKilled.sqf @@ -28,7 +28,7 @@ if (_attachedList isEqualTo []) exitWith {}; TRACE_2("detaching",_xObject,_deadUnit); detach _xObject; //If it's a vehicle, also delete the attached - if (!(_deadUnit isKindOf "CAManBase")) then { + if !(_deadUnit isKindOf "CAManBase") then { _xObject setPos ((getPos _deadUnit) vectorAdd [0, 0, -1000]); [{deleteVehicle (_this select 0)}, [_xObject], 2] call CBA_fnc_waitAndExecute; }; diff --git a/addons/ballistics/stringtable.xml b/addons/ballistics/stringtable.xml index aa746e543ff..a4c67c68d53 100644 --- a/addons/ballistics/stringtable.xml +++ b/addons/ballistics/stringtable.xml @@ -3540,6 +3540,7 @@ Utilisation de l'IA Utilização por IA Использование ИИ + Uso de la IA Illum @@ -3551,6 +3552,7 @@ Fusées éclairantes Sinalizadoras Осветители + Iluminación Smoke @@ -3562,6 +3564,7 @@ Fumigènes Fumígenas Дым + Humo Inf @@ -3573,6 +3576,7 @@ Infanterie Infantaria Пехота + Infantería Veh @@ -3584,6 +3588,7 @@ Véhicule Veículo Техника + Vehículo Armor @@ -3595,6 +3600,7 @@ Blindage Blindagem Бронетехника + Blindados Air @@ -3606,6 +3612,7 @@ Aviation Aeronaves Авиация + Aeronaves diff --git a/addons/captives/XEH_postInit.sqf b/addons/captives/XEH_postInit.sqf index 951a710771e..2580e724633 100644 --- a/addons/captives/XEH_postInit.sqf +++ b/addons/captives/XEH_postInit.sqf @@ -24,7 +24,7 @@ if (isServer) then { }]; }; -["unit", FUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; +["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; [QGVAR(moveInCaptive), LINKFUNC(vehicleCaptiveMoveIn)] call CBA_fnc_addEventHandler; [QGVAR(moveOutCaptive), LINKFUNC(vehicleCaptiveMoveOut)] call CBA_fnc_addEventHandler; diff --git a/addons/captives/functions/fnc_doEscortCaptive.sqf b/addons/captives/functions/fnc_doEscortCaptive.sqf index 817745ece3b..7eb25ccc4c5 100644 --- a/addons/captives/functions/fnc_doEscortCaptive.sqf +++ b/addons/captives/functions/fnc_doEscortCaptive.sqf @@ -44,7 +44,7 @@ if (_state) then { }; }; - if (!(_unit getVariable [QGVAR(isEscorting), false])) then { + if !(_unit getVariable [QGVAR(isEscorting), false]) then { [(_this select 1)] call CBA_fnc_removePerFrameHandler; [objNull, _target, false] call EFUNC(common,claim); detach _target; diff --git a/addons/captives/functions/fnc_setHandcuffed.sqf b/addons/captives/functions/fnc_setHandcuffed.sqf index c13da8f9274..0c54d9a70a7 100644 --- a/addons/captives/functions/fnc_setHandcuffed.sqf +++ b/addons/captives/functions/fnc_setHandcuffed.sqf @@ -58,7 +58,7 @@ if (_state) then { // fix anim on mission start (should work on dedicated servers) [{ params ["_unit"]; - if (!(_unit getVariable [QGVAR(isHandcuffed), false])) exitWith {}; + if !(_unit getVariable [QGVAR(isHandcuffed), false]) exitWith {}; if ((vehicle _unit) == _unit) then { [_unit] call EFUNC(common,fixLoweredRifleAnimation); diff --git a/addons/captives/functions/fnc_setSurrendered.sqf b/addons/captives/functions/fnc_setSurrendered.sqf index 393465e08eb..4acc8529bbd 100644 --- a/addons/captives/functions/fnc_setSurrendered.sqf +++ b/addons/captives/functions/fnc_setSurrendered.sqf @@ -81,7 +81,7 @@ if (_state) then { if (_unit == ACE_player) then { //only re-enable HUD if not handcuffed - if (!(_unit getVariable [QGVAR(isHandcuffed), false])) then { + if !(_unit getVariable [QGVAR(isHandcuffed), false]) then { ["captive", []] call EFUNC(common,showHud); //same as showHud true; }; }; diff --git a/addons/captives/stringtable.xml b/addons/captives/stringtable.xml index 174022ea11b..4fc86ec58fe 100644 --- a/addons/captives/stringtable.xml +++ b/addons/captives/stringtable.xml @@ -146,6 +146,7 @@ 포로 눈 가리기 目隠しをする Завязать глаза пленному + Vendar ojos al prisionero Remove blindfold @@ -156,6 +157,7 @@ 눈가리개 풀기 目隠しを外す Снять повязку с глаз + Quitar vendas de los ojos Cable Tie diff --git a/addons/cargo/CfgVehicles.hpp b/addons/cargo/CfgVehicles.hpp index 6f6a93e820b..66fa98159e3 100644 --- a/addons/cargo/CfgVehicles.hpp +++ b/addons/cargo/CfgVehicles.hpp @@ -48,15 +48,7 @@ class CfgVehicles { class Car: LandVehicle { GVAR(space) = 4; GVAR(hasCargo) = 1; - class ACE_Cargo { - /* - class Cargo { - class ACE_medicalSupplyCrate { - type = "ACE_medicalSupplyCrate"; - amount = 1; - }; - };*/ - }; + class ADDON {}; }; class Tank: LandVehicle { @@ -75,7 +67,7 @@ class CfgVehicles { GVAR(hasCargo) = 1; }; - // HEMTTs - Default at 10, some variants are altered based on model size and/or expected level of free space inside. + // HEMTTs - Default at 30, some variants are altered based on model size and/or expected level of free space inside. class Truck_01_base_F: Truck_F { GVAR(space) = 30; }; @@ -523,6 +515,7 @@ class CfgVehicles { class EventHandlers { class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; }; + GVAR(space) = 3; GVAR(hasCargo) = 1; GVAR(size) = 3; diff --git a/addons/cargo/functions/fnc_addCargoItem.sqf b/addons/cargo/functions/fnc_addCargoItem.sqf index 38ccdc0dd94..de262bdcfb5 100644 --- a/addons/cargo/functions/fnc_addCargoItem.sqf +++ b/addons/cargo/functions/fnc_addCargoItem.sqf @@ -7,9 +7,10 @@ * 0: Item to be loaded or * 1: Holder object (vehicle) * 2: Amount (default: 1) + * 3: Ignore interaction distance and stability checks (default: false) * * Return Value: - * None + * Objects loaded * * Example: * ["ACE_Wheel", cursorObject] call ace_cargo_fnc_addCargoItem @@ -17,21 +18,29 @@ * Public: No */ -params ["_item", "_vehicle", ["_amount", 1]]; -TRACE_3("params",_item,_vehicle,_amount); +params ["_item", "_vehicle", ["_amount", 1], ["_ignoreInteraction", false]]; +TRACE_4("params",_item,_vehicle,_amount,_ignoreInteraction); + +private _loaded = 0; // Get config sensitive case name if (_item isEqualType "") then { _item = _item call EFUNC(common,getConfigName); for "_i" from 1 to _amount do { - [_item, _vehicle] call FUNC(loadItem); + if !([_item, _vehicle, _ignoreInteraction] call FUNC(loadItem)) exitWith {}; + + _loaded = _loaded + 1; }; } else { - [_item, _vehicle] call FUNC(loadItem); + _loaded = parseNumber ([_item, _vehicle, _ignoreInteraction] call FUNC(loadItem)); _item = typeOf _item; }; +TRACE_1("loaded",_loaded); + // Invoke listenable event -["ace_cargoAdded", [_item, _vehicle, _amount]] call CBA_fnc_globalEvent; +["ace_cargoAdded", [_item, _vehicle, _loaded]] call CBA_fnc_globalEvent; + +_loaded // return diff --git a/addons/cargo/functions/fnc_initVehicle.sqf b/addons/cargo/functions/fnc_initVehicle.sqf index af80761fe0c..25cebe5b130 100644 --- a/addons/cargo/functions/fnc_initVehicle.sqf +++ b/addons/cargo/functions/fnc_initVehicle.sqf @@ -52,14 +52,21 @@ if (isServer) then { private _cargoClassname = ""; private _cargoCount = 0; + private _loaded = 0; { _cargoClassname = getText (_x >> "type"); _cargoCount = getNumber (_x >> "amount"); - TRACE_3("adding ACE_Cargo",configName _x,_cargoClassname,_cargoCount); + TRACE_3("adding ace_cargo",configName _x,_cargoClassname,_cargoCount); - ["ace_addCargo", [_cargoClassname, _vehicle, _cargoCount]] call CBA_fnc_localEvent; + // Ignore stability check (distance check is also ignored with this, but it's ignored by default if item is a string) + _loaded = [_cargoClassname, _vehicle, _cargoCount, true] call FUNC(addCargoItem); + + // Let loop continue until the end, so that it prints everything into the rpt (there might be smaller items that could still fit in cargo) + if (_loaded != _cargoCount) then { + WARNING_5("%1 (%2) could not fit %3 %4 inside its cargo, only %5 were loaded.",_vehicle,_type,_cargoCount,_cargoClassname,_loaded); + }; } forEach ("true" configClasses (_config >> QUOTE(ADDON) >> "cargo")); }; diff --git a/addons/cargo/initSettings.inc.sqf b/addons/cargo/initSettings.inc.sqf index 029a845a254..4f92934d46a 100644 --- a/addons/cargo/initSettings.inc.sqf +++ b/addons/cargo/initSettings.inc.sqf @@ -6,8 +6,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; [LSTRING(ModuleSettings_enable), LSTRING(ModuleSettings_enable_Description)], _category, true, - 1, - {[QGVAR(enable), _this] call EFUNC(common,cbaSettings_settingChanged)} + 1 ] call CBA_fnc_addSetting; [ @@ -16,8 +15,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; [LSTRING(loadTimeCoefficient), LSTRING(loadTimeCoefficient_description)], _category, [0, 10, 5, 1], - 1, - {[QGVAR(loadTimeCoefficient), _this, true] call EFUNC(common,cbaSettings_settingChanged)} + 1 ] call CBA_fnc_addSetting; [ @@ -26,8 +24,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; [LSTRING(paradropTimeCoefficent), LSTRING(paradropTimeCoefficent_description)], _category, [0, 10, 2.5, 1], - 1, - {[QGVAR(paradropTimeCoefficent), _this, true] call EFUNC(common,cbaSettings_settingChanged)} + 1 ] call CBA_fnc_addSetting; [ @@ -35,9 +32,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; "LIST", [LSTRING(openAfterUnload), LSTRING(openAfterUnload_description)], _category, - [[0, 1, 2, 3], [ELSTRING(common,never), LSTRING(unloadObject), LSTRING(paradropButton), ELSTRING(common,both)], 0], - 0, - {[QGVAR(openAfterUnload), _this, true] call EFUNC(common,cbaSettings_settingChanged)} + [[0, 1, 2, 3], [ELSTRING(common,never), LSTRING(unloadObject), LSTRING(paradropButton), ELSTRING(common,both)], 0] ] call CBA_fnc_addSetting; [ @@ -45,9 +40,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; "CHECKBOX", [LSTRING(carryAfterUnload), LSTRING(carryAfterUnload_description)], _category, - true, - 0, - {[QGVAR(carryAfterUnload), _this] call EFUNC(common,cbaSettings_settingChanged)} + true ] call CBA_fnc_addSetting; [ @@ -56,8 +49,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; [LSTRING(enableDeploy), LSTRING(enableDeploy_description)], _category, true, - 1, - {[QGVAR(enableDeploy), _this] call EFUNC(common,cbaSettings_settingChanged)} + 1 ] call CBA_fnc_addSetting; [ @@ -65,7 +57,5 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; "CHECKBOX", [LSTRING(ModuleSettings_enableRename), LSTRING(ModuleSettings_enableRename_Description)], _category, - true, - 0, - {[QGVAR(enableRename), _this, true] call EFUNC(common,cbaSettings_settingChanged)} + true ] call CBA_fnc_addSetting; diff --git a/addons/cargo/stringtable.xml b/addons/cargo/stringtable.xml index 0a766ab221d..4e8d707f611 100644 --- a/addons/cargo/stringtable.xml +++ b/addons/cargo/stringtable.xml @@ -40,6 +40,8 @@ 配置する 배치하기 Déployer + Aufstellen + Desplegar Raise/Lower | (Ctrl + Scroll) Rotate @@ -287,6 +289,7 @@ Загружаем %1 в %2... %1을(를) %2에 싣는 중... Chargement %1 dans %2... + %1 wird in %2 geladen... Unloading %1 from %2... @@ -296,6 +299,7 @@ Выгружаем %1 из %2... %1을(를) %2(으)로부터 내리는 중... Déchargement %1 de %2... + %1 wird von %2 entladen... %1<br/>could not be loaded @@ -337,6 +341,7 @@ 荷降ろし不可能です 하역할 수가 없습니다 Не может быть выгружен + No puede ser descargado Cargo Size: %1 @@ -346,6 +351,7 @@ 貨物のサイズ: %1 화물 크기: %1 Размер груза: %1 + Tamaño de carga: %1 Custom Name @@ -584,6 +590,8 @@ 配置機能を有効化 배치 활성화 Permettre le placement + Aktiviere Aufbauen + Habilitar despliegue Controls whether cargo items can be unloaded via the deploy method. @@ -592,6 +600,8 @@ 配置機能を介して貨物アイテムを降ろすことが出来るかどうかを制御します。 배치 방법을 통해 화물 아이템을 내릴 수 있는지 여부를 제어합니다. Contrôler si les éléments de cargaison peuvent être déchargés via la méthode de déploiement. + Steuert, ob Frachtgegenstände über die Aufbaumethode entladen werden können. + Controla si los objetos de la carga pueden ser descargados mediante el método de despliegue. diff --git a/addons/common/XEH_PREP.hpp b/addons/common/XEH_PREP.hpp index fb64d464df8..f46d1689f90 100644 --- a/addons/common/XEH_PREP.hpp +++ b/addons/common/XEH_PREP.hpp @@ -103,6 +103,7 @@ PREP(getWeaponAzimuthAndInclination); PREP(getWeaponIndex); PREP(getWeaponState); PREP(getWeight); +PREP(getWheelHitPointsWithSelections); PREP(getWindDirection); PREP(getZoom); PREP(goKneeling); @@ -161,6 +162,7 @@ PREP(sendRequest); PREP(serverLog); PREP(setAimCoef); PREP(setApproximateVariablePublic); +PREP(setDead); PREP(setDefinedVariable); PREP(setDisableUserInputStatus); PREP(setHearingCapability); @@ -264,6 +266,7 @@ PREP(_handleRequestAllSyncedEvents); PREP(addActionEventHandler); PREP(addActionMenuEventHandler); PREP(addMapMarkerCreatedEventHandler); +PREP(addPlayerEH); PREP(removeActionEventHandler); PREP(removeActionMenuEventHandler); diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index f97009808ff..b569a4608e4 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -145,7 +145,7 @@ if (isServer) then { INFO_3("[%1] DC - Was Zeus [%2] while controlling unit [%3] - manually clearing `bis_fnc_moduleRemoteControl_owner`",[_x] call FUNC(getName),_dcPlayer,_x); _x setVariable ["bis_fnc_moduleRemoteControl_owner", nil, true]; }; - } forEach (curatorEditableObjects _zeusLogic); + } forEach (curatorEditableObjects _zeusLogic); }; }]; }; @@ -191,6 +191,7 @@ if (isServer) then { [QGVAR(switchMove), {(_this select 0) switchMove (_this select 1)}] call CBA_fnc_addEventHandler; [QGVAR(setVectorDirAndUp), {(_this select 0) setVectorDirAndUp (_this select 1)}] call CBA_fnc_addEventHandler; [QGVAR(addWeaponItem), {(_this select 0) addWeaponItem [(_this select 1), (_this select 2)]}] call CBA_fnc_addEventHandler; +[QGVAR(removeMagazinesTurret), {(_this select 0) removeMagazinesTurret [_this select 1, _this select 2]}] call CBA_fnc_addEventHandler; [QGVAR(setVanillaHitPointDamage), { params ["_object", "_hitPointAnddamage"]; @@ -222,6 +223,9 @@ if (isServer) then { [QGVAR(claimSafe), LINKFUNC(claimSafeServer)] call CBA_fnc_addEventHandler; }; +["CBA_SettingChanged", { + ["ace_settingChanged", _this] call CBA_fnc_localEvent; +}] call CBA_fnc_addEventHandler; ////////////////////////////////////////////////// // Set up remote execution diff --git a/addons/common/XEH_preInit.sqf b/addons/common/XEH_preInit.sqf index 9b5d27d12ca..b559cb5dd90 100644 --- a/addons/common/XEH_preInit.sqf +++ b/addons/common/XEH_preInit.sqf @@ -10,6 +10,7 @@ PREP_RECOMPILE_END; GVAR(syncedEvents) = createHashMap; GVAR(showHudHash) = createHashMap; GVAR(vehicleIconCache) = createHashMap; // for getVehicleIcon +GVAR(wheelSelections) = createHashMap; GVAR(blockItemReplacement) = false; diff --git a/addons/common/dev/test_cfgPatches.sqf b/addons/common/dev/test_cfgPatches.sqf index e2ce10b2c6b..c5f3c81ef55 100644 --- a/addons/common/dev/test_cfgPatches.sqf +++ b/addons/common/dev/test_cfgPatches.sqf @@ -50,7 +50,7 @@ private _allWeapons = []; private _vics = "(configName _x) select [0,3] == 'ace'" configClasses (configFile >> "CfgVehicles"); { if (((getNumber (_x >> "scope")) == 2) || {((getNumber (_x >> "scopeCurator")) == 2)}) then { - if (!((toLowerANSI configName _x) in _allUnits)) then { + if !((toLowerANSI configName _x) in _allUnits) then { WARNING_2("Not in any units[] - %1 from %2",configName _x,configSourceMod _x); _testPass = false; }; @@ -62,7 +62,7 @@ private _weapons = "(configName _x) select [0,3] == 'ace'" configClasses (config { private _type = toLowerANSI configName _x; if (((getNumber (_x >> "scope")) == 2) || {((getNumber (_x >> "scopeCurator")) == 2)}) then { - if (!((toLowerANSI configName _x) in _allWeapons)) then { + if !((toLowerANSI configName _x) in _allWeapons) then { WARNING_2("Not in any weapons[] - %1 from %2",configName _x,configSourceMod _x); _testPass = false; }; diff --git a/addons/common/functions/fnc_actionKeysNamesConverted.sqf b/addons/common/functions/fnc_actionKeysNamesConverted.sqf index dd62fc87892..27c3597a9b3 100644 --- a/addons/common/functions/fnc_actionKeysNamesConverted.sqf +++ b/addons/common/functions/fnc_actionKeysNamesConverted.sqf @@ -43,10 +43,10 @@ if (isNil "_keyTable") then { }; }; -private _keyCache = uiNamespace getVariable [QGVAR(keyNameCache), locationNull]; +private _keyCache = uiNamespace getVariable QGVAR(keyNameCache); // @TODO: Move cache creation to preStart/somewhere else -if (isNull _keyCache) then { - _keyCache = call CBA_fnc_createNamespace; +if (isNil "_keyCache") then { + _keyCache = createHashMap; uiNamespace setVariable [QGVAR(keyNameCache), _keyCache]; }; @@ -54,7 +54,7 @@ params [["_action", "", [""]]]; private _keybinds = actionKeysNamesArray _action apply { private _keyName = _x; - private _keybind = _keyCache getVariable _keyName; + private _keybind = _keyCache get _keyName; if (isNil "_keybind") then { private _key = -1; @@ -101,7 +101,7 @@ private _keybinds = actionKeysNamesArray _action apply { // cache _keybind = [_key, _shift, _ctrl, _alt]; - _keyCache setVariable [_keyName, _keybind]; + _keyCache set [_keyName, _keybind]; }; _keybind diff --git a/addons/common/functions/fnc_addPlayerEH.sqf b/addons/common/functions/fnc_addPlayerEH.sqf new file mode 100644 index 00000000000..81d030fb62a --- /dev/null +++ b/addons/common/functions/fnc_addPlayerEH.sqf @@ -0,0 +1,61 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Adds event handler just to ACE_player + * + * Arguments: + * 0: Key + * 1: Event Type + * 2: Event Code + * 3: Ignore Virtual Units (spectators, virtual zeus, uav RC) (default: false) + * + * Return Value: + * None + * + * Example: + * ["example", "FiredNear", {systemChat str _this}] call ace_common_fnc_addPlayerEH + * + * Public: Yes +*/ +params [["_key", "", [""]], ["_type", "", [""]], ["_code", {}, [{}]], ["_ignoreVirtual", false, [false]]]; +TRACE_3("addPlayerEH",_key,_type,_ignoreVirtual); + +if (isNil QGVAR(playerEventsHash)) then { // first-run init + GVAR(playerEventsHash) = createHashMap; + ["unit", { + params ["_newPlayer", "_oldPlayer"]; + // uav check only applies to direct controlling UAVs from zeus, no effect on normal UAV operation + private _isVirutal = (unitIsUAV _newPlayer) || {getNumber (configOf _newPlayer >> "isPlayableLogic") == 1}; + + TRACE_4("",_newPlayer,_oldPlayer,_isVirutal,count GVAR(playerEventsHash)); + { + _y params ["_type", "_code", "_ignoreVirtual"]; + + private _oldEH = _oldPlayer getVariable [_x, -1]; + if (_oldEH != -1) then { + _oldPlayer removeEventHandler [_type, _oldEH]; + _oldPlayer setVariable [_x, nil]; + }; + + _oldEH = _newPlayer getVariable [_x, -1]; + if (_oldEH != -1) then { continue }; // if respawned then var and EH already exists + if (_ignoreVirtual && _isVirutal) then { continue }; + + private _newEH = _newPlayer addEventHandler [_type, _code]; + _newPlayer setVariable [_x, _newEH]; + } forEach GVAR(playerEventsHash); + }, false] call CBA_fnc_addPlayerEventHandler; +}; + + +_key = format [QGVAR(playerEvents_%1), toLower _key]; +if (_key in GVAR(playerEventsHash)) exitWith { ERROR_1("bad key %1",_this); }; + +GVAR(playerEventsHash) set [_key, [_type, _code, _ignoreVirtual]]; + +if (isNull ACE_player) exitWith {}; +if (_ignoreVirtual && {(unitIsUAV ACE_player) || {getNumber (configOf ACE_player >> "isPlayableLogic") == 1}}) exitWith {}; + +// Add event now +private _newEH = ACE_player addEventHandler [_type, _code]; +ACE_player setVariable [_key, _newEH]; diff --git a/addons/common/functions/fnc_addWeapon.sqf b/addons/common/functions/fnc_addWeapon.sqf index 16ae92c4f5d..787c9fb24ad 100644 --- a/addons/common/functions/fnc_addWeapon.sqf +++ b/addons/common/functions/fnc_addWeapon.sqf @@ -2,22 +2,33 @@ /* * Author: commy2, johnb43 * Adds weapon to unit without taking a magazine. - * Same as CBA_fnc_addWeaponWithoutItems, but doesn't remove linked items. + * Same as CBA_fnc_addWeaponWithoutItems, but doesn't remove linked items by default. * * Arguments: - * 0: Unit to add the weapon to + * 0: Unit to add the weapon to * 1: Weapon to add + * 2: If linked items should be removed or not (default: false) + * 3: Magazines that should be added to the weapon (default: []) + * - 0: Magazine classname + * - 1: Ammo count * * Return Value: * None * * Example: - * [player, "arifle_AK12_F"] call ace_common_fnc_addWeapon + * [player, "arifle_MX_GL_F", true, [["30Rnd_65x39_caseless_mag", 30], ["1Rnd_HE_Grenade_shell", 1]]] call ace_common_fnc_addWeapon * * Public: Yes */ -params ["_unit", "_weapon"]; +params [ + ["_unit", objNull, [objNull]], + ["_weapon", "", [""]], + ["_removeLinkedItems", false, [false]], + ["_magazines", [], [[]]] +]; + +if (isNull _unit || {_weapon == ""}) exitWith {}; // Config case private _compatibleMagazines = compatibleMagazines _weapon; @@ -45,6 +56,35 @@ private _backpackMagazines = (magazinesAmmoCargo _backpack) select { // Add weapon _unit addWeapon _weapon; +// This doesn't remove magazines, but linked items can't be magazines, so it's fine +if (_removeLinkedItems) then { + switch (_weapon call FUNC(getConfigName)) do { + case (primaryWeapon _unit): { + removeAllPrimaryWeaponItems _unit; + }; + case (secondaryWeapon _unit): { + removeAllSecondaryWeaponItems _unit; + }; + case (handgunWeapon _unit): { + removeAllHandgunItems _unit; + }; + case (binocular _unit): { + removeAllBinocularItems _unit; + }; + }; +}; + +// Add magazines directly now, so that AI don't reload +if (_magazines isNotEqualTo []) then { + { + _x params [["_magazine", "", [""]], ["_ammoCount", -1, [0]]]; + + if (_magazine != "" && {_ammoCount > -1}) then { + _unit addWeaponItem [_weapon, [_magazine, _ammoCount], true]; + }; + } forEach _magazines; +}; + // Add all magazines back { _uniform addMagazineAmmoCargo [_x select 0, 1, _x select 1]; diff --git a/addons/common/functions/fnc_cbaSettings_settingChanged.sqf b/addons/common/functions/fnc_cbaSettings_settingChanged.sqf index 43711d4c970..cf9f18166ab 100644 --- a/addons/common/functions/fnc_cbaSettings_settingChanged.sqf +++ b/addons/common/functions/fnc_cbaSettings_settingChanged.sqf @@ -1,8 +1,8 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Function for handeling a cba setting being changed. - * Adds warning if global setting is changed after ace_settingsInitialized + * Function for handling a cba setting being changed. + * Adds warning if global setting is changed after ace_settingsInitialized. * * Arguments: * 0: Setting Name @@ -21,9 +21,7 @@ params ["_settingName", "_newValue", ["_canBeChanged", false]]; TRACE_2("",_settingName,_newValue); -["ace_settingChanged", [_settingName, _newValue]] call CBA_fnc_localEvent; - -if (!((toLower _settingName) in CBA_settings_needRestart)) exitWith {}; +if !((toLower _settingName) in CBA_settings_needRestart) exitWith {}; if (_canBeChanged) exitWith {WARNING_1("update cba setting [%1] to use correct Need Restart param",_settingName);}; if (!GVAR(settingsInitFinished)) exitWith {}; // Ignore changed event before CBA_settingsInitialized diff --git a/addons/common/functions/fnc_defineVariable.sqf b/addons/common/functions/fnc_defineVariable.sqf index 6cf537b1f8b..85eb7b447f2 100644 --- a/addons/common/functions/fnc_defineVariable.sqf +++ b/addons/common/functions/fnc_defineVariable.sqf @@ -24,7 +24,7 @@ params ["_name", "_value", "_defaultGlobal", "_category", ["_code", 0], ["_persi if (isNil "_defaultGlobal") exitWith {}; -if (!(_name isEqualType "")) exitwith { +if !(_name isEqualType "") exitwith { [format ["Tried to the deinfe a variable with an invalid name: %1 Arguments: %2", _name, _this]] call FUNC(debug); }; diff --git a/addons/common/functions/fnc_disableUserInput.sqf b/addons/common/functions/fnc_disableUserInput.sqf index 8db3c7e8110..b89750e656e 100644 --- a/addons/common/functions/fnc_disableUserInput.sqf +++ b/addons/common/functions/fnc_disableUserInput.sqf @@ -143,11 +143,7 @@ if (_state) then { _ctrl ctrlSetEventHandler ["ButtonClick", toString { closeDialog 0; - if (["ace_medical"] call FUNC(isModLoaded)) then { - [player, "respawn_button"] call EFUNC(medical_status,setDead); - } else { - player setDamage 1; - }; + [player, "respawn_button"] call FUNC(setDead); [false] call FUNC(disableUserInput); }]; diff --git a/addons/common/functions/fnc_errorMessage.sqf b/addons/common/functions/fnc_errorMessage.sqf index 021fdba10cc..72344299f39 100644 --- a/addons/common/functions/fnc_errorMessage.sqf +++ b/addons/common/functions/fnc_errorMessage.sqf @@ -137,11 +137,11 @@ if (_onCancel isEqualTo {}) then { ctrlSetFocus _ctrlButtonCancel; }; -_ctrlButtonOK ctrlAddEventHandler ["buttonClick", {(ctrlParent (_this select 0)) closeDisplay 1; true}]; -_ctrlButtonCancel ctrlAddEventHandler ["buttonClick", {(ctrlParent (_this select 0)) closeDisplay 2; true}]; +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", {(ctrlParent (_this select 0)) closeDisplay 1; true}]; +_ctrlButtonCancel ctrlAddEventHandler ["ButtonClick", {(ctrlParent (_this select 0)) closeDisplay 2; true}]; GVAR(errorOnOK) = _onOK; GVAR(errorOnCancel) = _onCancel; -_display displayAddEventHandler ["unload", {call ([{}, GVAR(errorOnOK), GVAR(errorOnCancel)] select (_this select 1))}]; -_display displayAddEventHandler ["keyDown", {_this select 1 == 1}]; +_display displayAddEventHandler ["Unload", {call ([{}, GVAR(errorOnOK), GVAR(errorOnCancel)] select (_this select 1))}]; +_display displayAddEventHandler ["KeyDown", {_this select 1 == 1}]; diff --git a/addons/common/functions/fnc_getSettingData.sqf b/addons/common/functions/fnc_getSettingData.sqf index a2dceb746c4..eeb8dff1d8a 100644 --- a/addons/common/functions/fnc_getSettingData.sqf +++ b/addons/common/functions/fnc_getSettingData.sqf @@ -32,7 +32,6 @@ scopeName "main"; if (_x select 0 == _name) then { _x breakOut "main"; }; - false -} count GVAR(settings); +} forEach GVAR(settings); [] diff --git a/addons/common/functions/fnc_getWheelHitPointsWithSelections.sqf b/addons/common/functions/fnc_getWheelHitPointsWithSelections.sqf new file mode 100644 index 00000000000..2194c2aca05 --- /dev/null +++ b/addons/common/functions/fnc_getWheelHitPointsWithSelections.sqf @@ -0,0 +1,104 @@ +#include "..\script_component.hpp" +/* + * Author: commy2, johnb43 + * Returns the wheel hitpoints and their selections. + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * 0: Wheel hitpoints + * 1: Wheel hitpoint selections + * + * Example: + * cursorObject call ace_common_fnc_getWheelHitPointsWithSelections + * + * Public: No + */ + +params ["_vehicle"]; +TRACE_1("params",_vehicle); + +// TODO: Fix for GM vehicles +GVAR(wheelSelections) getOrDefaultCall [typeOf _vehicle, { + // Get the vehicles wheel config + private _wheels = configOf _vehicle >> "Wheels"; + + if (isClass _wheels) then { + // Get all hitpoints and selections + (getAllHitPointsDamage _vehicle) params ["_hitPoints", "_hitPointSelections"]; + + // Get all wheels and read selections from config + _wheels = "true" configClasses _wheels; + + private _wheelHitPoints = []; + private _wheelHitPointSelections = []; + + { + private _wheelName = configName _x; + private _wheelCenter = getText (_x >> "center"); + private _wheelBone = getText (_x >> "boneName"); + private _wheelBoneNameResized = _wheelBone select [0, 9]; // Count "wheel_X_Y"; // this is a requirement for physx. Should work for all addon vehicles. + + TRACE_4("",_wheelName,_wheelCenter,_wheelBone,_wheelBoneNameResized); + + private _wheelHitPoint = ""; + private _wheelHitPointSelection = ""; + + // Commy's orginal method + { + if ((_wheelBoneNameResized != "") && {_x find _wheelBoneNameResized == 0}) exitWith { // same as above. Requirement for physx. + _wheelHitPoint = _hitPoints select _forEachIndex; + _wheelHitPointSelection = _hitPointSelections select _forEachIndex; + TRACE_2("wheel found [Orginal]",_wheelName,_wheelHitPoint); + }; + } forEach _hitPointSelections; + + + if (_vehicle isKindOf "Car") then { + // Backup method, search for the closest hitpoint to the wheel's center selection pos. + // Ref #2742 - RHS's HMMWV + if (_wheelHitPoint == "") then { + private _wheelCenterPos = _vehicle selectionPosition _wheelCenter; + if (_wheelCenterPos isEqualTo [0, 0, 0]) exitWith {TRACE_1("no center?",_wheelCenter);}; + + + private _bestDist = 99; + private _bestIndex = -1; + { + if (_x != "") then { + // Filter out things that definitly aren't wheeels (#3759) + if ((toLowerANSI (_hitPoints select _forEachIndex)) in ["hitengine", "hitfuel", "hitbody"]) exitWith {TRACE_1("filter",_x)}; + private _xPos = _vehicle selectionPosition _x; + if (_xPos isEqualTo [0, 0, 0]) exitWith {}; + private _xDist = _wheelCenterPos distance _xPos; + if (_xDist < _bestDist) then { + _bestIndex = _forEachIndex; + _bestDist = _xDist; + }; + }; + } forEach _hitPointSelections; + + TRACE_2("closestPoint",_bestDist,_bestIndex); + if (_bestIndex != -1) then { + _wheelHitPoint = _hitPoints select _bestIndex; + _wheelHitPointSelection = _hitPointSelections select _bestIndex; + TRACE_2("wheel found [Backup]",_wheelName,_wheelHitPoint); + }; + }; + }; + + if ((_wheelHitPoint != "") && {_wheelHitPointSelection != ""}) then { + _wheelHitPoints pushBack _wheelHitPoint; + _wheelHitPointSelections pushBack _wheelHitPointSelection; + }; + } forEach _wheels; + + [_wheelHitPoints, _wheelHitPointSelections] + } else { + // Exit with nothing if the vehicle has no wheels class + TRACE_1("No Wheels",_wheels); + + [[], []] + } +}, true] // return diff --git a/addons/common/functions/fnc_registerItemReplacement.sqf b/addons/common/functions/fnc_registerItemReplacement.sqf index ce2fd7e393b..f1e068c322f 100644 --- a/addons/common/functions/fnc_registerItemReplacement.sqf +++ b/addons/common/functions/fnc_registerItemReplacement.sqf @@ -20,15 +20,23 @@ params [["_oldItem", "", [0,""]], ["_newItems", "", ["", []]], ["_replaceInherited", false, [false]]]; TRACE_3("registerItemReplacement",_oldItem,_newItems,_replaceInherited); - // Setup on first run if (isNil QGVAR(itemReplacements)) then { - GVAR(itemReplacements) = [] call CBA_fnc_createNamespace; + GVAR(itemReplacements) = createHashMap; GVAR(inheritedReplacements) = []; GVAR(oldItems) = []; ["loadout", LINKFUNC(replaceRegisteredItems)] call CBA_fnc_addPlayerEventHandler; }; +// Get config case - if item doesn't exist, "" is returned +if (_oldItem isEqualType "") then { + _oldItem = _oldItem call FUNC(getConfigName); +}; + +if (_oldItem isEqualTo "") exitWith { + ERROR("Item doesn't exist"); +}; + // Save item replacement // $ prefix is used for types (numbers) and replacements with inheritance if (_replaceInherited) then { @@ -42,9 +50,8 @@ if (_newItems isEqualType "") then { _newItems = [_newItems]; }; -private _oldReplacements = GVAR(itemReplacements) getVariable [_oldItem, []]; +private _oldReplacements = GVAR(itemReplacements) getOrDefault [_oldItem, [], true]; _oldReplacements append _newItems; -GVAR(itemReplacements) setVariable [_oldItem, _oldReplacements]; // Force item scan when new replacement was registered in PostInit if !(isNull ACE_player) then { diff --git a/addons/common/functions/fnc_replaceRegisteredItems.sqf b/addons/common/functions/fnc_replaceRegisteredItems.sqf index bfe2e493e01..baa591c8d89 100644 --- a/addons/common/functions/fnc_replaceRegisteredItems.sqf +++ b/addons/common/functions/fnc_replaceRegisteredItems.sqf @@ -42,7 +42,7 @@ for "_i" from 0 to count _newItems - 1 do { private _replacements = []; // Determine replacement items: direct replacements, ... - private _directReplacements = GVAR(itemReplacements) getVariable _item; + private _directReplacements = GVAR(itemReplacements) get _item; if (!isNil "_directReplacements") then { _doReplace = true; _replacements append _directReplacements; @@ -50,7 +50,7 @@ for "_i" from 0 to count _newItems - 1 do { // ... item type replacements ... private _type = getNumber (_cfgWeapons >> _item >> "ItemInfo" >> "type"); - private _typeReplacements = GVAR(itemReplacements) getVariable ("$" + str _type); + private _typeReplacements = GVAR(itemReplacements) get ("$" + str _type); if (!isNil "_typeReplacements") then { _doReplace = true; _replacements append _typeReplacements; @@ -59,7 +59,7 @@ for "_i" from 0 to count _newItems - 1 do { // ... and inherited replacements { if (_item isKindOf [_x, _cfgWeapons]) then { - private _inheritedReplacements = GVAR(itemReplacements) getVariable _x; + private _inheritedReplacements = GVAR(itemReplacements) get _x; if (!isNil "_inheritedReplacements") then { _doReplace = true; _replacements append _inheritedReplacements; diff --git a/addons/common/functions/fnc_setDead.sqf b/addons/common/functions/fnc_setDead.sqf new file mode 100644 index 00000000000..f6d62abd349 --- /dev/null +++ b/addons/common/functions/fnc_setDead.sqf @@ -0,0 +1,44 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Kills a unit without changing visual appearance. + * + * Arguments: + * 0: Unit + * 1: Reason for death (only used if ace_medical is loaded) (default: "") + * 2: Killer (vehicle that killed unit) (default: objNull) + * 3: Instigator (unit who pulled trigger) (default: objNull) + * + * Return Value: + * None + * + * Example: + * [cursorObject, "", player, player] call ace_common_fnc_setDead; + * + * Public: Yes + */ + +params [["_unit", objNull, [objNull]], ["_reason", "", [""]], ["_source", objNull, [objNull]], ["_instigator", objNull, [objNull]]]; + +if (!local _unit) exitWith { + WARNING_1("setDead executed on non-local unit - %1",_this); +}; + +if (GETEGVAR(medical,enabled,false)) then { + [_unit, _reason, _source, _instigator] call EFUNC(medical_status,setDead); +} else { + // From 'ace_medical_status_fnc_setDead': Kill the unit without changing visual appearance + + // (#8803) Reenable damage if disabled to prevent having live units in dead state + // Keep this after death event for compatibility with third party hooks + if (!isDamageAllowed _unit) then { + WARNING_1("setDead executed on unit with damage blocked - %1",_this); + _unit allowDamage true; + }; + + private _currentDamage = _unit getHitPointDamage "HitHead"; + + _unit setHitPointDamage ["HitHead", 1, true, _source, _instigator]; + + _unit setHitPointDamage ["HitHead", _currentDamage, true, _source, _instigator]; +}; diff --git a/addons/common/functions/fnc_showHud.sqf b/addons/common/functions/fnc_showHud.sqf index 1ca7ca81068..5bb0153772d 100644 --- a/addons/common/functions/fnc_showHud.sqf +++ b/addons/common/functions/fnc_showHud.sqf @@ -56,7 +56,7 @@ private _resultMask = []; for "_index" from 0 to 9 do { private _set = true; //Default to true { - if (!(_x select _index)) exitWith { + if !(_x select _index) exitWith { _set = false; //Any false will make it false }; } forEach _masks; diff --git a/addons/common/stringtable.xml b/addons/common/stringtable.xml index 1c960e91739..96ad037cc11 100644 --- a/addons/common/stringtable.xml +++ b/addons/common/stringtable.xml @@ -1834,6 +1834,9 @@ 무기 흔들림 Oscillation de l'arme Колебание оружия + Waffen schwanken + Oscilación del arma + Oscillazione arma Enable Weapon Sway @@ -1841,6 +1844,9 @@ 무기 흔들림 추가 Activer l'oscillation de l'arme Включить колебание оружия + Aktiviere Waffen schwanken + Habilitar oscilación del arma + Abilita oscillazione arma Enables weapon sway influenced by sway factors, such as stance, fatigue and medical condition.\nDisabling this setting will defer sway to vanilla or other mods. @@ -1848,6 +1854,9 @@ 흔들림 계수, 자세, 피로도, 건강 상태 등의 요인에 영향을 받는 무기 흔들림을 활성화합니다.\n이 설정을 비활성화하면 바닐라 또는 다른 모드의 흔들림으로 대체됩니다. Active l'oscillation de l'arme influencé par les facteurs d'oscillation, tels que la position, la fatigue et l'état de santé.\nLa désactivation de ce paramètre reportera l'oscillation à vanilla ou à d'autres mods. Активируйте колебание оружия в зависимости от таких факторов, как стойка, усталость и состояние здоровья.\nОтключение этого параметра приведет к переносу раскачивания на vanilla или другие моды. + Ermöglicht die Beeinflussung des Waffen-Schwankens durch Beeinflussungsfaktoren wie Haltung, Müdigkeit und Gesundheitszustand.\nDie Deaktivierung dieser Einstellung erlaubt die Beeinflussung durch Vanilla oder andere Mods. + Habilita la oscilación del arma afectado por factores como la postura, la fatiga y la condición médica.\nDeshabilitar esta opción hará que el comportamiento de la oscilación venga definido por Vanilla o por otros mods. + Abilita l'oscillazione ACE, influenzata da fattori come postura, fatica e condizione medica.\nDisabilitare questa impostazione farà controllare l'oscillazione al gioco vanilla o altre mod. Sway factor @@ -1888,6 +1897,7 @@ Fattore di Oscillazione Appoggiato 静止依託時の手ぶれ係数 Коэффициент колебания прицела в состоянии покоя + Factor de oscilación apoyado Influences the amount of weapon sway while weapon is rested. @@ -1898,6 +1908,7 @@ Determina la quantità di oscillazione dell'arma quando questa è appoggiata. 静止し壁などに依託している時の武器の手ぶれの大きさに影響します。 Влияет на величину колебания прицела оружия в состоянии покоя. + Afecta la cantidad de oscilación del arma cuando se está apoyado. Deployed sway factor @@ -1908,6 +1919,7 @@ Fattore di Oscillazione su Bipode 接地展開時の手ぶれ係数 Коэффициент колебания прицела при развертывании + Factor de oscilación desplegado Influences the amount of weapon sway while weapon is deployed. @@ -1918,6 +1930,7 @@ Determina la quantità di oscillazione dell'arma quando questa è stabilizzata usando il bipode. 武器の接地展開時の武器の手ぶれの大きさに影響します。 Влияет на величину колебания прицела оружия при его развертывании. + Afecta la cantidad de oscilación del arma cuando se está desplegado. diff --git a/addons/compat_cup_terrains/CfgVehicles.hpp b/addons/compat_cup_terrains/CfgVehicles.hpp index 08176b77fed..3fbd69f2913 100644 --- a/addons/compat_cup_terrains/CfgVehicles.hpp +++ b/addons/compat_cup_terrains/CfgVehicles.hpp @@ -1,3 +1,6 @@ +class CBA_Extended_EventHandlers; +#define XEH_INHERITED class EventHandlers {class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {};} + class CfgVehicles { class House; class House_Small_F; @@ -5,7 +8,7 @@ class CfgVehicles { class House_EP1: House {}; class Land_Benzina_schnell: House { - transportFuel = 0; + XEH_INHERITED; EGVAR(refuel,hooks)[] = {{-1.5,-3.93,-1.25}, {2.35,-3.93,-1.25}}; EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; class ACE_Actions { @@ -18,22 +21,22 @@ class CfgVehicles { }; }; class Land_A_FuelStation_Feed: Strategic { - transportFuel = 0; + XEH_INHERITED; EGVAR(refuel,hooks)[] = {{-0.34,0,0}, {0.34,0,0}}; EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_Ind_FuelStation_Feed_EP1: House_EP1 { - transportFuel = 0; + XEH_INHERITED; EGVAR(refuel,hooks)[] = {{-0.34,0,0}, {0.34,0,0}}; EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_FuelStation_Feed_PMC: Strategic { - transportFuel = 0; + XEH_INHERITED; EGVAR(refuel,hooks)[] = {{-0.34,0,0}, {0.34,0,0}}; EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; }; class FuelStation: House_Small_F { - transportFuel = 0; + XEH_INHERITED; EGVAR(refuel,hooks)[] = {{1.25, .2, -1.1}}; EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; class ACE_Actions { @@ -45,4 +48,9 @@ class CfgVehicles { }; }; }; + class WarfareBBaseStructure; + class Base_WarfareBVehicleServicePoint: WarfareBBaseStructure { + // "vehicle service point" (a conex /w barrels) - need hooks??? + XEH_INHERITED; + }; }; diff --git a/addons/compat_cup_units/CfgGlasses.hpp b/addons/compat_cup_units/CfgGlasses.hpp new file mode 100644 index 00000000000..1620f74212b --- /dev/null +++ b/addons/compat_cup_units/CfgGlasses.hpp @@ -0,0 +1,492 @@ +class CfgGlasses { + + #define ESS_OVERLAY \ + ace_overlay = QPATHTOEF(goggles,textures\hud\combatgoggles.paa); \ + ace_overlayCracked = QPATHTOEF(goggles,textures\hud\combatgogglescracked.paa) + + class None; + class CUP_G_PMC_RadioHeadset_Glasses; + + // ESS Goggles - Dark + class CUP_G_ESS_BLK_Dark: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Blk: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Blk_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Blk_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Face_Blk: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_CBR_Dark: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Dark: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_RGR_Dark: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + + // ESS Goggles - Ember + class CUP_G_ESS_BLK_Ember: None { + ace_color[] = {1, 0, 0}; + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_CBR_Ember: None { + ace_color[] = {1, 0, 0}; + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_RGR_Ember: None { + ace_color[] = {1, 0, 0}; + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Ember: None { + ace_color[] = {1, 0, 0}; + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Facewrap_White: None { + ace_color[] = {1, 0, 0}; + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + + // ESS Goggles - Clear + class CUP_G_ESS_BLK: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_CBR: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_RGR: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Facewrap_Black: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Facewrap_Black_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Face_Grn: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Face_Grn_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Face_Red: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Face_White: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Face_White_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Grn: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Grn_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Grn_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Grn_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Grn_GPS_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Grn_GPS_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Red: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Red_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Red_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_White: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_White_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_White_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_White_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_White_GPS_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_White_GPS_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_CBR_Facewrap_Red: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Facewrap_Tan: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Face_Tan: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Face_Tan_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Tan: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Tan_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Tan_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Tan_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Tan_GPS_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Tan_GPS_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_RGR_Facewrap_Ranger: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_RGR_Facewrap_Skull: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_RGR_Facewrap_Tropical: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + + // Oakleys - Dark + class CUP_G_Oakleys_Drk: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Black_Glasses_Dark: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Black_Glasses_Dark_Headset: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Tan_Glasses_Dark: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Tan_Glasses_Dark_Headset: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Tropical_Glasses_Dark: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Tropical_Glasses_Dark_Headset: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Winter_Glasses_Dark: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Winter_Glasses_Dark_Headset: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_RadioHeadset_Glasses_Dark: CUP_G_PMC_RadioHeadset_Glasses { + ace_resistance = 1; + ace_tintAmount = 8; + }; + + // Oakleys - Ember + class CUP_G_Oakleys_Embr: None { + ace_color[] = {1, 0, 0}; + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Black_Glasses_Ember: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_color[] = {1, 0, 0}; + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Tan_Glasses_Ember: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_color[] = {1, 0, 0}; + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Tropical_Glasses_Ember: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_color[] = {1, 0, 0}; + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Winter_Glasses_Ember: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_color[] = {1, 0, 0}; + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_RadioHeadset_Glasses_Ember: CUP_G_PMC_RadioHeadset_Glasses { + ace_color[] = {1, 0, 0}; + ace_resistance = 1; + ace_tintAmount = 8; + }; + + // Shades - Dark + class CUP_G_Beard_Shades_Black: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_Beard_Shades_Blonde: CUP_G_Beard_Shades_Black { + ace_resistance = 1; + ace_tintAmount = 8; + }; + + // Shades - Clear + class CUP_G_Grn_Scarf_Shades: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_GPS: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_GPS_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_GPS_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_GPSCombo: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_GPSCombo_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_GPSCombo_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_GPS: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_GPS_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_GPS_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_GPSCombo: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_GPSCombo_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_GPSCombo_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_GPS: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_GPS_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_GPS_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_GPSCombo: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_GPSCombo_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_GPSCombo_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + + // Thug - Dark + class CUP_PMC_G_thug: None { + ace_tintAmount = 8; + }; +}; diff --git a/addons/compat_cup_units/config.cpp b/addons/compat_cup_units/config.cpp index bde1052a110..c3ba110e742 100644 --- a/addons/compat_cup_units/config.cpp +++ b/addons/compat_cup_units/config.cpp @@ -15,4 +15,5 @@ class CfgPatches { }; }; +#include "CfgGlasses.hpp" #include "CfgWeapons.hpp" 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 186690908c2..1042c0eacf3 100644 --- a/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/CfgVehicles.hpp +++ b/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/CfgVehicles.hpp @@ -1,35 +1,30 @@ class CfgVehicles { class CUP_T810_Unarmed_Base; class CUP_T810_Refuel_Base: CUP_T810_Unarmed_Base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-1.01, 0.21, -0.5},{1.08, 0.2, -0.5}}; EGVAR(refuel,fuelCargo) = 10000; }; class Truck_02_fuel_base_F; class CUP_Kamaz_5350_Refuel_Base: Truck_02_fuel_base_F { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-0.02, -3.33, -1.05}}; EGVAR(refuel,fuelCargo) = 10000; }; class CUP_Ural_Support_Base; class CUP_Ural_Refuel_Base: CUP_Ural_Support_Base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-0.05, -3.65, -0.42}}; EGVAR(refuel,fuelCargo) = 10000; }; class CUP_V3S_Open_Base; class CUP_V3S_Refuel_Base: CUP_V3S_Open_Base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-0.35, -3.35, -0.4},{0.40, -3.35, -0.4}}; EGVAR(refuel,fuelCargo) = 6500; }; class CUP_MTVR_Base; class CUP_MTVR_Refuel_Base: CUP_MTVR_Base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-1.09, -0.01, -0.5},{1, -0.01, -0.5}}; EGVAR(refuel,fuelCargo) = 10000; }; 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 a23cf87af02..112c3356389 100644 --- a/addons/compat_cup_weapons/compat_cup_weapons_csw/stringtable.xml +++ b/addons/compat_cup_weapons/compat_cup_weapons_csw/stringtable.xml @@ -6,36 +6,48 @@ [CSW] AGS30 ベルト [CSW] Лента AGS 30 [CSW] AGS-30 벨트 + [CSW] AGS30 Gurt + [CSW] Cinta de AGS30 [CSW] MK19 Belt [CSW] Mk19 ベルト [CSW] Лента Mk19 [CSW] Mk.19 벨트 + [CSW] MK19 Gurt + [CSW] Cinta de MK19 [CSW] TOW Tube [CSW] TOW チューブ [CSW] Туба TOW [CSW] TOW 튜브 + [CSW] TOW Rohr + [CSW] Tubo de TOW [CSW] TOW2 Tube [CSW] TOW2 チューブ [CSW] Туба TOW-2 [CSW] TOW2 튜브 + [CSW] TOW2 Rohr + [CSW] Tubo de TOW2 [CSW] PG-9 Round [CSW] PG-9 砲弾 [CSW] Снаряд ПГ-9 [CSW] PG-9 대전차고폭탄 + [CSW] PG-9 Rakete + [CSW] Carga de PG-9 [CSW] OG-9 Round [CSW] OG-9 砲弾 [CSW] Снаряд OГ-9 [CSW] OG-9 고폭파편탄 + [CSW] OG-9 Rakete + [CSW] Carga de OG-9 [CSW] M1 HE @@ -43,6 +55,8 @@ [CSW] M1 HE [CSW] M1 고폭탄 [CSW] M1 HE + [CSW] M1 HE + [CSW] HE de M1 [CSW] M84 Smoke @@ -50,6 +64,8 @@ [CSW] M84 Дымовая [CSW] M84 연막탄 [CSW] M84 Fumigène + [CSW] M84 Rauch + [CSW] Humo M84 [CSW] M60A2 WP @@ -57,6 +73,8 @@ [CSW] M60A2 WP [CSW] M60A2 백린연막탄 [CSW] M60A2 WP + [CSW] M60A2 WP + [CSW] M60A2 WP [CSW] M67 AT Laser Guided @@ -64,6 +82,8 @@ [CSW] M67 AT Laser Guided [CSW] M67 레이저유도 대전차탄 [CSW] M67 AT Guidé laser + [CSW] M67 AT Lasergelenkt + [CSW] AT Guiado por Láser M67 [CSW] M314 Illumination @@ -71,6 +91,8 @@ [CSW] M314 Осветительная [CSW] M314 조명탄 [CSW] M314 Illumination + [CSW] M314 Beleuchtung + [CSW] Iluminación M314 [CSW] 3OF56 HE @@ -78,6 +100,8 @@ [CSW] 3OF56 HE [CSW] 3OF56 고폭탄 [CSW] 3OF56 HE + [CSW] 3OF56 HE + [CSW] HE de 3OF56 [CSW] 3OF69M Laser Guided @@ -85,6 +109,8 @@ [CSW] 3OF69M Laser Guided [CSW] 3OF69M 레이저유도탄 [CSW] 3OF69M Guidé laser + [CSW] 3OF69M Lasergelenkt + [CSW] 3OF69M Guiado por Láser [CSW] 122mm WP @@ -92,6 +118,8 @@ [CSW] 122mm WP [CSW] 122mm 백린탄 [CSW] 122mm WP + [CSW] 122mm WP + [CSW] WP de 122mm [CSW] D-462 Smoke @@ -99,6 +127,8 @@ [CSW] D-462 Дымовая [CSW] D-462 연막탄 [CSW] D-462 Fumigène + [CSW] D-462 Rauch + [CSW] Humo D-462 [CSW] S-463 Illumination @@ -106,6 +136,8 @@ [CSW] S-463 Осветительная [CSW] S-463 조명탄 [CSW] S-463 Eclairante + [CSW] S-463 Beleuchtung + [CSW] Iluminación S-463 [CSW] BK-6M HEAT @@ -113,6 +145,8 @@ [CSW] BK-6M HEAT [CSW] BK-6M 대전차고폭탄 [CSW] BK-6M HEAT + [CSW] BK-6M HEAT + [CSW] BK-6M HEAT diff --git a/addons/compat_cup_weapons/compat_cup_weapons_nightvision/stringtable.xml b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/stringtable.xml index 47d35eba8c4..e1afbe21c8b 100644 --- a/addons/compat_cup_weapons/compat_cup_weapons_nightvision/stringtable.xml +++ b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/stringtable.xml @@ -10,6 +10,7 @@ AN/PVS-14 (백색광) AN/PVS-14 (WP) AN/PVS-14 (БФ) + AN/PVS-14 (WP) AN/PVS-15 (Black, WP) @@ -20,6 +21,7 @@ AN/PVS-15 (검정, 백색광) AN/PVS-15 (Noires, WP) AN/PVS-15 (Чёрный, БФ) + AN/PVS-15 (Negras, WP) AN/PVS-15 (Green, WP) @@ -30,6 +32,7 @@ AN/PVS-15 (녹색, 백색광) AN/PVS-15 (Vertes, WP) AN/PVS-15 (Зелёный, БФ) + AN/PVS-15 (Verdes, WP) AN/PVS-15 (Tan, WP) @@ -40,6 +43,7 @@ AN/PVS-15 (황갈색, 백색광) AN/PVS-15 (Marron clair, WP) AN/PVS-15 (Желтовато-коричневый, БФ) + AN/PVS-15 (Marrones, WP) AN/PVS-15 (Winter, WP) @@ -47,6 +51,8 @@ AN/PVS-15 (설상, 백색광) AN/PVS-15 (Белый, БФ) AN/PVS-15 (Blanc, WP) + AN/PVS-15 (Winter, WP) + AN/PVS-15 (Blancas, WP) GPNVG (Black, WP) @@ -57,6 +63,7 @@ GPNVG (검정, 백색광) GPNVG (Noires, WP) GPNVG (Чёрный, БФ) + GPNVG (Negras, WP) GPNVG (Tan, WP) @@ -67,6 +74,7 @@ GPNVG (황갈색, 백색광) GPNVG (Marron clair, WP) GPNVG (Желтовато-коричневый, БФ) + GPNVG (Marrones, WP) GPNVG (Green, WP) @@ -77,6 +85,7 @@ GPNVG (녹색, 백색광) GPNVG (Vertes, WP) GPNVG (Зелёный, БФ) + GPNVG (Verdes, WP) GPNVG (Winter, WP) @@ -84,6 +93,8 @@ GPNVG (설상, 백색광) AN/PVS-15 (Белый, БФ) GPNVG (Blanc, WP) + GPNVG (Winter, WP) + GPNVG (Blancas, WP) diff --git a/addons/compat_gm/compat_gm_refuel/CfgVehicles.hpp b/addons/compat_gm/compat_gm_refuel/CfgVehicles.hpp deleted file mode 100644 index 46a4deeefd6..00000000000 --- a/addons/compat_gm/compat_gm_refuel/CfgVehicles.hpp +++ /dev/null @@ -1,6 +0,0 @@ -class CfgVehicles { - class gm_ural4320_base; - class gm_ural4320_refuel_base: gm_ural4320_base { - transportFuel = 0; - }; -}; diff --git a/addons/compat_gm/compat_gm_refuel/config.cpp b/addons/compat_gm/compat_gm_refuel/config.cpp index 6becabe70a9..05688eff702 100644 --- a/addons/compat_gm/compat_gm_refuel/config.cpp +++ b/addons/compat_gm/compat_gm_refuel/config.cpp @@ -21,4 +21,3 @@ class CfgPatches { }; #include "CfgEventHandlers.hpp" -#include "CfgVehicles.hpp" diff --git a/addons/compat_rf/$PBOPREFIX$ b/addons/compat_rf/$PBOPREFIX$ new file mode 100644 index 00000000000..78e6f45daf4 --- /dev/null +++ b/addons/compat_rf/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\compat_rf diff --git a/addons/compat_rf/CfgWeapons.hpp b/addons/compat_rf/CfgWeapons.hpp new file mode 100644 index 00000000000..d1daa7c7100 --- /dev/null +++ b/addons/compat_rf/CfgWeapons.hpp @@ -0,0 +1,42 @@ +class CfgWeapons { + // Ballistics + class Pistol_Base_F; + class hgun_Glock19_RF: Pistol_Base_F { + ace_barrelTwist = 254; + ace_barrelLength = 102; + ace_twistDirection = 1; + }; + + class hgun_DEagle_RF: Pistol_Base_F { + ace_barrelTwist = 482; + ace_barrelLength = 127; + ace_twistDirection = 1; + }; + + class Rifle_Long_Base_F; + class srifle_h6_base_rf: Rifle_Long_Base_F { + ace_barrelTwist = 228.6; + ace_barrelLength = 460; + ace_twistDirection = 1; + }; + + class Rifle_Base_F; + class arifle_ash12_base_RF: Rifle_Base_F { + ace_barrelTwist = 228.6; + ace_barrelLength = 400; + ace_twistDirection = 1; + }; + + class arifle_ash12_LR_base_RF: arifle_ash12_base_RF { + ace_barrelLength = 450; + }; + + // Hearing + class H_HelmetIA; + class H_HelmetIA_sb_arid_RF: H_HelmetIA { + ace_hearing_protection = 0.75; + }; + class H_HelmetIA_sb_digital_RF: H_HelmetIA { + ace_hearing_protection = 0.75; + }; +}; diff --git a/addons/compat_rf/compat_rf_nouniformrestrictions/CfgVehicles.hpp b/addons/compat_rf/compat_rf_nouniformrestrictions/CfgVehicles.hpp new file mode 100644 index 00000000000..553c199ee6f --- /dev/null +++ b/addons/compat_rf/compat_rf_nouniformrestrictions/CfgVehicles.hpp @@ -0,0 +1,12 @@ +// Generated using ace_nouniformrestrictions_fnc_exportConfig +class CfgVehicles { + class B_Helipilot_F; + class C_Helipilot_Green_UniformHolder_RF; + + class C_Helipilot_Rescue_UniformHolder_RF: B_Helipilot_F { + modelSides[] = {6}; + }; + class B_Helipilot_Green_UniformHolder_RF: C_Helipilot_Green_UniformHolder_RF { + modelSides[] = {6}; + }; +}; diff --git a/addons/compat_rf/compat_rf_nouniformrestrictions/config.cpp b/addons/compat_rf/compat_rf_nouniformrestrictions/config.cpp new file mode 100644 index 00000000000..2de1cf96735 --- /dev/null +++ b/addons/compat_rf/compat_rf_nouniformrestrictions/config.cpp @@ -0,0 +1,21 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "RF_Data_Loadorder", + "ace_nouniformrestrictions" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Mike"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_rf/compat_rf_nouniformrestrictions/script_component.hpp b/addons/compat_rf/compat_rf_nouniformrestrictions/script_component.hpp new file mode 100644 index 00000000000..0b98185fa03 --- /dev/null +++ b/addons/compat_rf/compat_rf_nouniformrestrictions/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT nouniformrestrictions +#define SUBCOMPONENT_BEAUTIFIED No Uniform Restrictions +#include "..\script_component.hpp" diff --git a/addons/compat_rf/compat_rf_realisticnames/Attachments.hpp b/addons/compat_rf/compat_rf_realisticnames/Attachments.hpp new file mode 100644 index 00000000000..9915ad1d44f --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/Attachments.hpp @@ -0,0 +1,41 @@ +class optic_MRD; +class optic_MRD_khk_RF: optic_MRD { + displayName = SUBCSTRING(optic_mrd_khk_Name); +}; +class optic_MRD_tan_RF: optic_MRD { + displayName = SUBCSTRING(optic_mrd_tan_Name); +}; + +class optic_ACO_grn; +class optic_ACO_grn_desert_RF: optic_ACO_grn { + displayName = SUBCSTRING(optic_aco_grn_desert_Name); +}; +class optic_ACO_grn_wood_RF: optic_ACO_grn { + displayName = SUBCSTRING(optic_aco_grn_wood_Name); +}; + +class optic_Aco; +class optic_ACO_desert_RF: optic_Aco { + displayName = SUBCSTRING(optic_aco_desert_Name); +}; +class optic_ACO_wood_RF: optic_Aco { + displayName = SUBCSTRING(optic_aco_wood_Name); +}; + +class ItemCore; +class optic_rds_RF: ItemCore { + displayName = SUBCSTRING(optic_rds_Name); +}; + +class optic_VRCO_RF: ItemCore { + displayName = SUBCSTRING(optic_vrco_Name); +}; +class optic_VRCO_tan_RF: optic_VRCO_RF { + displayName = SUBCSTRING(optic_vrco_tan_Name); +}; +class optic_VRCO_khk_RF: optic_VRCO_RF { + displayName = SUBCSTRING(optic_vrco_khk_Name); +}; +class optic_VRCO_pistol_RF: optic_VRCO_RF { + displayName = SUBCSTRING(optic_vrco_pistol_Name); +}; diff --git a/addons/compat_rf/compat_rf_realisticnames/CfgMagazines.hpp b/addons/compat_rf/compat_rf_realisticnames/CfgMagazines.hpp new file mode 100644 index 00000000000..52231bcf071 --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/CfgMagazines.hpp @@ -0,0 +1,24 @@ +class CfgMagazines { + class CA_Magazine; + class 1Rnd_RC40_shell_RF: CA_Magazine { + displayName = SUBCSTRING(rc40_Name); + }; + class 1Rnd_RC40_HE_shell_RF: 1Rnd_RC40_shell_RF { + displayName = SUBCSTRING(rc40_he_Name); + }; + class 1Rnd_RC40_SmokeWhite_shell_RF: 1Rnd_RC40_shell_RF { + displayName = SUBCSTRING(rc40_white_Name); + }; + class 1Rnd_RC40_SmokeBlue_shell_RF: 1Rnd_RC40_shell_RF { + displayName = SUBCSTRING(rc40_blue_Name); + }; + class 1Rnd_RC40_SmokeRed_shell_RF: 1Rnd_RC40_shell_RF { + displayName = SUBCSTRING(rc40_red_Name); + }; + class 1Rnd_RC40_SmokeGreen_shell_RF: 1Rnd_RC40_shell_RF { + displayName = SUBCSTRING(rc40_green_Name); + }; + class 1Rnd_RC40_SmokeOrange_shell_RF: 1Rnd_RC40_shell_RF { + displayName = SUBCSTRING(rc40_orange_Name); + }; +}; diff --git a/addons/compat_rf/compat_rf_realisticnames/CfgVehicles.hpp b/addons/compat_rf/compat_rf_realisticnames/CfgVehicles.hpp new file mode 100644 index 00000000000..016a569c501 --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/CfgVehicles.hpp @@ -0,0 +1,134 @@ +class CfgVehicles { + class Heli_light_03_dynamicLoadout_base_F; + class B_Heli_light_03_dynamicLoadout_RF: Heli_light_03_dynamicLoadout_base_F { + displayName = SUBCSTRING(heli_light_03_Name); + }; + + class Heli_light_03_unarmed_base_F; + class B_Heli_light_03_unarmed_RF: Heli_light_03_unarmed_base_F { + displayName = SUBCSTRING(heli_light_03_unarmed_Name); + }; + + class I_Heli_light_03_dynamicLoadout_RF; + class I_E_Heli_light_03_dynamicLoadout_RF: I_Heli_light_03_dynamicLoadout_RF { + displayName = SUBCSTRING(heli_light_03_Name); + }; + + class I_Heli_light_03_unarmed_RF; + class I_E_Heli_light_03_unarmed_RF: I_Heli_light_03_unarmed_RF { + displayName = SUBCSTRING(heli_light_03_unarmed_Name); + }; + + class Heli_EC_01A_base_RF; + class Heli_EC_01A_military_base_RF: Heli_EC_01A_base_RF { + displayName = SUBCSTRING(ec_01a_military_Name); + }; + + class Helicopter_Base_H; + class Heli_EC_01_base_RF: Helicopter_Base_H { + displayName = SUBCSTRING(ec_01_base_Name); + }; + + class Heli_EC_01_civ_base_RF: Heli_EC_01_base_RF { + displayName = SUBCSTRING(ec_01_Name); + }; + + class Heli_EC_01A_civ_base_RF: Heli_EC_01A_base_RF { + displayName = SUBCSTRING(ec_01a_Name); + }; + + class Heli_EC_02_base_RF: Heli_EC_01_base_RF { + displayName = SUBCSTRING(ec_02_Name); + }; + + class Heli_EC_03_base_RF: Heli_EC_01_base_RF { + displayName = SUBCSTRING(ec_03_Name); + }; + + class Heli_EC_04_base_RF: Heli_EC_01_base_RF { + displayName = SUBCSTRING(ec_04_Name); + }; + + // Typhoon + class O_Truck_03_fuel_F; + class C_Truck_03_water_rf: O_Truck_03_fuel_F { + displayName = SUBCSTRING(truck_03_water_Name); + }; + + // RAM 1500 (Pickup) + class Offroad_01_unarmed_base_F; + class Pickup_01_base_rf: Offroad_01_unarmed_base_F { + displayName = SUBCSTRING(pickup_01_Name); + }; + class Pickup_fuel_base_rf: Pickup_01_base_rf { + displayName = SUBCSTRING(pickup_01_fuel_Name); + }; + class Pickup_service_base_rf: Pickup_01_base_rf { + displayName = SUBCSTRING(pickup_01_service_Name); + }; + class Pickup_repair_base_rf: Pickup_service_base_rf { + displayName = SUBCSTRING(pickup_01_repair_Name); + }; + class Pickup_comms_base_rf: Pickup_service_base_rf { + displayName = SUBCSTRING(pickup_01_comms_Name); + }; + class Pickup_repair_ig_base_rf: Pickup_repair_base_rf { + displayName = SUBCSTRING(pickup_01_repair_Name); + }; + class Pickup_01_hmg_base_rf: Pickup_01_base_rf { + displayName = SUBCSTRING(pickup_01_hmg_Name); + }; + class Pickup_01_mmg_base_rf: Pickup_01_base_rf { + displayName = SUBCSTRING(pickup_01_mmg_Name); + }; + class Pickup_01_mrl_base_rf: Pickup_01_base_rf { + displayName = SUBCSTRING(pickup_01_mrl_Name); + }; + class Pickup_01_aat_base_rf: Pickup_01_base_rf { + displayName = SUBCSTRING(pickup_01_aa_Name); + }; + class Pickup_covered_base_rf: Pickup_service_base_rf { + displayName = SUBCSTRING(pickup_01_covered_Name); + }; + + class C_IDAP_Pickup_rf; + class C_IDAP_Pickup_water_rf: C_IDAP_Pickup_rf { + displayName = SUBCSTRING(pickup_01_water_Name); + }; + + class StaticMortar; + class CommandoMortar_base_RF: StaticMortar { + displayName = SUBCSTRING(commando_Name); + }; + + class StaticMGWeapon; + class TwinMortar_base_RF: StaticMGWeapon { + displayName = SUBCSTRING(twinmortar_Name); + }; + + class Helicopter_Base_F; + class UAV_RC40_Base_RF: Helicopter_Base_F { + displayName = SUBCSTRING(rc40_base_Name); + }; + class UAV_RC40_Base_Sensor_RF: UAV_RC40_Base_RF { + displayName = SUBCSTRING(rc40_Name); + }; + class UAV_RC40_Base_HE_RF: UAV_RC40_Base_RF { + displayName = SUBCSTRING(rc40_he_Name); + }; + class UAV_RC40_Base_SmokeWhite_RF: UAV_RC40_Base_HE_RF { + displayName = SUBCSTRING(rc40_white_Name); + }; + class UAV_RC40_Base_SmokeBlue_RF: UAV_RC40_Base_HE_RF { + displayName = SUBCSTRING(rc40_blue_Name); + }; + class UAV_RC40_Base_SmokeRed_RF: UAV_RC40_Base_HE_RF { + displayName = SUBCSTRING(rc40_red_Name); + }; + class UAV_RC40_Base_SmokeGreen_RF: UAV_RC40_Base_HE_RF { + displayName = SUBCSTRING(rc40_green_Name); + }; + class UAV_RC40_Base_SmokeOrange_RF: UAV_RC40_Base_HE_RF { + displayName = SUBCSTRING(rc40_orange_Name); + }; +}; diff --git a/addons/compat_rf/compat_rf_realisticnames/CfgWeapons.hpp b/addons/compat_rf/compat_rf_realisticnames/CfgWeapons.hpp new file mode 100644 index 00000000000..c2d9003f11a --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/CfgWeapons.hpp @@ -0,0 +1,111 @@ +class CfgWeapons { + #include "Attachments.hpp" + + class Pistol_Base_F; + class hgun_Glock19_RF: Pistol_Base_F { + displayName = SUBCSTRING(glock19_Name); + }; + class hgun_Glock19_khk_RF: hgun_Glock19_RF { + displayName = SUBCSTRING(glock19_khk_Name); + }; + class hgun_Glock19_Tan_RF: hgun_Glock19_RF { + displayName = SUBCSTRING(glock19_tan_Name); + }; + class hgun_Glock19_auto_RF: hgun_Glock19_RF { + displayName = SUBCSTRING(glock19_auto_Name); + }; + class hgun_Glock19_auto_khk_RF: hgun_Glock19_auto_RF { + displayName = SUBCSTRING(glock19_auto_khk_Name); + }; + class hgun_Glock19_auto_Tan_RF: hgun_Glock19_auto_RF { + displayName = SUBCSTRING(glock19_auto_tan_Name); + }; + + class hgun_DEagle_RF: Pistol_Base_F { + displayName = SUBCSTRING(deagle_Name); + }; + class hgun_DEagle_classic_RF: hgun_DEagle_RF { + displayName = SUBCSTRING(deagle_classic_Name); + }; + class hgun_DEagle_bronze_RF: hgun_DEagle_RF { + displayName = SUBCSTRING(deagle_bronze_Name); + }; + class hgun_DEagle_copper_RF: hgun_DEagle_RF { + displayName = SUBCSTRING(deagle_copper_Name); + }; + class hgun_DEagle_gold_RF: hgun_DEagle_RF { + displayName = SUBCSTRING(deagle_gold_Name); + }; + + class srifle_h6_base_rf; + class srifle_h6_tan_rf: srifle_h6_base_rf { + displayName = SUBCSTRING(h6_tan_Name); + }; + class srifle_h6_oli_rf: srifle_h6_tan_rf { + displayName = SUBCSTRING(h6_oli_Name); + }; + class srifle_h6_blk_rf: srifle_h6_tan_rf { + displayName = SUBCSTRING(h6_blk_Name); + }; + class srifle_h6_digi_rf: srifle_h6_tan_rf { + displayName = SUBCSTRING(h6_digi_Name); + }; + class srifle_h6_gold_rf: srifle_h6_tan_rf { + displayName = SUBCSTRING(h6_gold_Name); + }; + + class srifle_DMR_01_F; + class srifle_DMR_01_black_RF: srifle_DMR_01_F { + displayName = SUBCSTRING(dmr_01_black_Name); + }; + class srifle_DMR_01_tan_RF: srifle_DMR_01_black_RF { + displayName = SUBCSTRING(dmr_01_tan_Name); + }; + + class SMG_01_F; + class SMG_01_black_RF: SMG_01_F { + displayName = SUBCSTRING(smg_01_black_Name); + }; + + class arifle_ash12_base_RF; + class arifle_ash12_blk_RF: arifle_ash12_base_RF { + displayName = SUBCSTRING(ash12_blk_Name); + }; + class arifle_ash12_desert_RF: arifle_ash12_base_RF { + displayName = SUBCSTRING(ash12_desert_Name); + }; + class arifle_ash12_urban_RF: arifle_ash12_base_RF { + displayName = SUBCSTRING(ash12_urban_Name); + }; + class arifle_ash12_wood_RF: arifle_ash12_base_RF { + displayName = SUBCSTRING(ash12_wood_Name); + }; + + class arifle_ash12_GL_base_RF; + class arifle_ash12_GL_blk_RF: arifle_ash12_GL_base_RF { + displayName = SUBCSTRING(ash12_gl_blk_Name); + }; + class arifle_ash12_GL_desert_RF: arifle_ash12_GL_blk_RF { + displayName = SUBCSTRING(ash12_gl_desert_Name); + }; + class arifle_ash12_GL_urban_RF: arifle_ash12_GL_blk_RF { + displayName = SUBCSTRING(ash12_gl_urban_Name); + }; + class arifle_ash12_GL_wood_RF: arifle_ash12_GL_blk_RF { + displayName = SUBCSTRING(ash12_gl_wood_Name); + }; + + class arifle_ash12_LR_base_RF; + class arifle_ash12_LR_blk_RF: arifle_ash12_LR_base_RF { + displayName = SUBCSTRING(ash12_lr_blk_Name); + }; + class arifle_ash12_LR_desert_RF: arifle_ash12_LR_blk_RF { + displayName = SUBCSTRING(ash12_lr_desert_Name); + }; + class arifle_ash12_LR_urban_RF: arifle_ash12_LR_blk_RF { + displayName = SUBCSTRING(ash12_lr_urban_Name); + }; + class arifle_ash12_LR_wood_RF: arifle_ash12_LR_blk_RF { + displayName = SUBCSTRING(ash12_lr_wood_Name); + }; +}; diff --git a/addons/compat_rf/compat_rf_realisticnames/config.cpp b/addons/compat_rf/compat_rf_realisticnames/config.cpp new file mode 100644 index 00000000000..47003c4a42b --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/config.cpp @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "RF_Data_Loadorder", + "ace_realisticnames" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Mike", "Marc"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgMagazines.hpp" +#include "CfgWeapons.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/compat_rf/compat_rf_realisticnames/script_component.hpp b/addons/compat_rf/compat_rf_realisticnames/script_component.hpp new file mode 100644 index 00000000000..b8d0682fa4f --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT realisticnames +#define SUBCOMPONENT_BEAUTIFIED Realistic Names +#include "..\script_component.hpp" diff --git a/addons/compat_rf/compat_rf_realisticnames/stringtable.xml b/addons/compat_rf/compat_rf_realisticnames/stringtable.xml new file mode 100644 index 00000000000..a31221294cb --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/stringtable.xml @@ -0,0 +1,297 @@ + + + + + EOTech MRDS (Khaki) + EOTech MRDS (カーキ) + + + EOTech MRDS (Tan) + EOTech MRDS (タン) + + + C-More Railway (Green, Desert) + C-More レイルウェイ (グリーン、砂漠迷彩) + + + C-More Railway (Green, Woodland) + C-More レイルウェイ (グリーン、森林迷彩) + + + C-More Railway (Red, Desert) + C-More レイルウェイ (グリーン、砂漠迷彩) + + + C-More Railway (Red, Woodland) + C-More レイルウェイ (グリーン、森林迷彩) + + + Aimpoint Micro R-1 + Aimpoint マイクロ R-1 + + + Vortex Spitfire Prism + Vortex スピットファイア プリズム + + + Vortex Spitfire Prism (Tan) + Vortex スピットファイア プリズム (タン) + + + Vortex Spitfire Prism (Khaki) + Vortex スピットファイア プリズム (カーキ) + + + Vortex Spitfire Prism (Pistol) + Vortex スピットファイア プリズム (ピストル用) + + + Glock 19X + グロック 19X + + + Glock 19X (Khaki) + グロック 19X (カーキ) + + + Glock 19X (Tan) + グロック 19X (タン) + + + Glock 19X Auto + グロック 19X オート + + + Glock 19X Auto (Khaki) + グロック 19X オート (カーキ) + + + Glock 19X Auto (Tan) + グロック 19X オート (タン) + + + Desert Eagle Mark XIX L5 + デザートイーグル Mark XIX L5 + + + Desert Eagle Mark XIX L5 (Classic) + デザートイーグル Mark XIX L5 (クラシック) + + + Desert Eagle Mark XIX L5 (Bronze) + デザートイーグル Mark XIX L5 (ブロンズ) + + + Desert Eagle Mark XIX L5 (Copper) + デザートイーグル Mark XIX L5 (カッパー) + + + Desert Eagle Mark XIX L5 (Gold) + デザートイーグル Mark XIX L5 (ゴールド) + + + Hera H6 (Tan) + ヘラ H6 (タン) + + + Hera H6 (Olive) + ヘラ H6 (オリーブ) + + + Hera H6 (Black) + ヘラ H6 (ブラック) + + + Hera H6 (Digital) + ヘラ H6 (AAF迷彩) + + + Hera H6 (Gold) + ヘラ H6 (ゴールド) + + + VS-121 (Black) + VS-121 (ブラック) + + + VS-121 (Tan) + VS-121 (タン) + + + Vector SMG (Black) + ベクター SMG (ブラック) + + + ASh-12 (Black) + ASh-12 (ブラック) + + + ASh-12 (Desert) + ASh-12 (砂漠迷彩) + + + ASh-12 (Urban) + ASh-12 (市街地迷彩) + + + ASh-12 (Woodland) + ASh-12 (森林迷彩) + + + ASh-12 GL (Black) + ASh-12 GL (ブラック) + + + ASh-12 GL (Desert) + ASh-12 GL (砂漠迷彩) + + + ASh-12 GL (Urban) + ASh-12 GL (市街地迷彩) + + + ASh-12 GL (Woodland) + ASh-12 GL (森林迷彩) + + + ASh-12 LR (Black) + ASh-12 LR (ブラック) + + + ASh-12 LR (Desert) + ASh-12 LR (砂漠迷彩) + + + ASh-12 LR (Urban) + ASh-12 LR (市街地迷彩) + + + ASh-12 LR (Woodland) + ASh-12 LR (森林迷彩) + + + AW159 Wildcat + AW159 ワイルドキャット + + + AW159 Wildcat (Unarmed) + AW159 ワイルドキャット (非武装) + + + H225M Super Cougar HADR + H225M シュペル クーガー HADR + + + H225M Super Cougar Transport + H225M シュペル クーガー 輸送 + + + H225 Super Puma Transport + H225 シュペル ピューマ 輸送 + + + H225 Super Puma VIP + H225 シュペル ピューマ VIP + + + H225M Super Cougar SOCAT + H225M シュペル クーガー SOCAT + + + H225M Super Cougar CSAR + H225M シュペル クーガー CSAR + + + H225 Super Puma SAR + H225 シュペル ピューマ SAR + + + Typhoon Water + タイフーン 給水 + + + Ram 1500 + ラム 1500 + + + Ram 1500 (Fuel) + ラム 1500 (燃料) + + + Ram 1500 (Services) + ラム 1500 (サービス) + + + Ram 1500 (Repair) + ラム 1500 (修理) + + + Ram 1500 (Comms) + ラム 1500 (通信) + + + Ram 1500 (HMG) + ラム 1500 (HMG) + + + Ram 1500 (MMG) + ラム 1500 (MMG) + + + Ram 1500 (MRL) + ラム 1500 (MRL) + + + Ram 1500 (AA) + ラム 1500 (対空) + + + Ram 1500 (Covered) + ラム 1500 (カバー) + + + Ram 1500 (Water) + ラム 1500 (給水) + + + RSG60 + RSG60 + + + AMOS + AMOS + + + Drone40 + ドローン40 + + + Drone40 Scout + ドローン40 偵察型 + + + Drone40 HE + ドローン40 榴弾 + + + Drone40 Smoke (White) + ドローン40 発煙弾 (白) + + + Drone40 Smoke (Blue) + ドローン40 発煙弾 (青) + + + Drone40 Smoke (Red) + ドローン40 発煙弾 (赤) + + + Drone40 Smoke (Green) + ドローン40 発煙弾 (緑) + + + Drone40 Smoke (Orange) + ドローン40 発煙弾 (橙) + + + diff --git a/addons/compat_rf/config.cpp b/addons/compat_rf/config.cpp new file mode 100644 index 00000000000..ab6fb942751 --- /dev/null +++ b/addons/compat_rf/config.cpp @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"RF_Data_Loadorder"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Mike"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgWeapons.hpp" diff --git a/addons/compat_rf/script_component.hpp b/addons/compat_rf/script_component.hpp new file mode 100644 index 00000000000..2cc45da4904 --- /dev/null +++ b/addons/compat_rf/script_component.hpp @@ -0,0 +1,6 @@ +#define COMPONENT compat_rf +#define COMPONENT_BEAUTIFIED Reaction Forces Compatibility + +#include "\z\ace\addons\main\script_mod.hpp" + +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/compat_rhs_afrf3/CfgAmmo.hpp b/addons/compat_rhs_afrf3/CfgAmmo.hpp index 54ff3bd2c2d..11aee03d795 100644 --- a/addons/compat_rhs_afrf3/CfgAmmo.hpp +++ b/addons/compat_rhs_afrf3/CfgAmmo.hpp @@ -219,6 +219,10 @@ class CfgAmmo { EGVAR(frag,force) = 0; }; + class SmokeShell; + class rhs_ammo_rdg2_white: SmokeShell { + EGVAR(grenades,rollVectorDirAndUp)[] = {{0, 1, 0}, {0, 0, 1}}; + }; class Sh_125mm_APFSDS; class Sh_125mm_HE; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/CfgVehicles.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/CfgVehicles.hpp deleted file mode 100644 index 047e264c6ec..00000000000 --- a/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/CfgVehicles.hpp +++ /dev/null @@ -1,10 +0,0 @@ -class CfgVehicles { - class RHS_Ural_Support_MSV_Base_01; - class RHS_Ural_Fuel_MSV_01: RHS_Ural_Support_MSV_Base_01 { - transportFuel = 0; - }; - class rhs_kraz255b1_base; - class rhs_kraz255b1_fuel_base: rhs_kraz255b1_base { - transportFuel = 0; - }; -}; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/config.cpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/config.cpp index 5101a383a31..8e1986b65f9 100644 --- a/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/config.cpp +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/config.cpp @@ -18,4 +18,4 @@ class CfgPatches { }; }; -#include "CfgVehicles.hpp" +// ADDON kept for backward compatiblity diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgVehicles.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgVehicles.hpp deleted file mode 100644 index 5aaf6b4e229..00000000000 --- a/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgVehicles.hpp +++ /dev/null @@ -1,15 +0,0 @@ -class CfgVehicles { - class rhsusf_M1078A1P2_B_M2_fmtv_usarmy; - class rhsusf_M1078A1R_SOV_M2_D_fmtv_socom: rhsusf_M1078A1P2_B_M2_fmtv_usarmy { - transportFuel = 0; - }; - - class rhsusf_M977A4_usarmy_wd; - class rhsusf_M978A4_usarmy_wd: rhsusf_M977A4_usarmy_wd { - transportFuel = 0; - }; - - class rhsusf_M978A4_BKIT_usarmy_wd: rhsusf_M977A4_usarmy_wd { - transportFuel = 0; - }; -}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/config.cpp b/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/config.cpp index 391e22d95e8..bf600d5d5ae 100644 --- a/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/config.cpp +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/config.cpp @@ -21,4 +21,3 @@ class CfgPatches { }; #include "CfgEventHandlers.hpp" -#include "CfgVehicles.hpp" diff --git a/addons/compat_sog/CfgAmmo/grenades.hpp b/addons/compat_sog/CfgAmmo/grenades.hpp index d280443b6e8..6395756f640 100644 --- a/addons/compat_sog/CfgAmmo/grenades.hpp +++ b/addons/compat_sog/CfgAmmo/grenades.hpp @@ -4,6 +4,13 @@ class vn_molotov_grenade_ammo: vn_grenadehand { EGVAR(frag,enabled) = 0; }; +class vn_t67_grenade_ammo: vn_grenadehand { + EGVAR(grenades,rollVectorDirAndUp)[] = {{-1, 0, 0}, {0, 0, 1}}; +}; +class vn_chicom_grenade_ammo: vn_grenadehand { + EGVAR(grenades,rollVectorDirAndUp)[] = {{1, 0, 0}, {0, 0, 1}}; +}; + class SmokeShell; class vn_m14_grenade_ammo: SmokeShell { EGVAR(grenades,incendiary) = 1; diff --git a/addons/compat_sog/CfgEventHandlers.hpp b/addons/compat_sog/CfgEventHandlers.hpp index fc6d80fc5f9..d28b79fb991 100644 --- a/addons/compat_sog/CfgEventHandlers.hpp +++ b/addons/compat_sog/CfgEventHandlers.hpp @@ -32,6 +32,16 @@ class Extended_InitPost_EventHandlers { init = QUOTE((_this select 0) setMass 1e-12); }; }; + class Land_vn_canisterfuel_f { + class ADDON { + init = QUOTE(call (missionNamespace getVariable [ARR_2(QQEFUNC(refuel,makeJerryCan),{})])); + }; + }; + class Land_vn_fuelcan { + class ADDON { + init = QUOTE(call (missionNamespace getVariable [ARR_2(QQEFUNC(refuel,makeJerryCan),{})])); + }; + }; class vn_bicycle_base { class ADDON { init = QUOTE(call FUNC(disableCookoff)); diff --git a/addons/compat_sog/CfgVehicles/land.hpp b/addons/compat_sog/CfgVehicles/land.hpp index c9390265900..70b305a31d2 100644 --- a/addons/compat_sog/CfgVehicles/land.hpp +++ b/addons/compat_sog/CfgVehicles/land.hpp @@ -1,18 +1,19 @@ +#define XEH_INHERITED class EventHandlers {class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {};} // fuel pumps class Land_vn_commercial_base; class Land_vn_fuelstation_01_pump_f: Land_vn_commercial_base { - transportFuel = 0; + XEH_INHERITED; EGVAR(refuel,hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_vn_fuelstation_02_pump_f: Land_vn_commercial_base { - transportFuel = 0; + XEH_INHERITED; EGVAR(refuel,hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_vn_fuelstation_feed_f: Land_vn_commercial_base { - transportFuel = 0; + XEH_INHERITED; EGVAR(refuel,hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; }; @@ -20,13 +21,47 @@ class Land_vn_fuelstation_feed_f: Land_vn_commercial_base { // fuel objects class Land_vn_building_b_base; class Land_vn_usaf_fueltank_75_01: Land_vn_building_b_base { - transportFuel = 0; - EGVAR(refuel,hooks)[] = {{0, -0.4, -0.5}}; + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{-2.52, -2.2, -2.05}, {2.5, 0, -1.3}}; EGVAR(refuel,fuelCargo) = 2840; // 750 * 3.785 }; +class Land_vn_b_prop_fuelbladder_01: Land_vn_usaf_fueltank_75_01 { + EGVAR(refuel,hooks)[] = {{-1.75, -6.7, -1}}; + EGVAR(refuel,fuelCargo) = 3785; // 1000 * 3.785 +}; +class Land_vn_b_prop_fuelbladder_03: Land_vn_b_prop_fuelbladder_01 { + EGVAR(refuel,hooks)[] = {{-1.55, -6.5, -1}}; +}; +class Land_vn_building_industrial_base; +class Land_vn_fuel_tank_stairs: Land_vn_building_industrial_base { + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{0, 0.4, -1.3}, {0, -0.4, -1.3}}; + EGVAR(refuel,fuelCargo) = 10000; // reference is B_Slingload_01_Fuel_F +}; class Land_vn_object_b_base; class Land_vn_b_prop_fueldrum_01: Land_vn_object_b_base { - transportFuel = 0; - EGVAR(refuel,hooks)[] = {{0, 0, 0.5}}; // reference is Land_FlexibleTank_01_F + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{0, 0, 0}}; EGVAR(refuel,fuelCargo) = 300; // reference is Land_FlexibleTank_01_F }; +class Land_vn_b_prop_fueldrum_02: Land_vn_b_prop_fueldrum_01 { + EGVAR(refuel,hooks)[] = {{0, -1.3, -0.15}, {2.3, 1.25, -0.15}}; + EGVAR(refuel,fuelCargo) = 14100; // (23 + 24) * 300 +}; +class vn_b_ammobox_supply_07; +class vn_b_ammobox_supply_09: vn_b_ammobox_supply_07 { // just a pallet + XEH_INHERITED; +}; +class vn_object_c_base_02; +class Land_vn_canisterfuel_f: vn_object_c_base_02 { + EGVAR(cargo,size) = 1; + EGVAR(cargo,canLoad) = 1; + EGVAR(cargo,noRename) = 1; +}; +class Land_vn_object_c_base; +class Land_vn_fuelcan: Land_vn_object_c_base { + XEH_INHERITED; + EGVAR(cargo,size) = 1; + EGVAR(cargo,canLoad) = 1; + EGVAR(cargo,noRename) = 1; +}; diff --git a/addons/compat_sog/CfgVehicles/wheeled.hpp b/addons/compat_sog/CfgVehicles/wheeled.hpp index 3525328d3f4..3a898519dd1 100644 --- a/addons/compat_sog/CfgVehicles/wheeled.hpp +++ b/addons/compat_sog/CfgVehicles/wheeled.hpp @@ -5,7 +5,6 @@ class vn_wheeled_m54_base: vn_wheeled_truck_base { }; class vn_wheeled_m54_cab_base; class vn_wheeled_m54_fuel_base: vn_wheeled_m54_cab_base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-1.15, -2.3, 0.28}}; EGVAR(refuel,fuelCargo) = 4542; }; @@ -25,7 +24,6 @@ class vn_wheeled_z157_base: vn_wheeled_truck_base { EGVAR(refuel,fuelCapacity) = 150; }; class vn_wheeled_z157_fuel_base: vn_wheeled_z157_base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-1.36, -3.575, -0.4}}; EGVAR(refuel,fuelCargo) = 4000; }; diff --git a/addons/compat_sog/config.cpp b/addons/compat_sog/config.cpp index 62b235773b9..04db68293cf 100644 --- a/addons/compat_sog/config.cpp +++ b/addons/compat_sog/config.cpp @@ -1,5 +1,4 @@ #include "script_component.hpp" -// ToDo: move refuel to subconfig #include "\z\ace\addons\refuel\defines.hpp" #include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp" @@ -47,6 +46,8 @@ class CfgPatches { }; }; +class CBA_Extended_EventHandlers; + #include "ACE_CSW_Groups.hpp" #include "ACE_Medical_Injuries.hpp" #include "ACE_Triggers.hpp" diff --git a/addons/compat_sog/functions/fnc_handlePunjiTrapTrigger.sqf b/addons/compat_sog/functions/fnc_handlePunjiTrapTrigger.sqf index d2e9abdbbcb..7cac6829c55 100644 --- a/addons/compat_sog/functions/fnc_handlePunjiTrapTrigger.sqf +++ b/addons/compat_sog/functions/fnc_handlePunjiTrapTrigger.sqf @@ -14,8 +14,10 @@ * * Public: No */ + params ["_trap"]; -if (!(["ace_medical"] call EFUNC(common,isModLoaded))) exitWith {}; + +if !(GETEGVAR(medical,enabled,false)) exitWith {}; private _radius = getNumber (configOf _trap >> "indirectHitRange"); private _affectedUnits = _trap nearEntities ["CAManBase", _radius]; diff --git a/addons/compat_spe/compat_spe_refuel/CfgVehicles.hpp b/addons/compat_spe/compat_spe_refuel/CfgVehicles.hpp index f47d6877f7b..fc1ebc9b4e0 100644 --- a/addons/compat_spe/compat_spe_refuel/CfgVehicles.hpp +++ b/addons/compat_spe/compat_spe_refuel/CfgVehicles.hpp @@ -1,13 +1,11 @@ class CfgVehicles { class SPE_Halftrack_base; class SPE_US_M3_Halftrack_Fuel: SPE_Halftrack_base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-0.23,-2.58,-0.59}}; EGVAR(refuel,fuelCargo) = 2000; }; class SPE_OpelBlitz_base; class SPE_OpelBlitz_Fuel: SPE_OpelBlitz_base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-0.23,-2.58,-0.59}}; EGVAR(refuel,fuelCargo) = 2000; }; diff --git a/addons/compat_ws/CfgWeapons.hpp b/addons/compat_ws/CfgWeapons.hpp index 30e6882b08e..a8b27fb1f3b 100644 --- a/addons/compat_ws/CfgWeapons.hpp +++ b/addons/compat_ws/CfgWeapons.hpp @@ -37,6 +37,11 @@ class CfgWeapons { ACE_twistDirection = 1; }; + class arifle_SLR_V_lxWS; + class arifle_SLR_Para_lxWS: arifle_SLR_V_lxWS { + ACE_barrelLength = 266.7; + }; + // Velko R4/R5 class arifle_Velko_base_lxWS: arifle_Galat_base_lxWS { ACE_barrelLength = 460; diff --git a/addons/compat_ws/compat_ws_realisticnames/Attachments.hpp b/addons/compat_ws/compat_ws_realisticnames/Attachments.hpp new file mode 100644 index 00000000000..95801e04e92 --- /dev/null +++ b/addons/compat_ws/compat_ws_realisticnames/Attachments.hpp @@ -0,0 +1,75 @@ +class optic_Arco; +class optic_arco_hex_lxWS: optic_Arco { + displayName = SUBCSTRING(arco_hex_Name); +}; + +class optic_Holosight; +class optic_Holosight_snake_lxWS: optic_Holosight { + displayName = SUBCSTRING(holosight_snake_Name); +}; + +class optic_Holosight_smg; +class optic_Holosight_smg_snake_lxWS: optic_Holosight_smg { + displayName = SUBCSTRING(holosight_snake_smg_Name); +}; + +class optic_Hamr; +class optic_Hamr_arid_lxWS: optic_Hamr { + displayName = SUBCSTRING(hamr_arid_Name); +}; +class optic_Hamr_lush_lxWS: optic_Hamr { + displayName = SUBCSTRING(hamr_lush_Name); +}; +class optic_Hamr_sand_lxWS: optic_Hamr { + displayName = SUBCSTRING(hamr_sand_Name); +}; +class optic_Hamr_snake_lxWS: optic_Hamr { + displayName = SUBCSTRING(hamr_snake_Name); +}; + +class ItemCore; +class optic_r1_high_lxWS: ItemCore { + displayName = SUBCSTRING(r1_high_black_Name); +}; +class optic_r1_high_khaki_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_high_khaki_Name); +}; +class optic_r1_high_sand_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_high_sand_Name); +}; +class optic_r1_high_snake_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_high_snake_Name); +}; +class optic_r1_high_arid_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_high_arid_Name); +}; +class optic_r1_high_lush_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_high_lush_Name); +}; +class optic_r1_high_black_sand_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_high_black_sand_Name); +}; + +class optic_r1_low_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_low_black_Name); +}; +class optic_r1_low_khaki_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_low_khaki_Name); +}; +class optic_r1_low_sand_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_low_sand_Name); +}; +class optic_r1_low_snake_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_low_snake_Name); +}; +class optic_r1_low_arid_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_low_arid_Name); +}; +class optic_r1_low_lush_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_low_lush_Name); +}; + +class optic_DMS; +class optic_DMS_snake_lxWS: optic_DMS { + displayName = SUBCSTRING(dms_snake_Name); +}; diff --git a/addons/compat_ws/compat_ws_realisticnames/CfgVehicles.hpp b/addons/compat_ws/compat_ws_realisticnames/CfgVehicles.hpp new file mode 100644 index 00000000000..fe1aed7e17d --- /dev/null +++ b/addons/compat_ws/compat_ws_realisticnames/CfgVehicles.hpp @@ -0,0 +1,60 @@ +class CfgVehicles { + class APC_Wheeled_01_base_F; + class APC_Wheeled_01_atgm_base_lxWS: APC_Wheeled_01_base_F { + displayName = SUBCSTRING(apc_wheeled_01_atgm_Name); + }; + class APC_Wheeled_01_command_base_lxWS: APC_Wheeled_01_base_F { + displayName = SUBCSTRING(apc_wheeled_01_command_Name); + }; + class APC_Wheeled_01_mortar_base_lxWS: APC_Wheeled_01_base_F { + displayName = SUBCSTRING(apc_wheeled_01_mortar_Name); + }; + + class Truck_02_base_F; + class Truck_02_aa_base_lxWS: Truck_02_base_F { + displayName = SUBCSTRING(truck_02_aa_Name); + }; + class Truck_02_cargo_base_lxWS: Truck_02_base_F { + displayName = SUBCSTRING(truck_02_cargo_Name); + }; + class Truck_02_box_base_lxWS: Truck_02_base_F { + displayName = SUBCSTRING(truck_02_repair_Name); + }; + class C_Truck_02_racing_lxWS: Truck_02_box_base_lxWS { + displayName = SUBCSTRING(truck_02_racing_Name); + }; + class Truck_02_Ammo_base_lxWS: Truck_02_base_F { + displayName = SUBCSTRING(truck_02_ammo_Name); + }; + class Truck_02_flatbed_base_lxWS: Truck_02_cargo_base_lxWS { + displayName = SUBCSTRING(truck_02_flatbed_Name); + }; + + class Heli_Transport_02_base_F; + class B_UN_Heli_Transport_02_lxWS: Heli_Transport_02_base_F { + displayName = SUBCSTRING(heli_transport_02_Name); + }; + + class O_APC_Tracked_02_cannon_F; + class O_APC_Tracked_02_30mm_lxWS: O_APC_Tracked_02_cannon_F { + displayName = SUBCSTRING(apc_tracked_02_Name); + }; + + class APC_Wheeled_02_base_v2_F; + class APC_Wheeled_02_hmg_base_lxws: APC_Wheeled_02_base_v2_F { + displayName = SUBCSTRING(apc_wheeled_02_hmg_Name); + }; + class APC_Wheeled_02_unarmed_base_lxws: APC_Wheeled_02_base_v2_F { + displayName = SUBCSTRING(apc_wheeled_02_unarmed_Name); + }; + + class O_Heli_Light_02_dynamicLoadout_F; + class B_ION_Heli_Light_02_dynamicLoadout_lxWS: O_Heli_Light_02_dynamicLoadout_F { + displayName = SUBCSTRING(heli_light_02_armed_Name); + }; + + class O_Heli_Light_02_unarmed_F; + class B_ION_Heli_Light_02_unarmed_lxWS: O_Heli_Light_02_unarmed_F { + displayName = SUBCSTRING(heli_light_02_unarmed_Name); + }; +}; diff --git a/addons/compat_ws/compat_ws_realisticnames/CfgWeapons.hpp b/addons/compat_ws/compat_ws_realisticnames/CfgWeapons.hpp index c09400a03c8..e9cf3c6934d 100644 --- a/addons/compat_ws/compat_ws_realisticnames/CfgWeapons.hpp +++ b/addons/compat_ws/compat_ws_realisticnames/CfgWeapons.hpp @@ -1,4 +1,6 @@ class CfgWeapons { + #include "Attachments.hpp" + // AA12 class sgun_aa40_base_lxWS; class sgun_aa40_lxWS: sgun_aa40_base_lxWS { @@ -99,6 +101,12 @@ class CfgWeapons { class arifle_SLR_V_camo_lxWS: arifle_SLR_V_lxWS { displayName = SUBCSTRING(SLR_Camo_Name); }; + class arifle_SLR_Para_lxWS: arifle_SLR_V_lxWS { + displayName = SUBCSTRING(SLR_Para_Name); + }; + class arifle_SLR_Para_snake_lxWS: arifle_SLR_Para_lxWS { + displayName = SUBCSTRING(SLR_Para_Snake_Name); + }; // Vektor R4/R5 class arifle_Velko_base_lxWS; @@ -156,4 +164,16 @@ class CfgWeapons { class arifle_XMS_M_Sand_lxWS: arifle_XMS_M_lxWS { displayName = SUBCSTRING(XMS_SW_Sand_Name); }; + + // GM6 Lynx + class srifle_GM6_F; + class srifle_GM6_snake_lxWS: srifle_GM6_F { + displayName = SUBCSTRING(gm6_snake_Name); + }; + + // RPG-32 + class launch_RPG32_F; + class launch_RPG32_tan_lxWS: launch_RPG32_F { + displayName = SUBCSTRING(rpg32_tan_Name); + }; }; diff --git a/addons/compat_ws/compat_ws_realisticnames/config.cpp b/addons/compat_ws/compat_ws_realisticnames/config.cpp index 5c8e166e000..0eb75926a82 100644 --- a/addons/compat_ws/compat_ws_realisticnames/config.cpp +++ b/addons/compat_ws/compat_ws_realisticnames/config.cpp @@ -19,3 +19,4 @@ class CfgPatches { }; #include "CfgWeapons.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/compat_ws/compat_ws_realisticnames/stringtable.xml b/addons/compat_ws/compat_ws_realisticnames/stringtable.xml index 092fd2a9ea4..30b53b79266 100644 --- a/addons/compat_ws/compat_ws_realisticnames/stringtable.xml +++ b/addons/compat_ws/compat_ws_realisticnames/stringtable.xml @@ -9,6 +9,7 @@ AA12 AA12 AA12 + AA12 AA12 (Sand) @@ -18,14 +19,16 @@ AA12 (サンド) AA12 (Песочный) AA12 (Sable) + AA12 (Arena) AA12 (Snake) AA-12 (뱀 위장) AA12 (Schlange) AA12 (Serpe) - AA12 (ヘビ柄) + AA12 (ヘビ柄迷彩) AA12 (Змея) + AA12 (Serpiente) Galil ARM @@ -35,15 +38,17 @@ ガリル ARM Galil ARM Galil ARM + Galil ARM Galil ARM (Old) 갈릴 ARM (낡음) Galil ARM (Alt) Galil ARM (Vecchio) - ガリル ARM (使い古し) + ガリル ARM (古びた) Galil ARM (Старый) Galil ARM (Ancien) + Galil ARM (Vieja) GLX 160 @@ -53,14 +58,16 @@ GLX 160 GLX 160 GLX 160 + GLX 160 GLX 160 (Snake) GLX-160 (뱀 위장) GLX 160 (Schlange) GLX-160 (Serpe) - GLX 160 (ヘビ柄) + GLX 160 (ヘビ柄迷彩) GLX 160 (Змея) + GLX 160 (Serpiente) GLX 160 (Hex) @@ -70,6 +77,7 @@ GLX 160 (六角形迷彩) GLX 160 (Гекс) GLX 160 (Hex) + GLX 160 (Hex) GLX 160 (Green Hex) @@ -79,15 +87,17 @@ GLX 160 (緑六角形迷彩) GLX 160 (Зеленый Гекс) GLX 160 (Vert Hex) + GLX 160 (Hex Verde) GLX 160 (Camo) GLX-160 (위장) GLX 160 (Tarn) GLX-160 (Mimetica) - GLX 160 (迷彩) + GLX 160 (AAF迷彩) GLX 160 (Камуфляж) GLX 160 (Camo) + GLX 160 (Camo) GLX 160 (Sand) @@ -97,6 +107,7 @@ GLX 160 (サンド) GLX 160 (Песочный) GLX 160 (Sable) + GLX 160 (Arena) Mk14 Mod 1 EBR (Black) @@ -106,14 +117,16 @@ Mk14 Mod 1 EBR (ブラック) Mk14 Mod 1 EBR (Черный) Mk14 Mod 1 EBR (Noir) + Mk14 Mod 1 EBR (Negra) Mk14 Mod 1 EBR (Snake) Mk.14 Mod 1 EBR (뱀 위장) Mk14 Mod 1 EBR (Schlange) Mk14 Mod 1 EBR (Serpe) - Mk14 Mod 1 EBR (ヘビ柄) + Mk14 Mod 1 EBR (ヘビ柄迷彩) Mk14 Mod 1 EBR (Змея) + Mk14 Mod 1 EBR (Serpiente) Vektor SS-77 @@ -122,15 +135,17 @@ ヴェクター SS-77 Vektor SS-77 Vektor SS-77 + Vektor SS-77 Vektor SS-77 (Camo) 벡터 SS-77 (위장) Vektor SS-77 (Tarn) Vektor SS-77 (Mimetica) - ヴェクター SS-77 (迷彩) + ヴェクター SS-77 (AAF迷彩) Vektor SS-77 (Камуфляж) Vektor SS-77 (Camo) + Vektor SS-77 (Camo) Vektor SS-77 (Hex) @@ -140,6 +155,7 @@ ヴェクター SS-77 (六角形迷彩) Vektor SS-77 (гекс) Vektor SS-77 (Hex) + Vektor SS-77 (Hex) Vektor SS-77 (Green Hex) @@ -149,6 +165,7 @@ ヴェクター SS-77 (緑六角形迷彩) Vektor SS-77 (зеленый гекс) Vektor SS-77 (VertHex) + Vektor SS-77 (Hex Verde) Vektor SS-77 (Desert) @@ -158,6 +175,7 @@ ヴェクター SS-77 (砂漠迷彩) Vektor SS-77 (песочныйt) Vektor SS-77 (Désert) + Vektor SS-77 (Desierto) Vektor SS-77 Compact @@ -167,32 +185,36 @@ ヴェクター SS-77 コンパクト Vektor SS-77 Compact Vektor SS-77 Compacte + Vektor SS-77 Compacta Vektor SS-77 Compact (Snake) 벡터 SS-77 단축형 (뱀 위장) Vektor SS-77 Compact (Schlange) Vektor SS-77 Compatto (Serpe) - ヴェクター SS-77 コンパクト (ヘビ柄) + ヴェクター SS-77 コンパクト (ヘビ柄迷彩) Vektor SS-77 Compact (змея) + Vektor SS-77 Compacta (Serpiente) FN FAL 50.00 (Wood) FN FAL 50.00 (목재) FN FAL 50.00 (Holz) FN FAL 50.00 (Legno) - FN FAL 50.00 (森林迷彩) + FN FAL 50.00 (木製) FN FAL 50.00 (лесной) FN FAL 50.00 (Bois) + FN FAL 50.00 (Madera) FN FAL 50.00 GL (Wood) FN FAL 50.00 GL (목재) FN FAL 50.00 GL (Holz) FN FAL 50.00 GL (Legno) - FN FAL 50.00 GL (森林迷彩) + FN FAL 50.00 GL (木製) FN FAL 50.00 GL (лесной) FN FAL 50.00 GL (Bois) + FN FAL 50.00 GL (Madera) FN FAL 50.00 @@ -202,6 +224,7 @@ FN FAL 50.00 FN FAL 50.00 FN FAL 50.00 + FN FAL 50.00 FN FAL 50.00 GL @@ -211,6 +234,7 @@ FN FAL 50.00 GL FN FAL 50.00 GL FN FAL 50.00 GL + FN FAL 50.00 GL FN FAL 50.00 (Desert) @@ -220,6 +244,7 @@ FN FAL 50.00 (砂漠迷彩) FN FAL 50.00 (песочный) FN FAL 50.00 (Désert) + FN FAL 50.00 (Desierto) FN FAL 50.00 (Jungle) @@ -229,15 +254,25 @@ FN FAL 50.00 (熱帯迷彩) FN FAL 50.00 (джунгли) FN FAL 50.00 (Jungle) + FN FAL 50.00 (Jungla) + + + FN FAL OSW Para + FN FAL OSW パラ + + + FN FAL OSW Para (Snake) + FN FAL OSW パラ (ヘビ柄迷彩) Vektor R4 벡터 R4 Vektor R4 Vektor R4 - ヴェクター R5 + ヴェクター R4 Vektor R4 Vektor R4 + Vektor R4 Vektor R5 Carbine @@ -247,6 +282,7 @@ ヴェクター R5 カービン Vektor R5 Carbine Vektor R5 Carbine + Vektor R5 Carabina Vektor R5 Carbine GL @@ -256,22 +292,25 @@ ヴェクター R5 カービン GL Vektor R5 Carbine GL Vektor R5 Carbine GL + Vektor R5 Carabina GL Vektor R5 Carbine (Snake) 벡터 R5 카빈 (뱀 위장) Vektor R5 Carbine (Schlange) Vektor R5 Carabina (Serpe) - ヴェクター R5 カービン (ヘビ柄) + ヴェクター R5 カービン (ヘビ柄迷彩) Vektor R5 Carbine (Змея) + Vektor R5 Carabina (Serpiente) Vektor R5 Carbine GL (Snake) 벡터 R5 카빈 GL (뱀 위장) Vektor R5 Carbine GL (Schlange) Vektor R5 Carabina GL (Serpe) - ヴェクター R5 カービン GL (ヘビ柄) + ヴェクター R5 カービン GL (ヘビ柄迷彩) Vektor R5 Carbine GL (Змея) + Vektor R5 Carabina GL (Serpiente) XMS @@ -417,5 +456,157 @@ XMS SW (모래) XMS SW (サンド) + + GM6 Lynx (Snake) + GM6 リンクス (ヘビ柄迷彩) + + + RPG-32 (Sand) + RPG-32 (サンド) + + + ELCAN SpecterOS (Hex) + ELCAN SpecterOS (六角形迷彩) + + + EOTech XPS3 (Snake) + EOTech XPS3 (ヘビ柄迷彩) + + + EOTech XPS3 SMG (Snake) + EOTech XPS3 SMG (ヘビ柄迷彩) + + + Leupold Mark 4 HAMR (Arid) + Leupold Mark 4 HAMR (乾燥地帯迷彩) + + + Leupold Mark 4 HAMR (Lush) + Leupold Mark 4 HAMR (緑地迷彩) + + + Leupold Mark 4 HAMR (Sand) + Leupold Mark 4 HAMR (サンド) + + + Leupold Mark 4 HAMR (Snake) + Leupold Mark 4 HAMR (ヘビ柄迷彩) + + + Aimpoint Micro R-1 (High, Black) + Aimpoint マイクロ R-1 (ハイマウント、ブラック) + + + Aimpoint Micro R-1 (High, Khaki) + Aimpoint マイクロ R-1 (ハイマウント、カーキ) + + + Aimpoint Micro R-1 (High, Sand) + Aimpoint マイクロ R-1 (ハイマウント、サンド) + + + Aimpoint Micro R-1 (High, Snake) + Aimpoint マイクロ R-1 (ハイマウント、ヘビ柄迷彩) + + + Aimpoint Micro R-1 (High, Arid) + Aimpoint マイクロ R-1 (ハイマウント、乾燥地帯迷彩) + + + Aimpoint Micro R-1 (High, Lush) + Aimpoint マイクロ R-1 (ハイマウント、緑地迷彩) + + + Aimpoint Micro R-1 (High, Black/Sand) + Aimpoint マイクロ R-1 (ハイマウント、ブラック/サンド) + + + Aimpoint Micro R-1 (Low, Black) + Aimpoint マイクロ R-1 (ローマウント、ブラック) + + + Aimpoint Micro R-1 (Low, Khaki) + Aimpoint マイクロ R-1 (ローマウント、カーキ) + + + Aimpoint Micro R-1 (Low, Sand) + Aimpoint マイクロ R-1 (ローマウント、サンド) + + + Aimpoint Micro R-1 (Low, Snake) + Aimpoint マイクロ R-1 (ローマウント、ヘビ柄迷彩) + + + Aimpoint Micro R-1 (Low, Arid) + Aimpoint マイクロ R-1 (ローマウント、乾燥地帯迷彩) + + + Aimpoint Micro R-1 (Low, Lush) + Aimpoint マイクロ R-1 (ローマウント、緑地迷彩) + + + Burris XTR II (Snake) + Burris XTR II (ヘビ柄迷彩) + + + Badger IFV (ATGM) + バジャー IFV (ATGM) + + + Badger IFV (Command) + バジャー IFV (指揮) + + + Badger IFV (Mortar) + バジャー IFV (迫撃砲) + + + KamAZ (Zu-23-2) + KamAZ (Zu-23-2) + + + KamAZ Cargo + KamAZ 貨物 + + + KamAZ Repair + KamAZ 修理 + + + KamAZ Racing + KamAZ レース仕様 + + + KamAZ Ammo + KamAZ 弾薬 + + + KamAZ Flatbed + KamAZ フラットベッド + + + AW101 Merlin + AW101 マーリン + + + BM-2T Stalker (Bumerang-BM) + BM-2T ストーカー (ブーメランク-BM) + + + Otokar ARMA (HMG) + オトカ アルマ (HMG) + + + Otokar ARMA (Unarmed) + オトカ アルマ (非武装) + + + Ka-60 Kasatka (UP) + Ka-60 カサートカ (UP) + + + Ka-60 Kasatka (UP, Unarmed) + Ka-60 カサートカ (UP、非武装) + diff --git a/addons/concertina_wire/functions/fnc_handleDamage.sqf b/addons/concertina_wire/functions/fnc_handleDamage.sqf index 02092044ef3..f5f1177df5d 100644 --- a/addons/concertina_wire/functions/fnc_handleDamage.sqf +++ b/addons/concertina_wire/functions/fnc_handleDamage.sqf @@ -22,7 +22,7 @@ params ["_wire", "", "_damage", "_source", ""]; if (_damage < 0.5) exitWith { 0 }; -if (!(isNull _source)) then { +if (!isNull _source) then { _wire setVariable [QGVAR(lastDamager), _source]; }; diff --git a/addons/cookoff/ACE_Settings.hpp b/addons/cookoff/ACE_Settings.hpp index ba4447dba99..37594bed51b 100644 --- a/addons/cookoff/ACE_Settings.hpp +++ b/addons/cookoff/ACE_Settings.hpp @@ -1,12 +1,8 @@ - class ACE_Settings { - class GVAR(enable) { - movedToSqf = 1; - }; class GVAR(enableAmmobox) { movedToSQF = 1; }; - class GVAR(enableAmmoCookoff) { // For CBA Setting Switch: we can eliminate and just use (ammoCookoffDuration == 0) + class GVAR(enableAmmoCookoff) { movedToSQF = 1; }; class GVAR(ammoCookoffDuration) { diff --git a/addons/cookoff/CfgCloudlets.hpp b/addons/cookoff/CfgCloudlets.hpp index c1671777054..a328451a7b8 100644 --- a/addons/cookoff/CfgCloudlets.hpp +++ b/addons/cookoff/CfgCloudlets.hpp @@ -1,4 +1,3 @@ - class CfgCloudlets { class GVAR(CookOff) { interval = 0.004; diff --git a/addons/cookoff/CfgEden.hpp b/addons/cookoff/CfgEden.hpp index 2b58daa3043..f973ef40261 100644 --- a/addons/cookoff/CfgEden.hpp +++ b/addons/cookoff/CfgEden.hpp @@ -1,28 +1,27 @@ - class Cfg3DEN { class Object { class AttributeCategories { class ace_attributes { class Attributes { - class GVAR(enable) { - property = QGVAR(enable); + class GVAR(enable) { // setting was previously GVAR(enable), so maintain for backwards compatiblity with missions + property = QGVAR(enable); // same as above control = "Checkbox"; - displayName = CSTRING(enable_hd_name); - tooltip = CSTRING(enable_hd_tooltip); - expression = QUOTE(if !(_value) then {_this setVariable [ARR_3('%s',_value,true)];};); + displayName = CSTRING(enableFire_name); + tooltip = CSTRING(enableFire_tooltip); + expression = QUOTE(if (!_value) then {_this setVariable [ARR_3('%s',_value,true)]}); typeName = "BOOL"; condition = "objectVehicle"; - defaultValue = QUOTE((GETMVAR(QGVAR(enable),0)) in [ARR_2(1,2)]); + defaultValue = QUOTE(GETMVAR(QGVAR(enableFire),true)); }; class GVAR(enableAmmoCookoff) { property = QGVAR(enableAmmoCookoff); control = "Checkbox"; displayName = CSTRING(enableAmmoCookoff_name); tooltip = CSTRING(enableAmmoCookoff_tooltip); - expression = QUOTE(if !(_value) then {_this setVariable [ARR_3('%s',_value,true)];};); + expression = QUOTE(if (!_value) then {_this setVariable [ARR_3('%s',_value,true)]}); typeName = "BOOL"; condition = "objectHasInventoryCargo"; - defaultValue = QUOTE(if (_this isKindOf 'ReammoBox_F') then { GETMVAR(QGVAR(enableAmmobox),true) } else { GETMVAR(QGVAR(enableAmmoCookoff),true) };); + defaultValue = QUOTE(if (_this isKindOf 'ReammoBox_F') then {GETMVAR(QGVAR(enableAmmobox),true)} else {GETMVAR(QGVAR(enableAmmoCookoff),true)}); }; }; }; diff --git a/addons/cookoff/CfgEventHandlers.hpp b/addons/cookoff/CfgEventHandlers.hpp index 6c29240403a..f6503c2479b 100644 --- a/addons/cookoff/CfgEventHandlers.hpp +++ b/addons/cookoff/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); diff --git a/addons/cookoff/CfgSFX.hpp b/addons/cookoff/CfgSFX.hpp index 0d670ead863..24329862fc7 100644 --- a/addons/cookoff/CfgSFX.hpp +++ b/addons/cookoff/CfgSFX.hpp @@ -1,4 +1,3 @@ - class CfgSFX { class GVAR(CookOff_low) { name = QGVAR(cookoff_low); diff --git a/addons/cookoff/CfgVehicles.hpp b/addons/cookoff/CfgVehicles.hpp index 78cbd0c6234..4451d120802 100644 --- a/addons/cookoff/CfgVehicles.hpp +++ b/addons/cookoff/CfgVehicles.hpp @@ -1,4 +1,3 @@ - class CfgVehicles { class Sound; class GVAR(Sound_low): Sound { @@ -7,7 +6,6 @@ class CfgVehicles { scope = 1; sound = QGVAR(CookOff_low); }; - class GVAR(Sound_mid): GVAR(Sound_low) { sound = QGVAR(CookOff_mid); }; @@ -17,47 +15,14 @@ class CfgVehicles { class Tank; class Tank_F: Tank { - GVAR(ammoLocation) = "HitHull"; GVAR(cookoffSelections)[] = {"poklop_gunner","poklop_commander"}; - GVAR(probability) = 0.5; - }; - class MBT_02_base_F: Tank_F { - GVAR(ammoLocation) = "HitTurret"; }; class Car_F; class Wheeled_APC_F: Car_F { - GVAR(ammoLocation) = "HitHull"; GVAR(cookoffSelections)[] = {"poklop_gunner","poklop_commander"}; - GVAR(probability) = 0.8; - // big explosions for wheeled APCs (same as for tanks) + // Big explosions for wheeled APCs (same as for tanks) explosionEffect = "FuelExplosionBig"; }; - - - class MRAP_01_base_F: Car_F { - GVAR(engineSmokeOffset)[] = {0,-2,0}; - }; - - class MRAP_02_base_F: Car_F { - GVAR(engineSmokeOffset)[] = {0,-2,0}; - }; - - class MRAP_03_base_F: Car_F { - GVAR(engineSmokeOffset)[] = {0,-2,0}; - }; - - class Quadbike_01_base_F: Car_F { - GVAR(engineSmokeOffset)[] = {0,1,0}; - }; - - class Truck_F; - class Truck_02_base_F: Truck_F { - GVAR(engineSmokeOffset)[] = {0,-2.6,-0.1}; - }; - - class Truck_02_MRL_base_F: Truck_02_base_F { - GVAR(engineSmokeOffset)[] = {0,0.3,-0.1}; - }; }; diff --git a/addons/cookoff/XEH_PREP.hpp b/addons/cookoff/XEH_PREP.hpp index 2cd87efaa7c..94059089535 100644 --- a/addons/cookoff/XEH_PREP.hpp +++ b/addons/cookoff/XEH_PREP.hpp @@ -1,10 +1,12 @@ - -PREP(handleDamageBox); -PREP(engineFire); -PREP(cookOff); -PREP(smoke); -PREP(cookOffEffect); -PREP(cookOffBox); -PREP(detonateAmmunition); +PREP(cookOffBoxLocal); +PREP(cookOffBoxServer); +PREP(cookOffLocal); +PREP(cookOffServer); +PREP(detonateAmmunitionServer); +PREP(detonateAmmunitionServerLoop); +PREP(engineFireLocal); +PREP(engineFireServer); PREP(getVehicleAmmo); +PREP(handleDamageBox); PREP(isMagazineFlare); +PREP(smoke); diff --git a/addons/cookoff/XEH_postInit.sqf b/addons/cookoff/XEH_postInit.sqf index eba4eeced06..63e1486c82b 100644 --- a/addons/cookoff/XEH_postInit.sqf +++ b/addons/cookoff/XEH_postInit.sqf @@ -1,63 +1,64 @@ #include "script_component.hpp" -[QGVAR(engineFire), LINKFUNC(engineFire)] call CBA_fnc_addEventHandler; -[QGVAR(cookOff), { - params ["_vehicle"]; - if (local _vehicle) then { - _this call FUNC(cookOff); - }; -}] call CBA_fnc_addEventHandler; -[QGVAR(cookOffEffect), LINKFUNC(cookOffEffect)] call CBA_fnc_addEventHandler; +[QGVAR(cookOffBoxLocal), LINKFUNC(cookOffBoxLocal)] call CBA_fnc_addEventHandler; +[QGVAR(cookOffLocal), LINKFUNC(cookOffLocal)] call CBA_fnc_addEventHandler; +[QGVAR(engineFireLocal), LINKFUNC(engineFireLocal)] call CBA_fnc_addEventHandler; [QGVAR(smoke), LINKFUNC(smoke)] call CBA_fnc_addEventHandler; -[QGVAR(cookOffBox), LINKFUNC(cookOffBox)] call CBA_fnc_addEventHandler; - -// handle cleaning up effects when vehicle is deleted mid-cookoff -[QGVAR(addCleanupHandlers), { - params ["_vehicle"]; - // Don't add a new EH if cookoff is run multiple times - if ((_vehicle getVariable [QGVAR(deletedEH), -1]) == -1) then { - private _deletedEH = _vehicle addEventHandler ["Deleted", { - params ["_vehicle"]; +if (isServer) then { + [QGVAR(cookOffBoxServer), LINKFUNC(cookOffBoxServer)] call CBA_fnc_addEventHandler; + [QGVAR(cookOffServer), LINKFUNC(cookOffServer)] call CBA_fnc_addEventHandler; + [QGVAR(detonateAmmunitionServer), LINKFUNC(detonateAmmunitionServer)] call CBA_fnc_addEventHandler; + [QGVAR(engineFireServer), LINKFUNC(engineFireServer)] call CBA_fnc_addEventHandler; +}; - [QGVAR(cleanupEffects), [_vehicle]] call CBA_fnc_localEvent; - }]; +// Handle cleaning up effects when objects are deleted mid cook-off +["AllVehicles", "Deleted", { + { + deleteVehicle _x; + } forEach ((_this select 0) getVariable [QGVAR(effects), []]); +}, true, ["CAManBase", "StaticWeapon"], true] call CBA_fnc_addClassEventHandler; - _vehicle setVariable [QGVAR(deletedEH), _deletedEH]; - }; -}] call CBA_fnc_addEventHandler; +["ReammoBox_F", "Deleted", { + { + deleteVehicle _x; + } forEach ((_this select 0) getVariable [QGVAR(effects), []]); +}, true, [], true] call CBA_fnc_addClassEventHandler; +// Raised when the flames have subsided or after the ammo of a box has finished cooking off [QGVAR(cleanupEffects), { - params ["_vehicle", ["_effects", []]]; + params ["_object"]; - _effects = _effects + (_vehicle getVariable [QGVAR(effects), []]); - if (_effects isNotEqualTo []) then { - { deleteVehicle _x } count _effects; - }; + { + deleteVehicle _x; + } forEach (_object getVariable [QGVAR(effects), []]); + + _object setVariable [QGVAR(effects), nil]; }] call CBA_fnc_addEventHandler; +// Ammo box damage handling ["ReammoBox_F", "init", { - (_this select 0) addEventHandler ["HandleDamage", { - if ((_this select 0) getVariable [QGVAR(enableAmmoCookoff), GVAR(enableAmmobox)]) then { - _this call FUNC(handleDamageBox); - }; - }]; -}, nil, nil, true] call CBA_fnc_addClassEventHandler; + // Calling this function inside curly brackets allows the usage of "exitWith", which would be broken with "HandleDamage" otherwise + (_this select 0) addEventHandler ["HandleDamage", {_this call FUNC(handleDamageBox)}]; +}, true, [], true] call CBA_fnc_addClassEventHandler; + +// Vehicle ammo cook-off (secondary explosions) +["AllVehicles", "Killed", { + if (!GVAR(enableAmmoCookoff) || {GVAR(ammoCookoffDuration) == 0}) exitWith {}; -// secondary explosions -["AllVehicles", "killed", { params ["_vehicle", "", "", "_useEffects"]; - if ( - _useEffects && - _vehicle getVariable [QGVAR(enableAmmoCookoff), GVAR(enableAmmoCookoff)] - ) then { - if (GVAR(ammoCookoffDuration) == 0) exitWith {}; - ([_vehicle] call FUNC(getVehicleAmmo)) params ["_mags", "_total"]; - - private _delay = (random MAX_AMMO_DETONATION_START_DELAY) max MIN_AMMO_DETONATION_START_DELAY; - [FUNC(detonateAmmunition), [_vehicle, _mags, _total], _delay] call CBA_fnc_waitAndExecute; + + if (_useEffects && {_vehicle getVariable [QGVAR(enableAmmoCookoff), true]}) then { + // We don't need to pass source and instigator, as vehicle is already dead + [QGVAR(detonateAmmunitionServer), [ + _vehicle, + false, + objNull, + objNull, + random [MIN_AMMO_DETONATION_START_DELAY, (MIN_AMMO_DETONATION_START_DELAY + MAX_AMMO_DETONATION_START_DELAY) / 2, MAX_AMMO_DETONATION_START_DELAY] + ]] call CBA_fnc_serverEvent; }; -}, nil, ["Man","StaticWeapon"]] call CBA_fnc_addClassEventHandler; +}, true, ["CAManBase", "StaticWeapon"], true] call CBA_fnc_addClassEventHandler; if (hasInterface) then { // Plays a sound locally, so that different sounds can be used for various distances @@ -68,7 +69,7 @@ if (hasInterface) then { private _distance = _object distance (positionCameraToWorld [0, 0, 0]); - TRACE_3("",_object,_sound,_maxDistance); + TRACE_2("",_object,_sound); // 3 classes of distances: close, mid and far, each having different sound files private _classDistance = switch (true) do { @@ -94,6 +95,6 @@ if (hasInterface) then { if (!fileExists _sound) exitWith {}; // Obeys speed of sound and takes doppler effects into account - playSound3D [_sound, objNull, insideBuilding _object >= 0.5, getPosASL _object, _volume, _pitch + (random 0.2) - 0.1, _maxDistance, 0, true]; + playSound3D [_sound, objNull, false, getPosASL _object, _volume, _pitch + (random 0.2) - 0.1, _maxDistance, 0, true]; }] call CBA_fnc_addEventHandler; }; diff --git a/addons/cookoff/functions/fnc_cookOff.sqf b/addons/cookoff/functions/fnc_cookOff.sqf deleted file mode 100644 index 57cde71682d..00000000000 --- a/addons/cookoff/functions/fnc_cookOff.sqf +++ /dev/null @@ -1,129 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: tcvm - * Start a cook-off in the given vehicle. - * - * Arguments: - * 0: Vehicle - * 1: Intensity of fire - * - * Return Value: - * None - * - * Example: - * [(vehicle player), 3] call ace_cookoff_fnc_cookOff - * - * Public: No - */ - -params ["_vehicle", "_intensity", ["_instigator", objNull], ["_smokeDelayEnabled", true], ["_ammoDetonationChance", 0], ["_detonateAfterCookoff", false], ["_fireSource", ""], ["_canRing", true], ["_maxIntensity", MAX_COOKOFF_INTENSITY, [0]], ["_canJet", true, [true]]]; - -if (GVAR(enable) == 0) exitWith {}; -if !(GVAR(enableFire)) exitWith {}; -if (_vehicle getVariable [QGVAR(enable), GVAR(enable)] in [0, false]) exitWith {}; -// exit if cook-off enabled only for players and no players in vehicle crew found -if (_vehicle getVariable [QGVAR(enable), GVAR(enable)] isEqualTo 1 && {fullCrew [_vehicle, "", false] findIf {isPlayer (_x select 0)} == -1}) exitWith {}; - - -TRACE_2("cooking off",_vehicle,_intensity); -TRACE_8("",_instigator,_smokeDelayEnabled,_ammoDetonationChance,_detonateAfterCookoff,_fireSource,_canRing,_maxIntensity,_canJet); - -if (_vehicle getVariable [QGVAR(isCookingOff), false]) exitWith {}; -_vehicle setVariable [QGVAR(isCookingOff), true, true]; - -[QGVAR(addCleanupHandlers), [_vehicle]] call CBA_fnc_globalEvent; - -// limit maximum value of intensity to prevent very long cook-off times -_intensity = _intensity min _maxIntensity; - -private _config = configOf _vehicle; -private _positions = getArray (_config >> QGVAR(cookoffSelections)) select {(_vehicle selectionPosition _x) isNotEqualTo [0,0,0]}; - -if (_positions isEqualTo []) then { - WARNING_1("no valid selection for cookoff found. %1",typeOf _vehicle); - { - private _pos = _vehicle selectionPosition _x; - if (_pos isEqualTo [0, 0, 0]) exitWith {}; - _positions pushBack _x; - } forEach DEFAULT_COMMANDER_HATCHES; - - if (_positions isEqualTo []) then { - _positions pushBack "#noselection"; - }; -}; - -private _delay = 0; -if (_smokeDelayEnabled) then { - _delay = SMOKE_TIME + random SMOKE_TIME; -}; -[QGVAR(smoke), [_vehicle, _positions]] call CBA_fnc_globalEvent; - -[{ - params ["_vehicle", "_positions", "_intensity", "_ammoDetonationChance", "_detonateAfterCookoff", "_instigator", "_fireSource", "_canRing", "_canJet"]; - _vehicle setVariable [QGVAR(intensity), _intensity]; - private _smokeEffects = _vehicle getVariable [QGVAR(effects), []]; - - [{ - params ["_args", "_pfh"]; - _args params ["_vehicle", "_positions", "_ammoDetonationChance", "_detonateAfterCookoff", "_instigator", "_fireSource", "_canRing", "_canJet", "_smokeEffects"]; - private _intensity = _vehicle getVariable [QGVAR(intensity), 0]; - if (isNull _vehicle || {_intensity <= 1}) exitWith { - [QGVAR(cleanupEffects), [_vehicle, _smokeEffects]] call CBA_fnc_globalEvent; - _vehicle setVariable [QGVAR(isCookingOff), false, true]; - [_pfh] call CBA_fnc_removePerFrameHandler; - - if (GVAR(destroyVehicleAfterCookoff) || _detonateAfterCookoff) then { - _vehicle setDamage [1, true]; - }; - }; - - private _lastFlameTime = _vehicle getVariable [QGVAR(lastFlame), 0]; - private _nextFlameTime = _vehicle getVariable [QGVAR(nextFlame), 0]; - - // Wait until we are ready for the next flame - // dt = Tcurrent - Tlast - // dt >= Tnext - if ((CBA_missionTime - _lastFlameTime) >= _nextFlameTime) then { - private _ring = (0.2 > random 1); - if (!_ring && _intensity >= 2) then { - _ring = (0.7 > random 1); - }; - - if !(_canRing) then { - _ring = false; - }; - - private _time = linearConversion [0, 10, _intensity, 3, 20] + random COOKOFF_TIME; - - if (_fireSource isEqualTo "") then { - _fireSource = selectRandom _positions; - }; - - [QGVAR(cookOffEffect), [_vehicle, _canJet, _ring, _time, _fireSource, _intensity]] call CBA_fnc_globalEvent; - - _intensity = _intensity - (0.5 max random 1); - _vehicle setVariable [QGVAR(intensity), _intensity]; - _vehicle setVariable [QGVAR(lastFlame), CBA_missionTime]; - _vehicle setVariable [QGVAR(nextFlame), _time + (MIN_TIME_BETWEEN_FLAMES max random MAX_TIME_BETWEEN_FLAMES)]; - - { - [QEGVAR(fire,burn), [_x, _intensity * 1.5, _instigator]] call CBA_fnc_globalEvent; - } forEach crew _vehicle - }; - - if (_ammoDetonationChance > random 1) then { - private _lastExplosiveDetonationTime = _vehicle getVariable [QGVAR(lastExplosiveDetonation), 0]; - private _nextExplosiveDetonation = _vehicle getVariable [QGVAR(nextExplosiveDetonation), 0]; - - if ((CBA_missionTime - _lastExplosiveDetonationTime) > _nextExplosiveDetonation) then { - if (_fireSource isEqualTo "") then { - _fireSource = selectRandom _positions; - }; - createVehicle ["ACE_ammoExplosionLarge", (_vehicle modelToWorld (_vehicle selectionPosition _fireSource)), [], 0 , "CAN_COLLIDE"]; - - _vehicle setVariable [QGVAR(lastExplosiveDetonation), CBA_missionTime]; - _vehicle setVariable [QGVAR(nextExplosiveDetonation), random 60]; - }; - }; - }, 0.25, [_vehicle, _positions, _ammoDetonationChance, _detonateAfterCookoff, _instigator, _fireSource, _canRing, _canJet, _smokeEffects]] call CBA_fnc_addPerFrameHandler -}, [_vehicle, _positions, _intensity, _ammoDetonationChance, _detonateAfterCookoff, _instigator, _fireSource, _canRing, _canJet], _delay] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_cookOffBox.sqf b/addons/cookoff/functions/fnc_cookOffBox.sqf deleted file mode 100644 index 8b8e60891cf..00000000000 --- a/addons/cookoff/functions/fnc_cookOffBox.sqf +++ /dev/null @@ -1,74 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: KoffeinFlummi, commy2, kymckay - * Start a cook-off in the given ammo box. - * - * Arguments: - * 0: Ammo box - * - * Return Value: - * None - * - * Example: - * [_box] call ace_cookoff_fnc_cookOffBox - * - * Public: No - */ - -params ["_box"]; - -if (_box getVariable [QGVAR(isCookingOff), false]) exitWith {}; -_box setVariable [QGVAR(isCookingOff), true]; - -if (local _box) then { - [QGVAR(cookOffBox), _box] call CBA_fnc_globalEvent; -}; - -[{ - params ["_box"]; - - // Box will start smoking - private _smoke = "#particlesource" createVehicleLocal [0,0,0]; - _smoke setParticleClass "AmmoSmokeParticles2"; - _smoke attachTo [_box, [0,0,0]]; - - private _effects = [_smoke]; - - if (isServer) then { - private _sound = createSoundSource ["Sound_Fire", position _box, [], 0]; - _effects pushBack _sound; - }; - - [{ - params ["_box", "_effects"]; - - // These functions are smart and do all the cooking off work - if (local _box) then { - if (GVAR(ammoCookoffDuration) == 0) exitWith {}; - ([_box] call FUNC(getVehicleAmmo)) params ["_mags", "_total"]; - [_box, _mags, _total] call FUNC(detonateAmmunition); - - // This shit is busy being on fire, magazines aren't accessible/usable - clearMagazineCargoGlobal _box; - }; - - // Light the fire (also handles lighting) - private _fire = "#particlesource" createVehicleLocal [0,0,0]; - _fire setParticleClass "AmmoBulletCore"; - _fire attachTo [_box, [0,0,0]]; - - _effects pushBack _fire; - - [{ - params ["_box", "_effects"]; - - { - deleteVehicle _x; - } forEach _effects; - - if (local _box) then { - _box setDamage 1; - }; - }, [_box, _effects], COOKOFF_TIME_BOX] call CBA_fnc_waitAndExecute; // TODO: Change so that box is alive until no ammo left, with locality in mind - }, [_box, _effects], SMOKE_TIME] call CBA_fnc_waitAndExecute; -}, _box, IGNITE_TIME] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_cookOffBoxLocal.sqf b/addons/cookoff/functions/fnc_cookOffBoxLocal.sqf new file mode 100644 index 00000000000..8285104daf8 --- /dev/null +++ b/addons/cookoff/functions/fnc_cookOffBoxLocal.sqf @@ -0,0 +1,52 @@ +#include "..\script_component.hpp" +/* + * Author: KoffeinFlummi, commy2, kymckay, johnb43 + * Spawns local cook-off effects for ammo boxes. + * + * Arguments: + * 0: Box + * 1: Source + * 2: Instigator + * 3: Start time of the cook-off + * + * Return Value: + * None + * + * Example: + * [cursorObject, player, player, CBA_missionTime + 10] call ace_cookoff_fnc_cookOffBoxLocal + * + * Public: No + */ + +params ["", "", "", "_startTime"]; + +[{ + params ["_box", "_source", "_instigator"]; + + // If box was deleted before smoke could be spawned, just exit + if (isNull _box) exitWith {}; + + private _boxPos = ASLToAGL getPosASL _box; + private _effects = []; + + // Box will start smoking + if (hasInterface) then { + private _smoke = createVehicleLocal ["#particlesource", _boxPos, [], 0, "CAN_COLLIDE"]; + _smoke setParticleClass "AmmoSmokeParticles2"; + _smoke attachTo [_box]; + + _effects pushBack _smoke; + }; + + if (isServer) then { + private _sound = createSoundSource ["Sound_Fire", _boxPos, [], 0]; + _sound attachTo [_box]; + + _effects pushBack _sound; + + // Detonate the ammunition + [QGVAR(detonateAmmunitionServer), [_box, true, _source, _instigator, random [DETONATION_DELAY / 2, DETONATION_DELAY, DETONATION_DELAY / 2 * 3]]] call CBA_fnc_localEvent; + }; + + _box setVariable [QGVAR(effects), _effects]; +}, _this, (_startTime - CBA_missionTime) max 0] call CBA_fnc_waitAndExecute; // This delay allows for synchronisation for JIP players diff --git a/addons/cookoff/functions/fnc_cookOffBoxServer.sqf b/addons/cookoff/functions/fnc_cookOffBoxServer.sqf new file mode 100644 index 00000000000..10d57876a72 --- /dev/null +++ b/addons/cookoff/functions/fnc_cookOffBoxServer.sqf @@ -0,0 +1,50 @@ +#include "..\script_component.hpp" +/* + * Author: KoffeinFlummi, commy2, kymckay, johnb43 + * Start an ammo cook-off in the given ammo box. + * + * Arguments: + * 0: Ammo box + * 1: Source (default: objNull) + * 2: Instigator (default: objNull) + * + * Return Value: + * None + * + * Example: + * cursorObject call ace_cookoff_fnc_cookOffBoxServer + * + * Public: No + */ + +if (!isServer) exitWith {}; +if (!GVAR(enableAmmobox) || {GVAR(ammoCookoffDuration) == 0}) exitWith {}; + +params ["_box", ["_source", objNull], ["_instigator", objNull]]; + +// Make sure it's a box (important, because deleted EH is assigned to ReammoBox_F only in postInit) +if !(_box isKindOf "ReammoBox_F") exitWith {}; + +if !(_box getVariable [QGVAR(enableAmmoCookoff), true]) exitWith {}; + +// Allow only 1 cook-off per box at a time +if (_box getVariable [QGVAR(isCookingOff), false]) exitWith {}; + +_box setVariable [QGVAR(isCookingOff), true, true]; + +private _delay = random [SMOKE_DELAY / 2, SMOKE_DELAY, SMOKE_DELAY / 2 * 3]; + +// Spawn cook-off effects on all connected machines and JIP +private _jipID = [QGVAR(cookOffBoxLocal), [ + _box, + _source, + _instigator, + CBA_missionTime + _delay // Generate a globally synced timestamp +]] call CBA_fnc_globalEventJIP; + +[_jipID, _box] call CBA_fnc_removeGlobalEventJIP; + +_box setVariable [QGVAR(cookoffBoxJipID), _jipID]; + +// API +[QGVAR(cookOffBox), [_box, _source, _instigator, _delay]] call CBA_fnc_globalEvent; diff --git a/addons/cookoff/functions/fnc_cookOffEffect.sqf b/addons/cookoff/functions/fnc_cookOffEffect.sqf deleted file mode 100644 index 44282f2f6b8..00000000000 --- a/addons/cookoff/functions/fnc_cookOffEffect.sqf +++ /dev/null @@ -1,200 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: tcvm - * Spawn cook-off effects - * - * Arguments: - * 0: Vehicle - * 1: Spawn fire jet - * 2: Spawn fire ring - * 3: How long effect will last (Max 20 seconds) - * 4: What selection will fire originate from - * 5: Cookoff intensity value - * - * Return Value: - * None - * - * Example: - * [vehicle player, true, false, 15, "commander_turret"] call ace_cookoff_fnc_cookOffEffect - * - * Public: No - */ - -params ["_obj", "_jet", "_ring", "_time", "_fireSelection", "_intensity"]; -private _light = "#lightpoint" createVehicleLocal [0,0,0]; -_light setLightBrightness 5; -_light setLightAmbient [0.8, 0.6, 0.2]; -_light setLightColor [1, 0.5, 0.2]; -_light lightAttachObject [_obj, [0,0,0]]; -_time = 0 max (_time min 20); - -private _sound = objNull; -if (isServer) then { - // ironically biggest performance hit is this. Creating a new sound source takes up aprox 400 milliseconds. - // I dont think there is an alternative that takes into effect distance and whatever, but if you find one please fix! - if (_jet || _ring) then { - private _soundName = selectRandomWeighted [QGVAR(Sound_low), 0.1, QGVAR(Sound_mid), 0.25, QGVAR(Sound_high), 0.65]; - _sound = createSoundSource [_soundName, position _obj, [], 0]; - }; - - if (_ring) then { - private _intensity = 6; - private _radius = 1.5 * ((boundingBoxReal _obj) select 2); - [QEGVAR(fire,addFireSource), [_obj, _radius, _intensity, format [QGVAR(%1), hashValue _obj]]] call CBA_fnc_localEvent; - }; -}; - -[{ - params ["_args", "_pfh"]; - _args params ["_obj", "_jet", "_ring", "_time", "_startTime", "_light", "_fireSelection", "_sound", "_intensity"]; - private _elapsedTime = CBA_missionTime - _startTime; - if (_elapsedTime >= _time) exitWith { - deleteVehicle _light; - deleteVehicle _sound; - if (isServer) then { - [QEGVAR(fire,removeFireSource), [format [QGVAR(%1), hashValue _obj]]] call CBA_fnc_localEvent; - }; - [_pfh] call CBA_fnc_removePerFrameHandler; - }; - private _factor = (1 + (_elapsedTime / 2) min 2); - private _flameSize = 1.5; - - if (_elapsedTime > (_time * (3 / 4))) then { - _factor = _factor * linearConversion [_time * (3 / 4), _time, _elapsedTime, 1, 0.5]; - }; - - _light setLightBrightness 5 * (_factor / 5); - - if (_jet) then { - private _particlePosition = (_obj selectionPosition _fireSelection) vectorAdd [-0.1 + random 0.2, -0.1 + random 0.2, 0]; - - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", - "Billboard", - 1, - (0.1 + (random 0.2)) * _factor, - _particlePosition, - [0, 0, 15 * (_factor / 2)], - 0, - 10, - 7.9, - 0.075, - [1.25 * _factor, 2.5 * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], - 1, - 0, - "", - "", - _obj - ]; - - // make flame push object into ground to make effect seem more "alive" - if (!isGamePaused && { local _obj }) then { - private _force = [0, 0, _factor * -(0.5 min random 1.5) * (0.3 min random 1)] vectorMultiply getMass _obj; - _obj addForce [_force, vectorUpVisual _obj]; - }; - }; - - if (_ring) then { - private _ringOrigin = (_obj selectionPosition _fireSelection) vectorAdd [-0.1 + random 0.2, -0.1 + random 0.2, -1]; - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal",16,2,32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [0, 20 * (_factor / 2), 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [0, -20 * (_factor / 2), 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [20 * (_factor / 2), 0, 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - [-0.1 + random 0.2, -0.1 + random 0.2, -1], - [-20 * (_factor / 2), 0, 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - - private _dir = 20 * (_factor / 2); - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [_dir, _dir, 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2],[1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - - _dir = -20 * (_factor / 2); - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [_dir, _dir, 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2],[1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - - _dir = 20 * (_factor / 2); - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal",16,2,32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [_dir, -_dir, 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - - _dir = 20 * (_factor / 2); - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [-_dir, _dir, 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - }; - - (getVehicleTIPars _obj) params ["_tiEngine", "_tiWheels", "_tiWeapon"]; - _obj setVehicleTIPars [ - // formula is designed to have the temperature ramp up quickly and then level out - (_tiEngine + (_intensity * 0.01))/1.005, - (_tiWheels + (_intensity * 0.004))/1.002, // wheels//tracks are further away from burning parts - (_tiWeapon + (_intensity * 0.01))/1.005 - ]; - -}, 0, [_obj, _jet, _ring, _time, CBA_missionTime, _light, _fireSelection, _sound, _intensity]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/cookoff/functions/fnc_cookOffLocal.sqf b/addons/cookoff/functions/fnc_cookOffLocal.sqf new file mode 100644 index 00000000000..cbd160bba1d --- /dev/null +++ b/addons/cookoff/functions/fnc_cookOffLocal.sqf @@ -0,0 +1,229 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm, johnb43 + * Spawn cook-off fire effects. + * + * Arguments: + * 0: Vehicle + * 1: Spawn fire jet + * 2: Spawn fire ring + * 3: What selection fire will originate from + * 4: Cookoff intensity value + * 5: Start time + * 6: Duration of effect (max 20 seconds) + * + * Return Value: + * None + * + * Example: + * [cursorObject, true, false, "commander_turret", 6, CBA_missionTime, 15] call ace_cookoff_fnc_cookOffLocal + * + * Public: No + */ + +#define FLAME_SIZE 1.5 +#define FIRE_INTENSITY 20 + +params ["_vehicle", "_jet", "_ring", "_fireSelection", "_intensity", "_startTime", "_duration"]; + +// Check if still valid for JIP players +if (isNull _vehicle || {CBA_missionTime - _startTime >= _duration}) exitWith {}; + +// Spawn light +private _light = objNull; + +if (hasInterface) then { + _light = "#lightpoint" createVehicleLocal [0, 0, 0]; + _light setLightBrightness 5; + _light setLightAmbient [0.8, 0.6, 0.2]; + _light setLightColor [1, 0.5, 0.2]; + _light lightAttachObject [_vehicle, [0, 0, 0]]; +}; + +_duration = 0 max _duration min 20; + +private _sound = objNull; +private _fireKey = ""; + +if (isServer) then { + // Spawn sound effect + if (_jet || _ring) then { + private _soundName = selectRandomWeighted [QGVAR(Sound_low), 0.1, QGVAR(Sound_mid), 0.25, QGVAR(Sound_high), 0.65]; + _sound = createSoundSource [_soundName, ASLToAGL getPosASL _vehicle, [], 0]; + _sound attachTo [_vehicle]; + }; + + // Make the ring a source of fire + if (_ring && {["ace_fire"] call EFUNC(common,isModLoaded)}) then { + _fireKey = format [QGVAR(cookoffFire_%1), hashValue _vehicle]; + + [QEGVAR(fire,addFireSource), [_vehicle, FLAME_SIZE * ((boundingBoxReal _vehicle) select 2), FIRE_INTENSITY, _fireKey]] call CBA_fnc_localEvent; + }; +}; + +[{ + (_this select 0) params ["_vehicle", "_jet", "_ring", "_startTime", "_duration", "_light", "_fireSelection", "_sound", "_intensity", "_fireKey"]; + + private _elapsedTime = CBA_missionTime - _startTime; + + // Clean up effects once effects have finished or vehicle has been deleted + if (isNull _vehicle || {_elapsedTime >= _duration}) exitWith { + (_this select 1) call CBA_fnc_removePerFrameHandler; + + deleteVehicle _light; + + if (isServer) then { + deleteVehicle _sound; + + if (["ace_fire"] call EFUNC(common,isModLoaded)) then { + [QEGVAR(fire,removeFireSource), _fireKey] call CBA_fnc_localEvent; + }; + }; + }; + + private _factor = 1 + (_elapsedTime / 2) min 2; + + if (_elapsedTime > _duration * 3 / 4) then { + _factor = _factor * linearConversion [_duration * 3 / 4, _duration, _elapsedTime, 1, 0.5]; + }; + + // Make flame push object into ground to make effect seem more "alive" + if (_jet && !isGamePaused && {local _vehicle} && {_vehicle getVariable [QGVAR(nextForceTime), 0] <= CBA_missionTime}) then { + private _force = [0, 0, _factor * -(0.5 min random 1.5) * (0.3 min random 1)] vectorMultiply getMass _vehicle; + _vehicle addForce [_force, vectorUpVisual _vehicle]; + _vehicle setVariable [QGVAR(nextForceTime), CBA_missionTime + 0.01]; // This prevents bad behaviour when setAccTime is small + }; + + // Don't spawn visual effects on machines without interfaces + if (!hasInterface) exitWith {}; + + _light setLightBrightness _factor; + + if (_jet) then { + private _particlePosition = (_vehicle selectionPosition _fireSelection) vectorAdd [-0.1 + random 0.2, -0.1 + random 0.2, 0]; + + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", + "Billboard", + 1, + (0.1 + random 0.2) * _factor, + _particlePosition, + [0, 0, 15 * (_factor / 2)], + 0, + 10, + 7.9, + 0.075, + [1.25 * _factor, 2.5 * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], + 1, + 0, + "", + "", + _vehicle + ]; + }; + + if (_ring) then { + private _ringOrigin = (_vehicle selectionPosition _fireSelection) vectorAdd [-0.1 + random 0.2, -0.1 + random 0.2, -1]; + + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal",16,2,32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + _ringOrigin, + [0, 20 * (_factor / 2), 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + _ringOrigin, + [0, -20 * (_factor / 2), 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + _ringOrigin, + [20 * (_factor / 2), 0, 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + [-0.1 + random 0.2, -0.1 + random 0.2, -1], + [-20 * (_factor / 2), 0, 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + + private _dir = 20 * (_factor / 2); + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + _ringOrigin, + [_dir, _dir, 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2],[1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + + _dir = -20 * (_factor / 2); + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, + _ringOrigin, + [_dir, _dir, 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2],[1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + + _dir = 20 * (_factor / 2); + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal",16,2,32], + "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, + _ringOrigin, + [_dir, -_dir, 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + + _dir = 20 * (_factor / 2); + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + _ringOrigin, + [-_dir, _dir, 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + }; + + (getVehicleTIPars _vehicle) params ["_tiEngine", "_tiWheels", "_tiWeapon"]; + + // Formula is designed to have the temperature ramp up quickly and then level out + _vehicle setVehicleTIPars [ + (_tiEngine + _intensity * 0.01) / 1.005, + (_tiWheels + _intensity * 0.004) / 1.002, // Wheels/tracks are further away from burning parts + (_tiWeapon + _intensity * 0.01) / 1.005 + ]; +}, 0, [_vehicle, _jet, _ring, _startTime, _duration, _light, _fireSelection, _sound, _intensity, _fireKey]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/cookoff/functions/fnc_cookOffServer.sqf b/addons/cookoff/functions/fnc_cookOffServer.sqf new file mode 100644 index 00000000000..303555ba28b --- /dev/null +++ b/addons/cookoff/functions/fnc_cookOffServer.sqf @@ -0,0 +1,202 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm, johnb43 + * Start a cook-off in the given vehicle. + * Spews flames in multiple directions at the same time (ring) or from the turret towards the sky (jet). + * + * Arguments: + * 0: Vehicle + * 1: Intensity of fire + * 2: Source (default: objNull) + * 3: Instigator (default: objNull) + * 4: Delay between smoke and fire enabled (default: true) + * 5: Ammo detonation chance (default: 0) + * 6: Detonate after cook-off (default: false) + * 7: Selection for fire source (default: "") + * 8: Can spawn fire ring (default: true) + * 9: Can spawn fire jet (default: true) + * 10: Maximum intensity (default: MAX_COOKOFF_INTENSITY) + * + * Return Value: + * None + * + * Example: + * [cursorObject, 3] call ace_cookoff_fnc_cookOffServer + * + * Public: No + */ + +if (!isServer) exitWith {}; +if (!GVAR(enableFire) || {GVAR(cookoffDuration) == 0}) exitWith {}; + +params [ + "_vehicle", + "_intensity", + ["_source", objNull], + ["_instigator", objNull], + ["_delayBetweenSmokeAndFire", true], + ["_ammoDetonationChance", 0], + ["_detonateAfterCookoff", false], + ["_fireSelection", ""], + ["_canRing", true], + ["_canJet", true], + ["_maxIntensity", MAX_COOKOFF_INTENSITY] +]; + +// Make sure it's a vehicle (important, because deleted EH is assigned to AllVehicles only in postInit) +if !(_vehicle isKindOf "AllVehicles") exitWith {}; + +if (_vehicle isKindOf "CAManBase" || {_vehicle isKindOf "StaticWeapon"}) exitWith {}; + +// If under water, ignore +// underwater is not very reliable, so use model center instead +if (underwater _vehicle || {private _posASL = getPosWorld _vehicle; surfaceIsWater _posASL && {(_posASL select 2) < 0}}) exitWith {}; + +// Check if cook-off is disabled on vehicle specifically +if !(_vehicle getVariable [QGVAR(enable), true]) exitWith {}; // QGVAR(enable) is API + +TRACE_3("cooking off",_vehicle,_intensity,_maxIntensity); +TRACE_8("",_source,_instigator,_delayBetweenSmokeAndFire,_ammoDetonationChance,_detonateAfterCookoff,_fireSelection,_canRing,_canJet); + +if (_vehicle getVariable [QGVAR(isCookingOff), false]) exitWith {}; + +_vehicle setVariable [QGVAR(isCookingOff), true, true]; + +// Limit maximum value of intensity to prevent very long cook-off times +_intensity = _intensity min _maxIntensity; + +private _selections = getArray (configOf _vehicle >> QGVAR(cookoffSelections)) select {(_vehicle selectionPosition _x) isNotEqualTo [0, 0, 0]}; + +if (_selections isEqualTo []) then { + WARNING_1("no valid selection for cookoff found. %1",typeOf _vehicle); + + { + if ((_vehicle selectionPosition _x) isNotEqualTo [0, 0, 0]) then { + _selections pushBack _x; + }; + } forEach DEFAULT_COMMANDER_HATCHES; + + if (_selections isEqualTo []) then { + _selections pushBack "#noselection"; + }; +}; + +// Not guaranteed to be active/used, but reserve it nonetheless +private _fireJipID = format [QGVAR(cookOffLocal_%1), hashValue _vehicle]; +[_fireJipID, _vehicle] call CBA_fnc_removeGlobalEventJIP; + +// Spawn smoke +private _smokeJipID = [QGVAR(smoke), [_vehicle, _selections]] call CBA_fnc_globalEventJIP; +[_smokeJipID, _vehicle] call CBA_fnc_removeGlobalEventJIP; + +// Save intensity for looping purposes +_vehicle setVariable [QGVAR(intensity), _intensity]; + +private _delay = 0; + +if (_delayBetweenSmokeAndFire) then { + _delay = random [SMOKE_DELAY, 1.5 * SMOKE_DELAY, 2 * SMOKE_DELAY]; +}; + +[{ + [{ + (_this select 0) params ["_vehicle", "_selections", "_ammoDetonationChance", "_detonateAfterCookoff", "_source", "_instigator", "_fireSelection", "_canRing", "_canJet", "_smokeJipID", "_fireJipID"]; + + if ( + isNull _vehicle || + !GVAR(enableFire) || + {!(_vehicle getVariable [QGVAR(enable), true])} || // QGVAR(enable) is API + {GVAR(cookoffDuration) == 0} || + {underwater _vehicle} || + {private _posASL = getPosWorld _vehicle; surfaceIsWater _posASL && {(_posASL select 2) < 0}} // Underwater is not very reliable, so use model center instead + ) exitWith { + // Effects are deleted when vehicle is deleted + (_this select 1) call CBA_fnc_removePerFrameHandler; + }; + + private _intensity = _vehicle getVariable [QGVAR(intensity), 0]; + + if (_intensity <= 1) exitWith { + (_this select 1) call CBA_fnc_removePerFrameHandler; + + // Wait until the previous flame has finished + private _nextFlameTime = (_vehicle getVariable [QGVAR(endCurrentFlame), CBA_missionTime]) - CBA_missionTime + (MIN_TIME_BETWEEN_FLAMES max random MAX_TIME_BETWEEN_FLAMES); + + if (_fireSelection isEqualTo "") then { + _fireSelection = selectRandom _selections; + }; + + [{ + params ["_vehicle", "_source", "_instigator", "_detonateAfterCookoff", "_fireSelection", "_smokeJipID", "_fireJipID"]; + + // Effects are deleted when vehicle is deleted + if (isNull _vehicle) exitWith {}; + + // Remove effects from JIP + _smokeJipID call CBA_fnc_removeGlobalEventJIP; + _fireJipID call CBA_fnc_removeGlobalEventJIP; + + // Remove effects + [QGVAR(cleanupEffects), _vehicle] call CBA_fnc_globalEvent; + + // Reset variable, so it can cook-off again + _vehicle setVariable [QGVAR(isCookingOff), nil, true]; + + if (GVAR(destroyVehicleAfterCookoff) || _detonateAfterCookoff) then { + createVehicle ["ACE_ammoExplosionLarge", _vehicle modelToWorld (_vehicle selectionPosition _fireSelection), [], 0 , "CAN_COLLIDE"]; + + _vehicle setDamage [1, true, _source, _instigator]; // Because it's running on the server, source and instigator can be set + }; + }, [_vehicle, _source, _instigator, _detonateAfterCookoff, _fireSelection, _smokeJipID, _fireJipID], _nextFlameTime] call CBA_fnc_waitAndExecute; + }; + + // Wait until we are ready for the next flame + if ((_vehicle getVariable [QGVAR(nextFlame), 0]) <= CBA_missionTime) then { + private _ring = false; + + if (_canRing) then { + _ring = 0.2 > random 1; + + if (!_ring && {_intensity >= 2}) then { + _ring = 0.7 > random 1; + }; + }; + + private _duration = linearConversion [0, 10, _intensity, 3, 20] + random COOKOFF_TIME; + + if (_fireSelection isEqualTo "") then { + _fireSelection = selectRandom _selections; + }; + + // Sync for JIP players + [QGVAR(cookOffLocal), [_vehicle, _canJet, _ring, _fireSelection, _intensity, CBA_missionTime, _duration], _fireJipID] call CBA_fnc_globalEventJIP; + + // If there are any crew, burn them + if (["ace_fire"] call EFUNC(common,isModLoaded)) then { + // Use current intensity, in case GVAR(cookoffDuration) is very large and only 1 flameout stage happens + { + [QEGVAR(fire,burn), [_x, _intensity * 1.5, _instigator]] call CBA_fnc_globalEvent; + } forEach (crew _vehicle); + }; + + _intensity = (_intensity - (0.5 max random 1) / GVAR(cookoffDuration)) max 0; + + _vehicle setVariable [QGVAR(intensity), _intensity]; + _vehicle setVariable [QGVAR(endCurrentFlame), CBA_missionTime + _duration]; + _vehicle setVariable [QGVAR(nextFlame), CBA_missionTime + _duration + (MIN_TIME_BETWEEN_FLAMES max random MAX_TIME_BETWEEN_FLAMES)]; + }; + + if (_ammoDetonationChance > random 1 && {_vehicle getVariable [QGVAR(nextExplosiveDetonation), 0] <= CBA_missionTime}) then { + if (_fireSelection isEqualTo "") then { + _fireSelection = selectRandom _selections; + }; + + createVehicle ["ACE_ammoExplosionLarge", _vehicle modelToWorld (_vehicle selectionPosition _fireSelection), [], 0 , "CAN_COLLIDE"]; + + _vehicle setVariable [QGVAR(nextExplosiveDetonation), CBA_missionTime + random 60]; + }; + }, 0.25, _this] call CBA_fnc_addPerFrameHandler; +}, [_vehicle, _selections, _ammoDetonationChance, _detonateAfterCookoff, _source, _instigator, _fireSelection, _canRing, _canJet, _smokeJipID, _fireJipID], _delay] call CBA_fnc_waitAndExecute; + +// API +[QGVAR(cookoff), [_vehicle, _intensity, _instigator, _smokeDelayEnabled, _ammoDetonationChance, _detonateAfterCookoff, _fireSelection, _canRing, _maxIntensity, _canJet]] call CBA_fnc_globalEvent; diff --git a/addons/cookoff/functions/fnc_detonateAmmunition.sqf b/addons/cookoff/functions/fnc_detonateAmmunition.sqf deleted file mode 100644 index 9b3c19ab42d..00000000000 --- a/addons/cookoff/functions/fnc_detonateAmmunition.sqf +++ /dev/null @@ -1,132 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: Glowbal - * Detonates ammunition from a vehicle until no ammo left - * - * Arguments: - * 0: vehicle - * 1: Ammo Array - * - 0: Magazine Classname - * - 1: Ammo Count - * 2: Total Ammo Count - * - * Return Value: - * None - * - * Example: - * [_vehicle, magazinesAmmo _vehicle] call ace_cookoff_fnc_detonateAmmunition - * - * Public: No - */ - -params ["_vehicle", "_magazines", "_totalAmmo"]; - -if (GVAR(enable) == 0) exitWith {}; -if !(GVAR(enableAmmoCookoff)) exitWith {}; - -if (isNull _vehicle) exitWith {}; // vehicle got deleted -if (_magazines isEqualTo []) exitWith {}; // nothing to detonate anymore -if (underwater _vehicle) exitWith {}; - -private _magazineIndex = floor random(count _magazines); -private _magazine = _magazines select _magazineIndex; -_magazine params ["_magazineClassname", "_amountOfMagazines"]; - -if (_amountOfMagazines < 0) exitWith { - ERROR_1("mag with no ammo - %1",_magazine); -}; -private _removed = _amountOfMagazines min floor(1 + random(6 / GVAR(ammoCookoffDuration))); - -_amountOfMagazines = _amountOfMagazines - _removed; -if (_amountOfMagazines <= 0) then { - _magazines deleteAt _magazineIndex; -} else { - _magazine set [1, _amountOfMagazines]; // clear out the magazine -}; -private _timeBetweenAmmoDetonation = (((random 10) / (sqrt _totalAmmo)) min MAX_TIME_BETWEEN_AMMO_DET) max 0.1; -TRACE_2("",_totalAmmo,_timeBetweenAmmoDetonation); -_totalAmmo = _totalAmmo - _removed; - -private _ammo = getText (configFile >> "CfgMagazines" >> _magazineClassname >> "ammo"); -private _ammoCfg = configFile >> "CfgAmmo" >> _ammo; - -private _speedOfAmmo = getNumber (configFile >> "CfgMagazines" >> _magazineClassname >> "initSpeed"); -private _simType = getText (_ammoCfg >> "simulation"); - -private _effect2pos = _vehicle selectionPosition "destructionEffect2"; - -private _spawnProjectile = { - params ["_vehicle", "_ammo", "_speed", "_flyAway"]; - - private _spawnPos = _vehicle modelToWorld [-0.2 + (random 0.4), -0.2 + (random 0.4), random 3]; - if (_spawnPos select 2 < 0) then { - _spawnPos set [2, 0]; - }; - - private _projectile = createVehicle [_ammo, _spawnPos, [], 0, "CAN_COLLIDE"]; - if (_flyAway) then { - private _vectorAmmo = [(-1 + (random 2)), (-1 + (random 2)), -0.2 + (random 1)]; - private _velVec = _vectorAmmo vectorMultiply _speed; - _projectile setVectorDir _velVec; - _projectile setVelocity _velVec; - } else { - _projectile setDamage 1; - }; - - _projectile; -}; - -private _speed = random (_speedOfAmmo / 10) max 1; -_simType = toLowerANSI _simType; -switch (_simType) do { - case ("shotbullet"): { - [QGVAR(playCookoffSound), [_vehicle, _simType]] call CBA_fnc_globalEvent; - if (random 1 < 0.6) then { - [_vehicle, _ammo, _speed, true] call _spawnProjectile; - }; - }; - case ("shotshell"): { - [QGVAR(playCookoffSound), [_vehicle, _simType]] call CBA_fnc_globalEvent; - if (random 1 < 0.15) then { - [_vehicle, _ammo, _speed, true] call _spawnProjectile; - }; - }; - case ("shotgrenade"): { - if (random 1 < 0.9) then { - _speed = 0; - }; - [_vehicle, _ammo, _speed, random 1 < 0.5] call _spawnProjectile; - }; - case ("shotrocket"); - case ("shotmissile"); - case ("shotsubmunitions"): { - if (random 1 < 0.1) then { - [QGVAR(playCookoffSound), [_vehicle, _simType]] call CBA_fnc_globalEvent; - [_vehicle, _ammo, _speed, random 1 < 0.3] call _spawnProjectile; - } else { - createvehicle ["ACE_ammoExplosionLarge", (_vehicle modelToWorld _effect2pos), [], 0 , "CAN_COLLIDE"]; - }; - }; - case ("shotmine"); - case ("shotdirectionalbomb"): { - if (random 1 < 0.5) then { - // Not all explosives detonate on destruction, some have scripted alternatives - private _scripted = getNumber (_ammoCfg >> "triggerWhenDestroyed") == 1; - if !(_scripted) then { - _ammo = getText (_ammoCfg >> "ace_explosives_Explosive"); - }; - // If a scripted alternative doesn't exist use generic explosion - if (_ammo != "") then { - [_vehicle, _ammo, 0, false] call _spawnProjectile; - } else { - createvehicle ["SmallSecondary", (_vehicle modelToWorld _effect2pos), [], 0 , "CAN_COLLIDE"]; - }; - }; - }; - case ("shotilluminating"): { - if (random 1 < 0.15) then { - [_vehicle, _ammo, _speed, random 1 < 0.3] call _spawnProjectile; - }; - }; -}; -[FUNC(detonateAmmunition), [_vehicle, _magazines, _totalAmmo], _timeBetweenAmmoDetonation] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_detonateAmmunitionServer.sqf b/addons/cookoff/functions/fnc_detonateAmmunitionServer.sqf new file mode 100644 index 00000000000..43ac730e09d --- /dev/null +++ b/addons/cookoff/functions/fnc_detonateAmmunitionServer.sqf @@ -0,0 +1,54 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Starts detonating ammunition from an object (e.g. vehicle or crate). + * + * Arguments: + * 0: Object + * 1: Destroy when finished (default: false) + * 2: Source (default: objNull) + * 3: Instigator (default: objNull) + * 4: Initial delay (default: 0) + * + * Return Value: + * None + * + * Example: + * [cursorObject] call ace_cookoff_fnc_detonateAmmunitionServer + * + * Public: No + */ + +if (!isServer) exitWith {}; + +params ["_object", ["_destroyWhenFinished", false], ["_source", objNull], ["_instigator", objNull], ["_initialDelay", 0]]; + +if (isNull _object) exitWith {}; + +// Check if the object can cook its ammo off +if ( + underwater _object || + {private _posASL = getPosWorld _object; surfaceIsWater _posASL && {(_posASL select 2) < 0}} || // Underwater is not very reliable, so use model center instead + {GVAR(ammoCookoffDuration) == 0} || + {!([GVAR(enableAmmoCookoff), GVAR(enableAmmobox)] select (_object isKindOf "ReammoBox_F"))} || + {!(_object getVariable [QGVAR(enableAmmoCookoff), true])} +) exitWith {}; + +// Don't have an object detonate its ammo twice +if (_object getVariable [QGVAR(isAmmoDetonating), false]) exitWith {}; + +_object setVariable [QGVAR(isAmmoDetonating), true, true]; + +_object setVariable [QGVAR(cookoffMagazines), _object call FUNC(getVehicleAmmo)]; + +// TODO: When setMagazineTurretAmmo and magazineTurretAmmo are fixed (https://feedback.bistudio.com/T79689), +// we can add gradual ammo removal during cook-off +if (GVAR(removeAmmoDuringCookoff)) then { + clearMagazineCargoGlobal _object; + + { + [QEGVAR(common,removeMagazinesTurret), [_object, _x select 0, _x select 1], _object, _x select 1] call CBA_fnc_turretEvent; + } forEach (magazinesAllTurrets _object); +}; + +[LINKFUNC(detonateAmmunitionServerLoop), [_object, _destroyWhenFinished, _source, _instigator], _initialDelay] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_detonateAmmunitionServerLoop.sqf b/addons/cookoff/functions/fnc_detonateAmmunitionServerLoop.sqf new file mode 100644 index 00000000000..7fdcedda51d --- /dev/null +++ b/addons/cookoff/functions/fnc_detonateAmmunitionServerLoop.sqf @@ -0,0 +1,181 @@ +#include "..\script_component.hpp" +/* + * Author: Glowbal, johnb43 + * Detonates ammunition from an object (e.g. vehicle or crate) until no ammo is left. + * + * Arguments: + * 0: Object + * 1: Destroy when finished + * 2: Source + * 3: Instigator + * + * Return Value: + * None + * + * Example: + * [cursorObject, true, player, player] call ace_cookoff_fnc_detonateAmmunitionServerLoop + * + * Public: No + */ + +params ["_object", "_destroyWhenFinished", "_source", "_instigator"]; + +if (isNull _object) exitWith {}; + +(_object getVariable QGVAR(cookoffMagazines)) params ["_magazines", "_totalAmmo"]; + +private _hasFinished = _totalAmmo <= 0 || {_magazines isEqualTo []}; + +// If the cook-off has finished or been interrupted, clean up the effects for boxes (no vehicle effects) +if ( + _hasFinished || + {underwater _object} || + {private _posASL = getPosWorld _object; surfaceIsWater _posASL && {(_posASL select 2) < 0}} || // Underwater is not very reliable, so use model center instead + {GVAR(ammoCookoffDuration) == 0} || + {!([GVAR(enableAmmoCookoff), GVAR(enableAmmobox)] select (_object isKindOf "ReammoBox_F"))} || + {!(_object getVariable [QGVAR(enableAmmoCookoff), true])} +) exitWith { + // Box cook-off fire ends after the ammo has detonated (vehicle cook-off fire does not depend on the ammo detonation) + if (_object isKindOf "ReammoBox_F") then { + [QGVAR(cleanupEffects), _object] call CBA_fnc_globalEvent; + + // Reset variable, so the box can cook-off again + _object setVariable [QGVAR(isCookingOff), nil, true]; + + // Remove cook-off effects from box + private _jipID = _object getVariable QGVAR(cookoffBoxJipID); + + if (isNil "_jipID") exitWith {}; + + _jipID call CBA_fnc_removeGlobalEventJIP; + + _object setVariable [QGVAR(cookoffBoxJipID), nil]; + }; + + // Reset variables, so the object can detonate its ammo again + _object setVariable [QGVAR(cookoffMagazines), nil]; + _object setVariable [QGVAR(isAmmoDetonating), nil, true]; + + // If done, destroy the object if necessary + if (_hasFinished && _destroyWhenFinished) then { + _object setDamage [1, true, _source, _instigator]; + }; +}; + +private _magazineIndex = floor random (count _magazines); +private _magazine = _magazines select _magazineIndex; +_magazine params ["_magazineClassname", "_ammoCount", "_spawnProjectile"]; + +// Make sure ammo is at least 0 +_ammoCount = _ammoCount max 0; + +// Remove some ammo, which will be detonated +private _removed = _ammoCount min floor (1 + random (6 / GVAR(ammoCookoffDuration))); + +_ammoCount = _ammoCount - _removed; + +if (_ammoCount <= 0) then { + _magazines deleteAt _magazineIndex; +} else { + _magazine set [1, _ammoCount]; // remove ammo that was detonated +}; + +private _timeBetweenAmmoDetonation = ((random 10 / sqrt _totalAmmo) min MAX_TIME_BETWEEN_AMMO_DET) max 0.1; +TRACE_2("",_totalAmmo,_timeBetweenAmmoDetonation); +_totalAmmo = _totalAmmo - _removed; + +_object setVariable [QGVAR(cookoffMagazines), [_magazines, _totalAmmo]]; + +// Get magazine info, which is used to spawn projectiles +private _configMagazine = configFile >> "CfgMagazines" >> _magazineClassname; +private _ammo = getText (_configMagazine >> "ammo"); +private _configAmmo = configFile >> "CfgAmmo" >> _ammo; + +private _simType = toLower getText (_configAmmo >> "simulation"); +private _speed = linearConversion [0, 1, random 1, 1, 20, true]; +private _effect2pos = _object selectionPosition "destructionEffect2"; + +// Spawns the projectiles, making them either fly in random directions or explode +private _fnc_spawnProjectile = { + // If the magazines are inside of the cargo (inventory), don't let their projectiles escape the interior of the vehicle + if (!_spawnProjectile) exitWith {}; + + params ["_object", "_ammo", "_speed", "_flyAway"]; + + private _spawnPos = _object modelToWorld [-0.2 + random 0.4, -0.2 + random 0.4, random 3]; + + if (_spawnPos select 2 < 0) then { + _spawnPos set [2, 0]; + }; + + private _projectile = createVehicle [_ammo, _spawnPos, [], 0, "CAN_COLLIDE"]; + + if (_flyAway) then { + private _vectorAmmo = [-1 + random 2, -1 + random 2, -0.2 + random 1]; + private _vectorVelocity = _vectorAmmo vectorMultiply _speed; + + _projectile setVectorDir _vectorVelocity; + _projectile setVelocity _vectorVelocity; + } else { + _projectile setDamage 1; + }; +}; + +switch (_simType) do { + case "shotbullet": { + [QGVAR(playCookoffSound), [_object, _simType]] call CBA_fnc_globalEvent; + + if (random 1 < 0.6) then { + [_object, _ammo, _speed, true] call _fnc_spawnProjectile; + }; + }; + case "shotshell": { + [QGVAR(playCookoffSound), [_object, _simType]] call CBA_fnc_globalEvent; + + if (random 1 < 0.15) then { + [_object, _ammo, _speed, true] call _fnc_spawnProjectile; + }; + }; + case "shotgrenade": { + if (random 1 < 0.9) then { + _speed = 0; + }; + + [_object, _ammo, _speed, random 1 < 0.5] call _fnc_spawnProjectile; + }; + case "shotrocket"; + case "shotmissile"; + case "shotsubmunitions": { + if (random 1 < 0.1) then { + [QGVAR(playCookoffSound), [_object, _simType]] call CBA_fnc_globalEvent; + + [_object, _ammo, _speed, random 1 < 0.3] call _fnc_spawnProjectile; + } else { + createVehicle ["ACE_ammoExplosionLarge", _object modelToWorld _effect2pos, [], 0 , "CAN_COLLIDE"]; + }; + }; + case "shotdirectionalbomb"; + case "shotmine": { + if (random 1 < 0.5) then { + // Not all explosives detonate on destruction, some have scripted alternatives + if (getNumber (_configAmmo >> "triggerWhenDestroyed") != 1) then { + _ammo = getText (_configAmmo >> QEGVAR(explosives,explosive)); + }; + + // If a scripted alternative doesn't exist use generic explosion + if (_ammo != "") then { + [_object, _ammo, 0, false] call _fnc_spawnProjectile; + } else { + createVehicle ["SmallSecondary", _object modelToWorld _effect2pos, [], 0 , "CAN_COLLIDE"]; + }; + }; + }; + case "shotilluminating": { + if (random 1 < 0.15) then { + [_object, _ammo, _speed, random 1 < 0.3] call _fnc_spawnProjectile; + }; + }; +}; + +// Detonate the remaining ammo after a delay +[LINKFUNC(detonateAmmunitionServerLoop), [_object, _destroyWhenFinished, _source, _instigator], _timeBetweenAmmoDetonation] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_engineFire.sqf b/addons/cookoff/functions/fnc_engineFire.sqf deleted file mode 100644 index 118537b30a3..00000000000 --- a/addons/cookoff/functions/fnc_engineFire.sqf +++ /dev/null @@ -1,51 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: KoffeinFlummi, commy2 - * Start fire in engine block of a car. - * - * Arguments: - * 0: Vehicle - * - * Return Value: - * None - * - * Example: - * (vehicle player) call ace_cookoff_fnc_engineFire - * - * Public: No - */ - -params ["_vehicle"]; - -if (_vehicle getVariable [QGVAR(isEngineSmoking), false]) exitWith {}; -_vehicle setVariable [QGVAR(isEngineSmoking), true]; - -if (local _vehicle) then { - [QGVAR(engineFire), _vehicle] call CBA_fnc_globalEvent; -}; - -private _offset = getArray (_vehicle call CBA_fnc_getObjectConfig >> QGVAR(engineSmokeOffset)); - -if (_offset isEqualTo []) then { - _offset = [0,0,0]; -}; - -private _position = [ - 0, - (boundingBoxReal _vehicle select 1 select 1) - 2, - (boundingBoxReal _vehicle select 0 select 2) + 2 -] vectorAdd _offset; - -private _smoke = "#particlesource" createVehicleLocal [0,0,0]; -_smoke setParticleClass "ObjectDestructionSmoke1_2Smallx"; -_smoke attachTo [_vehicle, _position]; - -[{ - (_this select 0) params ["_vehicle", "_smoke", "_time"]; - - if (isNull _vehicle || {!alive _vehicle} || {_vehicle getHitPointDamage "HitEngine" < 0.9} || {CBA_missionTime > _time}) then { - deleteVehicle _smoke; - _vehicle setVariable [QGVAR(isEngineSmoking), false]; - [_this select 1] call CBA_fnc_removePerFrameHandler; - }; -}, 5, [_vehicle, _smoke, CBA_missionTime + 240]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/cookoff/functions/fnc_engineFireLocal.sqf b/addons/cookoff/functions/fnc_engineFireLocal.sqf new file mode 100644 index 00000000000..afd6827d6b1 --- /dev/null +++ b/addons/cookoff/functions/fnc_engineFireLocal.sqf @@ -0,0 +1,81 @@ +#include "..\script_component.hpp" +/* + * Author: KoffeinFlummi, commy2, johnb43 + * Start fire in engine block of a car. + * + * Arguments: + * 0: Vehicle + * 1: End time + * + * Return Value: + * None + * + * Example: + * [cursorObject, CBA_missionTime + 10] call ace_cookoff_fnc_engineFireLocal + * + * Public: No + */ + +params ["_vehicle", "_endTime"]; + +// For JIP players and if the time wasn't set properly +if (_endTime < CBA_missionTime) exitWith {}; + +private _smoke = objNull; + +if (hasInterface) then { + private _hitPoints = getAllHitPointsDamage _vehicle; + + // Get hitpoint for engine + private _index = (_hitPoints select 0) findIf {_x == "hitengine"}; + + // Get corresponding selection + private _position = if (_index != -1) then { + _vehicle selectionPosition [(_hitPoints select 1) select _index, "HitPoints", "AveragePoint"] + } else { + [0, 0, 0] + }; + + if (_position isEqualTo [0, 0, 0]) then { + // Get offset for engine smoke if there is one + private _offset = getArray (configOf _vehicle >> QGVAR(engineSmokeOffset)); + + if (_offset isEqualTo []) then { + _offset = [0, 0, 0]; + }; + + _position = [ + 0, + (boundingBoxReal _vehicle select 1 select 1) - 2, + (boundingBoxReal _vehicle select 0 select 2) + 2 + ] vectorAdd _offset; + }; + + // Spawn smoke + _smoke = createVehicleLocal ["#particlesource", ASLToAGL getPosASL _vehicle, [], 0, "CAN_COLLIDE"];; + _smoke setParticleClass "ObjectDestructionSmoke1_2Smallx"; + _smoke attachTo [_vehicle, _position]; +}; + +[{ + (_this select 0) params ["_vehicle", "_smoke", "_endTime"]; + + if (alive _vehicle && {_vehicle getHitPointDamage "HitEngine" >= 0.9} && {CBA_missionTime < _endTime}) exitWith {}; + + (_this select 1) call CBA_fnc_removePerFrameHandler; + + deleteVehicle _smoke; + + if (!isServer || {isNull _vehicle}) exitWith {}; + + // Reset variable, so engine can smoke again in the future + _vehicle setVariable [QGVAR(isEngineSmoking), nil, true]; + + private _jipID = _vehicle getVariable QGVAR(engineFireJipID); + + if (isNil "_jipID") exitWith {}; + + _jipID call CBA_fnc_removeGlobalEventJIP; + + _vehicle setVariable [QGVAR(engineFireJipID), nil]; +}, 5, [_vehicle, _smoke, _endTime]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/cookoff/functions/fnc_engineFireServer.sqf b/addons/cookoff/functions/fnc_engineFireServer.sqf new file mode 100644 index 00000000000..0d435029b8c --- /dev/null +++ b/addons/cookoff/functions/fnc_engineFireServer.sqf @@ -0,0 +1,34 @@ +#include "..\script_component.hpp" +/* + * Author: KoffeinFlummi, commy2, johnb43 + * Start fire in engine block of a car. + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * None + * + * Example: + * cursorObject call ace_cookoff_fnc_engineFireServer + * + * Public: No + */ + +if (!isServer) exitWith {}; + +params ["_vehicle"]; + +// If already smoking, stop +if (_vehicle getVariable [QGVAR(isEngineSmoking), false]) exitWith {}; + +_vehicle setVariable [QGVAR(isEngineSmoking), true, true]; + +// Spawn engine fire effects on all connected machines +private _jipID = [QGVAR(engineFireLocal), [_vehicle, CBA_missionTime + random [ENGINE_FIRE_TIME / 2, ENGINE_FIRE_TIME, ENGINE_FIRE_TIME / 2 * 3]]] call CBA_fnc_globalEventJIP; +[_jipID, _vehicle] call CBA_fnc_removeGlobalEventJIP; + +_vehicle setVariable [QGVAR(engineFireJipID), _jipID]; + +// API +[QGVAR(engineFire), [_vehicle]] call CBA_fnc_globalEvent; diff --git a/addons/cookoff/functions/fnc_getVehicleAmmo.sqf b/addons/cookoff/functions/fnc_getVehicleAmmo.sqf index f6be84c1f90..df4385d30da 100644 --- a/addons/cookoff/functions/fnc_getVehicleAmmo.sqf +++ b/addons/cookoff/functions/fnc_getVehicleAmmo.sqf @@ -1,65 +1,76 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Gets all magazines inside of a vehicle. + * Gets all magazines inside of an object. * * Arguments: - * 0: Vehicle + * 0: Object * * Return Value: - * 0: Ammo Array - * - 0: Magazine Classname - * - 1: Ammo Count - * 1: Total Ammo Count + * 0: Ammo array + * - 0: Magazine classname + * - 1: Ammo count + * - 2: If a projectile should be spawned upon detonation + * 1: Total ammo count * * Example: - * [vehicle player] call ace_cookoff_fnc_getVehicleAmmo + * cursorObject call ace_cookoff_fnc_getVehicleAmmo * * Public: No */ -params ["_vehicle"]; -TRACE_1("getVehicleAmmo",_vehicle); +params ["_object"]; +TRACE_1("getVehicleAmmo",_object); private _ammoToDetonate = []; private _totalAmmo = 0; +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgAmmo = configFile >> "CfgAmmo"; +private _ammo = ""; // Get ammo from turrets { - _x params ["_mag", "_turret", "_count"]; - // if the turret is an FFV seat, it takes magazines from the soldier - if (_count > 0) then { - if (_mag call FUNC(isMagazineFlare)) then {continue}; - private _ammo = getText (configFile >> "CfgMagazines" >> _mag >> "ammo"); - private _model = getText (configFile >> "CfgAmmo" >> _ammo >> "model"); - if (_model == "\A3\weapons_f\empty") exitWith {TRACE_3("skipping",_mag,_ammo,_model);}; - _ammoToDetonate pushBack [_mag, _count]; + // If the turret is an FFV seat, it takes magazines from the soldier + _x params ["_magazine", "", "_count"]; + + if (_count > 0 && {!(_magazine call FUNC(isMagazineFlare))}) then { + _ammo = getText (_cfgMagazines >> _magazine >> "ammo"); + + if (getText (_cfgAmmo >> _ammo >> "model") == "\A3\weapons_f\empty") then { + TRACE_2("skipping",_magazine,_ammo); + + continue; + }; + + _ammoToDetonate pushBack [_magazine, _count, true]; _totalAmmo = _totalAmmo + _count; }; -} forEach (magazinesAllTurrets [_vehicle, true]); +} forEach (magazinesAllTurrets [_object, true]); // Get ammo from cargo space { - _x params ["_mag", "_count"]; - if (_count > 0) then { - if (_mag call FUNC(isMagazineFlare)) then {continue}; - _ammoToDetonate pushBack [_mag, _count]; + _x params ["_magazine", "_count"]; + + if (_count > 0 && {!(_magazine call FUNC(isMagazineFlare))}) then { + _ammoToDetonate pushBack [_magazine, _count, false]; _totalAmmo = _totalAmmo + _count; }; -} forEach (magazinesAmmoCargo _vehicle); +} forEach (magazinesAmmoCargo _object); // Get ammo from transportAmmo / ace_rearm -private _vehCfg = configOf _vehicle; +private _configVehicle = configOf _object; +private _configSupply = (getNumber (_configVehicle >> "transportAmmo")) max (getNumber (_configVehicle >> QEGVAR(rearm,defaultSupply))); -private _configSupply = (getNumber (_vehCfg >> "transportAmmo")) max (getNumber (_vehCfg >> QEGVAR(rearm,defaultSupply))); -if (_vehicle getVariable [QEGVAR(rearm,isSupplyVehicle), (_configSupply > 0)]) then { - TRACE_1("transportAmmo vehicle - adding virtual ammo",typeOf _vehicle); +if (_object getVariable [QEGVAR(rearm,isSupplyVehicle), _configSupply > 0]) then { + TRACE_1("transportAmmo vehicle - adding virtual ammo",typeOf _object); - _ammoToDetonate pushBack ["2000Rnd_65x39_belt", 2000]; + _ammoToDetonate pushBack ["2000Rnd_65x39_belt", 2000, false]; _totalAmmo = _totalAmmo + 2000; - _ammoToDetonate pushBack ["20Rnd_105mm_HEAT_MP", 100]; + + _ammoToDetonate pushBack ["20Rnd_105mm_HEAT_MP", 100, true]; _totalAmmo = _totalAmmo + 100; - _ammoToDetonate pushBack ["SatchelCharge_Remote_Mag", 10]; + + _ammoToDetonate pushBack ["SatchelCharge_Remote_Mag", 10, true]; _totalAmmo = _totalAmmo + 10; }; diff --git a/addons/cookoff/functions/fnc_handleDamageBox.sqf b/addons/cookoff/functions/fnc_handleDamageBox.sqf index 9368cd3193d..2d55db0fd02 100644 --- a/addons/cookoff/functions/fnc_handleDamageBox.sqf +++ b/addons/cookoff/functions/fnc_handleDamageBox.sqf @@ -1,13 +1,13 @@ #include "..\script_component.hpp" /* - * Author: KoffeinFlummi, commy2 - * Handles all incoming damage for boxi + * Author: KoffeinFlummi, commy2, johnb43 + * Handles all incoming damage for boxes. * * Arguments: * HandleDamage EH * * Return Value: - * Damage to be inflicted. + * Damage to be inflicted (can be nil) * * Example: * _this call ace_cookoff_fnc_handleDamageBox @@ -15,58 +15,48 @@ * Public: No */ -params ["_vehicle", "", "_damage", "_source", "_ammo", "_hitIndex", "_shooter"]; +// If cookoff for boxes is disabled, exit +if (!GVAR(enableAmmobox) || {GVAR(ammoCookoffDuration) == 0}) exitWith {}; -// it's already dead, who cares? -if (damage _vehicle >= 1) exitWith {}; +params ["_box", "", "_damage", "_source", "_ammo", "", "_instigator", "_hitPoint"]; -// If cookoff is disabled exit -if (_vehicle getVariable [QGVAR(enable), GVAR(enable)] in [0, false]) exitWith {}; +if (!local _box) exitWith {}; -// get hitpoint name -private _hitpoint = "#structural"; +// If it's already dead, ignore +if (!alive _box) exitWith {}; -if (_hitIndex != -1) then { - _hitpoint = toLowerANSI ((getAllHitPointsDamage _vehicle param [0, []]) select _hitIndex); -}; +if !(_box getVariable [QGVAR(enableAmmoCookoff), true]) exitWith {}; + +if !(_hitPoint == "" && {_damage > 0.5}) exitWith {}; // "" means structural damage -// get change in damage -private _oldDamage = 0; +private _ammoConfig = _ammo call CBA_fnc_getObjectConfig; -if (_hitpoint isEqualTo "#structural") then { - _oldDamage = damage _vehicle; +// Catch fire when hit by an explosive or incendiary round +if ((getNumber (_ammoConfig >> "explosive") >= 0.5) || {getNumber (_ammoConfig >> QEGVAR(vehicle_damage,incendiary)) > random 1}) then { + [QGVAR(cookOffBoxServer), [_box, _source, _instigator]] call CBA_fnc_serverEvent; } else { - _oldDamage = _vehicle getHitIndex _hitIndex; -}; + // There is a small chance of cooking a box off if it's shot by tracer ammo + if (random 1 >= _damage * 0.05) exitWith {}; -if (_hitpoint == "#structural" && _damage > 0.5) then { - // Almost always catch fire when hit by an explosive - if (IS_EXPLOSIVE_AMMO(_ammo)) then { - _vehicle call FUNC(cookOffBox); + // Need magazine to check for tracers + private _magazine = if (_source == _instigator) then { + currentMagazine _source } else { - // Need magazine to check for tracers - private _mag = ""; - if (_source == _shooter) then { - _mag = currentMagazine _source; - } else { - _mag = _source currentMagazineTurret ([_shooter] call CBA_fnc_turretPath); - }; - private _magCfg = configFile >> "CfgMagazines" >> _mag; + _source currentMagazineTurret (_source unitTurret _instigator) + }; - // Magazine could have changed during flight time (just ignore if so) - if (getText (_magCfg >> "ammo") == _ammo) then { - // If magazine's tracer density is high enough then low chance for cook off - private _tracers = getNumber (_magCfg >> "tracersEvery"); - if (_tracers >= 1 && {_tracers <= 4}) then { - if (random 1 < _oldDamage*0.05) then { - _vehicle call FUNC(cookOffBox); - }; - }; + private _configMagazine = configFile >> "CfgMagazines" >> _magazine; + + // Magazine could have changed during flight time (just ignore if so) + if (getText (_configMagazine >> "ammo") == _ammo) then { + // If magazine's tracer density is high enough then low chance for cook off + private _tracers = getNumber (_configMagazine >> "tracersEvery"); + + if (_tracers >= 1 && {_tracers <= 4}) then { + [QGVAR(cookOffBoxServer), [_box, _source, _instigator]] call CBA_fnc_serverEvent; }; }; - - // prevent destruction, let cook-off handle it if necessary - _damage min 0.89 -} else { - _damage }; + +// Prevent destruction, let cook-off handle it if necessary +_damage min 0.89 diff --git a/addons/cookoff/functions/fnc_isMagazineFlare.sqf b/addons/cookoff/functions/fnc_isMagazineFlare.sqf index b6c8a604be3..f856b21a9a4 100644 --- a/addons/cookoff/functions/fnc_isMagazineFlare.sqf +++ b/addons/cookoff/functions/fnc_isMagazineFlare.sqf @@ -1,24 +1,22 @@ #include "..\script_component.hpp" /* * Author: Cyruz - * Checks if the magazine has ammo which is a flare + * Checks if the magazine's ammo are flares. * * Arguments: * 0: Magazine * * Return Value: - * 0: If magazine is type of flare + * If magazine is type of flare * * Example: - * ["3Rnd_UGL_FlareWhite_F"] call ace_cookoff_fnc_isMagazineFlare + * "3Rnd_UGL_FlareWhite_F" call ace_cookoff_fnc_isMagazineFlare * * Public: No */ params ["_magazine"]; -private _ammo = getText (configFile >> "CfgMagazines" >> _magazine >> "ammo"); -private _intensity = getNumber (configFile >> "CfgAmmo" >> _ammo >> "intensity"); -private _flare = getNumber (configFile >> "CfgAmmo" >> _ammo >> QEGVAR(grenades,flare)); +private _configAmmo = configFile >> "CfgAmmo" >> getText (configFile >> "CfgMagazines" >> _magazine >> "ammo"); -_intensity != 0 || _flare == 1 +getNumber (_configAmmo >> "intensity") != 0 || {getNumber (_configAmmo >> QEGVAR(grenades,flare)) == 1} diff --git a/addons/cookoff/functions/fnc_smoke.sqf b/addons/cookoff/functions/fnc_smoke.sqf index ce50043413f..94055041de7 100644 --- a/addons/cookoff/functions/fnc_smoke.sqf +++ b/addons/cookoff/functions/fnc_smoke.sqf @@ -5,7 +5,7 @@ * * Arguments: * 0: Vehicle - * 1. Selections for smoke to come out of (default: []) + * 1: Selections for smoke to come out of * * Return Value: * None @@ -16,12 +16,11 @@ * Public: No */ -params ["_vehicle", ["_positions", []]]; +params ["_vehicle", "_selections"]; -private _turretConfig = [_vehicle, [0]] call CBA_fnc_getTurret; -private _positionBarrelEnd = getText (_turretConfig >> "gunBeg"); +private _positionBarrelEnd = getText ([_vehicle, [0]] call CBA_fnc_getTurret >> "gunBeg"); -// smoke out of cannon and hatches +// Smoke out of cannon and hatches private _smokeBarrel = "#particlesource" createVehicleLocal [0, 0, 0]; _smokeBarrel setParticleClass "MediumDestructionSmoke"; _smokeBarrel attachTo [_vehicle, [0, 0, 0], _positionBarrelEnd]; @@ -29,10 +28,10 @@ _smokeBarrel attachTo [_vehicle, [0, 0, 0], _positionBarrelEnd]; private _effects = [_smokeBarrel]; { - private _position = [0, -2, 0]; - - if (_x isNotEqualTo "#noselection") then { - _position = _vehicle selectionPosition _x; + private _position = if (_x != "#noselection") then { + _vehicle selectionPosition _x + } else { + [0, -2, 0] }; private _smoke = "#particlesource" createVehicleLocal [0, 0, 0]; @@ -40,6 +39,6 @@ private _effects = [_smokeBarrel]; _smoke attachTo [_vehicle, _position]; _effects pushBack _smoke; -} forEach _positions; +} forEach _selections; _vehicle setVariable [QGVAR(effects), _effects]; diff --git a/addons/cookoff/initSettings.inc.sqf b/addons/cookoff/initSettings.inc.sqf index 8912636fd6a..c7f1be8ffde 100644 --- a/addons/cookoff/initSettings.inc.sqf +++ b/addons/cookoff/initSettings.inc.sqf @@ -1,69 +1,71 @@ [ - QGVAR(enable), "LIST", - [LSTRING(enable_hd_name), LSTRING(enable_hd_tooltip)], + QGVAR(enableFire), + "CHECKBOX", + [LSTRING(enableFire_name), LSTRING(enableFire_tooltip)], LSTRING(category_displayName), - [[0, 1, 2], ["STR_A3_OPTIONS_DISABLED", ELSTRING(common,playerOnly), ELSTRING(common,playersAndAI)], 2], - true, // isGlobal - {[QGVAR(enable), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + true, + 1 ] call CBA_fnc_addSetting; [ - QGVAR(enableFire), "CHECKBOX", - [LSTRING(enableFire_name), LSTRING(enableFire_tooltip)], + QGVAR(cookoffDuration), + "SLIDER", + [LSTRING(cookoffDuration_name), LSTRING(cookoffDuration_tooltip)], + LSTRING(category_displayName), + [0, 10, 1, 2], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(probabilityCoef), + "SLIDER", + [LSTRING(probabilityCoef_name), LSTRING(probabilityCoef_tooltip)], LSTRING(category_displayName), - true, // default value - true, // isGlobal - {[QGVAR(enableFire), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart + [0, 10, 1, 2], + 1 ] call CBA_fnc_addSetting; [ - QGVAR(destroyVehicleAfterCookoff), "CHECKBOX", + QGVAR(destroyVehicleAfterCookoff), + "CHECKBOX", [LSTRING(destroyVehicleAfterCookoff_name), LSTRING(destroyVehicleAfterCookoff_tooltip)], LSTRING(category_displayName), - false, // default value - true, // isGlobal - {[QGVAR(destroyVehicleAfterCookoff), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart + false, + 1 ] call CBA_fnc_addSetting; [ - QGVAR(enableAmmoCookoff), "CHECKBOX", + QGVAR(enableAmmoCookoff), + "CHECKBOX", [LSTRING(enableAmmoCookoff_name), LSTRING(enableAmmoCookoff_tooltip)], LSTRING(category_displayName), - true, // default value - true, // isGlobal - {[QGVAR(enableAmmoCookoff), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart + true, + 1 ] call CBA_fnc_addSetting; [ - QGVAR(enableAmmobox), "CHECKBOX", + QGVAR(enableAmmobox), + "CHECKBOX", [LSTRING(enableBoxCookoff_name), LSTRING(enableBoxCookoff_tooltip)], LSTRING(category_displayName), - true, // default value - true, // isGlobal - {[QGVAR(enableAmmobox), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + true, + 1 ] call CBA_fnc_addSetting; [ - QGVAR(ammoCookoffDuration), "SLIDER", + QGVAR(ammoCookoffDuration), + "SLIDER", [LSTRING(ammoCookoffDuration_name), LSTRING(ammoCookoffDuration_tooltip)], LSTRING(category_displayName), - [0,5,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(ammoCookoffDuration), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + [0, 10, 1, 2], + 1 ] call CBA_fnc_addSetting; [ - QGVAR(probabilityCoef), "SLIDER", - [LSTRING(probabilityCoef_name), LSTRING(probabilityCoef_tooltip)], + QGVAR(removeAmmoDuringCookoff), + "CHECKBOX", + [LSTRING(removeAmmoDuringCookoff_name), LSTRING(removeAmmoDuringCookoff_tooltip)], LSTRING(category_displayName), - [0,5,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(probabilityCoef), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + true, + 1 ] call CBA_fnc_addSetting; diff --git a/addons/cookoff/script_component.hpp b/addons/cookoff/script_component.hpp index d41b8f675c3..bf8fd62dd5c 100644 --- a/addons/cookoff/script_component.hpp +++ b/addons/cookoff/script_component.hpp @@ -16,14 +16,12 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define IS_EXPLOSIVE_AMMO(ammo) (getNumber (ammo call CBA_fnc_getObjectConfig >> "explosive") > 0.5) - // Stages of cookoff in order (in seconds) -// Should be no un-synced randomness in these as the effects must be ran on each client -#define IGNITE_TIME 3 -#define SMOKE_TIME 10.5 +// Should be no un-synced randomness in these as the effects must be run on each client +#define SMOKE_DELAY 10.5 +#define DETONATION_DELAY 3 #define COOKOFF_TIME 14 // Cook off time should be 20s at most due to length of sound files -#define COOKOFF_TIME_BOX 82.5 // Cook off time for boxes should be significant to allow time for ammo to burn +#define ENGINE_FIRE_TIME 240 #define MIN_TIME_BETWEEN_FLAMES 5 #define MAX_TIME_BETWEEN_FLAMES 15 #define MAX_TIME_BETWEEN_AMMO_DET 25 @@ -32,9 +30,6 @@ #define MIN_AMMO_DETONATION_START_DELAY 1 // Min time to wait before a vehicle's ammo starts to cookoff #define MAX_AMMO_DETONATION_START_DELAY 6 // Max time to wait before a vehicle's ammo starts to cookoff -// Delay between flame effect for players in a cooking off vehicle -#define FLAME_EFFECT_DELAY 0.4 - // Common commander hatch defines for default vehicles #define DEFAULT_COMMANDER_HATCHES ["osa_poklop_commander", "hatch_commander_axis"] diff --git a/addons/cookoff/stringtable.xml b/addons/cookoff/stringtable.xml index 5f764a24b76..205b8d2b4df 100644 --- a/addons/cookoff/stringtable.xml +++ b/addons/cookoff/stringtable.xml @@ -2,7 +2,7 @@ - ACE Cook off + ACE Cook-off ACE Detonación inducida por calor ACE Detonazione Munizioni ACE 殉爆效果 @@ -16,158 +16,38 @@ ACE Cook off ACE Vznícení munice - - Damage handling and turret effects - Daño y efectos de torreta - Schadensberechnung und Geschützturmeffekte - 損傷処理と砲塔の効果 - Обработка урона и эффектов срыва башни - Manipulação de dano e efeitos de torre - Dégâts et effets de tourelle - 傷害控制及炮塔效果 - 损坏处理和炮塔效果 - Gestione danni ed effetti torretta - Poškodit ovládání a efekty věže - Obsługa obrażeń i efekty wieży - 피해량 조절 및 포탑에 효과 부여 - - - Changes damage handling for cook off and turret explosion effects - Cambia el daño de la detonación inducida por calor y los efectos de la explosión de la torreta - Ändert die Schadensberechnung für die Durchzündung und die Explosionseffekte des Geschützturmes - 誘爆の損傷処理と砲塔の爆発効果を変更します。 - Изменяет обработку урона для возгорания и эффекта срыва башни - Modifica a manipulação de dano para o cozinhamento de munição e efeitos de explosão da torre - Modifie la gestion des dégâts pour l'auto-inflammation et les effets d'explosion de tourelle. - 更改殉爆以及炮塔爆炸之傷害控制 - 改变殉爆和炮塔爆炸的损坏处理效果 - Modifica la gestione dei danni per l'esplosione di munizioni e gli effetti di esplosione della torretta - Změní poškození ovládání a efekty výbuchu veže - Zmienia obsługę obrażeń podczas samozapłonu i eksplozji wieży - 쿡오프로 인해 피해량의 변화와 포탑 터짐현상을 결정합니다. - - - Enable ammo box cook off - Habilitar detonación inducida por calor en las cajas de munición - 弾薬箱の誘爆を有効化 - Durchzündung für Munitionskisten ermöglichen - 탄약 상자 쿡오프 현상 활성화 - Aktywuj samozapłon skrzyń z amunicją - Auto-inflammation des caisses de munitions - Abilita esplosione casse munizioni - 開啟彈藥箱殉爆效果 - 开启弹药箱殉爆效果 - Разрешить детонацию ящиков с боеприпасами - Permitir cozinhar caixas de munição - Povolit vynícení munice v krabicích - - - Enables cooking off of ammo boxes. - Habilita la detonación inducida por calor en las cajas de munición - 弾薬箱が誘爆するようになります。 - Ermöglicht Durchzündung von Munitionskisten. - 탄약 상자에 쿡오프 현상을 적용합니다. - Aktywuje samozapłon skrzyń z amunicją - Permet l'auto-inflammation des caisses de munitions. - Abilita l'esplosione di casse di munizioni distrutte. - 開啟彈藥箱殉爆效果 - 开启弹药箱殉爆效果 - Активирует детонацию ящиков с боеприпасами - Permitir que caixas de munição cozinhem. - Zapíná vznícení munice v krabicích. - - - Enable Ammunition cook off - Habilitar la detonación inducida por calor en la munición - 弾薬の誘爆を有効化 - Durchzündung für Munition ermöglichen - 탄약 쿡오프 현상 활성화 - Aktywuj samozapłon amunicji - Auto-inflammation des munitions - Abilita Esplosione Munizioni - 開啟彈藥殉爆效果 - 开启弹药殉爆效果 - Разрешить детонацию боекомплекта - Permitir cozinhar munição - Povolit vznícení munice + + Enable vehicle cook-off fire + 車両の誘爆火災を有効化 + Вкл. возгорание техники - - Enables Ammunition cook off. Fires ammunition projectiles while vehicle is on fire and has ammunition. - Habilita la detonación inducida por calor en la munición. Dispara proyectiles de munición mientras el vehículo está ardiendo y tiene munición - 弾薬が誘爆します。車両が燃えると、搭載している弾薬が激しく燃え上がります。 - Ermöglicht Durchzündung von Munition. Feuert Projektile der Munition ab, solange das Fahrzeug brennt und Munition besitzt. - Aktywuje samozapłon amunicji. Wystrzeliwuje pociski podczas gdy pojazd płonie i posiada amunicję. - Permet l'auto-inflammation des munitions. Tire des projectiles tant que le véhicule est en feu et contient des munitions. - Abilita l'esplosione di munizioni. Spara proiettili di munizioni quando il veicolo va a fuoco e contiene ancora munizioni. - 開啟彈藥殉爆效果。當一台載有彈藥的載具起火時, 將會有殉爆的效果 - 开启弹药殉爆效果。当一台载有弹药的载具起火时,将会有殉爆的效果。 - 쿡오프 현상을 활성화 합니다. 이것은 탄약에 불이 붙어 있는 동안 주변에 발사체를 발사합니다. - Активирует детонацию боекомплекта в горящей технике. - Permite que a munição cozinhe. Dispara projéteis de munição enquanto o veículo está em chamas e tem munição. - Zapíná vznícení munice. Vystřeluje projektily po dobu kdy vozidlo hoří a má munici. + + Enables vehicle cook-off fire effects.\nThis doesn't include ammunition detonations. + 車両の誘爆火災エフェクトを有効化します。\nこれには弾薬の爆発は含まれません。 + Вкл. эффект горения техники. \nНе включает детонацию боекомплекта - - Ammunition cook off duration - Duración de la detonación inducida por calor de la munición - Munitionsdurchzündungsdauer - Czas trwania samozapłonu amunicji - 弾薬の誘爆持続時間 - Durée d'auto-inflammation des munitions - Durata Esplosione Munizioni - 彈藥殉爆效果持續時間 - 弹药殉爆效果持续时间 - 쿡오프 지속 시간 - Длительность детонации боеприпасов - Duração do cozinhamento de munição - Doba trvání vznícení munice + + Vehicle cook-off fire duration multiplier + 車両の誘爆火災の持続時間倍率 + Увел. продолжительности горения техники - - Multiplier for how long cook off lasts [Setting to 0 will disable ammo cookoff] - Multiplicador de cuanto dura la detonación inducida por calor [Ponerlo a cero la deshabilita] - Faktor für die Munitionsdurchzündungsdauer [0 zum Deaktivieren] - Multiplicateur permettant de régler la durée durant laquelle les munitions continuent d'exploser [Une valeur de 0 désactive l'auto-inflammation]. - Mnożnik decydujący jak długo ma trwać samozapłon amunicji [Ustawienie na 0 spowoduje wyłącznie samozapłonu] - 誘爆の持続時間を乗数で設定します。[0 に設定で誘爆を無効化] - Moltiplicatore della durata delle esplosioni di munizioni [Se impostato su 0 disabiliterà le esplosioni delle munizioni] - 設定彈藥殉爆效果會持續多久時間 [輸入0來關閉殉爆效果] - 设定弹药殉爆效果会持续多久时间 [输入0来关闭殉爆效果] - 쿡오프 지속 시간의 배수 [0 이면 비활성] - Множитель длительности детонации [0 - отключает детонацию боеприпасов] - Multiplicação da duração do cozinhamento [0 faz com que o cozinhamento seja desativado] - Multiplikátor doby trvání vznícení munice [Nastavte 0 pro vypnutí vznícení munice] + + Multiplier for how long vehicle cook-off fire lasts.\nSetting to 0 will disable vehicle cook-off fire. + 車両の誘爆火災の持続時間をどのくらいの長さにするかの倍率。\n0に設定すると車両の誘爆火災が無効化されます。 + Увел. продолжительности горения техники. \nУстановка значения на 0 выключает возгорание техники. - Cook-off probability coefficient - Coeficiente de probabilidad de detonación inducida por calor - 誘爆の可能性係数 - Coefficiente Probabilità Esplosione - Faktor für Wahrscheinlichkeit der Durchzündung - 殉爆發生機率係數 - 殉爆发生机率系数 - Coefficient de probabilité d'auto-inflammation - Współczynnik prawdopodobieństwa samozapłonu - Коэф. вероятности детонации - Probabilidade de Cozinhar - Koeficient pravděpodobnosti vznícení munice - 쿡오프 발생 확률 계수 + Vehicle cook-off fire probability multiplier + 車両の誘爆火災の可能性倍率 + Возможность усиления пожара при детонации техники - Multiplier for cook-off probability. Higher value results in higher cook-off probability - Multiplicador de probabilidad de detonación inducida por calor. Valores más altos producen mayor probabilidad - 誘爆する可能性の乗数。高い値では誘爆する可能性が高まります。 - Moltiplicatore per la probabilità dell'esplosione di munizioni. Un valore più alto aumenta la probabilità. - Faktor für Wahrscheinlichkeit der Durchzündung. Ein höherer Wert führt zu höherer Durchzündungswahrscheinlichkeit. - 調整殉爆發生機率係數。值越高代表越容易發生殉爆 - 调整殉爆发生机率系数。值越高代表越容易发生殉爆。 - Multiplicateur de probabilité de l'auto-inflammation. Plus la valeur est élevée, plus la probabilité de combustion est grande. - Mnożnik prawdopodobieństwa samozapłonu. Większa wartość oznacza większe prawdopodobieństwo samozapłonu - Множитель коэффициента вероятности детонации. Чем выше значение, тем выше вероятность - Multiplicador para a chance de cozinhamento. Valores mais altos aumentam as chances de ocorrer. - Multiplikátor pro pravděpodobnost vznícení munice. Vyšší hodnota znamená vyšší šanci vznícení munice. - 쿡오프가 일어날 확률에 계수를 곱합니다. 더 큰 숫자는 더 높은 확률의 쿡오프를 일으킵니다. + Multiplier for vehicle cook-off fire probability. Higher value results in higher cook-off probability.\nSetting to 0 will disable vehicle cook-off fire. + 車両の誘爆火災がどのくらいの可能性で発生するかの倍率。高い数値は高い誘爆の可能性につながります。\n0に設定すると車両の誘爆火災が無効化されます。 + Увел. вероятности возникновения возгорания техники. Большое значение указывает на высокую вероятность детонации. \nУстановка значения 0 предотвращает возгорание техники. - Destroy Vehicles After Cook-off + Destroy vehicles after cook-off 쿡오프 후 차량 파괴 殉爆发生后摧毁载具 Уничтожать технику после детонации @@ -181,7 +61,7 @@ Controls whether vehicles will always be destroyed after cooking off. - 誘爆後に車両を破壊するかどうかを設定する。 + 誘爆の終了後に車両を必ず完全破壊するかどうかを設定します。 Kontroluje, czy pojazdy będą zawsze niszczone po samozapłonie. Steuert, ob Fahrzeuge nach dem Durchzünden immer zerstört werden. Determina se veicoli saranno sempre distrutti dall'esplosione delle munizioni. @@ -189,32 +69,66 @@ Contrôle si les véhicules seront toujours détruits après l'auto-inflammation. Define se os veículos serão sempre destruídos após cozinhamento. Определяет, всегда ли транспортные средства будут уничтожаться после детонации. + Controla si los vehículos siempre será destruidos despues de la detonación inducida por calor. - - Enable Cook-Off Vehicle Fire - 誘爆火災を有効化 - Véhicules - Feu durant l'auto-inflammation - Вкл. горение техники от детонации - Aktiviert das in Brand setzen des Fahrzeugs während des Durchzündens der Munition - Abilita incendiamento veicoli - Włącz pożar pojazdu podczas samozapłonu - 启用殉爆载具火灾 - 차량 쿡오프 화재 활성화 - Habilitar incendio a causa de la detonación inducida por calor - Ativar incêndio de veículo durante cozinhamento + + Enable vehicle ammo cook-off + 車両弾薬の誘爆を有効化 + Вкл. детонацию боеприпасов в технике. - - Whether or not vehicles will catch on fire during cook-off - 誘爆により車両が炎上するかどうかを設定します。 - Définit si les véhicules prennent feu durant l'auto-inflammation de leurs munitions. - Будет ли техника гореть при детонации боеприпасов - Ob Fahrzeuge in Brand gesetzt werden, während deren Munition durchzündet. - Determina se veicoli cominceranno a bruciare se le loro munizioni esplodono. - Określa, czy pojazdy zapalą się podczas samozapłonu ich amunicji. - 车辆在殉爆过程中是否会起火 - 쿡오프가 일어나면 차량에 불이 붙습니다. - Define si los vehículos salen ardiendo despues de una detonación inducida por calor. - Define se os veículos pegarão fogo durante o cozinhamento. + + Enables cooking off of vehicle ammunition. Fires ammunition projectiles while vehicle has ammunition remaining.\nThis doesn't include fire effects. + 車両弾薬の誘爆を有効化します。車両に積載されたままの弾薬と弾頭が発射されます。\nこれには火災エフェクトは含まれません。 + Вкл. детонацию боеприпасов на технике. Боеприпасы и боеголовки, которые остаются заряженными на транспортном средстве, будут приведены в действие. \nЭто не включает эффекты пожара. + + + Enable ammo box cook-off + Habilitar detonación inducida por calor en las cajas de munición + 弾薬箱の誘爆を有効化 + Durchzündung für Munitionskisten ermöglichen + 탄약 상자 쿡오프 현상 활성화 + Aktywuj samozapłon skrzyń z amunicją + Auto-inflammation des caisses de munitions + Abilita esplosione casse munizioni + 開啟彈藥箱殉爆效果 + 开启弹药箱殉爆效果 + Разрешить детонацию ящиков с боеприпасами + Permitir cozinhar caixas de munição + Povolit vynícení munice v krabicích + + + Enables cooking off of ammo boxes.\nThis doesn't include fire effects. + 弾薬箱の誘爆を有効化します。\nこれには火災エフェクトは含まれません。 + Вкл. детонацию ящика с боеприпасами. \nЭто не включает эффекты огня. + + + Ammo cook-off duration multiplier + 弾薬の誘爆の持続時間倍率 + Увеличение продолжительности детонации боеприпасов. + + + 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. + 弾薬の誘爆の持続時間をどのくらいの長さにするかの倍率。車両弾薬と弾薬箱どちらにも影響します。\n0に設定すると弾薬の誘爆が無効化されます。 + Увеличение продолжительности детонации боеприпасов. Это влияет как на боеприпасы в технике, так и на ящики с боеприпасами. \nУстановка значения 0 отключает детонацию боеприпасов. + + + Enable ammo removal during cook-off + 誘爆による弾薬の除去を有効化 + Retirer les munitions durant l'auto-inflammation + Aktiviert/Deaktiviert Entfernung der Munition beim Durchzünden + Abilita rimozione munizioni dopo l'esplosione + Włącz/Wyłącz usuwanie amunicji podczas samozapłonu + 启用/禁用殉爆过程中的弹药移除功能 + 쿡오프시 탄약 제거 활성화/비활성화 + Вкл. удаление боеприпасов из-за детонации + Habilita/Deshabilita ka eliminación de munición durante la detonación inducida por calor + + + Removes all ammo during cook-off. + Retire des munitions des véhicules durant une auto-inflammation. + Entfernt Munition während dem Durchzünden der Munition eines Fahrzeuges. + 誘爆によって全ての弾薬を除去します。 + Все боеприпасы уничтожаются путем подрыва. diff --git a/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf b/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf index e5aa51d3429..d7af22d319a 100644 --- a/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf +++ b/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf @@ -25,7 +25,7 @@ params ["_vehicle", "_turret", "_magSource", "_carryMag", "_ammoReceived", ["_re TRACE_6("reload_handleAddTurretMag",_vehicle,_turret,_magSource,_carryMag,_ammoReceived,_returnTo); TRACE_2("",local _vehicle,_vehicle turretLocal _turret); -if (!(_vehicle turretLocal _turret)) exitWith {}; +if !(_vehicle turretLocal _turret) exitWith {}; ([_vehicle, _turret, _carryMag] call FUNC(reload_canLoadMagazine)) params ["_canAdd", "_loadedMag", "_neededAmmo", "_isBeltLinking"]; TRACE_4("canLoad",_canAdd,_loadedMag,_neededAmmo,_isBeltLinking); diff --git a/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf b/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf index 59d948ba279..51036b525a3 100644 --- a/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf +++ b/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf @@ -24,7 +24,7 @@ params ["_vehicle", "_turretPath", "_carryMag", "_vehMag", "_unloadTo"]; TRACE_5("removeTurretMag EH",_vehicle,_turretPath,_carryMag,_vehMag,_unloadTo); TRACE_3("",local _vehicle,_vehicle turretLocal _turretPath,local _unloadTo); -if (!(_vehicle turretLocal _turretPath)) exitWith {}; +if !(_vehicle turretLocal _turretPath) exitWith {}; private _magsInWeapon = []; // Check how much ammo it has now: { diff --git a/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf b/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf index da8383b6085..ca445400b02 100644 --- a/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf +++ b/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf @@ -41,7 +41,7 @@ if ((_fullMagazines == 0) && {_bulletsRemaining == 0}) exitWith {}; private _container = _unloadTo getVariable [QGVAR(container), objNull]; if ((_container distance _unloadTo) > 10) then { _container = objNull; }; if (isNull _container) then { - _container = (nearestObjects [_unloadTo, [QGVAR(ammo_holder), "GroundWeaponHolder"], 10]) param [0, objNull]; + _container = (nearestObjects [_unloadTo, [["GroundWeaponHolder"], [QGVAR(ammo_holder)]] select GVAR(handleExtraMagazinesType), 10]) param [0, objNull]; }; diff --git a/addons/csw/initSettings.inc.sqf b/addons/csw/initSettings.inc.sqf index de3976896be..bc157e1164b 100644 --- a/addons/csw/initSettings.inc.sqf +++ b/addons/csw/initSettings.inc.sqf @@ -45,17 +45,12 @@ private _categoryArray = [format ["ACE %1", localize LSTRING(DisplayName)]]; [LSTRING(progressBarTimeCoefficent_displayName), LSTRING(progressBarTimeCoefficent_description)], _categoryArray, [0,2,1,2], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(progressBarTimeCoefficent), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart + true // isGlobal ] call CBA_fnc_addSetting; [ QGVAR(dragAfterDeploy), "CHECKBOX", [LSTRING(dragAfterDeploy_displayName), LSTRING(dragAfterDeploy_description)], _categoryArray, - false, // default value - false, // isGlobal - {[QGVAR(dragAfterDeploy), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart + false // default value ] call CBA_fnc_addSetting; diff --git a/addons/csw/stringtable.xml b/addons/csw/stringtable.xml index 4aea2a24b4f..7c241a8a515 100644 --- a/addons/csw/stringtable.xml +++ b/addons/csw/stringtable.xml @@ -1120,5 +1120,22 @@ [CSW] Сумка с СПГ-9М орудием [CSW] SPG-9M 발사기 가방 + + + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[班组\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + diff --git a/addons/dagr/XEH_postInit.sqf b/addons/dagr/XEH_postInit.sqf index 6996ced7f21..34dc9818437 100644 --- a/addons/dagr/XEH_postInit.sqf +++ b/addons/dagr/XEH_postInit.sqf @@ -30,4 +30,4 @@ GVAR(vectorConnected) = false; GVAR(noVectorData) = true; GVAR(vectorGrid) = "00000000"; -[QEGVAR(vector,rangefinderData), FUNC(handleRangeFinderData)] call CBA_fnc_addEventHandler; +[QEGVAR(vector,rangefinderData), LINKFUNC(handleRangeFinderData)] call CBA_fnc_addEventHandler; diff --git a/addons/disarming/functions/fnc_disarmDropItems.sqf b/addons/disarming/functions/fnc_disarmDropItems.sqf index e1a4c379b4f..6e842e739a4 100644 --- a/addons/disarming/functions/fnc_disarmDropItems.sqf +++ b/addons/disarming/functions/fnc_disarmDropItems.sqf @@ -30,7 +30,7 @@ private _fncSumArray = { }; //Sanity Checks -if (!([_target] call FUNC(canBeDisarmed))) exitWith { +if !([_target] call FUNC(canBeDisarmed)) exitWith { [_caller, _target, "Debug: Cannot disarm target"] call FUNC(eventTargetFinish); }; if (_doNotDropAmmo && {({_x in _listOfItemsToRemove} count (magazines _target)) > 0}) exitWith { @@ -74,7 +74,6 @@ if (_holder getVariable [QGVAR(holderInUse), false]) exitWith { }; _holder setVariable [QGVAR(holderInUse), true]; - //Remove Magazines private _targetMagazinesStart = magazinesAmmo _target; private _holderMagazinesStart = magazinesAmmoCargo _holder; @@ -96,7 +95,7 @@ if (({((_x select 0) in _listOfItemsToRemove) && {(getNumber (configFile >> "Cfg [_caller, _target, "Debug: Didn't Remove Magazines"] call FUNC(eventTargetFinish); }; //Verify holder has mags unit had -if (!([_targetMagazinesStart, _targetMagazinesEnd, _holderMagazinesStart, _holderMagazinesEnd] call FUNC(verifyMagazinesMoved))) then { +if !([_targetMagazinesStart, _targetMagazinesEnd, _holderMagazinesStart, _holderMagazinesEnd] call FUNC(verifyMagazinesMoved)) then { _holder setVariable [QGVAR(holderInUse), false]; [_caller, _target, "Debug: Crate Magazines not in holder"] call FUNC(eventTargetFinish); }; @@ -238,7 +237,7 @@ if (_holderIsEmpty) then { [_caller, _target, "Debug: Drop Actions Timeout"] call FUNC(eventTargetFinish); }; //If target lost disarm status: - if (!([_target] call FUNC(canBeDisarmed))) exitWith { + if !([_target] call FUNC(canBeDisarmed)) exitWith { _holder setVariable [QGVAR(holderInUse), false]; [_caller, _target, "Debug: Target cannot be disarmed"] call FUNC(eventTargetFinish); }; diff --git a/addons/disarming/functions/fnc_eventTargetStart.sqf b/addons/disarming/functions/fnc_eventTargetStart.sqf index 7173f66a76d..a7154ce2e4c 100644 --- a/addons/disarming/functions/fnc_eventTargetStart.sqf +++ b/addons/disarming/functions/fnc_eventTargetStart.sqf @@ -32,7 +32,7 @@ private _itemsToAdd = []; } forEach _listOfObjectsToRemove; { - if (!(_x in _listOfObjectsToRemove)) then { + if !(_x in _listOfObjectsToRemove) then { _listOfObjectsToRemove pushBack _x; }; } forEach _itemsToAdd; diff --git a/addons/disarming/functions/fnc_openDisarmDialog.sqf b/addons/disarming/functions/fnc_openDisarmDialog.sqf index da9a860678a..6cf15f4cad1 100644 --- a/addons/disarming/functions/fnc_openDisarmDialog.sqf +++ b/addons/disarming/functions/fnc_openDisarmDialog.sqf @@ -16,11 +16,14 @@ * * Public: No */ + params ["_caller", "_target"]; -#define DEFUALTPATH "\A3\Ui_f\data\GUI\Cfg\Ranks\%1_gs.paa" + +#define DEFAULTPATH "\A3\Ui_f\data\GUI\Cfg\Ranks\%1_gs.paa" + //Sanity Checks if (_caller != ACE_player) exitWith {ERROR("Player isn't caller?");}; -if (!([_player, _target] call FUNC(canPlayerDisarmUnit))) exitWith {ERROR("Can't Disarm Unit");}; +if !([_player, _target] call FUNC(canPlayerDisarmUnit)) exitWith {ERROR("Can't Disarm Unit");}; if (dialog) then {ERROR("Dialog open when trying to open disarm dialog"); closeDialog 0;}; disableSerialization; @@ -74,8 +77,8 @@ GVAR(disarmTarget) = _target; private _rankPicture = _display displayCtrl 1203; //Show rank and name (just like BIS's inventory) - private _icon = format [DEFUALTPATH, toLowerANSI (rank _target)]; - if (_icon isEqualTo DEFUALTPATH) then {_icon = ""}; + private _icon = format [DEFAULTPATH, toLowerANSI (rank _target)]; + if (_icon isEqualTo DEFAULTPATH) then {_icon = ""}; _rankPicture ctrlSetText _icon; _playerName ctrlSetText ([GVAR(disarmTarget), false, true] call EFUNC(common,getName)); diff --git a/addons/dogtags/XEH_postInit.sqf b/addons/dogtags/XEH_postInit.sqf index d9c35dc172b..dae6b62247a 100644 --- a/addons/dogtags/XEH_postInit.sqf +++ b/addons/dogtags/XEH_postInit.sqf @@ -5,9 +5,11 @@ [QGVAR(getDogtagItem), LINKFUNC(getDogtagItem)] call CBA_fnc_addEventHandler; [QGVAR(addDogtagItem), LINKFUNC(addDogtagItem)] call CBA_fnc_addEventHandler; -// Add actions and event handlers only if ace_medical is loaded +// Add actions and event handlers only if ace_medical is enabled // - Adding actions via config would create a dependency -if (["ace_medical"] call EFUNC(common,isModLoaded)) then { +["CBA_settingsInitialized", { + if !(GETEGVAR(medical,enabled,false)) exitWith {}; + if (hasInterface) then { private _checkTagAction = [ "ACE_CheckDogtag", @@ -44,7 +46,7 @@ if (["ace_medical"] call EFUNC(common,isModLoaded)) then { }; }] call CBA_fnc_addEventHandler; }; -}; +}] call CBA_fnc_addEventHandler; // If the arsenal is loaded, show the custom names for dog tags when in the arsenal if (["ace_arsenal"] call EFUNC(common,isModLoaded)) then { diff --git a/addons/dogtags/XEH_preInit.sqf b/addons/dogtags/XEH_preInit.sqf index 5ad43b02291..f5fcb406b1d 100644 --- a/addons/dogtags/XEH_preInit.sqf +++ b/addons/dogtags/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -GVAR(disabledFactions) = [] call CBA_fnc_createNamespace; +GVAR(disabledFactions) = createHashMap; ADDON = true; diff --git a/addons/dogtags/functions/fnc_canCheckDogtag.sqf b/addons/dogtags/functions/fnc_canCheckDogtag.sqf index 399ad5db252..bec3ef0dfa2 100644 --- a/addons/dogtags/functions/fnc_canCheckDogtag.sqf +++ b/addons/dogtags/functions/fnc_canCheckDogtag.sqf @@ -21,6 +21,6 @@ params ["_player", "_target"]; if (isNull _target) exitWith {false}; // check if disabled for faction -if ([GVAR(disabledFactions) getVariable faction _target] param [0, false]) exitWith {false}; +if ((faction _target) in GVAR(disabledFactions)) exitWith {false}; (!alive _target) || {_target getVariable ["ACE_isUnconscious", false]} diff --git a/addons/dogtags/functions/fnc_canTakeDogtag.sqf b/addons/dogtags/functions/fnc_canTakeDogtag.sqf index 7ae38f7c410..c482d74c1c9 100644 --- a/addons/dogtags/functions/fnc_canTakeDogtag.sqf +++ b/addons/dogtags/functions/fnc_canTakeDogtag.sqf @@ -21,6 +21,6 @@ params ["_player", "_target"]; if (isNull _target) exitWith {false}; // check if disabled for faction -if ([GVAR(disabledFactions) getVariable faction _target] param [0, false]) exitWith {false}; +if ((faction _target) in GVAR(disabledFactions)) exitWith {false}; (!alive _target) || {_target getVariable ["ACE_isUnconscious", false]} diff --git a/addons/dogtags/functions/fnc_disableFactionDogtags.sqf b/addons/dogtags/functions/fnc_disableFactionDogtags.sqf index f1ea5f5c065..c4642ef4b5d 100644 --- a/addons/dogtags/functions/fnc_disableFactionDogtags.sqf +++ b/addons/dogtags/functions/fnc_disableFactionDogtags.sqf @@ -17,4 +17,9 @@ params [["_faction", "", [""]]]; -GVAR(disabledFactions) setVariable [_faction, true]; +_faction = configName (configFile >> "CfgFactionClasses" >> _faction); + +// Faction doesn't exist +if (_faction == "") exitWith {}; + +GVAR(disabledFactions) set [_faction, true]; diff --git a/addons/dragging/functions/fnc_dropObject_carry.sqf b/addons/dragging/functions/fnc_dropObject_carry.sqf index 184b1755c05..7a81d94a059 100644 --- a/addons/dragging/functions/fnc_dropObject_carry.sqf +++ b/addons/dragging/functions/fnc_dropObject_carry.sqf @@ -116,7 +116,7 @@ if (_loadCargo) then { private _vehicles = [_cursorObject, 0, true] call EFUNC(common,nearestVehiclesFreeSeat); if ([_cursorObject] isEqualTo _vehicles) then { - if (["ace_medical"] call EFUNC(common,isModLoaded)) then { + if (GETEGVAR(medical,enabled,false)) then { [_unit, _target, _cursorObject] call EFUNC(medical_treatment,loadUnit); } else { [_unit, _target, _cursorObject] call EFUNC(common,loadPerson); diff --git a/addons/dragging/stringtable.xml b/addons/dragging/stringtable.xml index 9552f50273d..c2f96ce55ac 100644 --- a/addons/dragging/stringtable.xml +++ b/addons/dragging/stringtable.xml @@ -167,6 +167,7 @@ Autoriser la course avec des objets légers Permitir corrida com objetos leves Позволяет работать с легкими объектами + Permitir correr con objetos ligeros Allow the player to run when carrying lightweight objects. @@ -178,6 +179,7 @@ Autorise le joueur à courir lorsqu'il porte un objet léger. Permite ao jogador correr enquanto carrega objetos leves. Разрешите игроку бегать при переноске легких предметов. + Permite al jugador correr cuando porta objetos ligeros. Skip Object Weight @@ -189,6 +191,7 @@ Ignorer le poids de l'objet Ignorar Peso do Objeto Игнорировать вес объекта + Ignora peso del objeto Determines whether object's weight is added onto weight calculations. @@ -200,6 +203,7 @@ Défini si le poids d'un objet est ajouté aux calculs du poids. Determina se o peso do objeto é adicionado aos cálculos de peso. Определяет, добавляется ли вес объекта при расчете веса. + Determina si el peso del objeto es añadido en los cálculos de peso. Max Weight Coefficient @@ -210,6 +214,7 @@ Maximaler Gewichtskoeffizient 最大重量係数 Максимальный коэффициент веса + Máximo Coeficiente de Peso Modifies weight limit calculations. Set to 0 to ignore. @@ -220,6 +225,7 @@ Ändert die Berechnung der Gewichtsbegrenzung. Zum Ignorieren auf 0 setzen. 重量制限の計算を変更します。 無視するには 0 に設定します。 Изменяет расчеты предельного веса. Установите значение 0 для игнорирования. + Modifica el límite de peso de los cálculos. Poner a 0 para que lo ignore. diff --git a/addons/dragon/XEH_postInit.sqf b/addons/dragon/XEH_postInit.sqf index 0305fe772a9..2360a5bd971 100644 --- a/addons/dragon/XEH_postInit.sqf +++ b/addons/dragon/XEH_postInit.sqf @@ -6,7 +6,7 @@ ["vehicle", { params ["","_vehicle"]; TRACE_2("vehicle change",_vehicle,typeOf _vehicle); - if (!(_vehicle isKindOf QGVAR(staticBase))) exitWith {}; + if !(_vehicle isKindOf QGVAR(staticBase)) exitWith {}; _vehicle animate ["rest_rotate", 0]; @@ -14,7 +14,7 @@ [GVAR(pfID)] call CBA_fnc_removePerFrameHandler; private _lastView = cameraView; - if (!(_lastView in ["INTERNAL", "EXTERNAL"])) then { _lastView == "INTERNAL"; }; + if !(_lastView in ["INTERNAL", "EXTERNAL"]) then { _lastView == "INTERNAL"; }; GVAR(pfID) = [{ params ["_args"]; diff --git a/addons/dragon/functions/fnc_sightAttach.sqf b/addons/dragon/functions/fnc_sightAttach.sqf index 76ad9c33565..de085942b7d 100644 --- a/addons/dragon/functions/fnc_sightAttach.sqf +++ b/addons/dragon/functions/fnc_sightAttach.sqf @@ -21,7 +21,7 @@ params ["_target", "_unit", ["_event", false]]; TRACE_3("sightAttach",_target,_unit,_event); if (_event isEqualTo true) then { // this is actually needed as 3rd arg may not be bool - if (!(_target turretLocal [0])) exitWith {}; + if !(_target turretLocal [0]) exitWith {}; _target setVariable [QGVAR(sightAttached), true, true]; _target animate ["optic_hide", 0]; _target addWeapon QGVAR(superStatic); diff --git a/addons/dragon/functions/fnc_sightDetach.sqf b/addons/dragon/functions/fnc_sightDetach.sqf index c9d03e22e64..a5ac159a335 100644 --- a/addons/dragon/functions/fnc_sightDetach.sqf +++ b/addons/dragon/functions/fnc_sightDetach.sqf @@ -23,7 +23,7 @@ params ["_target", "_unit", ["_event", false]]; TRACE_3("sightDetach",_target,_unit,_event); if (_event isEqualTo true) then { // this is actually needed as 3rd arg may not be bool - if (!(_target turretLocal [0])) exitWith {}; + if !(_target turretLocal [0]) exitWith {}; _target setVariable [QGVAR(sightAttached), false, true]; _target animate ["optic_hide", 1]; _target removeWeapon QGVAR(superStatic); diff --git a/addons/explosives/functions/fnc_addClacker.sqf b/addons/explosives/functions/fnc_addClacker.sqf index 2292bfcb79c..794aec0a107 100644 --- a/addons/explosives/functions/fnc_addClacker.sqf +++ b/addons/explosives/functions/fnc_addClacker.sqf @@ -31,7 +31,7 @@ private _detonators = [_unit] call FUNC(getDetonators); if !(_x in _detonators) exitWith{ _hasRequired = false; }; -} count _requiredItems; +} forEach _requiredItems; if !(_hasRequired) exitWith {}; private _config = ConfigFile >> "CfgMagazines" >> _magazineClass >> "ACE_Triggers" >> configName _config; diff --git a/addons/explosives/functions/fnc_addDetonateActions.sqf b/addons/explosives/functions/fnc_addDetonateActions.sqf index ea4b87128a7..d950278c357 100644 --- a/addons/explosives/functions/fnc_addDetonateActions.sqf +++ b/addons/explosives/functions/fnc_addDetonateActions.sqf @@ -53,7 +53,7 @@ private _explosivesList = []; // If the detonator is not active, is a clacker and has assigned explosives, generate an interaction to make it the active detonator for use with the "trigger all" keybind if ( _detonator != GVAR(activeTrigger) && - {_detonator != "Cellphone"} && + {_detonator != "Cellphone"} && { _explosivesList isNotEqualTo [] || {_detonator == "ACE_DeadManSwitch" && {_unit getVariable [QGVAR(deadmanInvExplosive), ""] != ""}} @@ -144,7 +144,7 @@ if (_detonator != "ACE_DeadManSwitch") then { private _procressedMags = []; { private _mag = _x; - if (!(_mag in _procressedMags)) then { + if !(_mag in _procressedMags) then { _procressedMags pushBack _x; private _magConfig = configFile >> "CfgMagazines" >> _mag; private _supportedTriggers = getArray (_magConfig >> "ACE_Triggers" >> "SupportedTriggers"); diff --git a/addons/explosives/functions/fnc_onIncapacitated.sqf b/addons/explosives/functions/fnc_onIncapacitated.sqf index 09d1d7b21f4..5e7b8797e1d 100644 --- a/addons/explosives/functions/fnc_onIncapacitated.sqf +++ b/addons/explosives/functions/fnc_onIncapacitated.sqf @@ -37,7 +37,7 @@ TRACE_2("placed",_deadman,_range); //Handle deadman connected to explosive in inventory private _connectedInventoryExplosive = _unit getVariable [QGVAR(deadmanInvExplosive), ""]; if (_connectedInventoryExplosive != "") then { - if (!(_connectedInventoryExplosive in (magazines _unit))) exitWith {}; + if !(_connectedInventoryExplosive in (magazines _unit)) exitWith {}; //Remove mag and reset variable _unit removeMagazine _connectedInventoryExplosive; diff --git a/addons/explosives/stringtable.xml b/addons/explosives/stringtable.xml index fccc685c4f0..168a8302542 100644 --- a/addons/explosives/stringtable.xml +++ b/addons/explosives/stringtable.xml @@ -76,6 +76,7 @@ 選択した点火装置を全て起爆 활성화된 격발기의 모든 것을 폭파 Détoner tout sur le détonateur actif + Detonar Todos al Activar el detonador Set Active Clacker @@ -85,6 +86,7 @@ この点火装置を選択 격발기 활성 설정 Définir le détonateur actif + Establecer el Detonador Activo Cycle Active Clacker @@ -94,6 +96,7 @@ 点火装置を切り替え 격발기 활성 전환 Modifier le détonateur actif + Ciclar el Detonador Activo Active Clacker @@ -103,6 +106,7 @@ 選択中の点火装置 격발기 활성 Détonateur actif + Activar Detonador Explosive code: %1 diff --git a/addons/fastroping/XEH_postInit.sqf b/addons/fastroping/XEH_postInit.sqf index 650b277dbf8..0ba92312153 100644 --- a/addons/fastroping/XEH_postInit.sqf +++ b/addons/fastroping/XEH_postInit.sqf @@ -9,7 +9,7 @@ // Keybinds ["ACE3 Vehicles", QGVAR(fastRope), localize LSTRING(Interaction_fastRope), { if ((vehicle ACE_player) == ACE_player) exitWith {false}; - if (!([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith))) exitWith {false}; + if !([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith)) exitWith {false}; if ([ACE_player, vehicle ACE_player] call FUNC(canFastRope)) then { [ACE_player, vehicle ACE_player] call FUNC(fastRope); true @@ -20,7 +20,7 @@ ["ACE3 Vehicles", QGVAR(cutRopes), localize LSTRING(Interaction_cutRopes), { if ((vehicle ACE_player) == ACE_player) exitWith {false}; - if (!([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith))) exitWith {false}; + if !([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith)) exitWith {false}; if ([vehicle ACE_player] call FUNC(canCutRopes)) then { [vehicle ACE_player] call FUNC(cutRopes); true @@ -43,7 +43,7 @@ if (isServer) then { #ifdef DRAW_FASTROPE_INFO addMissionEventHandler ["Draw3D", { - if (!(cursorObject isKindOf "Helicopter")) exitWith {}; + if !(cursorObject isKindOf "Helicopter") exitWith {}; private _config = configOf cursorObject; private _enabled = getNumber (_config >> QGVAR(enabled)); drawIcon3D ["", [.5,.5,1,1], (ASLtoAGL getPosASL cursorObject), 0.5, 0.5, 0, format ["%1 = %2", typeOf cursorObject, _enabled], 0.5, 0.025, "TahomaB"]; diff --git a/addons/fastroping/initSettings.inc.sqf b/addons/fastroping/initSettings.inc.sqf index 844de927a23..cde4a32b47e 100644 --- a/addons/fastroping/initSettings.inc.sqf +++ b/addons/fastroping/initSettings.inc.sqf @@ -5,9 +5,7 @@ private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(setting_c [LSTRING(setting_requireRopeItems_displayName)], _category, false, // default value - true, // isGlobal - {[QGVAR(requireRopeItems), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // needRestart + true // isGlobal ] call CBA_fnc_addSetting; [ diff --git a/addons/fastroping/stringtable.xml b/addons/fastroping/stringtable.xml index b68da23d28f..10ea50a7c51 100644 --- a/addons/fastroping/stringtable.xml +++ b/addons/fastroping/stringtable.xml @@ -325,6 +325,7 @@ Equipement automatique FRIES Auto-equipar FRIES Авто-подготовка канатов + Auto-Equipar FRIES Automatically add FRIES to helicopters that support them. @@ -336,6 +337,7 @@ Ajoute automatiquement des FRIES aux hélicoptères qui les supportent. Adiciona automaticamente FRIES a helicópteros que os suportam. Автоматически добавляйте канаты в вертолеты, которые их поддерживают. + Añadir automáticamente el FRIES a los helicópteros que lo soporten. diff --git a/addons/field_rations/XEH_postInit.sqf b/addons/field_rations/XEH_postInit.sqf index 9f643790945..9fc8406abaf 100644 --- a/addons/field_rations/XEH_postInit.sqf +++ b/addons/field_rations/XEH_postInit.sqf @@ -99,7 +99,7 @@ if !(hasInterface) exitWith {}; ["ace_interactMenuOpened", LINKFUNC(addWaterSourceInteractions)] call CBA_fnc_addEventHandler; // Add status modifiers - if (["ace_medical"] call EFUNC(common,isModLoaded)) then { + if (GETEGVAR(medical,enabled,false)) then { [0, { if (_this getVariable [QEGVAR(medical,isBleeding), false]) exitWith { 0.5 diff --git a/addons/field_rations/functions/fnc_handleEffects.sqf b/addons/field_rations/functions/fnc_handleEffects.sqf index 1981cc5f996..ad60a743ad0 100644 --- a/addons/field_rations/functions/fnc_handleEffects.sqf +++ b/addons/field_rations/functions/fnc_handleEffects.sqf @@ -21,24 +21,21 @@ params ["_player", "_thirst", "_hunger"]; // Kill unit with max thirst or hunger if ((_thirst > 99.9 || {_hunger > 99.9}) && {random 1 < 0.5}) exitWith { - if (["ace_medical"] call EFUNC(common,isModLoaded)) then { - [_player, "Hunger/Thirst empty"] call EFUNC(medical_status,setDead); - } else { - _player setDamage 1; - }; + [_player, "Hunger/Thirst empty"] call EFUNC(common,setDead); }; // Exit if unit is not awake, below are animation based consequences if !(_player call EFUNC(common,isAwake)) exitWith {}; // Set unit unconscious (chance based on how high thirst/hunger are) -if ((_thirst > 85 || {_hunger > 85}) && {random 1 < linearConversion [85, 100, _thirst max _hunger, 0.05, 0.1, true]}) exitWith { - if (["ace_medical"] call EFUNC(common,isModLoaded)) then { - [_player, true, 5, true] call EFUNC(medical,setUnconscious); - }; +if ( + GETEGVAR(medical,enabled,false) && + {(_thirst > 85 || {_hunger > 85}) && {random 1 < linearConversion [85, 100, _thirst max _hunger, 0.05, 0.1, true]}} +) exitWith { + [_player, true, 5, true] call EFUNC(medical,setUnconscious); }; // Make unit fall if moving fast -if ((_thirst > 93 || {_hunger > 93}) && {speed _player > 1} && {vehicle _player == _player}) exitWith { +if ((_thirst > 93 || {_hunger > 93}) && {speed _player > 1} && {isNull objectParent _player}) exitWith { [_player, "down"] call EFUNC(common,doGesture); }; diff --git a/addons/fieldmanual/stringtable.xml b/addons/fieldmanual/stringtable.xml index 05c7414f175..78b7ad6fe89 100644 --- a/addons/fieldmanual/stringtable.xml +++ b/addons/fieldmanual/stringtable.xml @@ -28,6 +28,7 @@ 空腹 Голод Faim + Hambre %3Hunger%4 increases linearly with soldier's movement speed. Restore by eating food.<br/><br/>%3Usage:%4<br/>%2Pick up food.<br/>%2Use [%3%12%4] and select %3Survival%4.<br/>%2Choose an item to consume. @@ -39,6 +40,7 @@ %3空腹度%4は兵士の移動速度に比例して増加します。食べ物を食べることで回復します。<br/><br/>%3使用方法:%4<br/>%2食べ物を持つ。<br/>%2[%3%12%4] を使って%3サバイバル%4を選択。<br/>%2食べたいものを選ぶ。 %3Голод%4 линейно увеличивается со скоростью передвижения солдата. Восстанавливайтесь, употребляя пищу.<br/><br/>%3 Использование:%4<br/>%2Возьмите еду.<br/>%2Используйте [%3%12%4] и выберите %3Выживание% 4.<br/>%2Выберите продукт для потребления. %3La faim%4 augmente linéairement avec la vitesse de déplacement du soldat. Il se régénère en consommant de la nourriture.<br/><br/>%3Utilisation:%4<br/>%2Ramasser la nourriture.<br/>%2Utilisez [%3%12%4] et sélectionnez %3Survie%4.<br/>%2Choisissez un article à consommer. + El %3Hambre%4 aumenta linealmente con los movimientos del soldado. Se reestablece comiendo comida.<br/><br/>%3Uso:%4<br/>%2Coger comida.<br/>%2Usar [%3%12%4] y seleccionar %3Sobrevivir%4.<br/>%2Elegir un objeto para consumir. Thirst @@ -50,6 +52,7 @@ 渇き Жажда Soif + Sed %3Thirst%4 increases linearly with soldier's movement speed. Restore by drinking liquids.<br/><br/>%3Usage:%4<br/>%2Pick up a drink.<br/>%2Use [%3%12%4] and select %3Survival%4.<br/>%2Choose an item to consume. @@ -61,6 +64,7 @@ %3喉の渇き%4は兵士の移動速度に比例して増加します。飲み物を飲むことで回復します。<br/><br/>%3使用方法:%4<br/>%2飲み物を持つ。<br/>%2[%3%12%4] を使って%3サバイバル%4を選択。<br/>%2飲みたいものを選ぶ。 %3Жажда%4 линейно увеличивается со скоростью передвижения солдата. Восстанавливайтесь, употребляя напитки.<br/><br/>%3 Использование:%4<br/>%2Возьмите напиток.<br/>%2Используйте [%3%12%4] и выберите %3Выживание% 4.<br/>%2Выберите напиток для потребления. %3La soif%4 augmente linéairement avec la vitesse de déplacement du soldat. Elle se régénère en buvant des liquides.<br/><br/>%3Utilisez [%3%12%4] et choisissez %3survival%4.<br />%2Choisissez un article à boire. + La %3Sed%4 aumenta linealmente con la velocidad de movimiento del soldado. Se restaura bebiendo líquidos.<br/><br/>%3Uso:%4<br/>%2Selecciona una bebida.<br/>%2Usar [%3%12%4] y seleccionar %3Sobrevivir%4.<br/>%2Elegir un objeto para consumir. Medical Treatment @@ -72,6 +76,7 @@ 治療 Медицинское лечение Traitement médical + Tratamiento Médico Decrease Heart Rate @@ -83,6 +88,7 @@ 心拍数を下げる Уменьшить частоту сердечных сокращений Diminution de la fréquence cardiaque + Disminuir Ritmo Cardíaco %3Adenosine%4 is used to decrease heart rate.<br/><br/>%3Usage:%4<br/>%2Use [%3%13%4] or [%3%14%4] and select an appendage.<br/>%2Inject %3Adenosine%4. @@ -94,6 +100,7 @@ %3アデノシン%4は心拍数を下げるのに使われます。<br/><br/>%3使用方法:%4<br/>%2[%3%13%4] または [%3%14%4] を使って四肢を選択します。<br/>%2そして%3アデノシン%4を注射します。 %3Аденозин%4 используется для снижения частоты сердечных сокращений.<br/><br/>%3Применение:%4<br/>%2Используйте [%3%13%4] или [%3%14%4] и выберите конечность.<br/>%2Введите %3Аденозин%4. L'%3adénosine%4 est utilisée pour réduire la fréquence cardiaque.<br/><br/>%3Utilisation:%4<br/>%2Utilisez [%3%13%4] ou [%3%14%4] et sélectionnez un membre.<br/>%2Injectez l'%3Adénosine%4. + La %3Adenosina%4 se usa para disminuir el ritmo cardíaco.<br/><br/>%3Uso:%4<br/>%2Uso [%3%13%4] o [%3%14%4] y selecciona una extremidad.<br/>%2Inyectar %3Adenosina%4. Bandages @@ -105,6 +112,7 @@ 包帯 Бинты Pansements + Vendas Close Wounds @@ -116,6 +124,7 @@ 傷口をふさぐ Закрыть раны Fermer les plaies + Cerrar Heridas %3Bandages%4 stop bleeding and close wounds. Depending on your settings, bandages may reopen if surgery is not performed.<br/><br/>%2%3Field Dressing:%4<br/>%11<t color='#D9D900'>Average</t> In All Categories<br/>%2%3Packing Bandage:%4<br/>%11<t color='#D9D900'>Average</t> Treatment<br/>%11<t color='#E60000'>Higher</t> Reopen Chance<br/>%11<t color='#00CC00'>Longer</t> Reopen Delay<br/>%2%3Elastic Bandage:%4<br/>%11<t color='#00CC00'>Higher</t> Treatment<br/>%11<t color='#E60000'>Higher</t> Reopen Chance<br/>%11<t color='#E60000'>Shorter</t> Reopen Delay<br/>%2%3Quickclot:%4<br/>%11<t color='#E60000'>Lower</t> Treatment<br/>%11<t color='#00CC00'>Lower</t> Reopen Chance<br/>%11<t color='#00CC00'>Longer</t> Reopening Delay<br/><br/>%3Usage:%4<br/>%2Use [%3%13%4] or [%3%14%4] and select a injured body part.<br/>%2Bandage body part by selecting desired %3Bandage%4 type. @@ -125,6 +134,7 @@ %3Verbände%4 stoppen Blutungen und schließen Wunden. Abhängig von Ihren Einstellungen können sich Verbände wieder öffnen, wenn keine Operation durchgeführt wird.<br/><br/>%2%3Einfache Bandage:%4<br/>%11<t color='#D9D900'>Durchschnittlich</t> In allen Kategorien<br/>%2%3Mullbinde:%4<br/>%11<t color='#D9D900'>Durchschnittliche</t> Behandlung<br/>%11<t color='#E60000' >Höhere</t> Wiedereröffnungswahrscheinlichkeit<br/>%11<t color='#00CC00'>Längere</t> Wiedereröffnungsverzögerung<br/>%2%3Elastischer Verband:%4<br/>%11<t color='#00CC00'>Längere</t> Behandlung<br/>%11<t color='#E60000'>Höhere</t> Chance auf Wiedereröffnung<br/>%11<t color='#E60000'> Kürzere</t> Wiedereröffnungsverzögerung<br/>%2%3Quickclot:%4<br/>%11<t color='#E60000'>Kürzere</t> Behandlung<br/>%11<t color=' #00CC00'>Geringere</t> Wiedereröffnungswahrscheinlichkeit<br/>%11<t color='#00CC00'>Längere</t> Wiedereröffnungsverzögerung<br/><br/>%3Verwende:%4<br/> %2Verwenden Sie [%3%13%4] oder [%3%14%4] und wähle ein verletztes Körperteil aus.<br/>%2Verbinde ein Körperteil, indem der gewünschte %3Bandagen%4-Typ ausgewählt wurde. %3Bende%4 fermano emorragie e chiudono ferite. A seconda delle tue impostazioni, ferite bendate potrebbero riaprirsi se non suturate.<br/><br/>%2%3Bendaggio Basico:%4<br/>%11<t color='#D9D900'>Media</t> In tutte le categorie<br/>%2%3Bendaggio Compressivo:%4<br/>%11<t color='#D9D900'>Media</t> Trattamenti<br/>%11<t color='#E60000'>Alta</t> Probabilità di riapertura<br/>%11<t color='#00CC00'>Lungo</t> Tempo di riapertura<br/>%2%3Bendaggio Elastico:%4<br/>%11<t color='#00CC00'>Alto</t> Trattamento<br/>%11<t color='#E60000'>Alto</t> Probabilità di riapertura<br/>%11<t color='#E60000'>Breve</t> Tempo di riapertura<br/>%2%3Quickclot:%4<br/>%11<t color='#E60000'>Basso</t> Trattamento<br/>%11<t color='#00CC00'>Basso</t> Probabilità di riapertura<br/>%11<t color='#00CC00'>Lungo</t> Tempo di riapertura<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%13%4] o [%3%14%4] seleziona una parte del corpo ferita.<br/>%2Benda la parte del corpo ferita selezionando la %3Benda%4 desiderato. %3包帯%4は傷口をとじて出血を止めます。設定によっては、手術を行わないと包帯が解けて傷が再開放し出血が再開する場合があります。<br/><br/>%2%3緊急圧迫包帯:%4<br/>%11<t color='#D9D900'>平均的な</t> 全体性能を持っています<br/>%2%3弾性包帯:%4<br/>%11<t color='#D9D900'>平均的な</t> 治療効果<br/>%11<t color='#E60000'>高い</t> 再解放の可能性<br/>%11<t color='#00CC00'>長い</t> 再解放の再計算間隔<br/>%2%3伸縮包帯:%4<br/>%11<t color='#00CC00'>高い</t> 治療効果<br/>%11<t color='#E60000'>高い</t> 再解放の可能性<br/>%11<t color='#E60000'>短い</t> 再解放の再計算間隔<br/>%2%クイッククロット:%4<br/>%11<t color='#E60000'>低い</t> 治療効果<br/>%11<t color='#00CC00'>低い</t> 再解放の可能性<br/>%11<t color='#00CC00'>長い</t> 再解放の再計算間隔<br/><br/>%3使用方法:%4<br/>%2[%3%13%4] または [%3%14%4] を使って身体の負傷個所を選択します。<br/>%2希望の%3包帯%4の種類を選択して部位に包帯を巻きます。 + Las %3Vendas%4 paran el sangrado y cierran las heridas. Dependiendo de las opciones configuradas, las heridas pueden reabrirse si no se realiza cirugía.<br/><br/>%2%3Vendaje de campaña:%4<br/>%11<t color='#D9D900'>Medio</t> en todas las categorias<br/>%2%3Vendaje compresivo:%4<br/>%11<t color='#D9D900'>Medio</t> Tratamiento<br/>%11<t color='#E60000'>Alto</t> Probabilidad de Reapertura<br/>%11<t color='#00CC00'>Larga</t> Retardo en reapertura<br/>%2%3Vendaje elástico:%4<br/>%11<t color='#00CC00'>Alto</t> Tratamiento<br/>%11<t color='#E60000'>Alto</t> Probabilidad de reapertura<br/>%11<t color='#E60000'>Corto</t> Retardo en reapertura<br/>%2%3Quickclot:%4<br/>%11<t color='#E60000'>Bajo</t> Tratamiento<br/>%11<t color='#00CC00'>Bajo</t> Probabilidad de Reapertura<br/>%11<t color='#00CC00'>Larga</t> Retardo en reapertura<br/><br/>%3Uso:%4<br/>%2Uso [%3%13%4] o [%3%14%4] y selecciona una parte del cuerpo herida.<br/>%2Venda la parte del cuerpo seleccionada eligiendo el tipo de %3Venda%4. IV Fluids @@ -135,6 +145,7 @@ Fluidi EV IV 輸液 IV Fluides + Fluidos IV Restore Blood Volume @@ -146,6 +157,7 @@ 血液量を回復する Внутривенные жидкости Restaurer le volume sanguin + Reestablece el volumen de sangre %3IV fluids%4 restore lost blood volume. Blood, Plasma, and Saline are functionally the same.<br/><br/>%3Usage:%4<br/>%2Use [%3%13%4] or [%3%14%4] and select an appendage.<br/>%2Restore blood volume by selecting desired %3IV Fluid%4 type. @@ -156,6 +168,7 @@ %3Fluidi EV%4 ristorano volume di sangue perso. Sangue, Plasma, e Salina sono funzionalmente identiche.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona un arto.<br/>%2Ristora il volume di sangue selezionando il tipo di %3Fluido EV%4 desiderato. %3IV 輸液%4は失われた血液を回復します。血液、血漿、生理食塩水は機能的には同じです。<br/><br/>%3使用方法:%4<br/>%2[%3%13%4] または [%3%14%4] を使って四肢を選択します。<br/>%2希望の%3IV 輸液%4の種類を選択して、血液量を復元します。 %%3Внутривенные жидкости%4восстанавливают потерянный объем крови. Кровь, плазма и физраствор функционально идентичны.<br/><br/>%3 Использование:%4<br/>%2 Используйте [%3%13%4] или [%3%14%4] и выберите добавку.<br/>%2 Восстановите объем крови выбрав желаемый %4тип %3жидкости + Los %3Fluidos IV%4 restauran el volumen de sangre. Sangre, Plasma, y Salino funcionan de manera similar.<br/><br/>%3Uso:%4<br/>%2Uso [%3%13%4] o [%3%14%4] y seleccionar una extremidad.<br/>%2Restaura el volumen de sangre seleccionando el tipo de %3Fluido IV%4 elegido. Increase Heart Rate | Wake Up Faster @@ -167,6 +180,7 @@ 心拍数を上げる | はやく起こす Увеличьте частоту сердечных сокращений | просыпайтесь быстрее Augmentation de la fréquence cardiaque - Réveil plus rapide + Incrementa el ritmo cardíaco | Despierta más rápido %3Epinephrine%4 increases a patient's pulse as well as potentially decreasing the time between consciousnesss checks (effectively reducing the time needed for the patient to wake up).<br/><br/>%3Usage%4<br/>%2Use [%3%13%4] or [%3%14%4] and select an appendage.<br/>%2Inject %3Epinephrine%4. @@ -176,6 +190,7 @@ %3Epinephrine%4 erhöht den Puls eines Patienten und verkürzt möglicherweise die Zeit zwischen Bewusstseinskontrollen (wodurch die Zeit, die der Patient zum Aufwachen benötigt, effektiv verkürzt wird).<br/><br/>%3Verwendung%4<br/>%2Verwende [%3%13%4] oder [%3%14%4] und wählen ein Körperteil aus.<br/>%2Injiziere %3Epinephrine%4. %3Epinefrina%4 aumenta il ritmo cardiaco di un paziente e riduce potenzialmente gli intervalli tra verifiche di coscienza (effettivamente riducendo il tempo necessario che questo paziente si svegli).<br/><br/>%3Utilizzo%4<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona un arto.<br/>%2Inietta %3Epinefrina%4. %3アドレナリン%4は、患者の脈拍を増加させるだけでなく、意識チェックの間隔を短縮する可能性があります。 (患者が目覚めるまでに必要な時間を効果的に短縮します)<br/><br/>%3使用方法%4<br/>%2[%3%13%4] または [%3%14%4] を使って四肢を選択します。<br/>%2%3アドレナリン%4を注射します。 + La %3Epinefrina%4 aumenta el pulso del paciente así como potencialmente disminuye el tiempo entre las comprobaciones sobre consciencia (reduciendo de manera efectiva el tiempo de despertar del paciente).<br/><br/>%3Uso%4<br/>%2Usa [%3%13%4] o [%3%14%4] y selecciona una extremidad.<br/>%2Inyecta %3Epinefrina%4. Restore Like New @@ -187,6 +202,7 @@ 生まれたてのように回復する Лечение тела Remettre comme neuf + Restaurar como nuevo The %3Personal Aid Kit%4 is an item that allows a soldier to be fully healed. Independent of %3ACE Settings%4, it requires that the patient is in %3Stable Condition%4 before use.<br/><br/>%3Stable Condition%4 qualifies as:<br/>%2Unit is %3Alive%4.<br/>%2Unit is %3Conscious%4.<br/>%2Unit has no active %3Bleeding%4.<br/>%2Heart Rate >= 40.<br/>%2Systolic BP >= 60.<br/>%2Diastolic BP >= 50.<br/><br/>%3Usage:%4<br/>%2Move to appropriate location depending on %3ACE Settings%4.<br/>%2Use [%3%13%4] or [%3%14%4] and select %3Advanced Treatments%4<br/>%2Select %3Use Personal Aid Kit%4. @@ -196,6 +212,7 @@ Das %3Persönliche Erste Hilfe Kit%4 ist ein Gegenstand, der es einem Soldaten ermöglicht, vollständig geheilt zu werden. Unabhängig von den %3ACE-Einstellungen%4 ist es erforderlich, dass sich der Patient vor der Verwendung in einem %3stabilen Zustand%4 befindet.<br/><br/>%3Stabiler Zustand%4 gilt wenn:<br/>%2Einheit ist %3am Leben%4 .<br/>%2Einheit ist %3Bei Bewusstsein%4.<br/>%2Einheit hat keine aktive %3Blutung%4.<br/>%2Herzfrequenz >= 40.<br/>%2Systolischer Blutdruck >= 60.< br/>%2Diastolischer Blutdruck >= 50.<br/><br/>%3Verwende:%4<br/>%2Bewege den Patienten je nach %3ACE-Einstellungen%4 an den entsprechenden Ort.<br/>%2Verwende [%3% 13%4] oder [%3%14%4] und wähle %3Erweiterte Behandlungen%4<br/>%2Wähle %3Persönliche Erste Hilfe Kit verwenden%4. Il %3Kit di Pronto Soccorso%4 è un oggetto che permette di curare completamente un soldato, indipendentemente da %3impostazioni ACE%4, richiede che il paziente sia in %3condizione stabile%4 prima dell'utilizzo.<br/><br/>%3Condizione stabile%4 significa:<br/>%2Paziente è %3Vivo%4.<br/>%2Paziente è %3Conscio%4.<br/>%2Paziente non sta %3Sanguinando%4.<br/>%2Ritmo cardiaco >= 40.<br/>%2Sistolico BC >= 60.<br/>%2Diastolico BC >= 50.<br/><br/>%3Utilizzo:%4<br/>%2Sposta in luogo specifico a seconda delle %3impostazioni ACE%4.<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona %3Trattamenti avanzati%4<br/>%2Seleziona %3Usa Kit di Pronto Soccorso%4. %3個人用治療キット%4は、兵士を完全に回復できるアイテムです。使用時には%3ACE 設定%4と関係なく、対象の患者が%3安定状態%4である必要があります。<br/><br/>%3安定状態%4とは次の状態です:<br/>%2ユニットが %3生存%4している。<br/>%2ユニットが %3覚醒状態%4である。<br/>%2ユニットが %3出血状態%4ではない。<br/>%2心拍数が40以上。<br/>%2収縮期血圧が60以上。<br/>%2拡張期血圧が50以上。<br/><br/>%3使用方法:%4<br/>%2%3ACE 設定%4で使用が許可された場所へ移動する。<br/>%2[%3%13%4] または [%3%14%4] を使って%3高度な治療%4を選択する。<br/>%2%3個人用治療キットを使う%4を選択して使用します。 + El %3Kit de Primeros Auxilios%4 es un objeto que permite al soldado ser curado totalmente. Independientemente de las %3Opciones de ACE%4, requiere que el paciente esté en %3Condición Estable%4 antes de usarse.<br/><br/>%3Condición Estable%4 significa que:<br/>%2La unidad está %3Viva%4.<br/>%2La unidad está %3Consciente%4.<br/>%2La unidad no está %3Sangrando%4.<br/>%2Ritmo Cardíaco >= 40.<br/>%2Presión Sistólica >= 60.<br/>%2Presión Diastólica >= 50.<br/><br/>%3Uso:%4<br/>%2Mover al lugar adecuado dependiendo de las%3Opciones de ACE%4.<br/>%2Uso [%3%13%4] o [%3%14%4] y seleccionar %3Tratamientos Avanzados%4<br/>%2Seleccionar %3Usar Kit de Primeros Auxilios%4. Fix Fractures @@ -207,6 +224,7 @@ 骨折を治す Исправлять переломы Réparation des fractures + Curar Fracturas A %3Splint%4 is used to fix fractures. The %3Splint%4 is consumed when used.<br/><br/>%3Usage:%4<br/>%2Use [%3%13%4] or [%3%14%4] and select an affected appendage.<br/>%2Select %3Apply Splint%4. @@ -216,6 +234,7 @@ Ein %3Splint%4 wird zur Fixierung von Frakturen verwendet. Der %3Splint%4 wird bei Verwendung verbraucht.<br/><br/>%3Verwendung:%4<br/>%2Verwende [%3%13%4] oder [%3%14%4] und wählen ein Körperteil aus.<br/>%2Wähle %3Schiene verwenden%4. Una %3Gessatura%4 è usata per risolvere fratture. La %3Gessatura%4 è consumata quando usata.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona un arto afflitto.<br/>%2Seleziona %3Applica Gessatura%4. %3添え木%4は骨折の治療に使います。%3添え木%4は使用時に消費します。<br/><br/>%3使用方法:%4<br/>%2[%3%13%4] または [%3%14%4] を使って使用したい四肢を選択します。<br/>%2%3添え木を当てる%4を選択して使用します。 + La %3Férula%4 se utiliza para curar fracturas. La %3Férula%4 se consume cuando es usada.<br/><br/>%3Uso:%4<br/>%2Usar [%3%13%4] o [%3%14%4] y seleccionar la extremidad adecuada.<br/>%2Seleccionar %3Aaplicar Férula%4. Prevent Wounds From Reopening @@ -226,6 +245,8 @@ 傷口が開くのを防ぐ Предотвратить повторное открытие ран Empêcher la réouverture des plaies + Verhindert, dass sich Wunden wieder öffnen + Prevenir la reapertura de heridas A %3Surgical Kit%4 is used to prevent wounds from reopening after being bandaged. Depending on settings, it can also clear trauma and may require additional %3Sutures%4 to close wounds. Sutures are consumable, much like bandages, and are not a replacement for the Surgical Kit.<br/><br/>%3Usage:%4<br/>%2Use [%3%13%4] or [%3%14%4] and select %3Advanced Treatment%4.<br/>%2Select %3Use Surgical Kit%4. @@ -234,6 +255,8 @@ O %3Kit Cirúrgico%4 é utilizado para prevenir a reabertura de feridas após a aplicação de bandagens. A depender das configurações, ele também pode remover traumas e pode requerir %3Suturas%4 adicionais para fechar feridas. Suturas são consumíveis, tal como as bandagens, e não são substituem o Kit Cirúrgico.<br/><br/>%3Uso:%4<br/>%2Utilize [%3%13%4] ou [%3%14%4] e selecione %3Tratamento Avançado%4.<br/>%2Selecione %3Usar Kit Cirúrgico%4. Un %3Kit Chirurgico%4 è usato per impedire che ferite bendate si riaprano. A seconda delle impostazioni, può anche azzerare danni o potrebbe richiedere %3Suture%4 aggiuntive per chiudere ferite. Suture sono consumabili proprio come bende, non sono un sostituto per un Kit Chirurgico.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona %3Trattamenti Avanzati%4.<br/>%2Seleziona %3Usa Kit Chirurgico%4. %3手術キット%4は包帯を巻いた傷口が再度開いて出血するのを防ぎます。設定によっては、負傷を取り除いたり、傷口を閉じるのに%3糸付縫合針%4を必要としたりします。糸付縫合針は消耗品で包帯のように使用され、手術キットを代替するものではありません。<br/><br/>%3使用方法:%4<br/>%2[%3%13%4] または [%3%14%4] を使って%3高度な治療%4を選択する。<br/>%2%3手術キット%4を選択して使用します。 + Ein %3Chirurgisches Kit%4 wird verwendet, um zu verhindern, dass sich Wunden nach dem Verbinden wieder öffnen. Abhängig von den Einstellungen kann es auch Traumata beseitigen und erfordert möglicherweise zusätzliche %3Nähte%4, um Wunden zu schließen. Nahtmaterial ist, ähnlich wie Bandagen, Verbrauchsmaterial und kein Ersatz für das Chirurgie-Set.<br/><br/>%3Verwendung:%4<br/>%2Verwenden Sie [%3%13%4] oder [%3% 14%4] und wählen Sie %3Erweiterte Behandlung%4.<br/>%2Wählen Sie %3Chirurgisches Kit verwenden%4. + El %3Kit Quirúrgico%4 se usa para prevenir la reapertura de heridas despues de ser vendadas. Dependiendo de las opciones, tambien puede curar traumatismos y puede requerir %3Sutura%4 adicional para cerrar las heridas. Las Suturas son consumibles, al igual que las vendas, y no son un reemplazo para el Kit Quirúgico.<br/><br/>%3Uso:%4<br/>%2Usar [%3%13%4] o [%3%14%4] y seleccionar %3Tratamientos Avanzados%4.<br/>%2Seleccionar %3Usar Kit Quirúgico%4. Stop Bleeding @@ -244,6 +267,8 @@ 出血を止める Остановить кровотечение Arrêter les saignements + Stoppt Blutung + Parar Sangrado A %3Tourniquet%4 stops bleeding temporarily so that a wound(s) can be bandaged. Can only be used on limbs.<br/><br/>%3Usage:%4<br/>%2Use [%3%13%4] or [%3%14%4] and select an affected appendage.<br/>%2Select %3Apply Tourniquet%4. @@ -252,6 +277,8 @@ O %3Torniquete%4 interrompe o sangramento temporariamente, para que feridas possam ser enfaixadas. Seu uso é restrito aos membros.<br/><br/>%3Uso:%4<br/>%2Utilize [%3%13%4] ou [%3%14%4] e selecione um membro afetado.<br/>%2Selecione %3Aplicar Torniquete%4. Un %3Laccio Emostatico%4 ferma emorragie temporaneamente in modo da poter bendare ferite con calma. Utilizzabile su arti.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona un arto afflitto.<br/>%2Seleziona %3Applica Laccio Emostatico%4. %3止血帯%4は一時的に出血を止め、その間に傷に包帯を巻くことができます。四肢にのみ使用できます。<br/><br/>%3使用方法:%4<br/>%2[%3%13%4] または [%3%14%4] を使って使用したい四肢を選択します。<br/>%2%3止血帯を巻く%4を選択して使用します。 + Ein %3Tourniquet%4 stoppt die Blutung vorübergehend, sodass eine oder mehrere Wunden verbunden werden können. Kann nur an Gliedmaßen verwendet werden.<br/><br/>%3Verwendung:%4<br/>%2Verwenden Sie [%3%13%4] oder [%3%14%4] und wählen Sie ein betroffenes Glied aus.< br/>%2Wählen Sie %3Tourniquet anwenden%4. + El %3Torniquete%4 para temporalmente el sangrado hasta que la herida sea vendada. Sólo puede ser usado en extremidades.<br/><br/>%3Uso:%4<br/>%2Usar [%3%13%4] o [%3%14%4] y seleccionar la extremidad afectada.<br/>%2Seleccionar %3Aplicar Torniquete%4. Medical Menu @@ -277,6 +304,7 @@ Tratamento, Simplificado 治療を簡略化する Traitement, simplifié + Tratamiento, Simplificado The %3Medical Menu%4 is a dedicated %3interface%4 to facilitate %3medical treatment%4. The %3R%4 and %3L%4 letters indicate the side of the patient's body being treated.<br/><br/>%3Usage:%4<br/>%2Use [%3%14%4] while looking at a patient to open the Medical Menu. Opening the menu without a patient allows for self-treatment.<br/>%2Alternatively, use [%3%12%4] or [%3%13%4] and select %3Medical Menu%4.<br/><br/>%3Keybinds:%4<br/>%2Use [%3W, A, S, D, X, and Z%4] to select body parts.<br/>%2Use your %3number keys%4 to select treatment categories. @@ -285,6 +313,7 @@ O %3Menu Médico%4 é uma %3interface%4 dedicada a facilitar o %3tratamento médico%4. As letras %3R%4 e %3L%4 indicam o lado do corpo do paciente que está recebendo o tratamento.<br/><br/>%3Uso:%4<br/>%2Utilize [%3%14%4] enquanto olha o paciente para abrir o Menu Médico. Se não houver paciente, o menu será de auto-tratamento.<br/>%2Alternativamente, utilize [%3%12%4] ou [%3%13%4] e selecione %3Menu Médico%4.<br/><br/>%3Atalhos de teclado:%4<br/>%2Utilize [%3W, A, S, D, X, e Z%4] para selecionar partes do corpo.<br/>%2Utilize as %3teclas numéricas%4 para selecionar as categorias de tratamento. Il %3Menù Medico%4 è un'%3interfaccia%4 dedicata a facilitare %3trattamenti medici%4. Le lettere %3Dx%4 e %3Sx%4 contrassegnano i lati del corpo del paziente che si stanno medicando.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%14%4] guardando il paziente per aprire il Menù Medico. Aprire il menù senza paziente di fronte permette l'automedicazione.<br/>%2In alternativa, usa [%3%12%4] o [%3%13%4] e seleziona %3Menù Medico%4.<br/><br/>%3Comandi:%4<br/>%2Usa [%3W, A, S, D, X, and Z%4] per selezionare parti del corpo.<br/>%2Usa %3tasti numerici%4 per selezionare categorie di cure. %3医療メニュー%4は%3治療%4をしやすくするための専用%3インターフェース%4です。%3右%4と%3左%4の文字は治療を受ける患者の向きを表しています。<br/><br/>%3使用方法:%4<br/>%2[%3%14%4] を患者に視点を合わせながら押すことで患者の医療メニューを開けます。視点を合わせないで押すと、自分の医療メニューを開くことが出来ます。<br/>%2もしくは [%3%12%4] または [%3%13%4] を使って%3医療メニュー%4を選択します。<br/><br/>%3キーバインド:%4<br/>%2[%3W, A, S, D, X, と Zキー%4] を使って身体の部位を選択できます。<br/>%2%3数字キー%4を使って治療項目を選択できます。 + El %3Menú Médico%4 es una %3interfaz%4 dedicada para facilitar el %3tratamiento médico%4. Las letras %3R%4 and %3L%4 indican el lado del paciente siendo tratado.<br/><br/>%3Uso:%4<br/>%2Usar [%3%14%4] mientras se mira al paciente para abrir el Menú Médico. Abrir el menú sin mirar a un paciente permite el tratamiento a uno mismo. <br/>%2Alternativamente, usar [%3%12%4] o [%3%13%4] y seleccionar %3Menú Médico%4.<br/><br/>%3Teclas asociadas:%4<br/>%2Usar [%3W, A, S, D, X, and Z%4] para seleccionar las partes del cuerpo.<br/>%2Usar las %3teclas numéricas%4 para seleccionar las categorías de tratamiento. Portable, Precise, Rugged @@ -294,6 +323,7 @@ Leggero, Preciso, Robusto 高機動、高精度、高耐久 Portable, précis, robuste + Portable, Preciso, Robusto The %3Horus ATragMX%4 considers atmospheric conditions, gun data, ammunition, range, speed, and muzzle velocity to calculate precise aiming solutions with %3Come-Up%4 results - and even accounts for %3Coriolis%4 and %3Spin Drift%4 effects. %3ATragMX%4, loaded on a handheld computer made by %3TDS Recon%4, is easy to use and lightning fast. The %3Recon%4 meets the rigorous %3MIL-STD-810F%4 military standard for drops, vibration, humidity, altitude and extreme temperatures.<br/><br/>%3Usage:%4<br/>Please visit the wiki page for more information. @@ -302,6 +332,7 @@ O %3Horus ATragMX%4 considera condições atmosféricas, dados de armas, munição, alcance, e velocidade do projétil - e até os efeitos Coriolis e Spin - para calcular as configurações necessárias da mira. O %3ATragMX%4, carregado em um computador portátil feito pela %3TDS Recon%4, é rápido e fácil de usar. O %3Recon%4 satisfaz os rigorosos padrões militares %3MIL-STD-810F%4 para quedas, vibrações, umidade, altitude e temperaturas extremas.<br/><br/>%3Uso:%4<br/>Por favor, visite a wiki para mais informações. L'%3Horus ATragMX%4 tiene conto di condizioni atmosferiche, caratteristiche del fucile, munizioni, portata e velocità alla volata per calcolare precise impostazioni di mira con risultati %3Come-Up%4 - considerando anche effetti %3Coriolis%4 e %3Magnus%4. L'%3ATragMX%4, caricato su un computer portabile %3TDS Recon%4, è facile da usare e molto rapido nei calcoli. Il %3Recon%4 soddisfa i rigorosi standard militari %3MIL-STD-810F%4 per cadute, vibrazioni, umidità, altitudine e temperature estreme.<br/><br/>%3Utilizzo:%4<br/>Visitate la pagina wiki per ulteriori informazioni. %3ホルス ATragMX%4は、大気条件、銃のデータ、弾薬、射程、速度、および初速を考慮した%3最適な結果が得られる%4正確な照準のための計算とその解法を提供します。さらに、%3コリオリ効果%4および%3スピン ドリフト効果%4も考慮します。%3ATragMX%4は%3TDS Recon製%4の携帯コンピュータに読み込まれており、使いやすく、超高速です。%3Recon%4はは、落下、振動、湿度、高度、極端な温度に関する厳格な%3MIL-STD-810F%4軍事規格を満たしています。<br/><br/>%3使用方法:%4<br/>詳細については、Wiki ページを参照してください。 + El %3Horus ATragMX%4 tiene en cuenta las condiciones atmosféricas, datos del arma, munición, distancia, velocidad y velocidad en boca para calcular con precisión soluciones de tiro precisas con %3Resultados%4 - e incluso tiene en cuenta los efectos %3Coriolis%4 y %3Movimiento Giroscópico%4. %3ATragMX%4, cargado en un ordenador portátil fabricado por %3TDS Recon%4, es facil de usar y muy rápido. El %3Recon%4 cumple con los rigurosos estándares militares %3MIL-STD-810F%4 en cuanto a caidas, vibraciones, humedad, altitud y temperaturas extremas.<br/><br/>%3Uso:%4<br/>Por favor, visita la página de la Wiki para más información. Bring Out Your Dead @@ -311,6 +342,7 @@ Recupera i tuoi morti 死者を連れ出す Récupérez vos morts + Trae de vuelta a los muertos %3Body Bags%4 are used to transport dead bodies. They can be dragged and loaded into vehicles.<br/><br/>%3Usage:%4<br/>%2Approach a dead body.<br/>%2Use [%3%13%4] or [%3%15%4] and select %3Place Body In Bodybag%4. @@ -319,6 +351,7 @@ OS %3Sacos de Cadáver%4 são utilizados para transportar cadáveres. Eles podem ser arrastados e embarcados em veículos.<br/><br/>%3Uso:%4<br/>%2Aproxime-se de um cadáver.<br/>%2Utilize [%3%13%4] ou [%3%15%4] e selecione %3Colocar cadáver dentro do saco%4. %3Sacche per cadaveri%4 sono usate per trasportare i morti. Possono essere trascinate e caricate su veicoli.<br/><br/>%3Utilizzo:%4<br/>%2Avvicinati ad un morto.<br/>%2Usa [%3%13%4] o [%3%15%4] e seleziona %3Metti il corpo nella sacca per cadaveri%4. %3遺体袋%4は、遺体の輸送に使用されます。引きずって車両に積み込むことができます。<br/><br/>%3使用方法:%4<br/>%2遺体に近寄る。<br/>%2[%3%13%4] または [%3%15%4] を使って%3遺体袋に入れる%4を選択して使用します。 + Las %3Bolsas para Cadáveres%4 se usan para transportar cadáveres. Pueden ser arrastradas y cargadas en vehículos. <br/><br/>%3Uso:%4<br/>%2Acercarse a un cadáver.<br/>%2Usar [%3%13%4] o [%3%15%4] y seleccionar %3Colocar cuerpo en la Bolsa para Cadáveres%4. Take Prisoners @@ -328,6 +361,7 @@ Prendi prigionieri 捕虜の捕り方 Faire des prisonniers + Tomar prisioneros %3Cable Ties%4 enable a soldier to capture and detain another soldier. Once apprehended, the captor gains the ability to inspect the prisoner's belongings, set them free, or accompany them to an alternate area. Transporting escorted prisoners is also possible, including loading them into vehicles if needed. Depending on your settings, units may need to surrender before being taken captive.<br/><br/>%3Usage:%4<br/>%2Approach the unit and use the [%3%13%4].<br/>%2The interaction is located around the hands in the form of a handcuffs icon.<br/>%2Repeat to release. @@ -336,6 +370,7 @@ As %3Algema Plásticas%4 permitem a captura e detenção de soldados. Quando apreendidos, o captor se torna capaz de inspecionar os pertences do prisioneiro, liberá-los, ou acompanhá-los a outro local. Transportes mais longos também são possíveis, podendo colocá-los em veículos, se necessário. A depender das configurações, pode ser necessário que as unidades estejam rendidas antes de serem detidas.<br/><br/>%3Uso:%4<br/>%2Aproxime-se da unidade e use [%3%13%4].<br/>%2A interação encontra-se próxima às mãos simbolizada por uma algema.<br/>%2Faça o mesmo para liberar. %3Fascette%4 permettono a soldati di catturare e ammanettare altri soldati. Una volta catturati è possibile ispezionare il loro inventario, liberarli o scortarli altrove. È inoltre possibile caricarli su veicoli se necessario. A seconda delle impostazioni, potrebbe essere necessaria la resa di unità prima di poterle ammanettare.<br/><br/>%3Uso:%4<br/>%2Avvicinati all'unità e usa [%3%13%4].<br/>%2L'interazione è localizzata intorno alle mani con l'icona di manette.<br/>%2Ripeti per liberare. %3ケーブル タイ%4は兵士が他の兵士を拘束できるようにします。一度拘束すれば、拘束者は捕虜の所持品を検査したり、釈放したり、別の場所に移送することができるようになります。必要に応じて車両に積み込むなどして捕虜の輸送や護送も可能です。設定によっては、ユニットは捕虜になる前に降伏する必要がある場合があります。<br/><br/>%3使用方法:%4<br/>%2対象に近づいて [%3%13%4] を使います。<br/>%2インタラクションは、手錠アイコンの形で手のあたりに表示されます。<br/>%2同様の方法で解放できます。 + Las %3Bridas%4 permiten a un soldado capturar y detener a otro soldado. Una vez atado, el capturador tiene la habilidad de inspeccionar las pertenencias del prisionero, liberarles de nuevo o transportarles a otro área diferente. Transportar prisioneros escoltados tambien es posible, incluído montarles en vehículos si es necesario. Dependiendo de las opciones, puede requerirse que las unidades se rindan antes de ser capturados.<br/><br/>%3Uso:%4<br/>%2Acercarse a la unidad y usar el [%3%13%4].<br/>%2El punto de interacción se situa sobre las manos en forma de un icono de unas esposas.<br/>%2Repetir el paso para liberar. Phone In An Explosion @@ -345,6 +380,7 @@ Cellulare per esplosivi 電話でドカン Explosifs téléphone portable + Teléfono explosivo The %3Cellphone%4 is functionally a %3Clacker%4. Use it to connect and detonate an explosive device. Multiple devices can be linked to the cellphone and called within the phonebook.<br/><br/>%3Usage:%4<br/>%2Place an explosive.<br/>%2Use [%3%13%4], select %3Explosives%4, and select %3Cellphone%4.<br/>%2Open the cellphone interface with [%3%12%4].<br/>%2Navigate the phone book with the arrows and select your calling number.<br/>%2Call the number to detonate. @@ -353,6 +389,7 @@ O %3Celular%4 serve como dispositivo de detonação ao explosivo. Utilize-o para conectar e detonar dispositivos explosivos. Múltiplos dispositivos podem estar conectados ao celular e aparecerão na lista telefônica.<br/><br/>%3Uso:%4<br/>%2Plante o explosivo.<br/>%2Utilize [%3%13%4], selecione %3Explosivos%4, e selecione %3Celular%4.<br/>%2Abra a interface do celular com [%3%12%4].<br/>%2Navegue pela lista telefônica utilizando as setas e selecione o número desejado.<br/>%2Ligue para o número para detonar. Il %3Cellulare%4 è essenzialmente una %3spoletta%4. Usalo per collegare e detonare esplosivi. Molteplici esplosivi possono essere collegati ad un cellulare e detonati chiamando numeri nella rubrica.<br/><br/>%3Utilizzo:%4<br/>%2Piazza un esplosivo.<br/>%2Usa [%3%13%4], seleziona %3Esplosivi%4, seleziona %3Cellulare%4.<br/>%2Apri l'interfaccia del telefono con [%3%12%4].<br/>%2Naviga la rubrica con le freccette e seleziona il numero da chiamare.<br/>%2Chiama il numero del dispositivo da detonare. %3携帯電話%4は%3点火装置%4として機能します。爆破装置を接続して起爆するために使用します。複数のデバイスを携帯電話に繋ぎ、電話帳から呼び出すことができます。<br/><br/>%3使用方法:%4<br/>%2爆発物を設置。<br/>%2[%3%13%4] を使い、%3爆発物%4を選択して、%3携帯電話%4を選択します。<br/>%2[%3%12%4] を使って携帯電話インターフェースを開きます。<br/>%2矢印ボタンで電話帳に移動し、発信番号を選択します。<br/>%2電話を掛けることで起爆します。 + El %3Teléfono%4 es funcionalmente un %3Detonador%4. Úsalo para conectarlo y detonar un dispositivo explosivo. Múltiples dispositivos pueden ser conectados al teléfono y llamados desde la agenda de contactos.<br/><br/>%3Uso:%4<br/>%2Colocar un explosivo.<br/>%2Usar [%3%13%4], seleccionar %3Explosivos%4, y seleccionar %3Teléfono%4.<br/>%2Abrir la interfaz del teléfono con [%3%12%4].<br/>%2Navegar por la agenda de contactos con las flechas y selecciona el número a llamar.<br/>%2Llamar al número para detonarlo. Portable Reading Lights @@ -362,6 +399,7 @@ Luci da Lettura Portabili 携帯読書灯 Lampes de lecture portables + Luces de Lectura Portátiles %3Chemlight Shields%4 give you the ability to read your map, even in dark environments. However, when using %3Chemlight Shields%4, you will have a slight glow around you.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2elect %3Chemlights%4 and %3Prepare Chemlight Shield (Color)%4.<br/>%2Open %3Map%4.<br/>%2Use [%3%12%4] and select %3Flashlights%4 where you will find your chemlight shield. @@ -370,6 +408,7 @@ Os %3Protetores de Bastão de Luz%4 possibilitam a leitura de mapas em ambientes escuros. Todavia, quando utilizados, eles iluminam parcialmente os seus arredores.<br/><br/>%3Uso:%4<br/>%2Utilize [%3%12%4] e selecione %3Equipamento%4.<br/>%2Selecione %3Bastões de Luz%4 e %Preparar Protetor de Bastão de Luz (Cor)%4.<br/>%2Abrir %3Mapa%4.<br/>%2Utilize [%3%12%4] e selecione %3Lanternas%4 onde você encontrará o seu bastão de luz. %3Scudi per Luci Chimiche%4 permettono di leggere la mappa anche in ambienti bui. Il loro utilizzo comporta però un leggero effetto di luminosità intorno alla testa del giocatore.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] e seleziona %3Eqipaggiamenti%4.<br/>%2Seleziona %3Luce Chimica%4 e %3Prepara Scudo Luce Chimica (Colore)%4.<br/>%2Apri %3Mappa%4.<br/>%2Usa [%3%12%4] e seleziona %3Torcia%4 dove troverai il tuo scudo per luce chimica. %3ケミライト シールド%4を使用すると、暗い環境でも地図を読み取ることができます。ただし、%3ケミライト シールド%4を使用すると、周囲がわずかに光ります。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3ケミライト%4を選択し%3ケミライト シールドを使う (色)%4を選択します。<br/>%2%3マップ%4を開きます。<br/>%2[%3%12%4] を使って%3フラッシュライト%4を選択し、ケミライト シールドを選択します。 + Los %3Protectores de Luz Química%4 proveen la habilidad de poder leer mapas en entornos oscuros. No obstante, cuando se usan los, %3Protectores de Luz Química%4, tendrás un ligero brillo alrededor tuyo.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar %3Luces químicas%4 y %3Preparar Protector de Luz Química (Color)%4.<br/>%2Abrir %3Mapa%4.<br/>%2Usar [%3%12%4] y seleccionar %3Linternas%4 donde encontrarás el protector de luz química. Remote Detonation @@ -379,6 +418,7 @@ Detonazione da remoto リモコン爆弾 Détonation à distance + Detonación Remota Use %3Clackers%4 to connect and detonate an explosive device. Multiple devices can be linked to a clacker and detonated on different channels.<br/><br/>%3Usage:%4<br/>%2Place an explosive.<br/>%2Use [%3%13%4], select %3Explosives%4, and select the %3Clacker%4 you wish to link to.<br/>%2Open the ACE interface with [%3%12%4].<br/>%2Select %3Explosives%4 and select a %3Clacker%4.<br/>%2Select the %3Explosive%4 you wish to detonate. @@ -386,6 +426,7 @@ %3격발기%4를 사용하여 폭발물을 연결하고 폭발시킬 수 있습니다. 여러 폭발물을 다른 채널에 연결하여 폭발시킬 수도 있습니다.<br/><br/>%3사용 방법:%4<br/>%2폭발물을 설치합니다.<br/>%2[%3%13%4]를 사용하여 %3폭발물%4을 선택하고 연결할 %3격발기%4를 선택하십시오.<br/>%2[%3%12%4] 키로 ACE 인터페이스를 여십시오.<br/>%2%3폭발물%4을 선택하고 %3격발기%4를 선택하십시오.<br/>%2%3폭발물%4을 선택하면 폭발합니다. Usa %3Spolette%4 per collegare e detonare dispositivi esplosivi. Molteplici dispositivi possono essere collagati a una spoletta e detonati individualmente come vari canali.<br/><br/>%3Utilizzo:%4<br/>%2Piazza esplosivo.<br/>%2Usa [%3%13%4], seleziona %3Esplosivo%4, seleziona la %3Spoletta%4 a cui intendi collegarlo.<br/>%2Apri l'interfaccia ACE con [%3%12%4].<br/>%2Seleziona %3Esplosivi%4 e scegli una %3Spoletta%4.<br/>%2Seleziona un %3Explosivo%4 da detonare. %3点火装置%4を爆破装置に接続し使用することで起爆することが出来ます。複数の爆破装置を接続しそれぞれ違うチャンネルから起爆することもできます。<br/><br/>%3使用方法:%4<br/>%2爆発物を設置。<br/>%2[%3%13%4] を使い、%3爆発物%4を選択して、接続したい%3点火装置%4を選択します。<br/>%2ACEインターフェースを [%3%12%4] で開きます。<br/>%2%3爆発物%4を選択し、%3点火装置%4を選びます。<br/>%2起爆したい%3爆破装置%4を選択します。 + Utiliza los %3Detonadores%4 para conectar y detonar un explosivo. Múltiple dispositivos pueden ser conectados a un detonador y detonados en diferentes canales.<br/><br/>%3Uso:%4<br/>%2 Coloca un explosivo.<br/>%2Usar [%3%13%4], seleccionar %3Explosivos%4, y selecciona el %3Detonador%4 al que quieres conectarlo.<br/>%2Abre la interfaz de ACE con [%3%12%4].<br/>%2Selecciona %3Explosivos%4 y selecciona un %3Detonador%4.<br/>%2Selecciona el %3Explosivo%4 que quieres detonar. Navigate @@ -395,6 +436,7 @@ 測位 Навигация Naviguer + Navegar The %3DAGR%4 is a simpler version of the %3MicroDAGR GPS%4. It has similar features but lacks the topographic and satellite imaging functions of the %3MicroDAGR GPS%4.<br/><br/>%3Usage:%4<br/>%2Equip a %3DAGR%4.<br/>%2Use [%3%12%4] and select %3Configure%4 or %3Toggle%4.<br/><br/>The following menus are available when configuring your %3DAGR:%4<br/>%11%2Data View: WIP<br/>%11%2GoTo WP: Select a waypoint to track.<br/>%11%2WP List: Add/Edit/Remove waypoints.<br/>%11%2Connect To: Connect %3DAGR%4 to the %3Vector 21 Rangefinder%4.<br/>%11%2Options @@ -402,6 +444,7 @@ %3DAGR%4은 %3마이크로DAGR GPS%4의 단순화 버전입니다. 유사한 기능을 가지고 있지만 %3마이크로DAGR GPS%4의 지형 및 위성 이미지 기능이 없습니다.<br/><br/>%3사용 방법:%4<br/>%2%3DAGR%4를 장착하십시오.<br/>%2[%3%12%4를 사용하고 %3DAGR 설정%4 또는 %3DAGR 토글%4을 선택하십시오.<br/><br/>%3DAGR%4을 구성할 때 다음 메뉴를 사용할 수 있습니다:<br/>%11%2Data View: 제작 중<br/>%11%2GoTo WP: 추적할 웨이포인트를 선택합니다.<br/>%11%2WP List: 경유지를 추가/편집/제거합니다.<br/>%11%2Connect To: %3DAGR%4을 %3벡터 21%4 거리계에 연동시킵니다.<br/>%11%2옵션입니다 Il %3DAGR%4 è una versione più semplice del %3GPS MicroDAGR%4. Ha funzioni simili, gli manca però la capacità di visualizzare informazioni topografiche e satellitari come il %3GPS MicroDAGR%4.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia il %3DAGR%4.<br/>%2Usa [%3%12%4] e seleziona %3Configura%4 o %3Apri%4.<br/><br/>I seguenti Menù sono disponibili durante la configurazione del tuo %3DAGR:%4<br/>%11%2Pagina Dati: WIP<br/>%11%2VaiA WP: Seleziona un waypoint da tracciare.<br/>%11%2Lista WP: Aggiungi/Modifica/Rimuovi waypoint.<br/>%11%2Collega A: Collega il %3DAGR%4 al %3Telemetro Vector 21%4.<br/>%11%2Opzioni %3DAGR%4はシンプルなバージョンの%3MicroDAGR GPS%4です。同様の機能を備えていますが、%3MicroDAGR GPS%4のような地形および衛星画像機能はありません。<br/><br/>%3使用方法:%4<br/>%2%3DAGR%4を装備する。<br/>%2[%3%12%4] を使って%3設定%4 もしくは %3表示切替%4を選択します。<br/><br/>%3DAGR%4の設定には次のメニューを使用できます:<br/>%11%2Data View: WIP<br/>%11%2GoTo WP: 追跡するウェイポイントを選択します。<br/>%11%2WP List: ウェイポイントを追加/編集/削除します。<br/>%11%2Connect To: %3DAGR%4を%3ベクター 21 レンジファインダー%4に接続できます。<br/>%11%2Options + El %3DAGR%4 es una versión simplificada del %3MicroDAGR GPS%4. Tiene unas funcionalidades similares pero le faltan las funciones de los mapas topográficos e imágenes satelitales del %3MicroDAGR GPS%4.<br/><br/>%3Usage:%4<br/>%2Equip a %3DAGR%4.<br/>%2Usar [%3%12%4] y seleccionar %3Configurar%4 o %3Activar%4.<br/><br/>Los siguientes menús están disponibles cuando configuras el %3DAGR:%4<br/>%11%2Vista de Datos: WIP<br/>%11%2Ir a WP: Selecciona un Punto de Ruta para seguir.<br/>%11%2Lista de WP: Añadir/Editar/Suprimir puntos de ruta.<br/>%11%2Conectar A: Conectar %3DAGR%4 a %3Telémetro Vector 21%4.<br/>%11%2Opciones Explosive Revenge @@ -411,6 +454,7 @@ 爆発的な復讐 Взрывная месть Homme mort + Venganza Explosiva The %3Dead Man's Switch%4 is a device that allows a soldier to detonate an %3Explosive%4 when the soldier dies.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Explosives%4.<br/>%2Select %3Dead Man's Switch%4 and connect the desired %3Explosive%4.<br/>%2Repeat the process and disconnect to reverse. @@ -418,6 +462,7 @@ %3자폭 장치%4는 병사가 사망했을 때 병사가 %3폭발물%4을 폭발시킬 수 있는 장치입니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4]를 사용하고 %3폭발물%4을 선택하십시오.<br/>%2%3자폭 장치%4를 선택하고 원하는 %3폭발물%4에 연결하십시오.<br/>%2반대로 해제하고 싶다면 같은 행동을 반복하십시오. Il %3Detonatore a rilascio%4 è un dispositivo che permette a soldati di detonare un %3Esplosivo%4 quando perdono i sensi.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] e seleziona %3Esplosivi%4.<br/>%2Seleziona %3Detonatore a rilascio%4 e collega l'%3Esplosivo%4 desiderato.<br/>%2Ripeti il processo e scollega per disarmare il detonatore. %3自爆装置%4は、兵士の死亡時に%3爆発物%4を起爆させることができる装置です。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3爆発物%4を選択します。<br/>%2%3自爆装置%4を選択し、接続したい%3爆発物%4を選びます。<br/>%2同様の手順を逆に行うことで接続を解除できます。 + El %3Detonador de Hombre Muerto%4 es un dispositivo que permite a un soldado detonar un %3Explosivo%4 cuando el soldado muere.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Explosivos%4.<br/>%2Seleccionar %3Detonador de Hombre Muerto%4 y conectar el %3Explosivo%4.<br/> deseado%2Repetir el proceso y desconectar para revertirlo. The %3Defusal Kit%4 allows defusal of explosives.<br/><br/>%3Usage:%4<br/>%2Equip a %3Defusal Kit%4.<br/>%2Safely approach an %3Explosive%4.<br/>%2Use [%3%13%4] and select %3Defuse%4. @@ -425,6 +470,7 @@ %3해체 장비%4를 사용하면 폭발물을 제거할 수 있습니다.<br/><br/>%3사용 방법:%4<br/>%2%3해체 장비%4를 장착하십시오.<br/>%2%3폭발물%4에 안전하게 접근하십시오.<br/>%2[%3%13%4]를 사용하고 %3해체%4를 선택하십시오. The %3Kit E.O.D.%4 permette il disinnesco di esplosivi.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia un %3Kit E.O.D.%4.<br/>%2Avvicinati in modo sicuro ad un %3Esplosivo%4.<br/>%2Usa [%3%13%4] e seleziona %3Disinnesca%4. %3解除キット%4は爆発物の無力化を行うことができます。<br/><br/>%3使用方法:%4<br/>%2%3解除キット%4を装備。<br/>%2慎重に%3爆発物%4に接近します。<br/>%2[%3%13%4] を使って%3無力化%4を選択します。 + El %3Kit de Desactivación%4 permite la desactivación de explosivos.<br/><br/>%3Uso:%4<br/>%2Equipa un %3Kit de Desactivación%4.<br/>%2Aproxímate al %3Explosivo%4<br/> de forma segura.%2Usa [%3%13%4] y selecciona %3Desactivar%4. Defuse Explosives @@ -434,6 +480,7 @@ 爆発物の解除 Обезвреживание взрывчатки Désamorcer les explosifs + Desactivar Explosivos Protect Your Hearing @@ -443,6 +490,7 @@ 聴覚の保護 Защитите свой слух Protéger votre audition + Protege tus oídos %3Ear Plugs%4 help prevent hearing damage from repeat loud noises near a soldier. Insert %3Ear Plugs%4 to lower volume of a soldier's environment and prevent %3Combat Deafness%4.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Insert %3Ear Plugs%4. @@ -450,6 +498,7 @@ %3Tappi auricolari%4 aiutano a prevenire danni all'udito da ripetuti rumori forti in prossimità del soldato. Inserisci %3Tappi auricolari%4 per ridurre il volume dell'ambiente per il soldato e impedire %3Assordamento%4.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] e seleziona %3Equipaggiamento%4.<br/>%2Indossa %3Tappi Auricolari%4. %3귀마개%4는 병사 주변에서 반복되는 시끄러운 소리로 인한 청력 손상을 방지하는 데 도움이 됩니다. %3귀마개%4를 끼워서 병사가 있는 환경의 소리 크기를 낮추고 %3전투로 인한 청력손상%4을 방지하십시오.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4]를 사용하여 %3장비%4를 선택하십시오.<br/>%2%3귀마개%4를 삽입하십시오. %3耳栓%4は、兵士の近くで繰り返される大きな騒音による聴覚障害を防ぐのに役立ちます。%3耳栓%4を耳に挿入することで兵士の環境の音量を下げ、%3戦闘難聴%4を防ぎます。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3耳栓を着ける%4ことで使用できます。 + Los %3Tapones de oídos%4 ayudan a prevenir el daño auditivo de ruidos altos repetidos cerca de un soldado. Inserta los %3Tapones de oídos%4 para reducir el volumen del entorno del soldado y prevenir la %3Sordera de Combate%4.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Insertar %3Tapones de oídos%4. Get To Cover @@ -459,6 +508,7 @@ 遮蔽を造り出す Добраться до укрытия Se mettre à couvert + Ponerse A Cubierto The %3Entrenching Tool%4 allows soldiers to dig trenches to help defend their position. The soldier must be on soil in order to dig a trench.<br/><br/>%3Usage:%4<br/>%2Equip an %3Entrenching Tool%4.<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select the type of trench you wish to build. @@ -466,6 +516,7 @@ La %3Pala da Trincea%4 permette a soldati di scavare trincee per difendere meglio la loro posizione. Il soldato deve trovarsi su suolo scavabile per poter creare trincee.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia una %3Pala da Trincea%4.<br/>%2Usa [%3%12%4] e seleziona %3Equipaggiamento%4.<br/>%2Seleziona il tipo di trincea che vuoi costruire. %3야전삽%4을 사용하면 병사들의 진지 방어를 위한 참호를 팔 수 있습니다. 병사가 참호를 파려면 흙 위에 있어야 합니다.<br/><br/>%3사용 방법:%4<br/>%2%3야전삽%4을 장비하십시오.<br/>%2[%3%12%4]를 사용하여 %3장비%4를 선택하십시오.<br/>%2짓고 싶은 종류의 참호를 선택하십시오. %3塹壕ツール%4を使用すると、兵士は自分の陣地を守るために塹壕を掘ることができます。塹壕を掘るには、兵士は土の上にいる必要があります。<br/><br/>%3使用方法:%4<br/>%2%3塹壕ツール%4を装備します。<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2構築する塹壕の種類を選択します。 + La %3Pala de Trincheras%4 permite a los soldados excavar trincheras para ayudarles a defender su posición. El soldado debe estar sobre tierra para poder excavar una trinchera.<br/><br/>%3Uso:%4<br/>%2Equipar la %3Pala de Trincheras%4.<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar el tipo de trinchera que quieres construir. Flashlights @@ -475,6 +526,7 @@ フラッシュライト Фонари Lampes de poche + Linternas Illuminate Your Map @@ -484,6 +536,7 @@ 地図に光あれ Осветите свою карту Éclairer votre carte + Ilumina Tu Mapa %3Flashlights%4 give you the ability to read your map, even in dark environments. However, when using %3Flashlights%4, you will have a slight glow around you.<br/><br/>%3Usage:%4<br/>%2On the map screen, use [%3%12%4] and select %3Flashlights%4.<br/>%2Select the %3Flashlight%4 you want to use and select %3On%4.<br/><br/>%3Available Flashlight Items%4:<br/>%2 Fulton MX-991<br/>%2 KSF-1<br/>%2 Maglite XL50<br/><br/>%3NOTE:%4<br/>Flashlight states are persistent. @@ -491,6 +544,7 @@ %3Torce%4 permettono di leggere la tua mappa anche in ambienti bui. Però quando le utilizzi avrai un leggero effetto luminoso intorno a te.<br/><br/>%3Utilizzo:%4<br/>%2Sulla mappa usa [%3%12%4] e seleziona %3Torcia%4.<br/>%2Seleziona la %3Torcia%4 che vuoi usare e seleziona %3Accendi%4.<br/><br/>%3Oggetti Torcia Disponibili%4:<br/>%2 Fulton MX-991<br/>%2 KSF-1<br/>%2 Maglite XL50<br/><br/>%3NOTE:%4<br/>Lo stato di una torcia è persistente. %3손전등%4은 어두운 환경에서도 지도를 읽을 수 있는 기능을 제공합니다. 단, %3손전등%4을 사용할 때 주변에 약간 빛이 납니다.<br/><br/>%3사용 방법:%4<br/>%2지도 화면에서 [%3%12%4]를 사용하고 %3손전등%4을 선택하십시오.<br/>%2사용할 %3손전등%4을 선택하고 %3켜기%4를 선택하십시오.<br/><br/>%3사용 가능한 손전등 아이템%4:<br/>%2풀턴 MX-991<br/>%2 KSF-1<br/>%2 매그라이트 XL50<br/><br/>%3참고:%4<br/>손전등 상태는 영구적입니다. %3フラッシュライト%4を使用すると、暗い環境でも地図を読むことができます。ただし、%3フラッシュライト%4を使用すると、周囲がわずかに光ります。<br/><br/>%3使用方法:%4<br/>%2マップ画面で [%3%12%4] を使用し、%3フラッシュライト%4を選択します。<br/>%2%3フラッシュライト%4を選択し、使用したいライトを%3点ける%4。<br/><br/>%3使用可能なフラッシュライトのアイテム%4:<br/>%2 フルトン MX-991<br/>%2 KSF-1<br/>%2 マグライト XL50<br/><br/>%3備考:%4<br/>フラッシュライトの状態は継続します。 + Las %3Linternas%4 proveen la habilidad para leer tu mapa, incluso en entornos oscuros. No obstante, cuando se usen las %3Linternas%4, aparecerá un ligero brillo alrededor tuya.<br/><br/>%3Uso:%4<br/>%2En la pantalla del mapa, utilizar [%3%12%4] y seleccionar %3Linternas%4.<br/>%2Seleccionar la %3Linterna%4 Que quieres utilizar y selecciona %3On%4.<br/><br/>%3Objetos de Linternas disponibles%4:<br/>%2 Fulton MX-991<br/>%2 KSF-1<br/>%2 Maglite XL50<br/><br/>%3NOTA:%4<br/>Los estados de las Linternas son persistentes. Observe From The Skies @@ -500,6 +554,7 @@ 空から戦場を見てみよう Наблюдайте с Небес Observer depuis le ciel + Observar Desde El Cielo The %3High-Altitude Unit Navigated Tactical Imaging Round (HuntIR)%4 is designed to be fired from a grenade launcher. After being fired in the air, the built-in parachute will be deployed and the IR CMOS camera will activate, providing a video stream until it touches the ground or is shot down.<br/><br/>%3Usage:%4<br/>%2Equip a %3HuntIR Monitor%4 and compatible ammunition.<br/>%2Fire the %3HuntIR Round%4 as high as possible over the area you want to observe.<br/>%2Open the %3HuntIR Monitor%4.<br/>%2Use [%3%12%4], select %3Equipment%4.<br/>%2Select %3Activate HuntIR Monitor%4. @@ -507,6 +562,7 @@ Il %3High-Altitude Unit Navigated Tactical Imaging Round (HuntIR)%4 è progettato per essere sparato da un lanciagranate. Dopo essere stato sparato verso l'alto, verrà aperto un paracadute incorporato e attivata una videocamera IR CMOS, inviando una diretta video finché toccherà terra o verrà abbattuto.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia un %3Monitor HuntIR%4 e munizioni compatibili.<br/>%2Spara un %3Colpo HuntIR%4 il più alto possibile sopra l'area che vuoi osservare.<br/>%2Apri il %3Monitor HuntIR%4.<br/>%2Usa [%3%12%4], seleziona %3Equipaggiamento%4.<br/>%2Seleziona %3Attiva Monitor HuntIR%4. %3고고도 유닛 탐색용 전술 영상화 탄약 (HuntIR)%4은 유탄발사기에서 발사될 수 있도록 설계되었습니다.공주에서 발사된 후 내장된 낙하산이 전개되고 적외선 CMOS 카메라가 작동하여 지상에 닿거나 격추될 때까지 비디오 스트림이 제공됩니다.<br/><br/>%3사용 방법:%4<br/>%2%3헌트IR 모니터%4와 호환 탄약을 장착하십시오.<br/>%2%3헌트IR 유탄%4을 발사하려는 구역에서 가능한 한 높게 발사하십시오.<br/>%2%3헌트IR 모니터%4를 여십시오.<br/>%2[%3%12%4]를 사용하여 %3장비%4를 선택하십시오.<br/>%2%3헌트IR 모니터 활성화%4를 선택하십시오. %3High-Altitude Unit Navigated Tactical Imaging Round (HuntIR)%4はグレネードランチャーから発射されるように設計されています。空中で発射された後、内蔵のパラシュートが展開され、IR CMOS カメラが起動し、地面に着くか撃墜されるまでビデオ ストリームを提供します。<br/><br/>%3使用方法:%4<br/>%2%3HuntIR モニター%4と互換性のある弾薬を装備します。<br/>%2観測したいエリアに向けてできるだけ高く%3HuntIR 弾頭%4を発射します。<br/>%2%3HuntIR モニター%4を開きます。<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3HuntIRを起動する%4からモニターを起動します。 + El %3High-Altitude Unit Navigated Tactical Imaging Round (HuntIR)%4 está diseñado para ser disparado desde un lanzagranadas. Despues de ser disparada al aire, desplegará su paracaídas integrado y activará su cámara IR CMOS integrada, proveyendo de un flujo de video hasta que toque el suelo o sea derribado.<br/><br/>%3Uso:%4<br/>%2Equipa un %3Monitor HuntIR%4 y la munición compatible.<br/>%2Dispara la %3Munición HuntIR%4 tan alto como sea posible sobre el área que quieres observar.<br/>%2Abre el %3Monitor HuntIR%4.<br/>%2Usar [%3%12%4], seleccionar %3Equipamiento%4.<br/>%2Seleccionar %3Activar Monitor HuntIR%4. Track Your Team With Stealth @@ -516,6 +572,7 @@ 自分の部隊を追う Следите за своей командой незаметно Suivez votre équipe en toute discrétion + Sigue A Tu Equipo Con Sigilo The %3IR Strobe%4 is a throwable that emits an IR light pulse intermittently. The %3IR Strobe%4 can also be attached to a soldier, making it useful for tracking teammates under night vision devices.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select %3Attach%4 and select the %3IR Strobe%4. @@ -523,6 +580,7 @@ La %3Strobo IR%4 è un lanciabile che emette un impulso intermittente di luce IR. La %3Strobo IR%4 può anche essere attaccata ad un soldato, facilitando l'identificazione di alleati con visori notturni.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] e seleziona %3Equipaggiamento%4.<br/>%2Seleziona %3Attacca%4 e scegli la %3Strobo IR%4. %3적외선 스트로브%4는 던질 수 있는 적외선 광펄스를 간헐적으로 방출하는 투척형 아이템입니다. %3적외선 스트로브%4는 병사에게도 부착 가능하기 때문에 야간투시장치로 팀원을 추적할 때 유용합니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4]를 사용하여 %3장비%4를 선택하십시오.<br/>%2%3아이템 부착%4을 선택하고 %3적외선 스트로브%4를 선택하십시오. %3赤外線ストロボ%4は、赤外線光パルスを断続的に放射します。投擲可能です。%3赤外線ストロボ%4は兵士に取り付けることもできるため、暗視装置の下でチームメイトを追跡するのに役立ちます。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3アイテムを取り付ける%4を選択して%3赤外線ストロボ%4を選び使用します。 + El %3Estroboscópico IR%4 es un objeto lanzable que emite un pulso intermitente de luz IR. El %3Estroboscópico IR%4 tambien puede ser sujeto a un soldado, haciéndolo útil para el seguimiento de los compañeros utilizando gafas de visión nocturna.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar %3Sujetar%4 y seleccionar el %3Estroboscópico IR%4. Pocket Weatherstation @@ -532,6 +590,7 @@ 携帯気象予報所 Карманная метеостанция Station météo de poche + Estación Climática de Bolsillo The %3Kestrel 4500 Pocket Weather Tracker%4 is a mini weather station useful for collecting the the following weather data:<br/>%2Heading and wind direction<br/>%2Crosswind and headwind<br/>%2Altitude and barometric pressure<br/>%2Wet bulb temperature<br/>%2Humidity and dewpoint<br/>%2Density altitude<br/>%2Wind chill and temperature<br/>%2Time and date<br/>%2Minimum, maximum, and average values<br/><br/>%3Usage:%4<br/>%2Equip a %3Kestrel%4.<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select %3Open%4. @@ -539,6 +598,7 @@ Il %3Kestrel 4500 Indicatore Meteorologico Tascabile%4 è una mini-stazione meteo utile per ricavare le seguenti informazioni meteorologiche:<br/>%2Prua e direzione del vento<br/>%2Vento di traverso e frontale<br/>%2Altitudine and pressione barometrica<br/>%2Temperatura di bulbo umido<br/>%2Umidità e punto di rugiada<br/>%2Density altitude<br/>%2Temperatura e gelo del vento<br/>%2Data e Ora<br/>%2Valori minimi, massimi, e medi<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia %3Kestrel%4.<br/>%2Usa [%3%12%4] e seleziona %3Equipaggiamento%4.<br/>%2Seleziona %3Apri%4. %3케스트렐 4500 휴대용 기상 추적 장비%4는 다음 날씨 데이터들을 수집하는 데 유용한 소형 기상 관측 장비입니다:<br/>%2바람이 오는 방향과 가는 방향<br/>%2옆바람과 맞바람<br/>%2고도 및 기압<br/>%2습구온도<br/>%2습도 및 이슬점<br/>%2밀도고도<br/>%2체감온도<br/>%2시간 및 날짜<br/>%2최소, 최대, 평균값<br/><br/>%3사용 방법:%4<br/>%2%3케스트렐 4500NV%4를 장착하십시오.<br/>%2[%3%12%4]를 사용하고 %3장비%4를 선택하십시오.<br/>%2%3열기%4를 선택하십시오. %3ケストレル 4500 携帯気象計%4は、次の気象データの収集に役立つミニ気象ステーションです:<br/>%2方位と風向<br/>%2横風と向かい風<br/>%2高度と気圧<br/>%2湿球温度<br/>%2湿度と露点<br/>%2密度高度<br/>%2ウィンドチルと温度<br/>%2日付と時刻<br/>%2最小値、最大値、平均値<br/><br/>%3使用方法:%4<br/>%2%3ケストレル%4を装備します。<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3ケストレルを開く%4で使用できます。 + La %3Estación Climática de Bolsillo Kestrel 4500%4 es una pequeña estación climática portátil para recolectar la siguiente información del tiempo:<br/>%2Dirección y Sentido del Viento<br/>%2VIento cruzado y Viento en cola<br/>%2Altitud y presión barométrica<br/>%2Temperatura húmeda<br/>%2Humedad y punto de condensación<br/>%2Densidad de altitud<br/>%2Sensación térmica y temperatura<br/>%2Hora y fecha<br/>%2Valores mínimos, máximos y medios<br/><br/>%3Uso:%4<br/>%2Equipa un %3Kestrel%4.<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar %3Abrir%4. Triangulate Your Position @@ -548,6 +608,7 @@ 三角測量で位置を特定 Передавайте свое местоположение Trianguler votre position + Triangular Tu Posición The %3Map Tools%4 are a set of tools that allows a soldier to measure distances and angles. Useful for land, and calculating firing solutions for artillery.<br/><br/>%3Usage:%4<br/>%2Open %3Map%4.<br/>%2Use [%3%12%4] and select %3Map Tools%4.<br/>%2 The Tool can be moved by dragging with [%3Left-Click%4] while holding [%3ALT%4]. @@ -556,6 +617,7 @@ %3독도용 도구%4는 병사가 거리와 각도를 측정할 수 있는 도구 세트입니다. 지상에서 유용하며 포병 사격 솔루션 계산에 유용합니다,<br/><br/>%3사용 방법:%4<br/>%2%3지도%4를 여십시오.<br/>%2[%3%12%4]를 사용하여 %3독도용 도구%4를 선택하십시오.<br/>%2도구는 [%3Alt 키%4]를 누른 상태에서 [%3마우스 왼쪽 클릭%4]으로 드래그하여 이동할 수 있습니다. %3マップ ツール%4は、兵士が距離と角度を測定できるようにするツールのセットです。陸上や大砲の射撃工程の計算を解くのに役立ちます。<br/><br/>%3使用方法:%4<br/>%2%3マップ%4を開きます。<br/>%2[%3%12%4] を使って%3マップ ツール%4を選択します。<br/>%2 [%3ALT%4] を押しながら [%3左クリック%4] でドラッグするとツールを移動できます。 Les %3Outils cartographiques%4 sont un ensemble d'outils permettant au soldat de mesurer des distances et des angles. Utile pour la terre et le calcul des solutions de tir pour l'artillerie.<br/><br/>%3Utilisation:%4<br/>%2Ouvrir la%3Carte%4.<br/>%2Utiliser [%3%12%4] et sélectionner %3Outils cartographiques%4.<br/>%2 L'outil peut être déplacé en le faisant glisser avec [%3Clic gauche%4] tout en maintenant [%3ALT%4]. + Las %3Herramientas de mapa%4 son un conjunto de herramientas que permiten a un soldado medir distancias y ángulos. Util para terrenos, y para calcular soluciones de tiro para artillería.<br/><br/>%3Uso:%4<br/>%2Abrir %3Mapa%4.<br/>%2Usar [%3%12%4] y seleccionar %3Herramientas de Mapa%4.<br/>%2 La herramienta puede ser movida siendo arrastrada con [%3CLick-Izquierdo%4] mientras se pulsa [%3ALT%4]. Advanced DAGR @@ -565,6 +627,7 @@ より高度なDAGR Продвинутый DAGR DAGR avancé + DAGR Avanzado The %3MicroDAGR GPS%4 is an advanced version of the %3DAGR%4. It provides position, navigation, and timing (PNT) data to include:<br/>%2Compass and heading<br/>%2Date and hour synced to the mission<br/>%2Elevation (relative to sea level)<br/>%2Current speed<br/>%2GPS with topographic and satellite view<br/>%2Creating, naming, and deleting waypoints<br/>%2Friendly identification (Requires ACE BLUFOR Tracker Setting)<br/>Connection to the Vector-21 Rangefinder for data import (waypoint creation and grid reference of ranged targets)<br/><br/>%3Usage:%4<br/>%2For usage instructions, please visit the dedicated %3MicroDAGR%4 wiki. @@ -572,6 +635,7 @@ Il %3GPS MicroDAGR%4 è una versione avanzata del %3DAGR%4. Esso mostra dati su posizione, navigazione e tempismo (PNT), includendo:<br/>%2Bussola e azimut<br/>%2Data e ora sincronizzate con la missione<br/>%2Elevazione (dal livello del mare)<br/>%2Velocità attuale<br/>%2GPS con visuale topografica e satellitare<br/>%2Creazione, rinomina e rimozione di waypoint<br/>%2Identificazione di alleati (Richiede Impostazioni ACE BLUFOR Tracker)<br/>Connessione al Telemetro Vector-21 per importazione di dati (creazione waypoint e indicazione di griglia su bersagli puntati)<br/><br/>%3Utilizzo:%4<br/>%2Per informazioni sull'utilizzo sei pregato di visitare la pagina wiki dedicata al %3MicroDAGR%4. %3마이크로DAGR GPS%4는 %3DAGR%4의 고급 버전입니다. 다음과 같이 위치, 내비게이션 및 타이밍(PNT) 데이터를 제공합니다:<br/>%2나침반 및 방향<br/>%2임무와 동기화된 날짜 및 시간<br/>%2고도 (해수면 기준)<br/>%2현재 속도<br/>%2지형 및 위성 시점 기능이 있는 GPS<br/>%2웨이포인트 생성, 작명 및 삭제<br/>%2아군 식별 (ACE의 GPS 피아식별기 켜기 체크 필요)<br/>%2데이터를 가져오기 위한 벡터-21 거리계에 연결(원거리 대상의 웨이포인트 생성 및 좌표 참조)<br/><br/>%3사용 방법:%4<br/>%2사용 방법을 보려면 전용 %3마이크로DAGR%4의 위키를 방문하십시오. %3MicroDAGR GPS%4は%3DAGR%4のより高度なバージョンです。測位、航法、計時(PNT)データが提供されます。これには以下の情報を含みます:<br/>%2コンパスと方位<br/>%2ミッションに同期された日付と時間<br/>%2標高 (海面に対する相対値)<br/>%2現在の速度<br/>%2地形図と衛星ビューを備えたGPS<br/>%2ウェイポイントの作成、名前付け、および削除<br/>%2友軍の識別 (ACE ブルーフォーストラッキング設定が必要)<br/>ベクター21レンジファインダーへの接続とデータのインポート (ウェイポイントの作成と遠距離ターゲットのグリッド参照)<br/><br/>%3使用方法:%4<br/>%2使用手順については、専用の %3MicroDAGR%4 wiki を参照してください。 + El %3GPS MicroDAGR%4 es una versión avanzada del %3DAGR%4. Provee de posicionamiento, navegación y datos de temporización (PNT) que incluye:<br/>%2Brújula y dirección<br/>%2Fecha y hora sincronizada con la misión<br/>%2Elevación (relativa al nivel del mar)<br/>%2Velocidad actual<br/>%2GPS con vista topográfica y satelital<br/>%2Creación, nombrado y borrado de puntos de ruta<br/>%2Identificación de aliados (Requiere la opción de ACE BLUFOR Tracker)<br/>Conexión con el telémetro Vector-21 para importación de datos (creación de puntos de ruta y referenciado en eje de coordenada para objetivos a distancia)<br/><br/>%3Uso:%4<br/>%2Para instrucciones de uso, por favor visita la Wiki dedicada de %3MicroDAGR%4. Range Tables @@ -581,6 +645,7 @@ 射表 Таблицы диапазонов Tables de tir + Tablas de Distancia Get A Firing Solution @@ -590,6 +655,7 @@ 撃ち方の解を得る Получите расчёт Obtenir une solution de tir + Obtener Una Solución de Tiro %3Range Tables%4 allow for a soldier to estimate accurate shot placement on direct or indirect targets (depending on asset). The %3Range Table%4 will automatically fill depending on the soldiers selected weapon/vehicle.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select the desired %3Range Table%4. @@ -597,6 +663,7 @@ %3Tavole di tiro%4 permettono al soldato di stimare piazzamenti accurati di colpi mediante fuoco diretto o indiretto (a seconda dell'arma). La %3Tavola di tiro%4 si modificherà in automatico a seconda dell'arma/veicolo del soldato.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] and seleziona %3Equipaggiamento%4.<br/>%2Seleziona la portata desiderata sulla %3Tavola di tiro%4. %3사거리표%4를 사용하면 병사가 직접 또는 간접 표적(자산에 따라 다름)에 대한 정확한 사격 배치를 추정할 수 있습니다. %3사거리표%4는 선택한 병사의 무기/차량에 따라 자동으로 작성됩니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4]를 사용하고 %3장비%4를 선택하십시오.<br/>%2원하는 %3사거리표%4를 선택하십시오. %3射表%4 を使用すると、兵士は (手段に応じて) 直接的または間接的なターゲットへの正確な射撃位置を推定できます。%3射表%4は、兵士が選択した武器/車両に応じて自動的に入力されます。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2目的の%3射表%4を選択します。 + La %3Tabla de distancias%4 permite a un soldado estimar con precisión el posicionamiento de un disparo sobre un objetivo de manera directa o indirecta (dependiendo del dispositivo). La %3Tabla de distancias%4 se autorellena dependiendo del arma o vehículo seleccionado por el soldado.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Selecciona la %3Tabla de distancias%4 deseada. Ropes @@ -606,6 +673,7 @@ ロープ Канаты Corde + Cuerdas Tow With Ease @@ -615,6 +683,7 @@ 楽々けん引 Буксируйте с легкостью Remorquer avec facilité + Remolcar Con Facilidad %3Ropes%4 have multiple uses including %3Towing%4 vehicles and %3Fast Roping%4 from helicopters.<br/><br/>%3Towing:%4<br/>%2Approach a vehicle.<br/>%2Use [%3%13%4] and select %3Towing%4.<br/>%2Select rope length.<br/>%2Select attachment point on towing vehicle.<br/>%2Select attachment on towed vehicle.<br/><br/>%3Available Rope Lengths:%4<br/>%2 3.2 meters<br/>%2 6.2 meters<br/>%2 12.2 meters<br/>%2 15.2 meters<br/>%2 18.3 meters<br/>%2 27.4 meters<br/>%2 36.6 meters @@ -622,6 +691,7 @@ %3Corde%4 hanno molteplici utilizzi, come %3Trainare%4 veicoli e %3Fast Roping%4 da elicotteri.<br/><br/>%3Traino:%4<br/>%2Avvicinati a un veicolo.<br/>%2Usa [%3%13%4] e seleziona %3Traina%4.<br/>%2Seleziona lunghezza corda.<br/>%2Seleziona punto di attacco su veicolo trainante.<br/>%2Seleziona attacco su veicolo trainato.<br/><br/>%3Lunghezze corde a disposizione:%4<br/>%2 3.2 metri<br/>%2 6.2 metri<br/>%2 12.2 metri<br/>%2 15.2 metri<br/>%2 18.3 metri<br/>%2 27.4 metri<br/>%2 36.6 metri %3로프%4는 차량 %3견인%4 및 헬기의 %3패스트로프%4 등 여러 용도로 사용됩니다.<br/><br/>%3견인 방법:%4<br/>%2차량에 접근하십시오.<br/>%2[%3%13%4]를 사용하고 %3견인%4을 선택하십시오.<br/>%2로프 길이를 선택하십시오.<br/>%2견인할 차량의 부착 지점을 선택하십시오.<br/>%2견인될 차량의 부착 지점을 선택하십시오.<br/><br/>%3사용 가능한 로프 길이:%4<br/>%2 3.2m<br/>%2 6.2m<br/>%2 12.2m<br/>%2 15.2m<br/>%2 18.3m<br/>%2 27.4m<br/>%2 36.6m %3ロープ%4には、車両の%3けん引%4やヘリコプターからの%3ファストロープ%4など、複数の用途があります。<br/><br/>%3けん引方法:%4<br/>%2車両に近づきます。<br/>%2[%3%13%4] を使って%3けん引%4を選択します。<br/>%2ロープの長さを選択します。<br/>%2けん引する車両のロープ取付位置を選択します。<br/>%2けん引される車両のロープ取付位置を選択します。<br/><br/>%3利用可能なロープの長さ:%4<br/>%2 3.2 メートル<br/>%2 6.2 メートル<br/>%2 12.2 メートル<br/>%2 15.2 メートル<br/>%2 18.3 メートル<br/>%2 27.4 メートル<br/>%2 36.6 メートル + Las %3Cuerdas%4 tienen múltiples usos incluyendo el %3Remolcado%4 de vehículos y el %3Descenso con Cuerda%4 desde helicópteros.<br/><br/>%3Remolcado:%4<br/>%2Acércate a un vehículo.<br/>%2Usar [%3%13%4] y seleccionar %3Remolcado%4.<br/>%2Selecciona la longitud de la cuerda.<br/>%2Selecciona un punto de anclaje en el vehículo de remolcado.<br/>%2Selecciona una sujección en el vehículo remolcado.<br/><br/>%3Longitudes de Cuerda Disponibles:%4<br/>%2 3.2 metros<br/>%2 6.2 metros<br/>%2 12.2 metros<br/>%2 15.2 metros<br/>%2 18.3 metros<br/>%2 27.4 metros<br/>%2 36.6 metros Expand Your Fortifications @@ -631,6 +701,7 @@ 要塞を拡張する Расширить свои укрепления Élargissez vos fortifications + Expande Tus Fortificaciones %3Sandbags%4 are sacks made of sturdy material, filled with sand, used for a variety of purposes such as creating barriers or providing stability in construction projects. Useful in expanding larger placed fortifications.<br/><br/>%3Usage:%4<br/>%2Equip a %3Sandbag (Empty)%4.<br/>%2Use [%3%12%4] and select %3Deploy Sandbag%4.<br/>%2Follow on-screen instructions for placement. @@ -638,6 +709,7 @@ %3Sacchi di Sabbia%4 sono sacchi di un materiale robusto, riempiti di sabbia, usati per una varietà di utilizzi come creare barriere o aumentare la stabilità di fortificazioni.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia una %3Sacco di Sabbia (Vuoto)%4.<br/>%2Usa [%3%12%4] e seleziona %3Posiziona Sacco di Sabbia%4.<br/>%2Segui le istruzioni sullo schermo per il piazzamento. %3모래주머니%4는 튼튼한 재료로 만든 주머니로 모래를 채워 장벽을 만들거나 건설 작업에서 안정성을 제공하는 등 다양한 용도로 사용되며, 더 큰 요새를 확장하는 데 유용합니다.<br/><br/>%3사용 방법:%4<br/>%2%3모래주머니(비어있음)%4을 장착하십시오.<br/>%2[%3%12%4]를 사용하고 %3모래주머니 배치%4를 선택하십시오.<br/>%2화면의 지시에 따라 배치하십시오. %3土のう%4は、砂が詰められた頑丈な素材で作られた袋で、建設プロジェクトでの障壁の作成や安定性の提供など、さまざまな目的に使用されます。より大きな配置の要塞を拡張するのに役立ちます。<br/><br/>%3使用方法:%4<br/>%2%3土のう (空)%4を装備します。<br/>%2[%3%12%4] を使って%3土のうを作る%4を選択します。<br/>%2画面上の指示に従って配置します。 + Los %3Sacos de tierra%4 son sacos hechos de un material resistente, rellenados de tierra, usados para una diversa variedad de propósitos como la construcción de barreras o proveer estabilidad en los proyectos de construcción. Son útiles en la expansión de proyectos de construcción más grandes.<br/><br/>%3Uso:%4<br/>%2Equipa un %3Saco de tierra (Vacío)%4.<br/>%2Usar [%3%12%4] y seleccionar %3Desplegar Saco de tierra%4.<br/>%2Seguir las instrucciones en pantalla para su colocación. Lower Firearm Temperature @@ -647,6 +719,7 @@ 銃の熱を冷ます Понизьте температуру оружия Refroidir l'arme + Bajar la Temperatura del Arma %3Spare Barrels%4 allow a soldier to reduce their weapon's heat significantly. After a short delay, the weapon's barrel will be swapped and its heat reduced. A soldier may also check the temperature of any barrels within their inventory. Not all weapons support swapping barrels.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select %3Swap Barrel%4.<br/>%2Resume operation after barrel swap is complete. @@ -654,6 +727,7 @@ %3Canne di Ricambio%4 permettono ai soldati di raffreddare la loro arma notevolmente. Dopo una breve attesa, la canna dell'arma verrà sostituita e la temperatura ridotta. Un soldato può anche controllare la temperatura di canne di ricambio presenti nel proprio inventario. Non tutte le armi consentono lo scambio canna.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] e seleziona %3Equipaggiamento%4.<br/>%2Seleziona %3Sostituisci Canna%4.<br/>%2Continua l'ingaggio dopo sostituzione avvenuta. %3예비 총열%4을 사용하면 병사의 무기의 발열을 크게 줄일 수 있습니다. 잠시 뒤에 무기의 총신이 교체되고 발열이 감소합니다. 군인은 소지품에 있는 총열의 온도도 확인할 수 있습니다. 모든 무기가 총열 교환을 지원하는 것은 아닙니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4]를 사용하고 %3장비%4를 선택하십시오.<br/>%2%3총열 교체%4를 선택하십시오.<br/>%2총열 교체가 완료된 후 작전을 계속하십시오. %3予備銃身%4を使用すると、兵士は武器の熱を大幅に下げることができます。少し経つと、武器の銃身が交換され熱が下がります。兵士はインベントリ内の銃身の温度を確認することもできます。すべての武器が銃身の交換をサポートしているわけではありません。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3銃身を交換%4を選択します。<br/>%2銃身交換が完了すると、再度射撃することが出来ます。 + El %3Cañón de Repuesto%4 permite a un soldado reducir el calor del arma significativamente. Tras un pequeño periodo, el cañón del arma habrá sido sustituido y el calor reducido. Un soldado puede tambien comprobar la temperatura de cualquier cañón en su inventario. No todas las armas soportan el cambio de cañón.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar %3Cambiar Cañón%4.<br/>%2Continuar con la operación una vez se haya cambiado el cañón. Spray Paint @@ -663,6 +737,7 @@ ペイントスプレー Аэрозольная краска Bombe de peinture + Pintura En Spray Tag Your Territory @@ -672,6 +747,7 @@ 自分のテリトリーをマーキング Пометьте свою территорию Marquez votre territoire + Marca Tu Territorio %3Spray Paint%4 is used to tag surfaces with various symbols.<br/><br/>%3Usage:%4<br/>%2Move close to a surface (wall, vehicle, ground, etc).<br/>%2Use [%3%12%4] and select %3Tag%4.<br/>%2Choose a symbol.<br/><br/>%3Available Colors:%4<br/>%2Black<br/>%2Blue<br/>%2Green<br/>%2Red @@ -679,6 +755,7 @@ %3Bombolette Spray%4 vengono usate per marcare superfici con vari simboli.<br/><br/>%3Utilizzo:%4<br/>%2Muoviti vicino a una superfice (muro, veicolo, suolo, etc).<br/>%2Usa [%3%12%4] e seleziona %3Marca%4.<br/>%2Seleziona un simbolo.<br/><br/>%3Colori disponibili:%4<br/>%2Nero<br/>%2Blu<br/>%2Verde<br/>%2Rosso %3스프레이 페인트%4다양한 기호로 표면에 태그를 지정하는 데 사용됩니다.<br/><br/>%3사용 방법:%4<br/>%2표면(벽, 차량, 지면 등)에 가까이 가십시오.<br/>%2[%3%12%4]를 사용하고 %3태그%4를 선택하십시오.<br/>%2모양을 고르십시오.<br/><br/>%3사용 가능 색상:%4<br/>%2검정<br/>%2파랑<br/>%2초록<br/>%2빨강 %3ペイントスプレー%4は、地面や壁、車両の表面などに様々な図形のタグを付けるために使えます。<br/><br/>%3使用方法:%4<br/>%2塗りたい面に近づきます。(壁、車両、地面など)<br/>%2[%3%12%4] を使って%3タグ (スプレーペイント)%4を選択します。<br/>%2図形を選びます。<br/><br/>%3利用可能な色:%4<br/>%2黒<br/>%2白<br/>%2赤<br/>%2青<br/>%2緑<br/>%2黄 + La %3Pintura en Spray%4 se usa para marcar superficies con varios símbolos.<br/><br/>%3Uso:%4<br/>%2Acércate a una superficie (pared, vehículo, suelo, etc).<br/>%2Usar [%3%12%4] y seleccionar %3Tag%4.<br/>%2Elige un símbolo.<br/><br/>%3Colores disponibles:%4<br/>%2Negro<br/>%2Azul<br/>%2Verde<br/>%2Rojo Brace From Anywhere @@ -688,6 +765,7 @@ どこでも支持器 Опора может быть установлена в любом месте Stabilisé partout + Apoyarte En Cualquier Lugar The %3SSWT Kit%4 is a deployable tripod that allows a soldier to brace their aim when deployed. Use it when you need an elevated shooting position and there are no other objects around.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select %3SSWT Kit%4 and follow the on screen prompts to place. @@ -695,6 +773,7 @@ Il %3Kit SSWT%4 è un treppiede piazzabile che permette al soldato di appoggiare la sua arma. Usalo quando ti serve una posizione di tiro rialzata e non ci sono altri oggetti utili nelle vicinanze.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] e seleziona %3Equipaggiamento%4.<br/>%2Seleziona %3Kit SSWT%4 e segui le indicazioni di piazzamento. %3SSWT 키트%4는 병사가 배치 시 조준력을 상승시킬 수 있는 배치 가능한 삼각대입니다. 높이 조절이 된 사격 위치가 필요하고 주위에 다른 물체가 없을 때 사용하십시오.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4] 를 사용하고 %3장비%4를 선택하십시오.<br/>%2%3SSWT 키트%4를 선택하고 화면의 지시에 따라 배치하십시오. %3SSWT キット%4は展開可能な三脚で、展開時に兵士が狙いを定めることができます。高い射撃位置が必要で、周囲に他の物体がない場合に使用してください。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3SSWT キット%4を選択し、画面上の指示に従って配置します。 + El %3Kit SSWT%4 es un trípode desplegable que permite a un soldado apoyarse para apuntar cuando está desplegado. Úsalo cuando necesites una posición de tiro elevada y no hay ningún otro objeto alrededor.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar %3Kit SSWT%4 y sigue las indicaciones en pantalla para colocarlo. Keep Eyes In The Sky @@ -705,6 +784,7 @@ Не Отрывай Глаз От Неба Gardez les yeux au ciel Gardez les yeux au ciel + Manten Tus Ojos En El Cielo %3UAV Batteries%4 are used to recharge a UAV's energy storage. Especially useful for small UAVs.<br/><br/>%3Usage:%4<br/>%2Equip a %3UAV Battery%4<br/>%2Approach a %3UAV%4 with its %3Engine Off%4.<br/>%2Use [%3%13%4] and select %3Recharge%4. @@ -712,6 +792,7 @@ %3Batteria UAV%4 vengono usate per ricaricare gli UAV. Molto utile per piccoli UAV.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia una %3Batteria UAV%4<br/>%2Avvicinati al %3UAV%4 con il %3Motore Spento%4.<br/>%2Usa [%3%13%4] e seleziona %3Ricarica%4. %3무인기 배터리%4는 무인기의 에너지 저장소를 재충전하는 데 사용됩니다. 소형 무인기에 특히 유용합니다.<br/><br/>%3사용 방법:%4<br/>%2%3무인기 배터리%4를 장착하십시오.<br/>%2%3엔진을 끄고%4 %3무인기%4에 접근하십시오.<br/>%2[%3%13%4]를 사용하고 %3재충전%4을 선택하십시오. %3UAVバッテリー%4は、UAVの電源容量を充電するために使用されます。<br/><br/>%3使用方法:%4<br/>%2%3UAV バッテリー%4を装備します。<br/>%2%3エンジンをオフ%4にした%3UAV%4に近づきます。<br/>%2[%3%13%4] を使って%3充電%4を選択します。 + La %3Batería de VANT%4 se utilizan para recargar el almacenamiento de energía de un VANT. Especialmente útiles para pequeños VANTs.<br/><br/>%3Uso:%4<br/>%2Equipa una %3Batería de VANT%4<br/>%2Acércate a un %3VANT%4 con su %3Motor Apagado%4.<br/>%2Usa [%3%13%4] y selecciona %3Recargar%4. Making An Entrance @@ -721,6 +802,7 @@ 堂々入場する Создание собственного входа Faire son entrée + Abriendo Una Entrada %3Wirecutters%4 are a tool that allows a soldier to bypass wired fencing. Useful for creating backdoor entrances into secure areas.<br/><br/>%3Usage:%4<br/>%2Move close to a fence.<br/>%2Use [%3%12%4] and select %3Cut Fence%4. @@ -728,6 +810,7 @@ La %3Trancia%4 è un utensile che permette ai soldati di sorpassare filo spinato e recinzioni. Utile per creare punti di accesso nel retro di zone protette.<br/><br/>%3Utilizzo:%4<br/>%2Avvicinati a una barriera.<br/>%2Usa [%3%12%4] e seleziona %3Taglia%4. %3절단기%4는 병사가 철조망을 통과할 수 있게 해주는 도구입니다. 보안 구역에 뒷입구를 만드는 데 유용합니다.<br/><br/>%3사용 방법:%4<br/>%2철조망에 가까이 가십시오.<br/>%2[%3%13%4]를 사용하고 %3철조망 자르기%4를 선택하십시오. %3ワイヤーカッター%4は、兵士が有線フェンスを回避できるようにするツールです。安全にエリアへの裏口を作成するのに役立ちます。<br/><br/>%3使用方法:%4<br/>%2フェンスの近くに移動します。<br/>%2[%3%12%4] を使って%3フェンスを切断する%4を選択します。 + La %3Cizalla%4 es una herramienta que permite a un soldado atravesar una valla de alambre. Es útil para crear entradas traseras en áreas seguras.<br/><br/>%3Uso:%4<br/>%2Acércate a una valla.<br/>%2Usar [%3%12%4] y seleccionar %3Cortar Valla%4. Items @@ -770,6 +853,7 @@ 要塞を構築する Стройте укрепления Construire des fortifications + Construir Fortificaciones The %3Fortify Tool%4 allows soldiers to build fortifications provided by their mission creator.<br/><br/>%3Usage:%4<br/>%2Pick up a %3Fortify Tool%4.<br/>%2Use [%3%12%4] and select %3Fortify%4.<br/>%2Select an available fortification and follow the on screen prompts for placement. @@ -777,6 +861,7 @@ L'%3Attrezzo di Fortificazione%4 permette ai soldati di costruire fortificazioni permesse dal creatore della missione.<br/><br/>%3Utilizzo:%4<br/>%2Raccogli un %3Attrezzo di Fortificazione%4.<br/>%2Usa [%3%12%4] e seleziona %3Fortifica%4.<br/>%2Seleziona una fortificazione disponibile e segui le indicazioni di piazzamento sullo schermo. %3요새화 도구%4를 사용하면 병사들이 임무 생성자가 제공한 요새를 구축할 수 있습니다.<br/><br/>%3사용 방법:%4<br/>%2%3요새화 도구%4를 가지십시오.<br/>%2[%3%12%4]를 사용하고 %3요새화%4를 선택하십시오.<br/>%2사용 가능한 요새를 선택하고 화면의 지시에 따라 배치하십시오. %3要塞ツール%4を使用すると、兵士はミッション作成者が提供した要塞を構築できます。<br/><br/>%3使用方法:%4<br/>%2%3要塞ツール%4を持つ。<br/>%2[%3%12%4] を使って%3要塞%4を選択します。<br/>%2利用可能な構造物を選択し、画面上の指示に従って配置します。 + La %3Herramienta de Fortificación%4 permite a los soldados construir fortificaciones provistas por su creador de mision.<br/><br/>%3Uso:%4<br/>%2Coge una %3Herramienta de Fortificación%4.<br/>%2Usar [%3%12%4] y seleccionar %3Fortificar%4.<br/>%2Selecciona una fortificación disponible y sigue las instrucciones en pantalla para su colocación. Breaking and Entering @@ -786,6 +871,7 @@ 破壊して乗り込む Взлом и проникновение Entrée par effraction + Romper y Entrar %3Lockpicks%4 are used to gain access to locked vehicles.<br/><br/>%3Usage:%4<br/>%2Equip a %3Lockpick%4.<br/>%2Approach a %3Locked%4 vehicle.<br/>Use [%3%13%4] and select %3Lockpick Vehicle%4.<br/><br/><t underline='1'>%3Note:%4</t> Lockpicks and keys are only available via scripting or ACE Vehicle Key modules. @@ -793,6 +879,7 @@ I %3Grimaldelli%4 sono usati per forzare l'accesso a veicoli bloccati.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia un %3Grimaldello%4.<br/>%2Avvicinati a un veicolo %3Bloccato%4 vehicle.<br/>Usa [%3%13%4] e seleziona %3Scassina Veicolo%4.<br/><br/><t underline='1'>%3Note:%4</t> Grimaldelli e chiavi sono solo reperibili mediante scripting o moduli ACE di assegnazione Chiavi Veicoli. %3해정도구%4는 잠긴 차량에 들어가는 데 사용됩니다.<br/><br/>%3사용 방법:%4<br/>%2%3해정도구%4를 장착하십시오.<br/>%2%3잠긴%4 차량에 접근하십시오.<br/>[%3%13%4]를 사용하고 %3차량 잠금해제%4를 선택하십시오.<br/><br/><t underline='1'>%3참고:%4</t> 해정도구와 열쇠는 스크립팅 또는 ACE 차량 열쇠 모듈에서만 사용할 수 있습니다. %3Lockpick%4は、ロックされた車両にアクセスするために使用されます。<br/><br/>%3使用方法:%4<br/>%2%3Lockpick%4を装備します。<br/>%2%3鍵の掛かった%4車両に近づきます。<br/>[%3%13%4] を使って%3鍵をこじ開ける%4を選択します。<br/><br/><t underline='1'>%3備考:%4</t> ロックピックとキーは、スクリプトまたは ACE Vehicle Key モジュールを介してのみ使用できます。 + La %3Ganzúa%4 es usada para lograr acceso a vehículos bloqueados.<br/><br/>%3Uso:%4<br/>%2Equipar %3Ganzúa%4.<br/>%2Acércate a un vehículo %3Bloqueado%4.<br/>Usar [%3%13%4] y seleccionar %3Ganzuar Vehículo%4.<br/><br/><t underline='1'>%3Nota:%4</t>Ganzúas y Llaves sólo están disponibles mediante scripting o módulos de Llaves de Vehículos ACE. Vehicle Keys @@ -802,6 +889,7 @@ 車両キー Взлом и проникновение Clés de véhicule + Llaves de Vehículos Lock/Unlock Vehicles @@ -811,6 +899,7 @@ 車両のロック/ロック解除 Взлом и проникновение Verrouiller/déverrouiller un véhicule + Bloquear/Desbloquear vehículos %3Vehicle Keys%4 are used to lock/unlock your vehicles. Vehicle keys can exist for the whole side, or keys can be created for a particular vehicle itself.<br/><br/>%3Usage:%4<br/>%2Equip a %3Vehicle Key%4.<br/>%2Approach the vehicle that the key belongs to.<br/>Use [%3%13%4] and select %3Lock/Unlock Vehicle%4.<br/><br/><t underline='1'>%3Note:%4</t> Lockpicks and keys are only available via scripting or ACE Vehicle Key modules. @@ -818,6 +907,7 @@ Le %3Chiavi di Veicoli%4 vengono usate per bloccare/sbloccare i propri veicoli. Chiavi di veicoli possono esistere per un'intera fazione, oppure per un veicolo particolare.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia una %3Chiave di Veicolo%4.<br/>%2Avvicinati al veicolo a cui appartiene la chiave.<br/>Usa [%3%13%4] e seleziona %3Blocca/Sblocca Veicolo%4.<br/><br/><t underline='1'>%3Note:%4</t> Grimaldelli e chiavi sono solo disponibili mediante scripting o moduli ACE Chiavi Veicoli. %3차량 열쇠%4는 차량을 잠그거나 잠금해제하는 데 사용됩니다. 차량 열쇠는 모든 세력에게 존재할 수도 있고, 특정 차량 자체에 대해 열쇠를 생성할 수도 있습니다.<br/><br/>%3사용 방법:%4<br/>%2%3차량 열쇠%4를 장착하십시오.<br/>%2해당 열쇠에 속한 차량에 접근하십시오.<br/>[%3%13%4]를 사용하고 %3차량 잠금/잠금해제%4를 선택하십시오.<br/><br/><t underline='1'>%3참고:%4</t> 해정도구와 열쇠는 스크립팅 또는 ACE 차량 열쇠 모듈에서만 사용할 수 있습니다. %3Vehicle Key%4は、車両のロック/ロック解除に使用されます。車両キーは陣営全体に存在することも、特定の車両だけに対してキーを作成することもできます。<br/><br/>%3使用方法:%4<br/>%2%3Vehicle Key%4を装備します。<br/>%2鍵の対応している車両に近づきます。<br/>[%3%13%4] を使って%3鍵を解錠/施錠%4します。<br/><br/><t underline='1'>%3備考:%4</t> ロックピックとキーは、スクリプトまたは ACE Vehicle Key モジュールを介してのみ使用できます。 + Las %3Llaves de Vehículos%4 son usadas para bloquear/desbloquear tus vehículos. Las Llaves de Vehículos existen para un bando entero o para un vehículo concreto.<br/><br/>%3Uso:%4<br/>%2Equipa una %3Llave de Vehículo%4.<br/>%2Acércate a un vehículo cuya llave corresponda.<br/>Usar [%3%13%4] y selecciona %3Bloquear/Desbloquear Vehículo%4.<br/><br/><t underline='1'>%3Nota:%4</t> Ganzúas y Llaves sólo están disponibles mediante scripting o módulos de Llaves de Vehículos ACE diff --git a/addons/fire/XEH_PREP.hpp b/addons/fire/XEH_PREP.hpp index d9eacfdee00..8b2e8f6bd1f 100644 --- a/addons/fire/XEH_PREP.hpp +++ b/addons/fire/XEH_PREP.hpp @@ -1,6 +1,5 @@ PREP(burn); PREP(isBurning); -PREP(isPlant); PREP(burnIndicator); PREP(burnReaction); PREP(fireManagerPFH); diff --git a/addons/fire/XEH_preInit.sqf b/addons/fire/XEH_preInit.sqf index 2fc794454d3..894773534a4 100644 --- a/addons/fire/XEH_preInit.sqf +++ b/addons/fire/XEH_preInit.sqf @@ -8,6 +8,4 @@ PREP_RECOMPILE_END; #include "initSettings.inc.sqf" -GVAR(burningPlants) = []; - ADDON = true; diff --git a/addons/fire/functions/fnc_burnIndicator.sqf b/addons/fire/functions/fnc_burnIndicator.sqf index 13db8862c9f..d876d18a075 100644 --- a/addons/fire/functions/fnc_burnIndicator.sqf +++ b/addons/fire/functions/fnc_burnIndicator.sqf @@ -30,7 +30,7 @@ if !(IS_UNCONSCIOUS(_unit)) then { _unit setVariable [QGVAR(indicatorIteration), _iteration]; }; -if (!([_unit] call FUNC(isBurning)) || { !alive _unit }) then { +if (!([_unit] call FUNC(isBurning)) || {!alive _unit}) then { [_pfhHandle] call CBA_fnc_removePerFrameHandler; _unit setVariable [QGVAR(burnUIPFH), -1]; }; diff --git a/addons/fire/functions/fnc_isBurning.sqf b/addons/fire/functions/fnc_isBurning.sqf index 3bdbe560be0..7cc06dc01de 100644 --- a/addons/fire/functions/fnc_isBurning.sqf +++ b/addons/fire/functions/fnc_isBurning.sqf @@ -17,7 +17,4 @@ params [["_unit", objNull, [objNull]]]; -_unit getVariable [QGVAR(burning), false] || { - GVAR(burningPlants) = GVAR(burningPlants) select {!isNull _x}; - _unit in GVAR(burningPlants) -} +_unit getVariable [QGVAR(burning), false] diff --git a/addons/fire/functions/fnc_isPlant.sqf b/addons/fire/functions/fnc_isPlant.sqf deleted file mode 100644 index f132fc72be5..00000000000 --- a/addons/fire/functions/fnc_isPlant.sqf +++ /dev/null @@ -1,20 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: commy2 - * Check if object is a map placed bush or tree. - * - * Arguments: - * 0: Object - * - * Return Value: - * Is bush or tree? - * - * Example: - * cursorObject call ace_fire_fnc_isPlant - * - * Public: No - */ - -params [["_object", objNull, [objNull]]]; - -_object in nearestTerrainObjects [_object, ["TREE", "SMALL TREE", "BUSH"], 0.1] diff --git a/addons/fortify/functions/fnc_setupModule.sqf b/addons/fortify/functions/fnc_setupModule.sqf index f032d98ebe0..1215393a467 100644 --- a/addons/fortify/functions/fnc_setupModule.sqf +++ b/addons/fortify/functions/fnc_setupModule.sqf @@ -48,10 +48,10 @@ if IS_NUMBER(_preset) then { // Legacy support }; private _budget = _logic getVariable ["Budget", -1]; -if (!(_budget isEqualType 0)) then {_budget = -1}; +if !(_budget isEqualType 0) then {_budget = -1}; private _addToolItem = _logic getVariable ["AddToolItem", false]; -if (!(_addToolItem isEqualType false)) then {_addToolItem = false}; +if !(_addToolItem isEqualType false) then {_addToolItem = false}; private _objects = [_preset] call FUNC(getPlaceableSet); diff --git a/addons/frag/CfgAmmoFragSpawner.hpp b/addons/frag/CfgAmmoFragSpawner.hpp index 95f9ee5d26c..6d5a4c86513 100644 --- a/addons/frag/CfgAmmoFragSpawner.hpp +++ b/addons/frag/CfgAmmoFragSpawner.hpp @@ -5,7 +5,7 @@ class GVAR(DOUBLES(size,spawner_2_mid)): GVAR(DOUBLES(size,spawner_2_short)) {\ submunitionConeAngle = 2;\ };\ class GVAR(DOUBLES(size,spawner_2_far)): GVAR(DOUBLES(size,spawner_2_short)) {\ - submunitionConeAngle = 0.7;\ + submunitionConeAngle = 0.9;\ };\ class GVAR(DOUBLES(size,spawner_3_short)): GVAR(DOUBLES(size,spawner_2_short)) {\ submunitionConeType[] = {"random", 3};\ @@ -14,26 +14,26 @@ class GVAR(DOUBLES(size,spawner_3_mid)): GVAR(DOUBLES(size,spawner_3_short)) {\ submunitionConeAngle = 2;\ };\ class GVAR(DOUBLES(size,spawner_3_far)): GVAR(DOUBLES(size,spawner_3_short)) {\ - submunitionConeAngle = 0.7;\ + submunitionConeAngle = 0.9;\ } #define RANDOM_SPAWNER_PROTOTYPE(size,count) class GVAR(DOUBLES(TRIPLES(random,size,count),mid)): GVAR(spawnbase) {\ submunitionConeType[] = {"random", count};\ submunitionAmmo = QGVAR(size);\ submunitionConeAngle = 85;\ - triggerSpeedCoef[] = {-1.25, 1.25};\ + triggerSpeedCoef[] = {-1.5, 1.5};\ };\ class GVAR(DOUBLES(TRIPLES(random,size,count),high)): GVAR(spawnbase) {\ submunitionConeType[] = {"random", count};\ submunitionAmmo = QGVAR(size);\ submunitionConeAngle = 80;\ - triggerSpeedCoef[] = {0.75, 1.25};\ + triggerSpeedCoef[] = {0.75, 1.5};\ };\ class GVAR(DOUBLES(TRIPLES(random,size,count),top)): GVAR(spawnbase) {\ submunitionConeType[] = {"random", count};\ submunitionAmmo = QGVAR(size);\ submunitionConeAngle = 60;\ - triggerSpeedCoef[] = {0.75, 1.25};\ + triggerSpeedCoef[] = {0.75, 1.5};\ } class GVAR(spawnbase): B_65x39_Caseless { @@ -48,7 +48,7 @@ class GVAR(spawnbase): B_65x39_Caseless { submunitionInitialOffset[] = {0,0,0}; submunitionInitSpeed = 0; submunitionParentSpeedCoef = 1; - triggerSpeedCoef[] = {0.75, 1.25}; + triggerSpeedCoef[] = {0.75, 1.5}; triggerTime = 0; }; @@ -65,7 +65,7 @@ class GVAR(spawnbase): B_65x39_Caseless { class GVAR(spawnbase_targeted): GVAR(spawnbase) { submunitionConeType[] = {"random", 2}; submunitionConeAngle = 4.5; - triggerSpeedCoef[] = {0.625, 1}; + triggerSpeedCoef[] = {0.5, 1}; }; diff --git a/addons/frag/functions/fnc_findReflections.sqf b/addons/frag/functions/fnc_findReflections.sqf index a028a2f70b3..a753934fe85 100644 --- a/addons/frag/functions/fnc_findReflections.sqf +++ b/addons/frag/functions/fnc_findReflections.sqf @@ -120,7 +120,7 @@ if (_zIndex < 5) then { // _dirvec = _pos vectorFromTo ((player modelToWorldVisualWorld (player selectionPosition "Spine3"))); // _dirvec = _dirvec vectorMultiply 100; // _can setVelocity _dirvec; - [DFUNC(doExplosions), 0, [_explosions, 0]] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(doExplosions), 0, [_explosions, 0]] call CBA_fnc_addPerFrameHandler; [_pfhID] call CBA_fnc_removePerFrameHandler; }; END_COUNTER(fnc_findReflections); diff --git a/addons/frag/script_component.hpp b/addons/frag/script_component.hpp index 194d2011fa0..8c2a614d3ce 100644 --- a/addons/frag/script_component.hpp +++ b/addons/frag/script_component.hpp @@ -27,7 +27,7 @@ #define ACE_FRAG_COUNT_MAX_TIME 1 #define ACE_FRAG_COUNT_MAX 50 // Default hitpoint targets -#define ACE_FRAG_HITPOINTS ["spine1", "spine1", "spine1", "spine2", "spine2", "spine2", "spine3", "spine3", "spine3", "pelvis", "pelvis", "pelvis", "head", "leftarm", "leftarmroll", "leftforearm", "rightarm", "rightarmroll", "rightforearm", "leftupleg", "leftuplegroll", "leftlegroll", "rightupleg", "rightuplegroll", "rightleg", "rightlegroll", "neck"] +#define ACE_FRAG_HITPOINTS ["spine1", "spine1", "spine1", "spine2", "spine2", "spine2", "spine3", "spine3", "spine3", "pelvis", "pelvis", "pelvis", "head", "leftarm", "leftarmroll", "leftforearm", "rightarm", "rightarmroll", "rightforearm", "leftupleg", "leftuplegroll", "leftlegroll", "leftfoot", "rightupleg", "rightuplegroll", "rightleg", "rightlegroll", "rightfoot", "neck"] // half of gravity approx 9.81/2 #define ACE_FRAG_HALF_GRAVITY_APPROX 4.905 // Lowest chance to hit of 0.5% diff --git a/addons/gforces/functions/fnc_pfhUpdateGForces.sqf b/addons/gforces/functions/fnc_pfhUpdateGForces.sqf index 7ff3444b7dc..4bb680ee47a 100644 --- a/addons/gforces/functions/fnc_pfhUpdateGForces.sqf +++ b/addons/gforces/functions/fnc_pfhUpdateGForces.sqf @@ -71,7 +71,7 @@ private _suitCoef = if ((uniform ACE_player) != "") then { private _gBlackOut = MAXVIRTUALG / _classCoef + MAXVIRTUALG / _suitCoef - MAXVIRTUALG; // Unconsciousness -if ((_average > _gBlackOut) && {["ace_medical"] call EFUNC(common,isModLoaded) && {!(ACE_player getVariable ["ACE_isUnconscious", false])}}) then { +if (_average > _gBlackOut && {GETEGVAR(medical,enabled,false) && {ACE_player call EFUNC(common,isAwake)}}) then { [ACE_player, true, (10 + floor(random 5)), true] call EFUNC(medical,setUnconscious); }; diff --git a/addons/grenades/CfgAmmo.hpp b/addons/grenades/CfgAmmo.hpp index 5082dd432d9..2b0849d2f71 100644 --- a/addons/grenades/CfgAmmo.hpp +++ b/addons/grenades/CfgAmmo.hpp @@ -1,4 +1,3 @@ - class CfgAmmo { class Default; class Grenade: Default { @@ -153,7 +152,7 @@ class CfgAmmo { class ACE_G_M14: SmokeShell { GVAR(incendiary) = 1; model = QPATHTOF(models\ace_anm14th3_armed.p3d); - hit = 5; + hit = 10; indirectHit = 4; indirectHitRange = 1.1; dangerRadiusHit = 50; diff --git a/addons/grenades/CfgEventHandlers.hpp b/addons/grenades/CfgEventHandlers.hpp index 6c29240403a..f6503c2479b 100644 --- a/addons/grenades/CfgEventHandlers.hpp +++ b/addons/grenades/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); diff --git a/addons/grenades/CfgMagazines.hpp b/addons/grenades/CfgMagazines.hpp index ea4641ab7fb..2ff86c443d4 100644 --- a/addons/grenades/CfgMagazines.hpp +++ b/addons/grenades/CfgMagazines.hpp @@ -1,4 +1,3 @@ - class CfgMagazines { class HandGrenade; class ACE_HandFlare_Base: HandGrenade { diff --git a/addons/grenades/CfgVehicles.hpp b/addons/grenades/CfgVehicles.hpp index f9ac60d9fe6..34cf4196e6c 100644 --- a/addons/grenades/CfgVehicles.hpp +++ b/addons/grenades/CfgVehicles.hpp @@ -1,4 +1,3 @@ - class CfgVehicles { class NATO_Box_Base; class Box_NATO_Grenades_F: NATO_Box_Base { diff --git a/addons/grenades/CfgWeapons.hpp b/addons/grenades/CfgWeapons.hpp index 842862f7f98..683ec7532bc 100644 --- a/addons/grenades/CfgWeapons.hpp +++ b/addons/grenades/CfgWeapons.hpp @@ -1,4 +1,3 @@ - class CfgWeapons { class GrenadeLauncher; class Throw: GrenadeLauncher { diff --git a/addons/grenades/Effects.hpp b/addons/grenades/Effects.hpp index 95c3f12ba89..b4a16c6412f 100644 --- a/addons/grenades/Effects.hpp +++ b/addons/grenades/Effects.hpp @@ -1,4 +1,3 @@ - class ACE_M84FlashbangEffect { // empty }; diff --git a/addons/grenades/XEH_PREP.hpp b/addons/grenades/XEH_PREP.hpp index 6b5fb578016..06ceebc6b4f 100644 --- a/addons/grenades/XEH_PREP.hpp +++ b/addons/grenades/XEH_PREP.hpp @@ -1,8 +1,8 @@ - +PREP(addChangeFuseItemContextMenuOptions); +PREP(damageEngineAndWheels); PREP(flare); PREP(flashbangExplosionEH); PREP(flashbangThrownFuze); PREP(incendiary); PREP(nextMode); PREP(throwGrenade); -PREP(addChangeFuseItemContextMenuOptions); diff --git a/addons/grenades/XEH_postInit.sqf b/addons/grenades/XEH_postInit.sqf index c23640bca59..c13bc81b43d 100644 --- a/addons/grenades/XEH_postInit.sqf +++ b/addons/grenades/XEH_postInit.sqf @@ -1,8 +1,10 @@ // by commy2 #include "script_component.hpp" +#include "\a3\ui_f\hpp\defineDIKCodes.inc" ["ace_flashbangExploded", LINKFUNC(flashbangExplosionEH)] call CBA_fnc_addEventHandler; +[QGVAR(damageEngineAndWheels), LINKFUNC(damageEngineAndWheels)] call CBA_fnc_addEventHandler; // Register fired event handlers ["ace_firedPlayer", LINKFUNC(throwGrenade)] call CBA_fnc_addEventHandler; @@ -15,20 +17,45 @@ GVAR(flashbangPPEffectCC) = ppEffectCreate ["ColorCorrections", 4265]; GVAR(flashbangPPEffectCC) ppEffectForceInNVG true; // Add keybinds -["ACE3 Weapons", QGVAR(switchGrenadeMode), localize LSTRING(SwitchGrenadeMode), { +["ACE3 Weapons", QGVAR(switchGrenadeMode), LLSTRING(SwitchGrenadeMode), { // Conditions: canInteract - if !([ACE_player, objNull, ["isNotEscorting"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if !([ACE_player, objNull, ["isNotEscorting", "isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + if !(ACE_player call CBA_fnc_canUseWeapon) exitWith {false}; + // Don't change mode or show hint if advanced throwing is active if (ACE_player getVariable [QEGVAR(advanced_throwing,inHand), false]) exitWith {false}; // Statement - [] call FUNC(nextMode); -}, {false}, [9, [false, false, false]], false] call CBA_fnc_addKeybind; //8 Key + call FUNC(nextMode) // return +}, {}, [DIK_8, [false, false, false]], false] call CBA_fnc_addKeybind; // 8 Key ["CBA_settingsInitialized", { if (GVAR(convertExplosives)) then { - [] call FUNC(addChangeFuseItemContextMenuOptions); + call FUNC(addChangeFuseItemContextMenuOptions); }; }] call CBA_fnc_addEventHandler; + +["vehicle", { + private _currentThrowable = currentThrowable ACE_player; + + // Make sure grenade can be rolled if in roll mode (detonation time has to be >= 1 second and player isn't in a vehicle) + if !( + GVAR(currentThrowMode) == 3 && + {_currentThrowable isNotEqualTo []} && + { + !isNull objectParent ACE_player || + {getNumber (configFile >> "CfgAmmo" >> getText (configFile >> "CfgMagazines" >> _currentThrowable select 0 >> "ammo") >> "explosionTime") < MIN_EXPLOSION_TIME_FOR_ROLL} + } + ) exitWith {}; + + // If the player can't use throwables, don't change it + if !(ACE_player call CBA_fnc_canUseWeapon) exitWith {}; + + // Force the user into the normal throw mode + // Next throw mode after roll would be drop, which isn't ideal if the user tries to throw unknowingly... + [format [LLSTRING(RollGrenadeDisabled), LLSTRING(NormalThrow)], 2] call EFUNC(common,displayTextStructured); + + GVAR(currentThrowMode) = 0; + GVAR(throwModePFEH) call CBA_fnc_removePerFrameHandler; +}, true] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/grenades/XEH_preInit.sqf b/addons/grenades/XEH_preInit.sqf index 894773534a4..9456dc9c9fb 100644 --- a/addons/grenades/XEH_preInit.sqf +++ b/addons/grenades/XEH_preInit.sqf @@ -6,6 +6,9 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +GVAR(currentThrowMode) = 0; +GVAR(throwModePFEH) = -1; + #include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/grenades/functions/fnc_addChangeFuseItemContextMenuOptions.sqf b/addons/grenades/functions/fnc_addChangeFuseItemContextMenuOptions.sqf index d778ca33497..c0b5c9dc801 100644 --- a/addons/grenades/functions/fnc_addChangeFuseItemContextMenuOptions.sqf +++ b/addons/grenades/functions/fnc_addChangeFuseItemContextMenuOptions.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: Cyruz - * Allows conversion of explosive charges in to throwable versions + * Allows conversion of explosive charges into throwable versions. * * Arguments: * None @@ -14,7 +14,8 @@ * * Public: No */ - TRACE_1("addChangeFuseItemContextMenuOptions",_this); + +LOG("addChangeFuseItemContextMenuOptions"); { _x params ["_mag", "_throwableMag"]; @@ -29,21 +30,25 @@ {true}, { params ["", "", "_item", "", "_magArr"]; - _item isEqualTo (_magArr select 0); + + _item == (_magArr select 0) } ], { params ["_unit", "", "", "_slot", "_magArr"]; - private _container = ""; - switch _slot do { + + private _container = switch (_slot) do { case "UNIFORM_CONTAINER": { - _container = "uniform"; + "uniform" }; case "VEST_CONTAINER": { - _container = "vest"; + "vest" }; case "BACKPACK_CONTAINER": { - _container = "backpack"; + "backpack" + }; + default { + "" }; }; @@ -54,7 +59,7 @@ false }, true, - [_mag,_throwableMag] + [_mag, _throwableMag] ] call CBA_fnc_addItemContextMenuOption; [ @@ -67,21 +72,25 @@ {true}, { params ["", "", "_item", "", "_magArr"]; - _item isEqualTo (_magArr select 1); + + _item == (_magArr select 1) } ], { params ["_unit", "", "", "_slot", "_magArr"]; - private _container = ""; - switch _slot do { + + private _container = switch (_slot) do { case "UNIFORM_CONTAINER": { - _container = "uniform"; + "uniform" }; case "VEST_CONTAINER": { - _container = "vest"; + "vest" }; case "BACKPACK_CONTAINER": { - _container = "backpack"; + "backpack" + }; + default { + "" }; }; @@ -92,7 +101,7 @@ false }, true, - [_mag,_throwableMag] + [_mag, _throwableMag] ] call CBA_fnc_addItemContextMenuOption; } forEach [ ["SatchelCharge_Remote_Mag", "ACE_SatchelCharge_Remote_Mag_Throwable"], diff --git a/addons/grenades/functions/fnc_damageEngineAndWheels.sqf b/addons/grenades/functions/fnc_damageEngineAndWheels.sqf new file mode 100644 index 00000000000..ab95ecbe6a2 --- /dev/null +++ b/addons/grenades/functions/fnc_damageEngineAndWheels.sqf @@ -0,0 +1,44 @@ +#include "..\script_component.hpp" +/* + * Author: commy2, johnb43 + * Damage a vehicle's wheels and engine. + * + * Arguments: + * 0: Vehicle + * 1: Incendiary position AGL + * + * Return Value: + * None + * + * Example: + * [cursorObject, position cursorObject] call ace_grenades_fnc_damageEngineAndWheels + * + * Public: No + */ + +params ["_vehicle", "_position"]; +TRACE_2("damageWheelsAndEngine",_vehicle,_position); + +// Vehicle needs to be local and vulnerable +if !(local _vehicle && {isDamageAllowed _vehicle}) exitWith {}; + +{ + // If wheel is close enough to incendiary, burn it + if (_position distance (_vehicle modelToWorld (_vehicle selectionPosition _x)) < EFFECT_SIZE * 2) then { + _vehicle setHit [_x, 1]; + }; +} forEach ((_vehicle call EFUNC(common,getWheelHitPointsWithSelections)) select 1); + +// Burn car engines only +if (_vehicle isKindOf "Wheeled_APC_F") exitWith {}; + +private _engineSelection = getText (configOf _vehicle >> "HitPoints" >> "HitEngine" >> "name"); +private _enginePosition = _vehicle modelToWorld (_vehicle selectionPosition _engineSelection); + +if (_position distance _enginePosition < EFFECT_SIZE * 2) then { + _vehicle setHit [_engineSelection, 1]; + + if (["ace_cookoff"] call EFUNC(common,isModLoaded)) then { + [QEGVAR(cookoff,engineFireServer), _vehicle] call CBA_fnc_serverEvent; + }; +}; diff --git a/addons/grenades/functions/fnc_flare.sqf b/addons/grenades/functions/fnc_flare.sqf index 8214a5600dc..2db6335a77a 100644 --- a/addons/grenades/functions/fnc_flare.sqf +++ b/addons/grenades/functions/fnc_flare.sqf @@ -4,7 +4,7 @@ * Makes flare shine. * * Arguments: - * 0: The flare + * 0: Flare * 1: Color of flare * 2: Intensity of flare * 3: Flare lifetime @@ -34,6 +34,5 @@ _light setLightFlareMaxDistance 1000; _light setLightDayLight true; _light lightAttachObject [_projectile, [0,0,0]]; -//_light attachTo [_projectile, [0,0,0]]; [{deleteVehicle _this}, _light, _timeToLive] call CBA_fnc_waitAndExecute; diff --git a/addons/grenades/functions/fnc_flashbangExplosionEH.sqf b/addons/grenades/functions/fnc_flashbangExplosionEH.sqf index 5e8d17e50cf..33c4bdffc21 100644 --- a/addons/grenades/functions/fnc_flashbangExplosionEH.sqf +++ b/addons/grenades/functions/fnc_flashbangExplosionEH.sqf @@ -4,7 +4,7 @@ * Creates the flashbang effect and knock out AI units. * * Arguments: - * 0: The flashBang position ASL + * 0: Flashbang position ASL * * Return Value: * None @@ -18,152 +18,148 @@ params ["_grenadePosASL"]; TRACE_1("params",_grenadePosASL); -// Create flash to illuminate environment -if (hasInterface) then { - private _light = "#lightpoint" createVehicleLocal ASLtoAGL _grenadePosASL; - _light setPosASL _grenadePosASL; - - _light setLightBrightness 20; - _light setLightAmbient [1,1,1]; - _light setLightColor [1,1,1]; - _light setLightDayLight true; - _light setLightAttenuation [0, 1, 5, 1000, 0, 20]; - - // Reduce the light after 0.1 seconds - [{ - params ["_light"]; - _light setLightBrightness 5; - // Delete the light after 0.2 more seconds - [{ - params ["_light"]; - deleteVehicle _light; - }, [_light], 0.2] call CBA_fnc_waitAndExecute; - }, [_light], 0.1] call CBA_fnc_waitAndExecute; -}; - // Affect local AI (players are not local, except for ACE_player) // @todo: Affect units in static weapons, turned out, etc -private _affected = (ASLtoAGL _grenadePosASL) nearEntities ["CAManBase", 20]; -_affected = _affected - [ACE_player]; +private _affected = ((ASLtoAGL _grenadePosASL) nearEntities ["CAManBase", 20]) - [ACE_player]; + { - if (local _x && {_x call EFUNC(common,isAwake)}) then { - private _unit = _x; - private _strength = 1 - (((eyePos _unit) vectorDistance _grenadePosASL) min 20) / 20; + private _unit = _x; + private _strength = 1 - (((eyePos _unit) vectorDistance _grenadePosASL) min 20) / 20; + + TRACE_3("FlashBangEffect Start",_unit,((getPosASL _unit) vectorDistance _grenadePosASL),_strength); + + [_unit, true] call EFUNC(common,disableAI); - TRACE_3("FlashBangEffect Start",_unit,((getPosASL _unit) vectorDistance _grenadePosASL),_strength); + // Make AI try to look away + private _dirToFlash = _unit getDir _grenadePosASL; + _unit setDir (_dirToFlash + linearConversion [0.2, 1, _strength, 40, 135] * selectRandom [-1, 1]); - [_unit, true] call EFUNC(common,disableAI); + private _flashReactionDebounce = _unit getVariable [QGVAR(flashReactionDebounce), 0]; + _unit setVariable [QGVAR(flashReactionDebounce), _flashReactionDebounce max (CBA_missionTime + (7 * _strength))]; - // Make AI try to look away - private _dirToFlash = _unit getDir _grenadePosASL; - _unit setDir (_dirToFlash + linearConversion [0.2, 1, _strength, 40, 135] * selectRandom [-1, 1]); + if (_flashReactionDebounce < CBA_missionTime) then { + // Not used internally but could be useful for other mods + _unit setVariable [QGVAR(flashStrength), _strength, true]; + + [QGVAR(flashbangedAI), [_unit, _strength, _grenadePosASL]] call CBA_fnc_localEvent; + + { + _unit setSkill [_x, (_unit skill _x) / 50]; + } forEach SUBSKILLS; + + [{ + CBA_missiontime >= _this getVariable [QGVAR(flashReactionDebounce), 0] + }, { + params ["_unit"]; + + _unit setVariable [QGVAR(flashStrength), 0, true]; + + // Make sure we don't enable AI for unconscious units + if (_unit call EFUNC(common,isAwake)) then { + [_unit, false] call EFUNC(common,disableAI); + }; - private _flashReactionDebounce = _unit getVariable [QGVAR(flashReactionDebounce), 0]; - _unit setVariable [QGVAR(flashReactionDebounce), _flashReactionDebounce max (CBA_missionTime + (7 * _strength))]; - if (_flashReactionDebounce < CBA_missionTime) then { - // Not used interally but could be useful for other mods - _unit setVariable [QGVAR(flashStrength), _strength, true]; - [QGVAR(flashbangedAI), [_unit, _strength, _grenadePosASL]] call CBA_fnc_localEvent; { - _unit setSkill [_x, (_unit skill _x) / 50]; + _unit setSkill [_x, (_unit skill _x) * 50]; } forEach SUBSKILLS; - [{ - params ["_unit"]; - CBA_missiontime >= _unit getVariable [QGVAR(flashReactionDebounce), 0] - },{ - params ["_unit"]; - - _unit setVariable [QGVAR(flashStrength), 0, true]; - - // Make sure we don't enable AI for unconscious units - if !(_unit getVariable ["ace_isUnconscious", false]) then { - [_unit, false] call EFUNC(common,disableAI); - }; - { - _unit setSkill [_x, (_unit skill _x) * 50]; - } forEach SUBSKILLS; - }, [_unit]] call CBA_fnc_waitUntilAndExecute; - }; + }, _unit] call CBA_fnc_waitUntilAndExecute; }; -} forEach _affected; +} forEach (_affected select {local _x && {_x call EFUNC(common,isAwake)}}); -// Affect local player, independently of distance -if (hasInterface && {!isNull ACE_player} && {alive ACE_player}) then { - if ((getNumber (configOf ACE_player >> "isPlayableLogic")) == 1) exitWith { - TRACE_1("skipping playable logic",typeOf ACE_player); // VirtualMan_F (placeable logic zeus / spectator) - }; - // Do effects for player - // is there line of sight to the grenade? - private _eyePos = eyePos ACE_player; //PositionASL - _grenadePosASL set [2, (_grenadePosASL select 2) + 0.2]; // compensate for grenade glitching into ground - - private _strength = 1 - ((_eyePos vectorDistance _grenadePosASL) min 20) / 20; - - // Check for line of sight (check 4 points in case grenade is stuck in an object or underground) - private _losCoefficient = 1; - private _losCount = { - !lineIntersects [_grenadePosASL vectorAdd _x, _eyePos, ACE_player] - } count [[0,0,0], [0,0,0.2], [0.1, 0.1, 0.1], [-0.1, -0.1, 0.1]]; - TRACE_1("Line of sight count (out of 4)",_losCount); - if (_losCount <= 1) then { - _losCoefficient = 0.1; - }; - _strength = _strength * _losCoefficient; +if (!hasInterface) exitWith {}; - // Add ace_hearing ear ringing sound effect - if (["ace_hearing"] call EFUNC(common,isModLoaded) && {_strength > 0 && {EGVAR(hearing,damageCoefficent) > 0.25}}) then { - private _earringingStrength = 40 * _strength; - [_earringingStrength] call EFUNC(hearing,earRinging); - TRACE_1("Earringing Strength",_earringingStrength); - }; +// Create flash to illuminate environment +private _light = "#lightpoint" createVehicleLocal ASLtoAGL _grenadePosASL; +_light setPosASL _grenadePosASL; - // add ace_medical pain effect: - if (["ace_medical"] call EFUNC(common,isModLoaded) && {_strength > 0.1} && {isDamageAllowed _unit} && {_unit getVariable [QEGVAR(medical,allowDamage), true]}) then { - [ACE_player, _strength / 2] call EFUNC(medical,adjustPainLevel); - }; +_light setLightBrightness 20; +_light setLightAmbient [1,1,1]; +_light setLightColor [1,1,1]; +_light setLightDayLight true; +_light setLightAttenuation [0, 1, 5, 1000, 0, 20]; - // Effect on vision has a wider range, with a higher falloff - _strength = 1 - (((_eyePos vectorDistance _grenadePosASL) min 25) / 25) ^ 0.4; - _strength = _strength * _losCoefficient; - // Account for people looking away by slightly reducing the effect for visual effects. - private _eyeDir = ((AGLtoASL positionCameraToWorld [0,0,1]) vectorDiff (AGLtoASL positionCameraToWorld [0,0,0])); - private _dirToUnitVector = _eyePos vectorFromTo _grenadePosASL; - private _angleDiff = acos (_eyeDir vectorDotProduct _dirToUnitVector); - TRACE_2("",_angleDiff,((1 - (_angleDiff - 45) / (120 - 45)) max 0)); - // from 0-45deg, full effect - if (_angleDiff > 45) then { - _strength = _strength * ((1 - (_angleDiff - 45) / (120 - 45)) max 0); - }; +// Reduce the light after 0.1 seconds +[{ + _this setLightBrightness 5; - // Blind player - if (_strength > 0.1) then { - private _blend = [[1,1,1,0], [0.3,0.3,0.3,1]] select EGVAR(common,epilepsyFriendlyMode); + // Delete the light after 0.2 more seconds + [{deleteVehicle _this}, _this, 0.2] call CBA_fnc_waitAndExecute; +}, _light, 0.1] call CBA_fnc_waitAndExecute; - GVAR(flashbangPPEffectCC) ppEffectEnable true; - GVAR(flashbangPPEffectCC) ppEffectAdjust [1, 1, (0.8 + _strength) min 1, _blend, [0,0,0,1], [0,0,0,0]]; - GVAR(flashbangPPEffectCC) ppEffectCommit 0.01; +// Ignore dead and placeable logic (zeus / spectator) +if (!alive ACE_player || {(getNumber (configOf ACE_player >> "isPlayableLogic")) == 1}) exitWith {}; - //PARTIALRECOVERY - start decreasing effect over time - [{ - params ["_strength", "_blend"]; +// Affect local player, independently of distance +// Check for line of sight to the grenade +private _eyePos = eyePos ACE_player; // PositionASL +_grenadePosASL set [2, (_grenadePosASL select 2) + 0.2]; // compensate for grenade glitching into ground + +private _strength = 1 - ((_eyePos vectorDistance _grenadePosASL) min 20) / 20; + +// Check for line of sight (check 4 points in case grenade is stuck in an object or underground) +private _losCount = { + !lineIntersects [_grenadePosASL vectorAdd _x, _eyePos, ACE_player] +} count [[0, 0, 0], [0, 0, 0.2], [0.1, 0.1, 0.1], [-0.1, -0.1, 0.1]]; +TRACE_1("Line of sight count (out of 4)",_losCount); + +private _losCoefficient = [1, 0.1] select (_losCount <= 1); +_strength = _strength * _losCoefficient; + +// Add ace_hearing ear ringing sound effect +if (["ace_hearing"] call EFUNC(common,isModLoaded) && {_strength > 0} && {EGVAR(hearing,damageCoefficent) > 0.25}) then { + private _earringingStrength = 40 * _strength; + [_earringingStrength] call EFUNC(hearing,earRinging); + TRACE_1("Earringing Strength",_earringingStrength); +}; - GVAR(flashbangPPEffectCC) ppEffectAdjust [1, 1, 0, _blend, [0,0,0,1], [0,0,0,0]]; - GVAR(flashbangPPEffectCC) ppEffectCommit (10 * _strength); - }, [_strength, _blend], 7 * _strength] call CBA_fnc_waitAndExecute; +// Add ace_medical pain effect +if (GETEGVAR(medical,enabled,false) && {_strength > 0.1} && {isDamageAllowed _unit} && {_unit getVariable [QEGVAR(medical,allowDamage), true]}) then { + [ACE_player, _strength / 2] call EFUNC(medical,adjustPainLevel); +}; - //FULLRECOVERY - end effect - [{ - GVAR(flashbangPPEffectCC) ppEffectEnable false; - }, [], 17 * _strength] call CBA_fnc_waitAndExecute; - }; +// Effect on vision has a wider range, with a higher falloff +_strength = 1 - (((_eyePos vectorDistance _grenadePosASL) min 25) / 25) ^ 0.4; +_strength = _strength * _losCoefficient; + +// Account for people looking away by slightly reducing the effect for visual effects. +private _eyeDir = ((AGLtoASL positionCameraToWorld [0, 0, 1]) vectorDiff (AGLtoASL positionCameraToWorld [0, 0, 0])); +private _dirToUnitVector = _eyePos vectorFromTo _grenadePosASL; +private _angleDiff = acos (_eyeDir vectorDotProduct _dirToUnitVector); +TRACE_2("",_angleDiff,((1 - (_angleDiff - 45) / (120 - 45)) max 0)); - // Make player flinch - if (_strength <= 0.2) exitWith {}; - private _minFlinch = linearConversion [0.2, 1, _strength, 0, 60, true]; - private _maxFlinch = linearConversion [0.2, 1, _strength, 0, 95, true]; - private _flinch = (_minFlinch + random (_maxFlinch - _minFlinch)) * selectRandom [-1, 1]; - ACE_player setDir (getDir ACE_player + _flinch); +// From 0-45deg, full effect +if (_angleDiff > 45) then { + _strength = _strength * ((1 - (_angleDiff - 45) / (120 - 45)) max 0); +}; + +// Blind player +if (_strength > 0.1) then { + private _blend = [[1, 1, 1, 0], [0.3, 0.3, 0.3, 1]] select EGVAR(common,epilepsyFriendlyMode); + + GVAR(flashbangPPEffectCC) ppEffectEnable true; + GVAR(flashbangPPEffectCC) ppEffectAdjust [1, 1, (0.8 + _strength) min 1, _blend, [0, 0, 0, 1], [0, 0, 0, 0]]; + GVAR(flashbangPPEffectCC) ppEffectCommit 0.01; + + // PARTIALRECOVERY - start decreasing effect over time + [{ + params ["_strength", "_blend"]; - [QGVAR(flashbangedPlayer), [_strength, _grenadePosASL]] call CBA_fnc_localEvent; + GVAR(flashbangPPEffectCC) ppEffectAdjust [1, 1, 0, _blend, [0, 0, 0, 1], [0, 0, 0, 0]]; + GVAR(flashbangPPEffectCC) ppEffectCommit (10 * _strength); + }, [_strength, _blend], 7 * _strength] call CBA_fnc_waitAndExecute; + + // FULLRECOVERY - end effect + [{ + GVAR(flashbangPPEffectCC) ppEffectEnable false; + }, [], 17 * _strength] call CBA_fnc_waitAndExecute; }; -true + +// Make player flinch +if (_strength <= 0.2) exitWith {}; + +private _minFlinch = linearConversion [0.2, 1, _strength, 0, 60, true]; +private _maxFlinch = linearConversion [0.2, 1, _strength, 0, 95, true]; +private _flinch = (_minFlinch + random (_maxFlinch - _minFlinch)) * selectRandom [-1, 1]; +ACE_player setDir (getDir ACE_player + _flinch); + +[QGVAR(flashbangedPlayer), [_strength, _grenadePosASL]] call CBA_fnc_localEvent; diff --git a/addons/grenades/functions/fnc_flashbangThrownFuze.sqf b/addons/grenades/functions/fnc_flashbangThrownFuze.sqf index 7f1a52417cf..89020842d2a 100644 --- a/addons/grenades/functions/fnc_flashbangThrownFuze.sqf +++ b/addons/grenades/functions/fnc_flashbangThrownFuze.sqf @@ -4,7 +4,7 @@ * Waits for the flashbang grenade fuze to trigger and 'explode' * * Arguments: - * 0: projectile - Flashbang Grenade + * 0: Flashbang grenade * * Return Value: * None @@ -18,8 +18,17 @@ params ["_projectile"]; TRACE_1("params",_projectile); -if (alive _projectile) then { - playSound3D ["A3\Sounds_F\arsenal\explosives\grenades\Explosion_HE_grenade_01.wss", _projectile, false, getPosASL _projectile, 5, 1.2, 400]; +if (!alive _projectile) exitWith {}; - ["ace_flashbangExploded", [getPosASL _projectile]] call CBA_fnc_globalEvent; -}; +private _posASL = getPosASL _projectile; +private _sounds = getArray (_projectile call CBA_fnc_getObjectConfig >> QGVAR(flashbangExplodeSound)); + +(if (_sounds isEqualTo []) then { + [format ["A3\Sounds_F\arsenal\explosives\grenades\Explosion_HE_grenade_0%1.wss", floor (random 4) + 1], 5, 1.2, 400] +} else { + selectRandom _sounds +}) params ["_file", "_volume", "_pitch", "_distance"]; + +playSound3D [_file, _projectile, false, _posASL, _volume, _pitch, _distance]; + +["ace_flashbangExploded", [_posASL]] call CBA_fnc_globalEvent; diff --git a/addons/grenades/functions/fnc_incendiary.sqf b/addons/grenades/functions/fnc_incendiary.sqf index 11d89d4ca53..f0caf82ed8e 100644 --- a/addons/grenades/functions/fnc_incendiary.sqf +++ b/addons/grenades/functions/fnc_incendiary.sqf @@ -1,11 +1,12 @@ #include "..\script_component.hpp" /* * Author: commy2 - * Makes incendiary burn. + * Makes an incendiary grenade burn. * * Arguments: - * 0: The grenade + * 0: Incendiary grenade * 1: Incendiary lifetime + * 2: Instigator's side * * Return Value: * None @@ -30,11 +31,11 @@ #define PARTICLE_SMOKE_LIFTING 1 #define PARTICLE_SMOKE_WIND_EFFECT 1 -#define EFFECT_SIZE 1 #define ORIENTATION 5.4 #define EXPANSION 1 #define DESTRUCTION_RADIUS 1.8 +#define SEARCH_RADIUS 5 params ["_projectile", "_timeToLive", "_center"]; @@ -42,16 +43,16 @@ if (isNull _projectile) exitWith {TRACE_1("null",_projectile);}; private _position = position _projectile; -// --- AI +// Alert nearby hostile AI private _nearLocalEnemies = []; { { - if (local _x && {[_center, side _x] call BIS_fnc_sideIsEnemy}) then { // WE WANT THE OBJECTS SIDE HERE! + if (local _x && {[_center, side group _x] call BIS_fnc_sideIsEnemy}) then { // WE WANT THE OBJECT'S SIDE HERE! _nearLocalEnemies pushBackUnique _x; }; } forEach crew _x; -} forEach (_position nearObjects ALERT_NEAR_ENEMY_RANGE); +} forEach (_position nearObjects ALERT_NEAR_ENEMY_RANGE); //@todo replace with nearEntities in 2.18 { if (behaviour _x in ["SAFE", "AWARE"]) then { @@ -59,7 +60,7 @@ private _nearLocalEnemies = []; }; } forEach _nearLocalEnemies; -// --- fire +// Fire particles private _fire = "#particlesource" createVehicleLocal _position; _fire setParticleParams [ @@ -99,7 +100,7 @@ _fire setParticleRandom [PARTICLE_LIFE_TIME / 4, [0.15 * EFFECT_SIZE, 0.15 * EFF _fire setParticleFire [1.2,1.0,0.1]; _fire setDropInterval (1 / PARTICLE_DENSITY); -// --- smoke +// Smoke particles private _smoke = "#particlesource" createVehicleLocal _position; _smoke setParticleParams [ @@ -137,7 +138,7 @@ _smoke setParticleParams [ _smoke setParticleRandom [PARTICLE_SMOKE_LIFE_TIME / 2, [0.5 * EFFECT_SIZE, 0.5 * EFFECT_SIZE, 0.2 * EFFECT_SIZE], [0.3,0.3,0.5], 1, 0, [0,0,0,0.06], 0, 0]; _smoke setDropInterval (1 / PARTICLE_SMOKE_DENSITY); -// --- light +// Light private _light = "#lightpoint" createVehicleLocal (_position vectorAdd [0,0,0.5]); _light setLightBrightness 1.0; @@ -150,92 +151,72 @@ _light setLightDayLight false; _light lightAttachObject [_projectile, [0,0,0]]; -// --- sound +// Sound private _sound = objNull; if (isServer) then { _sound = createSoundSource ["Sound_Fire", _position, [], 0]; private _radius = 1.5 * getNumber (configOf _projectile >> "indirectHitRange"); private _intensity = getNumber (configOf _projectile >> "hit"); - [QEGVAR(fire,addFireSource), [_projectile, _radius, _intensity, _projectile, {CBA_missionTime < _this}, CBA_missionTime + _timeToLive]] call CBA_fnc_serverEvent; -}; - -[{ - {deleteVehicle _x} forEach _this; -}, [_fire, _smoke, _light, _sound], _timeToLive] call CBA_fnc_waitAndExecute; - -// --- damage -{ - if (local _x) then { - //systemChat format ["burn: %1", _x]; - // --- destroy nearby static weapons and ammo boxes - if (_x isKindOf "StaticWeapon" || {_x isKindOf "ACE_RepairItem_Base"}) then { - _x setDamage 1; - }; - if (_x isKindOf "ReammoBox_F") then { - if ( - "ace_cookoff" call EFUNC(common,isModLoaded) && - {GETVAR(_x,EGVAR(cookoff,enableAmmoCookoff),EGVAR(cookoff,enableAmmobox))} - ) then { - _x call EFUNC(cookoff,cookOffBox); - } else { - _x setDamage 1; - }; - }; + [QEGVAR(fire,addFireSource), [_projectile, _radius, _intensity, _projectile, { + params ["_endTime", "_projectile"]; - // --- delete nearby ground weapon holders - if (_x isKindOf "WeaponHolder" || {_x isKindOf "WeaponHolderSimulated"}) then { - deleteVehicle _x; + // If incendiary no longer exists, exit + if (isNull _projectile) exitWith { + false // return }; - // --- inflame fireplace, barrels etc. - _x inflame true; - }; -} forEach (_position nearObjects DESTRUCTION_RADIUS); - -// --- damage local vehicle -private _vehicle = _position nearestObject "Car"; - -if (!local _vehicle) exitWith {}; - -private _config = configOf _vehicle; + // Need to get the position every time, as grenade might have been moved + private _position = position _projectile; -// --- burn tyres -private _fnc_isWheelHitPoint = { - params ["_selectionName"]; + { + // Damage vehicles + [QGVAR(damageEngineAndWheels), [_x, _position], _x] call CBA_fnc_targetEvent; + } forEach (_position nearEntities ["Car", SEARCH_RADIUS]); - // wheels must use a selection named "wheel_X_Y_steering" for PhysX to work - _selectionName select [0, 6] == "wheel_" && { - _selectionName select [count _selectionName - 9] == "_steering" - } // return + CBA_missionTime < _endTime // return + }, [CBA_missionTime + _timeToLive, _projectile]]] call CBA_fnc_serverEvent; }; +[{ + {deleteVehicle _x} forEach _this; +}, [_fire, _smoke, _light, _sound], _timeToLive] call CBA_fnc_waitAndExecute; + +// Damage { - private _wheelSelection = getText (_config >> "HitPoints" >> _x >> "name"); + // Inflame fireplace, barrels etc. + _x inflame true; - if (_wheelSelection call _fnc_isWheelHitPoint) then { - private _wheelPosition = _vehicle modelToWorld (_vehicle selectionPosition _wheelSelection); + // Destroy nearby static weapons and ammo boxes + if (_x isKindOf "StaticWeapon" || {_x isKindOf "ACE_RepairItem_Base"}) then { + _x setDamage 1; - if (_position distance _wheelPosition < EFFECT_SIZE * 2) then { - _vehicle setHit [_wheelSelection, 1]; - }; + continue; }; -} forEach (getAllHitPointsDamage _vehicle param [0, []]); - -// --- burn car engine -if (_vehicle isKindOf "Wheeled_APC_F") exitWith {}; -private _engineSelection = getText (_config >> "HitPoints" >> "HitEngine" >> "name"); -private _enginePosition = _vehicle modelToWorld (_vehicle selectionPosition _engineSelection); + if (_x isKindOf "ReammoBox_F") then { + if ( + (["ace_cookoff"] call EFUNC(common,isModLoaded)) && + {EGVAR(cookoff,enableAmmobox)} && + {EGVAR(cookoff,ammoCookoffDuration) != 0} && + {_x getVariable [QEGVAR(cookoff,enableAmmoCookoff), true]} + ) then { + [QEGVAR(cookOff,cookOffBoxServer), _box] call CBA_fnc_serverEvent; + } else { + _x setDamage 1; + }; -if (_position distance _enginePosition < EFFECT_SIZE * 2) then { - _vehicle setHit [_engineSelection, 1]; + continue; + }; - if ("ace_cookoff" call EFUNC(common,isModLoaded)) then { - private _enabled = _vehicle getVariable [QEGVAR(cookoff,enable), EGVAR(cookoff,enable)]; - if (_enabled in [2, true] || {_enabled isEqualTo 1 && {fullCrew [_vehicle, "", false] findIf {isPlayer (_x select 0)} != -1}}) then { - _vehicle call EFUNC(cookoff,engineFire); - }; + // Delete nearby ground weapon holders + if (_x isKindOf "WeaponHolder" || {_x isKindOf "WeaponHolderSimulated"}) then { + deleteVehicle _x; }; -}; +} forEach ((_position nearObjects DESTRUCTION_RADIUS) select {local _x && {isDamageAllowed _x}}); + +{ + // Damage vehicles (locality is checked in FUNC(damageEngineAndWheels)) + [_x, _position] call FUNC(damageEngineAndWheels); +} forEach (_position nearEntities ["Car", SEARCH_RADIUS]); diff --git a/addons/grenades/functions/fnc_nextMode.sqf b/addons/grenades/functions/fnc_nextMode.sqf index 1a64cf9f7ba..f33fa7a5a5d 100644 --- a/addons/grenades/functions/fnc_nextMode.sqf +++ b/addons/grenades/functions/fnc_nextMode.sqf @@ -7,25 +7,29 @@ * None * * Return Value: - * Handeled + * Handled * * Example: - * [] call ace_grenades_fnc_nextMode + * call ace_grenades_fnc_nextMode * * Public: No */ -private _mode = missionNamespace getVariable [QGVAR(currentThrowMode), 0]; +// _mode is 0-4, don't overflow +private _mode = (GVAR(currentThrowMode) + 1) % 5; -if (_mode == 4) then { - _mode = 0; -} else { - _mode = _mode + 1; -}; +private _currentThrowable = currentThrowable ACE_player; -// ROLL GRENADE DOESN'T WORK RIGHT NOW -if (_mode == 3) then { - _mode = 4; +// Make sure grenade can be rolled if in roll mode (detonation time has to be >= 1 second and player isn't in a vehicle) +if ( + _mode == 3 && + {_currentThrowable isNotEqualTo []} && + { + !isNull objectParent ACE_player || + {getNumber (configFile >> "CfgAmmo" >> getText (configFile >> "CfgMagazines" >> _currentThrowable select 0 >> "ammo") >> "explosionTime") < MIN_EXPLOSION_TIME_FOR_ROLL} + } +) then { + _mode = _mode + 1; }; private _hint = localize ([ @@ -38,6 +42,37 @@ private _hint = localize ([ [_hint] call EFUNC(common,displayTextStructured); +GVAR(throwModePFEH) call CBA_fnc_removePerFrameHandler; GVAR(currentThrowMode) = _mode; +// If in rolling mode, check every frame if current throwable is rollable +if (GVAR(currentThrowMode) == 3) then { + GVAR(currentThrowable) = _currentThrowable; + + GVAR(throwModePFEH) = { + private _currentThrowable = currentThrowable ACE_player; + + if (GVAR(currentThrowable) isEqualTo _currentThrowable) exitWith {}; + + GVAR(currentThrowable) = _currentThrowable; + + // Make sure grenade can be rolled if in roll mode (detonation time has to be >= 1 second and player isn't in a vehicle) + if !( + GVAR(currentThrowMode) == 3 && + {_currentThrowable isNotEqualTo []} && + { + !isNull objectParent ACE_player || + {getNumber (configFile >> "CfgAmmo" >> getText (configFile >> "CfgMagazines" >> _currentThrowable select 0 >> "ammo") >> "explosionTime") < MIN_EXPLOSION_TIME_FOR_ROLL} + } + ) exitWith {}; + + // Force the user into the normal throw mode + // Next throw mode after roll would be drop, which isn't ideal if the user tries to throw unknowingly... + [format [LLSTRING(RollGrenadeDisabled), LLSTRING(NormalThrow)], 2] call EFUNC(common,displayTextStructured); + + GVAR(throwModePFEH) call CBA_fnc_removePerFrameHandler; + GVAR(currentThrowMode) = 0; + } call CBA_fnc_addPerFrameHandler; +}; + true diff --git a/addons/grenades/functions/fnc_throwGrenade.sqf b/addons/grenades/functions/fnc_throwGrenade.sqf index 9a0168da3ea..a440c8fd1b7 100644 --- a/addons/grenades/functions/fnc_throwGrenade.sqf +++ b/addons/grenades/functions/fnc_throwGrenade.sqf @@ -27,40 +27,26 @@ if (isNull _projectile) then { private _config = configFile >> "CfgAmmo" >> _ammo; -// handle special grenades and sounds +// Handle special grenades and sounds if (local _unit) then { - // handle priming sound, if present - private _soundConfig = getArray (configFile >> "CfgAmmo" >> _ammo >> QGVAR(pullPinSound)); + // Handle priming sound, if present + private _soundConfig = getArray (_config >> QGVAR(pullPinSound)); + if (_soundConfig isNotEqualTo []) then { _soundConfig params ["_file", "_volume", "_pitch", "_distance"]; - playSound3D [_file, objNull, false, getPosASL _projectile, _volume, _pitch, _distance]; + playSound3D [_file, objNull, insideBuilding _unit >= 0.5, getPosASL _projectile, _volume, _pitch, _distance]; }; if (getNumber (_config >> QGVAR(flashbang)) == 1) then { - private _bangs = 1; - private _entry = _config >> QGVAR(flashbangBangs); - if (isNumber _entry || isText _entry) then { - _bangs = getNumber _entry; - }; - private _fuzeTimeBase = getNumber (_config >> "explosionTime"); - - private _interval = 0.5; - _entry = _config >> QGVAR(flashbangInterval); - if (isNumber _entry || isText _entry) then { - _interval = getNumber _entry; - }; - - private _maxDeviation = 0.1; - _entry = _config >> QGVAR(flashbangIntervalMaxDeviation); - if (isNumber _entry || isText _entry) then { - _maxDeviation = getNumber _entry; - }; + private _bangs = [_config >> QGVAR(flashbangBangs), "NUMBER", 1] call CBA_fnc_getConfigEntry; + private _interval = [_config >> QGVAR(flashbangInterval), "NUMBER", 0.5] call CBA_fnc_getConfigEntry; + private _maxDeviation = [_config >> QGVAR(flashbangIntervalMaxDeviation), "NUMBER", 0.1] call CBA_fnc_getConfigEntry; for "_i" from 0 to (_bangs - 1) do { - private _fuzeTime = _fuzeTimeBase + _i*_interval + random [- _maxDeviation, 0, _maxDeviation]; + private _fuzeTime = _fuzeTimeBase + _i * _interval + random [-_maxDeviation, 0, _maxDeviation]; - [FUNC(flashbangThrownFuze), [_projectile], _fuzeTime] call CBA_fnc_waitAndExecute; + [LINKFUNC(flashbangThrownFuze), _projectile, _fuzeTime] call CBA_fnc_waitAndExecute; }; }; }; @@ -71,47 +57,56 @@ if (getNumber (_config >> QGVAR(flare)) == 1) then { private _color = getArray (_config >> QGVAR(color)); private _intensity = _color deleteAt 3; - [FUNC(flare), [_projectile, _color, _intensity, _timeToLive], _fuzeTime] call CBA_fnc_waitAndExecute; + [LINKFUNC(flare), [_projectile, _color, _intensity, _timeToLive], _fuzeTime] call CBA_fnc_waitAndExecute; }; if (getNumber (_config >> QGVAR(incendiary)) == 1) then { private _fuzeTime = getNumber (_config >> "explosionTime"); private _timeToLive = getNumber (_config >> "timeToLive"); - [FUNC(incendiary), [_projectile, _timeToLive, side _unit], _fuzeTime] call CBA_fnc_waitAndExecute; // WE WANT THE OBJECTS SIDE HERE! + [LINKFUNC(incendiary), [_projectile, _timeToLive, side group _unit], _fuzeTime] call CBA_fnc_waitAndExecute; // Get the unit's real side (will return civilian if unconscious) }; -// handle throw modes +// Handle throw modes if (_unit != ACE_player) exitWith {}; if (_unit getVariable [QEGVAR(advanced_throwing,primed), false]) exitWith {LOG("advanced_throwing throw");}; -private _mode = missionNamespace getVariable [QGVAR(currentThrowMode), 0]; +if (GVAR(currentThrowMode) == 0) exitWith {}; -if (_mode != 0) then { - private _velocity = velocity _projectile; +private _velocity = velocity _projectile; - switch (_mode) do { - //high throw - case 1 : { - _velocity = [ - 0.5 * (_velocity select 0), - 0.5 * (_velocity select 1), - [0, 0, 0] distance (_velocity vectorMultiply 0.5) - ]; - }; - //precise throw - case 2 : { - _velocity = (_unit weaponDirection _weapon) vectorMultiply (vectorMagnitude _velocity); - }; - //roll grande - case 3 : { - //@todo - }; - //drop grenade - case 4 : { - _velocity = [0, 0, 0]; - }; +switch (GVAR(currentThrowMode)) do { + // High throw + case 1: { + _velocity = _velocity vectorMultiply 0.5; + + _velocity set [2, vectorMagnitude _velocity]; + }; + // Precise throw + case 2: { + _velocity = (_unit weaponDirection _weapon) vectorMultiply (vectorMagnitude _velocity); }; + // Roll grenade + case 3: { + private _posASL = getPosASL _projectile; + + // getPos is unreliable, as surfaces in some ruins are not recognised as surfaces + private _lisPos = (lineIntersectsSurfaces [_posASL, _posASL vectorAdd [0, 0, -1e11], ACE_player, objNull, true, 1, "ROADWAY", "FIRE"]) select 0; + _projectile setPosASL ((_lisPos select 0) vectorAdd [0, 0, 0.2]); + + // Rotate throwables by 90° to the side by default, so cylindrical throwables can be rolled + private _vectorDirAndUp = getArray (_config >> QGVAR(rollVectorDirAndUp)); + _vectorDirAndUp params [["_vectorDir", [0, 1, 0], [[]], 3], ["_vectorUp", [1, 0, 0], [[]], 3]]; - _projectile setVelocity _velocity; + // Do as if object were facing north + _projectile setVectorDirAndUp ([[_vectorDir, _vectorUp], -(direction _projectile), 0, 0] call BIS_fnc_transformVectorDirAndUp); + + _velocity = (vectorDir _unit) vectorMultiply 10; + }; + // Drop grenade + case 4: { + _velocity = [0, 0, 0]; + }; }; + +_projectile setVelocity _velocity; diff --git a/addons/grenades/initSettings.inc.sqf b/addons/grenades/initSettings.inc.sqf index b6fa36f459c..6a6ceb8c37b 100644 --- a/addons/grenades/initSettings.inc.sqf +++ b/addons/grenades/initSettings.inc.sqf @@ -1,9 +1,10 @@ [ - QGVAR(convertExplosives), "CHECKBOX", + QGVAR(convertExplosives), + "CHECKBOX", [LSTRING(convertExplosives_DisplayName), LSTRING(convertExplosives_Description)], LSTRING(Settings_DisplayName), true, - true, - {}, - true + 1, + {[QGVAR(convertExplosives), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_fnc_addSetting; diff --git a/addons/grenades/script_component.hpp b/addons/grenades/script_component.hpp index 49dbe92a3f3..e49fa21ca90 100644 --- a/addons/grenades/script_component.hpp +++ b/addons/grenades/script_component.hpp @@ -16,7 +16,6 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define EFFECT_STAGE_RESETAI 0 -#define EFFECT_STAGE_DELETELIGHT 1 -#define EFFECT_STAGE_PARTIALRECOVERY 2 -#define EFFECT_STAGE_FULLRECOVERY 3 +#define EFFECT_SIZE 1 + +#define MIN_EXPLOSION_TIME_FOR_ROLL 1 diff --git a/addons/grenades/stringtable.xml b/addons/grenades/stringtable.xml index d5c1b142a65..1a571093f8f 100644 --- a/addons/grenades/stringtable.xml +++ b/addons/grenades/stringtable.xml @@ -103,6 +103,11 @@ 下丟投擲 Bombayı Yere Bırak + + Can't roll this grenade, switched to %1 + この手榴弾は転がせません、 %1 に切り替えます + Эта граната не может быть брошена, переключитесь на %1 + M84 Stun Grenade M84 Blendgranate diff --git a/addons/gunbag/functions/fnc_offGunbagCallback.sqf b/addons/gunbag/functions/fnc_offGunbagCallback.sqf index 8edd3e4582b..68b22fb1ef3 100644 --- a/addons/gunbag/functions/fnc_offGunbagCallback.sqf +++ b/addons/gunbag/functions/fnc_offGunbagCallback.sqf @@ -11,7 +11,7 @@ * None * * Example: - * [player, target] call ace_gunbag_fnc_offGunbagCallback + * [player, cursorObject] call ace_gunbag_fnc_offGunbagCallback * * Public: No */ @@ -23,39 +23,28 @@ private _gunbag = backpackContainer _target; private _state = _gunbag getVariable [QGVAR(gunbagWeapon), []]; if (_state isEqualTo []) exitWith { - [localize LSTRING(empty)] call EFUNC(common,displayTextStructured); + [LLSTRING(empty)] call EFUNC(common,displayTextStructured); }; _state params ["_weapon", "_items", "_magazines"]; -_unit addWeapon _weapon; +[_unit, _weapon, true, _magazines] call EFUNC(common,addWeapon); -// Game will auto add magazines from player's inventory, put these back in player inventory as they will be overwritten -([_unit, _weapon] call EFUNC(common,getWeaponState)) params ["", "", "_addedMags", "_addedAmmo"]; +// Add attachments { - if (((_x select 0) != "") && {(_addedMags select _forEachIndex) != ""}) then { - TRACE_2("Re-adding mag",_x,_addedMags select _forEachIndex); - _unit addMagazine [_addedMags select _forEachIndex, _addedAmmo select _forEachIndex]; - }; -} forEach _magazines; - -removeAllPrimaryWeaponItems _unit; - -{ - _unit addWeaponItem [_weapon, _x]; -} forEach (_items + _magazines); + _unit addWeaponItem [_weapon, _x, true]; +} forEach (_items select {_x != ""}); _unit selectWeapon _weapon; -_magazines = _magazines apply {_x select 0}; +private _mass = [_weapon, _items, _magazines apply {_x select 0}] call FUNC(calculateMass); -private _mass = [_weapon, _items, _magazines] call FUNC(calculateMass); - -// remove virtual load +// Remove virtual load [_target, _gunbag, -_mass] call EFUNC(movement,addLoadToUnitContainer); + _gunbag setVariable [QGVAR(gunbagWeapon), [], true]; -// play sound +// Play sound if (["ace_backpacks"] call EFUNC(common,isModLoaded)) then { [_target, _gunbag] call EFUNC(backpacks,backpackOpened); }; diff --git a/addons/gunbag/functions/fnc_swapGunbagCallback.sqf b/addons/gunbag/functions/fnc_swapGunbagCallback.sqf index a7d319506bf..cb4bca2ea4a 100644 --- a/addons/gunbag/functions/fnc_swapGunbagCallback.sqf +++ b/addons/gunbag/functions/fnc_swapGunbagCallback.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author: Ir0n1E and mjc4wilton + * Author: Ir0n1E, mjc4wilton * Swap primary weapon and weapon in gunbag. * * Arguments: @@ -11,66 +11,49 @@ * None * * Example: - * [player, target] call ace_gunbag_fnc_swapGunbagCallback + * [player, cursorObject] call ace_gunbag_fnc_swapGunbagCallback * * Public: No */ params ["_unit", "_target"]; -private _currentWeapon = primaryWeapon _unit; //Get Current Weapon -private _gunbag = backpackContainer _target; - - -//---Set up current weapon for storing -private _currentWeaponState = [_unit, _currentWeapon] call EFUNC(common,getWeaponState); //Gets weapon attachments -/* - * example return value _state - * [["","","optic_Aco",""],["arifle_MX_GL_ACO_F","GL_3GL_F"],["30Rnd_65x39_caseless_mag","1Rnd_HE_Grenade_shell"],[30,1]] - */ +// Set up current weapon for storing +private _gunbag = backpackContainer _target; +private _currentItems = (getUnitLoadout _unit) select 0; -_currentWeaponState params ["_currentWeaponItems", "", "_currentWeaponMagazines", "_currentWeaponAmmo"]; //Extract Weapon Attachments to separate arrays +private _currentMagazines = _currentItems select [4, 2]; +_currentItems deleteRange [4, 2]; -private _currentWeaponMass = [_currentWeapon, _currentWeaponItems, _currentWeaponMagazines] call FUNC(calculateMass); +private _currentWeapon = _currentItems deleteAt 0; -{ - _currentWeaponMagazines set [_forEachIndex, [_x, _currentWeaponAmmo select _forEachIndex]]; -} forEach _currentWeaponMagazines; +private _currentMass = [_currentWeapon, _currentItems, _currentMagazines apply {_x select 0}] call FUNC(calculateMass); -//---Set up weapon in gunbag -private _newWeaponState = _gunbag getVariable [QGVAR(gunbagWeapon), []]; +// Set up weapon in gunbag +private _newState = _gunbag getVariable [QGVAR(gunbagWeapon), []]; -if (_newWeaponState isEqualTo []) exitWith { +if (_newState isEqualTo []) exitWith { [LLSTRING(empty)] call EFUNC(common,displayTextStructured); }; -_newWeaponState params ["_newWeapon", "_newWeaponItems", "_newWeaponMagazines"]; +_newState params ["_newWeapon", "_newItems", "_newMagazines"]; -//---Swap Weapons +// Swap Weapons _unit removeWeapon _currentWeapon; -_unit addWeapon _newWeapon; - -// Game will auto add magazines from player's inventory, put these back in player inventory as they will be overwritten -([_unit, _newWeapon] call EFUNC(common,getWeaponState)) params ["", "", "_addedMags", "_addedAmmo"]; -{ - if (((_x select 0) != "") && {(_addedMags select _forEachIndex) != ""}) then { - TRACE_2("Re-adding mag",_x,_addedMags select _forEachIndex); - _unit addMagazine [_addedMags select _forEachIndex, _addedAmmo select _forEachIndex]; - }; -} forEach _newWeaponMagazines; -removeAllPrimaryWeaponItems _unit; +[_unit, _newWeapon, true, _newMagazines] call EFUNC(common,addWeapon); +// Add attachments { - _unit addWeaponItem [_newWeapon, _x]; -} forEach (_newWeaponItems + _newWeaponMagazines); + _unit addWeaponItem [_newWeapon, _x, true]; +} forEach (_newItems select {_x != ""}); _unit selectWeapon _newWeapon; -_newWeaponMagazines = _newWeaponMagazines apply {_x select 0}; +private _newMass = [_newWeapon, _newItems, _newMagazines apply {_x select 0}] call FUNC(calculateMass); -private _newWeaponMass = [_newWeapon, _newWeaponItems, _newWeaponMagazines] call FUNC(calculateMass); +// Update virtual load +[_target, _gunbag, _currentMass - _newMass] call EFUNC(movement,addLoadToUnitContainer); -// update virtual load -[_target, _gunbag, _currentWeaponMass - _newWeaponMass] call EFUNC(movement,addLoadToUnitContainer); -_gunbag setVariable [QGVAR(gunbagWeapon), [_currentWeapon, _currentWeaponItems, _currentWeaponMagazines], true]; //Replace weapon in gunbag +// Replace weapon in gunbag +_gunbag setVariable [QGVAR(gunbagWeapon), [_currentWeapon, _currentItems, _currentMagazines], true]; diff --git a/addons/gunbag/functions/fnc_toGunbagCallback.sqf b/addons/gunbag/functions/fnc_toGunbagCallback.sqf index 4930d1d95ae..9958eed32b6 100644 --- a/addons/gunbag/functions/fnc_toGunbagCallback.sqf +++ b/addons/gunbag/functions/fnc_toGunbagCallback.sqf @@ -11,38 +11,32 @@ * None * * Example: - * [player, target] call ace_gunbag_fnc_toGunbagCallback + * [player, cursorObject] call ace_gunbag_fnc_toGunbagCallback * * Public: No */ params ["_unit", "_target"]; -private _weapon = primaryWeapon _unit; +// Set up current weapon for storing private _gunbag = backpackContainer _target; +private _items = (getUnitLoadout _unit) select 0; -private _state = [_unit, _weapon] call EFUNC(common,getWeaponState); +private _magazines = _items select [4, 2]; +_items deleteRange [4, 2]; -/* - * example return value _state - * [["","","optic_Aco",""],["arifle_MX_GL_ACO_F","GL_3GL_F"],["30Rnd_65x39_caseless_mag","1Rnd_HE_Grenade_shell"],[30,1]] - */ - -_state params ["_items", "", "_magazines", "_ammo"]; +private _weapon = _items deleteAt 0; -private _mass = [_weapon, _items, _magazines] call FUNC(calculateMass); - -{ - _magazines set [_forEachIndex, [_x, _ammo select _forEachIndex]]; -} forEach _magazines; +private _mass = [_weapon, _items, _magazines apply {_x select 0}] call FUNC(calculateMass); _unit removeWeapon _weapon; -// add virtual load +// Add virtual load [_target, _gunbag, _mass] call EFUNC(movement,addLoadToUnitContainer); + _gunbag setVariable [QGVAR(gunbagWeapon), [_weapon, _items, _magazines], true]; -// play sound +// Play sound if (["ace_backpacks"] call EFUNC(common,isModLoaded)) then { [_target, _gunbag] call EFUNC(backpacks,backpackOpened); }; diff --git a/addons/headless/XEH_PREP.hpp b/addons/headless/XEH_PREP.hpp index 11e09adf100..e1c65cc083d 100644 --- a/addons/headless/XEH_PREP.hpp +++ b/addons/headless/XEH_PREP.hpp @@ -1,3 +1,4 @@ +ACEX_PREP(blacklist); ACEX_PREP(endMissionNoPlayers); ACEX_PREP(handleConnectHC); ACEX_PREP(handleDisconnect); diff --git a/addons/headless/XEH_postInit.sqf b/addons/headless/XEH_postInit.sqf index d1c76a332bd..90677042f45 100644 --- a/addons/headless/XEH_postInit.sqf +++ b/addons/headless/XEH_postInit.sqf @@ -1,5 +1,7 @@ #include "script_component.hpp" +if (!isMultiplayer) exitWith {}; + ["CBA_settingsInitialized", { // Register and remove HCs if not client that is not server and distribution or end mission enabled if ((!hasInterface || isServer) && {XGVAR(enabled) || XGVAR(endMission) != 0}) then { @@ -10,6 +12,38 @@ }; // Add disconnect EH addMissionEventHandler ["HandleDisconnect", {call FUNC(handleDisconnect)}]; + + [QGVAR(transferGroupsRebalance), { + params ["_groups", "_owner", "_rebalance"]; + + if (_groups isNotEqualTo [] && {_owner > 1}) then { + { + _x setGroupOwner _owner; + } forEach _groups; + }; + + // Rebalance units + if (_rebalance in [REBALANCE, FORCED_REBALANCE]) then { + (_rebalance == FORCED_REBALANCE) call FUNC(rebalance); + }; + }] call CBA_fnc_addEventHandler; + + // If CBA's loadout validation is enabled, warn users + if (XGVAR(transferLoadout) > 0 && {(missionNamespace getVariable ["CBA_network_loadoutValidation", 0]) isEqualTo 2}) then { + WARNING("CBA_network_loadoutValidation is enabled - acex_headless_transferLoadout should therefore be disabled"); + [QEGVAR(common,displayTextStructured), ["CBA_network_loadoutValidation is enabled - acex_headless_transferLoadout should therefore be disabled", 3]] call CBA_fnc_globalEvent; + }; + + ["CBA_SettingChanged", { + params ["_setting", "_value"]; + + if (_setting != "CBA_network_loadoutValidation") exitWith {}; + + if (XGVAR(transferLoadout) > 0 && {_value isEqualTo 2}) then { + WARNING("CBA_network_loadoutValidation is enabled - acex_headless_transferLoadout should therefore be disabled"); + [QEGVAR(common,displayTextStructured), ["CBA_network_loadoutValidation is enabled - acex_headless_transferLoadout should therefore be disabled", 3]] call CBA_fnc_globalEvent; + }; + }] call CBA_fnc_addEventHandler; } else { // Register HC (this part happens on HC only) [QXGVAR(headlessClientJoined), [player]] call CBA_fnc_globalEvent; // Global event for API purposes diff --git a/addons/headless/functions/fnc_blacklist.sqf b/addons/headless/functions/fnc_blacklist.sqf new file mode 100644 index 00000000000..1c15406ba61 --- /dev/null +++ b/addons/headless/functions/fnc_blacklist.sqf @@ -0,0 +1,51 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Modifies which units are blacklisted from being transferred to HCs. + * + * Arguments: + * 0: Units + * 1: Add (true) or remove (false) from blacklist (default: true) + * 2: Owner to transfer units to (default: -1) + * 3: Rebalance (default: 0) + * + * Return Value: + * None + * + * Example: + * [cursorObject, true] call ace_headless_fnc_blacklist + * + * Public: Yes + */ + +params [["_units", objNull, [objNull, grpNull, []]], ["_blacklist", true, [false]], ["_owner", -1, [false]], ["_rebalance", NO_REBALANCE, [0]]]; + +if !(_units isEqualType []) then { + _units = [_units]; +}; + +// Make sure passed arguments are objects or groups +_units = _units select {_x isEqualType objNull || {_x isEqualType grpNull}}; +_units = _units select {!isNull _x}; + +if (_units isEqualTo []) exitWith {}; + +private _transfer = _blacklist && {_owner > 1}; +private _groups = []; + +{ + _x setVariable [QXGVAR(blacklist), _blacklist, true]; + + if (_transfer) then { + if (_x isEqualType objNull) then { + _groups pushBack group _x; + } else { + _groups pushBack _x; + }; + }; +} forEach _units; + +// Try to move AI to new owner; Also takes care of rebalancing groups +if (_transfer || {_rebalance in [REBALANCE, FORCED_REBALANCE]}) then { + [QGVAR(transferGroupsRebalance), [_groups arrayIntersect _groups, _owner, _rebalance]] call CBA_fnc_serverEvent; +}; diff --git a/addons/headless/functions/fnc_transferGroups.sqf b/addons/headless/functions/fnc_transferGroups.sqf index 60d3c093d11..0efbe263652 100644 --- a/addons/headless/functions/fnc_transferGroups.sqf +++ b/addons/headless/functions/fnc_transferGroups.sqf @@ -17,6 +17,9 @@ params ["_force"]; +// Filter out any invalid entries +GVAR(headlessClients) = GVAR(headlessClients) select {!isNull _x}; + GVAR(headlessClients) params [ ["_HC1", objNull, [objNull]], ["_HC2", objNull, [objNull]], @@ -36,12 +39,13 @@ private _idHC2 = -1; private _idHC3 = -1; private _currentHC = 0; -if (!local _HC1) then { +// objNull is never local +if (!local _HC1 && !isNull _HC1) then { _idHC1 = owner _HC1; _currentHC = 1; }; -if (!local _HC2) then { +if (!local _HC2 && !isNull _HC2) then { _idHC2 = owner _HC2; if (_currentHC == 0) then { @@ -49,7 +53,7 @@ if (!local _HC2) then { }; }; -if (!local _HC3) then { +if (!local _HC3 && !isNull _HC3) then { _idHC3 = owner _HC3; if (_currentHC == 0) then { @@ -57,84 +61,150 @@ if (!local _HC3) then { }; }; +if (_currentHC == 0) exitWith { + TRACE_1("No Valid HC to transfer to",_currentHC); + + if (XGVAR(log)) then { + INFO("No Valid HC to transfer to"); + }; +}; + // Prepare statistics private _numTransferredHC1 = 0; private _numTransferredHC2 = 0; private _numTransferredHC3 = 0; +private _units = []; +private _transfer = false; +private _previousOwner = -1; + // Transfer AI groups { - // No transfer if empty group - private _transfer = ((units _x) isNotEqualTo []) && {!(_x getVariable [QXGVAR(blacklist), false])}; - if (_transfer) then { - // No transfer if waypoints with synchronized triggers exist for the group - private _allWaypointsWithTriggers = (waypoints _x) select {(synchronizedTriggers _x) isNotEqualTo []}; - if (_allWaypointsWithTriggers isNotEqualTo []) exitWith { + _units = units _x; + + // No transfer if empty group or if group is blacklisted + if (_units isEqualTo [] || {_x getVariable [QXGVAR(blacklist), false]}) then { + continue; + }; + + // No transfer if waypoints with synchronized triggers exist for the group + if (((waypoints _x) select {(synchronizedTriggers _x) isNotEqualTo []}) isNotEqualTo []) then { + continue; + }; + + { + // No transfer if already transferred + if (!_force && {(owner _x) in [_idHC1, _idHC2, _idHC3]}) exitWith { _transfer = false; }; - { - // No transfer if already transferred - if (!_force && {(owner _x) in [_idHC1, _idHC2, _idHC3]}) exitWith { - _transfer = false; - }; + // No transfer if any unit in group is blacklisted + if (_x getVariable [QXGVAR(blacklist), false]) exitWith { + _transfer = false; + }; - // No transfer if player or UAV in this group - if (isPlayer _x || {unitIsUAV _x}) exitWith { - _transfer = false; - }; + // No transfer if player or UAV in this group + if (isPlayer _x || {unitIsUAV _x}) exitWith { + _transfer = false; + }; - // No transfer if any unit in group is blacklisted - if (_x getVariable [QXGVAR(blacklist), false]) exitWith { - _transfer = false; - }; + private _vehicle = objectParent _x; - private _vehicle = objectParent _x; + // No transfer if the vehicle the unit is in or if the crew in that vehicle is blacklisted + if ((_vehicle getVariable [QXGVAR(blacklist), false]) || {unitIsUAV _vehicle}) exitWith { + _transfer = false; + }; - // No transfer if the vehicle the unit is in or if the crew in that vehicle is blacklisted - if ((_vehicle getVariable [QXGVAR(blacklist), false]) || {unitIsUAV _vehicle}) exitWith { - _transfer = false; - }; + // Save gear if unit about to be transferred with current loadout (naked unit work-around) + if (XGVAR(transferLoadout) == 1) then { + _x setVariable [QGVAR(loadout), _x call CBA_fnc_getLoadout, true]; + }; + } forEach _units; - // Save gear if unit about to be transferred with current loadout (naked unit work-around) - if (XGVAR(transferLoadout) == 1) then { - _x setVariable [QGVAR(loadout), _x call CBA_fnc_getLoadout, true]; - }; - } forEach (units _x); + if (!_transfer) then { + continue; }; // Round robin between HCs if load balance enabled, else pass all to one HC - if (_transfer) then { - switch (_currentHC) do { - case 1: { - private _transferred = _x setGroupOwner _idHC1; - if (_loadBalance) then { - _currentHC = [3, 2] select (!local _HC2); - }; - if (_transferred) then { - _numTransferredHC1 = _numTransferredHC1 + 1; + _previousOwner = groupOwner _x; + + switch (_currentHC) do { + case 1: { + if (_loadBalance) then { + // Find the next valid HC + // If none are valid, _currentHC will remain the same + if (_idHC2 != -1) then { + _currentHC = 2; + } else { + if (_idHC3 != -1) then { + _currentHC = 3; + }; }; }; - case 2: { - private _transferred = _x setGroupOwner _idHC2; - if (_loadBalance) then { - _currentHC = [1, 3] select (!local _HC3); - }; - if (_transferred) then { - _numTransferredHC2 = _numTransferredHC2 + 1; - }; + + // Don't transfer if it's already local to HC1 + if (_previousOwner == _idHC1) exitWith {}; + + [QGVAR(groupTransferPre), [_x, _HC1, _previousOwner, _idHC1], [_previousOwner, _idHC1]] call CBA_fnc_targetEvent; // API + + private _transferred = _x setGroupOwner _idHC1; + + [QGVAR(groupTransferPost), [_x, _HC1, _previousOwner, _idHC1, _transferred], [_previousOwner, _idHC1]] call CBA_fnc_targetEvent; // API + + if (_transferred) then { + _numTransferredHC1 = _numTransferredHC1 + 1; }; - case 3: { - private _transferred = _x setGroupOwner _idHC3; - if (_loadBalance) then { - _currentHC = [2, 1] select (!local _HC1); + }; + case 2: { + if (_loadBalance) then { + // Find the next valid HC + // If none are valid, _currentHC will remain the same + if (_idHC3 != -1) then { + _currentHC = 3; + } else { + if (_idHC1 != -1) then { + _currentHC = 1; + }; }; - if (_transferred) then { - _numTransferredHC3 = _numTransferredHC3 + 1; + }; + + // Don't transfer if it's already local to HC2 + if (_previousOwner == _idHC2) exitWith {}; + + [QGVAR(groupTransferPre), [_x, _HC2, _previousOwner, _idHC2], [_previousOwner, _idHC2]] call CBA_fnc_targetEvent; // API + + private _transferred = _x setGroupOwner _idHC2; + + [QGVAR(groupTransferPost), [_x, _HC2, _previousOwner, _idHC2, _transferred], [_previousOwner, _idHC2]] call CBA_fnc_targetEvent; // API + + if (_transferred) then { + _numTransferredHC2 = _numTransferredHC2 + 1; + }; + }; + case 3: { + if (_loadBalance) then { + // Find the next valid HC + // If none are valid, _currentHC will remain the same + if (_idHC1 != -1) then { + _currentHC = 1; + } else { + if (_idHC2 != -1) then { + _currentHC = 2; + }; }; }; - default { - TRACE_1("No Valid HC to transfer to",_currentHC); + + // Don't transfer if it's already local to HC3 + if (_previousOwner == _idHC3) exitWith {}; + + [QGVAR(groupTransferPre), [_x, _HC3, _previousOwner, _idHC3], [_previousOwner, _idHC3]] call CBA_fnc_targetEvent; // API + + private _transferred = _x setGroupOwner _idHC2; + + [QGVAR(groupTransferPost), [_x, _HC3, _previousOwner, _idHC3, _transferred], [_previousOwner, _idHC3]] call CBA_fnc_targetEvent; // API + + if (_transferred) then { + _numTransferredHC3 = _numTransferredHC3 + 1; }; }; }; diff --git a/addons/headless/initSettings.inc.sqf b/addons/headless/initSettings.inc.sqf index d00cb6eb307..ec720fce7c0 100644 --- a/addons/headless/initSettings.inc.sqf +++ b/addons/headless/initSettings.inc.sqf @@ -5,8 +5,8 @@ format ["ACE %1", LLSTRING(Module)], false, 1, - {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + {[QXGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -15,8 +15,7 @@ [LSTRING(Delay), LSTRING(DelayDesc)], format ["ACE %1", LLSTRING(Module)], [0, 60, 15, -1], - 1, - {[QGVAR(delay), _this] call EFUNC(common,cbaSettings_settingChanged)} + 1 ] call CBA_fnc_addSetting; [ @@ -26,8 +25,8 @@ format ["ACE %1", LLSTRING(Module)], [[0, 1, 2], [ELSTRING(Common,Disabled), LSTRING(Instant), LSTRING(Delayed)], 0], 1, - {[QGVAR(delay), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + {[QXGVAR(endMission), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -36,8 +35,7 @@ [LSTRING(Log), LSTRING(LogDesc)], format ["ACE %1", LLSTRING(Module)], false, - 1, - {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)} + 1 ] call CBA_fnc_addSetting; [ @@ -47,6 +45,6 @@ format ["ACE %1", LLSTRING(Module)], [[0, 1, 2], [ELSTRING(Common,Disabled), LSTRING(TransferLoadoutCurrent), LSTRING(TransferLoadoutConfig)], 0], 1, - {}, - true // needs mission restart + {[QXGVAR(transferLoadout), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_fnc_addSetting; diff --git a/addons/headless/script_component.hpp b/addons/headless/script_component.hpp index 73761a7bb16..272b288d5f4 100644 --- a/addons/headless/script_component.hpp +++ b/addons/headless/script_component.hpp @@ -17,3 +17,7 @@ #include "\z\ace\addons\main\script_macros.hpp" #define DELAY_DEFAULT 15 + +#define NO_REBALANCE 0 +#define REBALANCE 1 +#define FORCED_REBALANCE 2 diff --git a/addons/hearing/CfgEventHandlers.hpp b/addons/hearing/CfgEventHandlers.hpp index 8143e2ce0df..59cd1b36296 100644 --- a/addons/hearing/CfgEventHandlers.hpp +++ b/addons/hearing/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); diff --git a/addons/hearing/CfgVehicles.hpp b/addons/hearing/CfgVehicles.hpp index a7625344608..636184ecd22 100644 --- a/addons/hearing/CfgVehicles.hpp +++ b/addons/hearing/CfgVehicles.hpp @@ -5,7 +5,7 @@ class CfgVehicles { class ACE_Equipment { class ACE_PutInEarplugs { displayName = CSTRING(EarPlugs_On); - condition = QUOTE(GVAR(EnableCombatDeafness) && {!([_player] call FUNC(hasEarPlugsIn)) && {'ACE_EarPlugs' in items _player}}); + condition = QUOTE(GVAR(enableCombatDeafness) && {!(_player call FUNC(hasEarPlugsIn)) && {[ARR_2(_player,'ACE_EarPlugs')] call EFUNC(common,hasItem)}}); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; statement = QUOTE([ARR_2(_player,true)] call FUNC(putInEarPlugs)); showDisabled = 0; @@ -13,7 +13,7 @@ class CfgVehicles { }; class ACE_RemoveEarplugs { displayName = CSTRING(EarPlugs_Off); - condition = QUOTE(GVAR(EnableCombatDeafness) && {[_player] call FUNC(hasEarPlugsIn)}); + condition = QUOTE(GVAR(enableCombatDeafness) && {_player call FUNC(hasEarPlugsIn)}); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; statement = QUOTE([ARR_2(_player,true)] call FUNC(removeEarPlugs)); showDisabled = 0; diff --git a/addons/hearing/CfgWeapons.hpp b/addons/hearing/CfgWeapons.hpp index 23ebe5c1d2f..8cef02edfd8 100644 --- a/addons/hearing/CfgWeapons.hpp +++ b/addons/hearing/CfgWeapons.hpp @@ -80,7 +80,7 @@ class CfgWeapons { class H_HelmetO_ocamo: H_HelmetB { HEARING_PROTECTION_PELTOR; - }; // Defender and Assasin Helmet inherit. + }; // Defender and Assassin Helmet inherit. class H_HelmetO_ViperSP_hex_f: H_HelmetB { HEARING_PROTECTION_PELTOR; diff --git a/addons/hearing/XEH_PREP.hpp b/addons/hearing/XEH_PREP.hpp index e06fa5d56c0..a2bcbb708a4 100644 --- a/addons/hearing/XEH_PREP.hpp +++ b/addons/hearing/XEH_PREP.hpp @@ -1,8 +1,8 @@ - PREP(addEarPlugs); PREP(earRinging); PREP(explosionNear); PREP(firedNear); +PREP(getAmmoLoudness); PREP(handleRespawn); PREP(hasEarPlugsIn); PREP(moduleHearing); diff --git a/addons/hearing/XEH_postInit.sqf b/addons/hearing/XEH_postInit.sqf index e6f328ad78c..4261933bd92 100644 --- a/addons/hearing/XEH_postInit.sqf +++ b/addons/hearing/XEH_postInit.sqf @@ -2,9 +2,10 @@ if (isServer) then { ["CBA_settingsInitialized", { - TRACE_1("settingInit - server",GVAR(EnableCombatDeafness)); + TRACE_1("settingInit - server",GVAR(enableCombatDeafness)); + // Only install event handler if combat deafness is enabled - if (!GVAR(EnableCombatDeafness)) exitWith {}; + if (!GVAR(enableCombatDeafness)) exitWith {}; ["CAManBase", "Init", LINKFUNC(addEarPlugs), true, [], true] call CBA_fnc_addClassEventHandler; }] call CBA_fnc_addEventHandler; @@ -14,7 +15,7 @@ if (!hasInterface) exitWith {}; #include "initKeybinds.inc.sqf" -GVAR(cacheAmmoLoudness) = call CBA_fnc_createNamespace; +GVAR(cacheAmmoLoudness) = createHashMap; GVAR(deafnessDV) = 0; GVAR(deafnessPrior) = 0; @@ -26,18 +27,20 @@ GVAR(volumeAttenuation) = 1; GVAR(lastPlayerVehicle) = objNull; ["CBA_settingsInitialized", { - TRACE_1("settingInit",GVAR(EnableCombatDeafness)); + TRACE_1("settingInit",GVAR(enableCombatDeafness)); + // Only run PFEH and install event handlers if combat deafness is enabled - if (!GVAR(EnableCombatDeafness)) exitWith {}; + if (!GVAR(enableCombatDeafness)) exitWith {}; // Spawn volume updating process - [LINKFUNC(updateVolume), 1, [false]] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(updateVolume), 1, false] call CBA_fnc_addPerFrameHandler; [QGVAR(updateVolume), LINKFUNC(updateVolume)] call CBA_fnc_addEventHandler; // Update veh attunation when player veh changes ["vehicle", { params ["_player", "_vehicle"]; + TRACE_2("vehicle change",_player,_vehicle); _this call FUNC(updatePlayerVehAttenuation); @@ -48,6 +51,7 @@ GVAR(lastPlayerVehicle) = objNull; GVAR(lastPlayerVehicle) = objNull; TRACE_2("removed veh eh",_firedEH,GVAR(lastPlayerVehicle)); }; + if ((!isNull _vehicle) && {_player != _vehicle}) then { private _firedEH = _vehicle addEventHandler ["FiredNear", {call FUNC(firedNear)}]; _vehicle setVariable [QGVAR(firedEH), _firedEH]; @@ -55,8 +59,8 @@ GVAR(lastPlayerVehicle) = objNull; TRACE_2("added veh eh",_firedEH,GVAR(lastPlayerVehicle)); }; }, true] call CBA_fnc_addPlayerEventHandler; - ["turret", LINKFUNC(updatePlayerVehAttenuation), false] call CBA_fnc_addPlayerEventHandler; + ["turret", LINKFUNC(updatePlayerVehAttenuation), false] call CBA_fnc_addPlayerEventHandler; // Reset deafness on respawn (or remote control player switch) ["unit", { @@ -67,9 +71,11 @@ GVAR(lastPlayerVehicle) = objNull; private _firedEH = _oldPlayer getVariable [QGVAR(firedEH), -1]; _oldPlayer removeEventHandler ["FiredNear", _firedEH]; _oldPlayer setVariable [QGVAR(firedEH), nil]; + private _explosionEH = _oldPlayer getVariable [QGVAR(explosionEH), -1]; _oldPlayer removeEventHandler ["Explosion", _explosionEH]; _oldPlayer setVariable [QGVAR(explosionEH), nil]; + TRACE_3("removed unit eh",_oldPlayer,_firedEH,_explosionEH); }; // Don't add a new EH if the unit respawned @@ -77,17 +83,21 @@ GVAR(lastPlayerVehicle) = objNull; if ((getNumber (configOf _player >> "isPlayableLogic")) == 1) exitWith { TRACE_1("skipping playable logic",typeOf _player); // VirtualMan_F (placeable logic zeus / spectator) }; + private _firedEH = _player addEventHandler ["FiredNear", {call FUNC(firedNear)}]; _player setVariable [QGVAR(firedEH), _firedEH]; + private _explosionEH = _player addEventHandler ["Explosion", {call FUNC(explosionNear)}]; _player setVariable [QGVAR(explosionEH), _explosionEH]; + TRACE_3("added unit eh",_player,_firedEH,_explosionEH); }; GVAR(deafnessDV) = 0; GVAR(deafnessPrior) = 0; GVAR(time3) = 0; - [] call FUNC(updateHearingProtection); + + call FUNC(updateHearingProtection); }, true] call CBA_fnc_addPlayerEventHandler; // Update protection on possible helmet change diff --git a/addons/hearing/XEH_preInit.sqf b/addons/hearing/XEH_preInit.sqf index 7a6195ec460..e47eafa56e8 100644 --- a/addons/hearing/XEH_preInit.sqf +++ b/addons/hearing/XEH_preInit.sqf @@ -10,15 +10,20 @@ PREP_RECOMPILE_END; ["CBA_loadoutSet", { params ["_unit", "_loadout", "_extendedInfo"]; + if (_extendedInfo getOrDefault ["ace_earplugs", false]) then { _unit setVariable ["ACE_hasEarPlugsIn", true, true]; - [QGVAR(updateVolume), [[true]], _unit] call CBA_fnc_targetEvent; + // Only force update volume if unit is a player (including remote controlled) + if (_unit call EFUNC(common,isPlayer)) then { + [QGVAR(updateVolume), true, _unit] call CBA_fnc_targetEvent; + }; }; }] call CBA_fnc_addEventHandler; ["CBA_loadoutGet", { params ["_unit", "_loadout", "_extendedInfo"]; + if (_unit getVariable ["ACE_hasEarPlugsin", false]) then { _extendedInfo set ["ace_earplugs", true] }; diff --git a/addons/hearing/functions/fnc_addEarPlugs.sqf b/addons/hearing/functions/fnc_addEarPlugs.sqf index fdbcfbc6215..11999f77378 100644 --- a/addons/hearing/functions/fnc_addEarPlugs.sqf +++ b/addons/hearing/functions/fnc_addEarPlugs.sqf @@ -4,7 +4,7 @@ * Called on unit initialization. Adds earplugs if the unit is equipped with either a really loud primary weapon or a rocket launcher. * * Arguments: - * 0: A Soldier + * 0: Unit * * Return Value: * None @@ -15,9 +15,9 @@ * Public: No */ -// only run this after the settings are initialized -if !(EGVAR(common,settingsInitFinished)) exitWith { - EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(addEarPlugs), _this]; +// Only run this after the settings are initialized +if (!EGVAR(common,settingsInitFinished)) exitWith { + EGVAR(common,runAtSettingsInitialized) pushBack [LINKFUNC(addEarPlugs), _this]; }; // Exit if hearing is disabled or if autoAdd is disabled @@ -29,42 +29,48 @@ TRACE_2("params",_unit,typeOf _unit); // Exit if the unit already has earplugs (in ears (persistence scenarios) or inventory) if (_unit call FUNC(hasEarPlugsIn) || {[_unit, "ACE_EarPlugs"] call EFUNC(common,hasItem)}) exitWith {}; -// Add earplugs if enabled for everyone or if the soldier has a rocket launcher +// Add earplugs if enabled for everyone or if the unit has a rocket launcher if (GVAR(autoAddEarplugsToUnits) == 2 || {(secondaryWeapon _unit) != ""}) exitWith { TRACE_1("has launcher - adding",_unit); _unit addItem "ACE_EarPlugs"; }; -// otherwise add earplugs if the soldier has a big rifle -if ((primaryWeapon _unit) == "") exitWith {}; +// Otherwise add earplugs if the unit has a big rifle +private _weapon = primaryWeapon _unit; -(primaryWeaponMagazine _unit) params [["_magazine", ""]]; -if (_magazine == "") exitWith {}; +if (_weapon == "") exitWith {}; -private _cfgMagazine = configFile >> "CfgMagazines" >> _magazine; +if (isNil QGVAR(cacheMaxAmmoLoudness)) then { + GVAR(cacheMaxAmmoLoudness) = createHashMap; +}; -private _initSpeed = getNumber (_cfgMagazine >> "initSpeed"); -private _ammo = getText (_cfgMagazine >> "ammo"); -private _count = getNumber (_cfgMagazine >> "count"); +// Cache maximum loudness for future calls +private _maxLoudness = GVAR(cacheMaxAmmoLoudness) getOrDefaultCall [_weapon, { + // Get the weapon's compatible magazines, so that all magazines are cached + // From all the loudness factors, take the max + private _maxLoudness = selectMax ((compatibleMagazines _weapon) apply {_x call FUNC(getAmmoLoudness)}); -private _cfgAmmo = configFile >> "CfgAmmo"; + // ace_gunbag_fnc_isMachineGun + private _config = _weapon call CBA_fnc_getItemConfig; -private _caliber = getNumber (_cfgAmmo >> _ammo >> "ACE_caliber"); -_caliber = call { - if (_ammo isKindOf ["ShellBase", _cfgAmmo]) exitWith { 80 }; - if (_ammo isKindOf ["RocketBase", _cfgAmmo]) exitWith { 200 }; - if (_ammo isKindOf ["MissileBase", _cfgAmmo]) exitWith { 600 }; - if (_ammo isKindOf ["SubmunitionBase", _cfgAmmo]) exitWith { 80 }; - [_caliber, 6.5] select (_caliber <= 0); -}; -private _loudness = (_caliber ^ 1.25 / 10) * (_initspeed / 1000) / 5; + // Definition of a machine gun by BIS_fnc_itemType + private _cursor = getText (_config >> "cursor"); + + if (toLowerANSI _cursor in ["", "emptycursor"]) then { + _cursor = getText (_config >> "cursorAim"); + }; + + // If unit has a machine gun boost effective loudness 50% + if (_cursor == "MG") then { + _maxLoudness = _maxLoudness * 1.5; + }; -//If unit has a machine gun boost effective loudness 50% -if (_count >= 50) then {_loudness = _loudness * 1.5}; + _maxLoudness +}, true]; -TRACE_2("primaryWeapon",_unit,_loudness); +TRACE_3("primaryWeapon",_unit,_weapon,_maxLoudness); -if (_loudness > 0.2) then { +if (_maxLoudness > 0.2) then { TRACE_1("loud gun - adding",_unit); _unit addItem "ACE_EarPlugs"; }; diff --git a/addons/hearing/functions/fnc_earRinging.sqf b/addons/hearing/functions/fnc_earRinging.sqf index f5a2a714dbd..57888e90a2e 100644 --- a/addons/hearing/functions/fnc_earRinging.sqf +++ b/addons/hearing/functions/fnc_earRinging.sqf @@ -1,24 +1,25 @@ #include "..\script_component.hpp" /* * Author: KoffeinFlummi, commy2, Rocko, Rommel, Ruthberg - * Handle new sound souce near ace_player and apply hearing damage + * Handle new sound souce near ace_player and apply hearing damage. * * Arguments: - * 0: strength of ear ringing + * 0: Strength of ear ringing * * Return Value: * None * * Example: - * [_strength] call ace_hearing_fnc_earRinging + * 10 call ace_hearing_fnc_earRinging * * Public: No */ + params ["_strength"]; if (_strength < 0.05) exitWith {}; if (!isNull curatorCamera) exitWith {}; -if ((!GVAR(enabledForZeusUnits)) && {player != ACE_player}) exitWith {}; +if (!GVAR(enabledForZeusUnits) && {player != ACE_player}) exitWith {}; TRACE_2("adding",_strength * GVAR(damageCoefficent),GVAR(deafnessDV)); diff --git a/addons/hearing/functions/fnc_explosionNear.sqf b/addons/hearing/functions/fnc_explosionNear.sqf index c65cf31c764..583c55749e9 100644 --- a/addons/hearing/functions/fnc_explosionNear.sqf +++ b/addons/hearing/functions/fnc_explosionNear.sqf @@ -4,8 +4,8 @@ * Handles deafness due to explosions going off near the player. * * Arguments: - * 0: vehicle - Object the event handler is assigned to (player) - * 1: damage - Damage inflicted to the object + * 0: Unit + * 1: Damage inflicted to the unit * * Return Value: * None @@ -21,7 +21,6 @@ params ["_unit", "_damage"]; TRACE_2("explosion near player",_unit,_damage); private _strength = (0 max _damage) * 30; -if (_strength < 0.01) exitWith {}; -// Call inmediately, as it will get pick up later anyway by the update thread -[_strength] call FUNC(earRinging); +// Call immediately, as it will get picked up later by the update thread anyway +_strength call FUNC(earRinging); diff --git a/addons/hearing/functions/fnc_firedNear.sqf b/addons/hearing/functions/fnc_firedNear.sqf index 4dd81862b9b..1c9a1c54968 100644 --- a/addons/hearing/functions/fnc_firedNear.sqf +++ b/addons/hearing/functions/fnc_firedNear.sqf @@ -4,97 +4,60 @@ * Handles deafness due to large-caliber weapons going off near the player. * * Arguments: - * 0: Unit - Object the event handler is assigned to - * 1: Firer: Object - Object which fires a weapon near the unit - * 2: Distance - Distance in meters between the unit and firer - * 3: weapon - Fired weapon - * 4: muzzle - Muzzle that was used (not used) - * 5: mode - Current mode of the fired weapon (not used) - * 6: ammo - Ammo used + * 0: Object the event handler is assigned to (unused) + * 1: Object which fires a weapon near the unit + * 2: Distance in meters between the unit and firer + * 3: Weapon + * 4: Muzzle + * 5: Current mode of the fired weapon + * 6: Ammo + * 7: Unit that fired the weapon * * Return Value: * None * * Example: - * [clientFiredNearEvent] call ace_hearing_fnc_firedNear - * [player, player, 10, "arifle_MX_ACO_pointer_F", "arifle_MX_ACO_pointer_F", "single", "B_65x39_Caseless"] call ace_hearing_fnc_firedNear + * [player, player, 10, "arifle_MX_ACO_pointer_F", "arifle_MX_ACO_pointer_F", "single", "B_65x39_Caseless", player] call ace_hearing_fnc_firedNear * * Public: No */ -params ["_object", "_firer", "_distance", "_weapon", "", "", "_ammo"]; +params ["", "_firer", "_distance", "_weapon", "_muzzle", "_mode", "_ammo", "_gunner"]; if (_weapon in ["Throw", "Put"]) exitWith {}; if (_distance > 50) exitWith {}; -private _vehAttenuation = [GVAR(playerVehAttenuation), 1] select ( - (ACE_player == (vehicle ACE_player)) || {isTurnedOut ACE_player} -); -private _distance = 1 max _distance; - -private _silencer = switch (_weapon) do { - case (primaryWeapon _firer) : {(primaryWeaponItems _firer) select 0}; - case (secondaryWeapon _firer) : {(secondaryWeaponItems _firer) select 0}; - case (handgunWeapon _firer) : {(handgunItems _firer) select 0}; - default {""}; -}; - +_distance = 1 max _distance; private _audibleFireCoef = 1; -if (_silencer != "") then { - _audibleFireCoef = getNumber (configFile >> "CfgWeapons" >> _silencer >> "ItemInfo" >> "AmmoCoef" >> "audibleFire"); -}; -private _loudness = GVAR(cacheAmmoLoudness) getVariable (format ["%1%2",_weapon,_ammo]); -if (isNil "_loudness") then { - private _muzzles = getArray (configFile >> "CfgWeapons" >> _weapon >> "muzzles"); - private _weaponMagazines = getArray (configFile >> "CfgWeapons" >> _weapon >> "magazines"); - { - if (_x != "this") then { - private _muzzleMagazines = getArray (configFile >> "CfgWeapons" >> _weapon >> _x >> "magazines"); - _weaponMagazines append _muzzleMagazines; - }; - } forEach _muzzles; - { - private _ammoType = getText(configFile >> "CfgMagazines" >> _x >> "ammo"); - _weaponMagazines set [_forEachIndex, [_x, _ammoType]]; - } forEach _weaponMagazines; +// Unit that fired is on foot +private _magazine = if (_gunner == _firer) then { + // Check if the unit has a suppressor + private _suppressor = (_firer weaponAccessories _weapon) select 0; - private _magazine = ""; - { - _x params ["_magazineType", "_ammoType"]; - if (_ammoType == _ammo) exitWith { - _magazine = _magazineType; - }; - } forEach _weaponMagazines; + if (_suppressor != "") then { + _audibleFireCoef = getNumber (configFile >> "CfgWeapons" >> _suppressor >> "ItemInfo" >> "AmmoCoef" >> "audibleFire"); + }; - if (_magazine == "") then { - _loudness = 0; - TRACE_2("No mag for Weapon/Ammo??",_weapon,_ammo); - } else { - private _initSpeed = getNumber(configFile >> "CfgMagazines" >> _magazine >> "initSpeed"); - private _caliber = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ACE_caliber"); - _caliber = call { - // If explicilty defined, use ACE_caliber - if ((count configProperties [(configFile >> "CfgAmmo" >> _ammo), "configName _x == 'ACE_caliber'", false]) == 1) exitWith {_caliber}; - if (_ammo isKindOf ["ShellBase", (configFile >> "CfgAmmo")]) exitWith { 80 }; - if (_ammo isKindOf ["RocketBase", (configFile >> "CfgAmmo")]) exitWith { 200 }; - if (_ammo isKindOf ["MissileBase", (configFile >> "CfgAmmo")]) exitWith { 600 }; - if (_ammo isKindOf ["SubmunitionBase", (configFile >> "CfgAmmo")]) exitWith { 80 }; - [_caliber, 6.5] select (_caliber <= 0) - }; + (_firer weaponState _muzzle) select 3 +} else { + // Unit that fired is in a vehicle + (weaponState [_firer, _firer unitTurret _gunner, _weapon, _muzzle, _mode]) select 3 +}; - _loudness = (_caliber ^ 1.25 / 10) * (_initspeed / 1000) / 5; - TRACE_6("building cache",_weapon,_ammo,_magazine,_initSpeed,_caliber,_loudness); - }; - GVAR(cacheAmmoLoudness) setVariable [(format ["%1%2",_weapon,_ammo]), _loudness]; +if (_magazine == "") exitWith { + TRACE_5("No mag for weapon/ammo??",_weapon,_muzzle,_ammo,_firer,_gunner); }; +TRACE_6("mag",_magazine,_weapon,_muzzle,_ammo,_firer,_gunner); + +private _vehAttenuation = [GVAR(playerVehAttenuation), 1] select (isNull objectParent ACE_player || {isTurnedOut ACE_player}); +private _loudness = _magazine call FUNC(getAmmoLoudness); + _loudness = _loudness * _audibleFireCoef; private _strength = _vehAttenuation * (_loudness - (_loudness / 50 * _distance)); // linear drop off TRACE_1("result",_strength); -if (_strength < 0.01) exitWith {}; - -// Call inmediately, as it will get pick up later anyway by the update thread -[_strength] call FUNC(earRinging); +// Call immediately, as it will get picked up later by the update thread anyway +_strength call FUNC(earRinging); diff --git a/addons/hearing/functions/fnc_getAmmoLoudness.sqf b/addons/hearing/functions/fnc_getAmmoLoudness.sqf new file mode 100644 index 00000000000..062b96fa718 --- /dev/null +++ b/addons/hearing/functions/fnc_getAmmoLoudness.sqf @@ -0,0 +1,44 @@ +#include "..\script_component.hpp" +/* + * Author: KoffeinFlummi, commy2, johnb43 + * Get the loudness of ammo. + * However, because `initSpeed` is a magazine attribute, the magazine name needs to be used instead of the ammo. + * + * Arguments: + * 0: Magazine + * + * Return Value: + * None + * + * Example: + * "30Rnd_65x39_caseless_mag" call ace_hearing_fnc_getAmmoLoudness + * + * Public: No + */ + +params ["_magazine"]; + +GVAR(cacheAmmoLoudness) getOrDefaultCall [_magazine, { + private _magazineConfig = configFile >> "CfgMagazines" >> _magazine; + private _ammo = getText (_magazineConfig >> "ammo"); + private _initSpeed = getNumber (_magazineConfig >> "initSpeed"); + + private _cfgAmmo = configFile >> "CfgAmmo"; + private _ammoConfig = _cfgAmmo >> _ammo; + private _caliber = getNumber (_ammoConfig >> "ACE_caliber"); + + _caliber = switch (true) do { + // If explicilty defined, use ACE_caliber + case (inheritsFrom (_ammoConfig >> "ACE_caliber") isEqualTo _ammoConfig): {_caliber}; + case (_ammo isKindOf ["ShellBase", _cfgAmmo]): {80}; + case (_ammo isKindOf ["RocketBase", _cfgAmmo]): {200}; + case (_ammo isKindOf ["MissileBase", _cfgAmmo]): {600}; + case (_ammo isKindOf ["SubmunitionBase", _cfgAmmo]): {80}; + default {[_caliber, 6.5] select (_caliber <= 0)}; + }; + + private _loudness = (_caliber ^ 1.25 / 10) * (_initspeed / 1000) / 5; + TRACE_5("building cache",_ammo,_magazine,_initSpeed,_caliber,_loudness); + + _loudness +}, true] diff --git a/addons/hearing/functions/fnc_handleRespawn.sqf b/addons/hearing/functions/fnc_handleRespawn.sqf index b436aa7c410..a075d7901e0 100644 --- a/addons/hearing/functions/fnc_handleRespawn.sqf +++ b/addons/hearing/functions/fnc_handleRespawn.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Reset earplugs on respawn, and then re-add if appropriate + * Reset earplugs on respawn, and then re-add if appropriate. * * Arguments: * 0: Unit @@ -10,29 +10,29 @@ * None * * Example: - * [player] call ACE_hearing_fnc_handleRespawn; + * player call ace_hearing_fnc_handleRespawn; * * Public: No */ +// Do not add or remove earplugs if gear should be preserved +if (missionNamespace getVariable [QEGVAR(respawn,savePreDeathGear), false]) exitWith {}; + params ["_unit"]; TRACE_2("params",_unit,typeOf _unit); -if (!local _unit) exitWith {}; //XEH should only be called on local units - -//Do not add or remove earplugs if gear should be preserved -if (missionNamespace getVariable [QEGVAR(respawn,SavePreDeathGear), false]) exitWith {}; +if (!local _unit) exitWith {}; // XEH should only be called on local units private _respawn = [0] call BIS_fnc_missionRespawnType; -//if respawn is not Group or side: +// If respawn is not group or side: if (_respawn <= 3) then { - //Remove earplugs if they have them: + // Remove earplugs if they have them: if (_unit getVariable ["ACE_hasEarPlugsin", false]) then { TRACE_1("had EarPlugs in - removing",_unit); _unit setVariable ["ACE_hasEarPlugsin", false, true]; }; }; -//Re-add if they need them: -[_unit] call FUNC(addEarPlugs); +// Re-add if they need them +_unit call FUNC(addEarPlugs); diff --git a/addons/hearing/functions/fnc_hasEarPlugsIn.sqf b/addons/hearing/functions/fnc_hasEarPlugsIn.sqf index f4b84281fb6..fd6682e4de2 100644 --- a/addons/hearing/functions/fnc_hasEarPlugsIn.sqf +++ b/addons/hearing/functions/fnc_hasEarPlugsIn.sqf @@ -4,16 +4,17 @@ * Check if the unit has earplugs put in. * * Arguments: - * 0: Unit (player) + * 0: Unit * * Return Value: - * Have Earplugs in + * Has Earplugs in * * Example: - * [ace_player] call ace_hearing_fnc_hasEarPlugsIn + * player call ace_hearing_fnc_hasEarPlugsIn * * Public: No */ + params ["_unit"]; _unit getVariable ["ACE_hasEarPlugsin", false] diff --git a/addons/hearing/functions/fnc_moduleHearing.sqf b/addons/hearing/functions/fnc_moduleHearing.sqf index 924f2baa211..f7943a712e9 100644 --- a/addons/hearing/functions/fnc_moduleHearing.sqf +++ b/addons/hearing/functions/fnc_moduleHearing.sqf @@ -10,7 +10,7 @@ * None * * Example: - * [player] call ACE_hearing_fnc_moduleHearing + * player call ace_hearing_fnc_moduleHearing * * Public: No */ @@ -23,6 +23,8 @@ params ["_logic"]; if ((_logic getVariable "DisableEarRinging") != -1) then { [_logic, QGVAR(DisableEarRinging), "DisableEarRinging"] call EFUNC(common,readSettingFromModule); }; + [_logic, QGVAR(enabledForZeusUnits), "enabledForZeusUnits"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(autoAddEarplugsToUnits), "autoAddEarplugsToUnits"] call EFUNC(common,readSettingFromModule); + INFO("Hearing Module Initialized."); diff --git a/addons/hearing/functions/fnc_putInEarplugs.sqf b/addons/hearing/functions/fnc_putInEarplugs.sqf index 2af4df8e86c..aa2166a112f 100644 --- a/addons/hearing/functions/fnc_putInEarplugs.sqf +++ b/addons/hearing/functions/fnc_putInEarplugs.sqf @@ -1,38 +1,35 @@ #include "..\script_component.hpp" /* - * Author: Hope Johnson and commy2 + * Author: Hope Johnson, commy2 * Puts in earplugs. * * Arguments: - * 0: Unit (player) + * 0: Unit * 1: Display hint (default: false) * * Return Value: * None * * Example: - * [ace_player, false] call ace_hearing_fnc_putInEarplugs + * [player, false] call ace_hearing_fnc_putInEarplugs * * Public: No */ -params ["_player", ["_displayHint", false, [false]]]; +if (!GVAR(enableCombatDeafness)) exitWith {}; -if (!GVAR(EnableCombatDeafness)) exitWith {}; +params ["_unit", ["_displayHint", false]]; // Plugs in inventory, putting them in -_player removeItem "ACE_EarPlugs"; +_unit removeItem "ACE_EarPlugs"; -_player setVariable ["ACE_hasEarPlugsIn", true, true]; +_unit setVariable ["ACE_hasEarPlugsIn", true, true]; if (_displayHint) then { - [localize LSTRING(EarPlugs_Are_On)] call EFUNC(common,displayTextStructured); + [LLSTRING(EarPlugs_Are_On)] call EFUNC(common,displayTextStructured); }; -//Force an immediate fast volume update: -[[true]] call FUNC(updateVolume); +// Force an immediate volume update +true call FUNC(updateVolume); -// No Earplugs in inventory, telling user -//[localize LSTRING(NoPlugs)] call EFUNC(common,displayTextStructured); - -[] call FUNC(updateHearingProtection); +call FUNC(updateHearingProtection); diff --git a/addons/hearing/functions/fnc_removeEarplugs.sqf b/addons/hearing/functions/fnc_removeEarplugs.sqf index 20a49bb5300..743e89ef531 100644 --- a/addons/hearing/functions/fnc_removeEarplugs.sqf +++ b/addons/hearing/functions/fnc_removeEarplugs.sqf @@ -1,39 +1,40 @@ #include "..\script_component.hpp" /* - * Author: Hope Johnson and commy2 + * Author: Hope Johnson, commy2 * Takes out earplugs. * * Arguments: - * 0: Unit (player) - * 1: Display hint (default false) + * 0: Unit + * 1: Display hint (default: false) * * Return Value: * None * * Example: - * [ace_player, false] call ace_hearing_fnc_removeEarplugs + * [player, false] call ace_hearing_fnc_removeEarplugs * * Public: No */ -params ["_player", ["_displayHint", false, [false]]]; +if (!GVAR(enableCombatDeafness)) exitWith {}; -if (!GVAR(EnableCombatDeafness)) exitWith {}; +params ["_unit", ["_displayHint", false]]; -if !([_player, "ACE_EarPlugs"] call CBA_fnc_canAddItem) exitWith { // inventory full +// Inventory full +if !([_unit, "ACE_EarPlugs"] call CBA_fnc_canAddItem) exitWith { [LELSTRING(common,Inventory_Full)] call EFUNC(common,displayTextStructured); }; // Plugs already in and removing them. -_player addItem "ACE_EarPlugs"; +_unit addItem "ACE_EarPlugs"; -_player setVariable ["ACE_hasEarPlugsIn", false, true]; +_unit setVariable ["ACE_hasEarPlugsIn", false, true]; if (_displayHint) then { - [localize LSTRING(EarPlugs_Are_Off)] call EFUNC(common,displayTextStructured); + [LLSTRING(EarPlugs_Are_Off)] call EFUNC(common,displayTextStructured); }; -//Force an immediate fast volume update: -[[true]] call FUNC(updateVolume); +// Force an immediate volume update +true call FUNC(updateVolume); -[] call FUNC(updateHearingProtection); +call FUNC(updateHearingProtection); diff --git a/addons/hearing/functions/fnc_updateHearingProtection.sqf b/addons/hearing/functions/fnc_updateHearingProtection.sqf index 15973b73a92..b9d7f1f9a0b 100644 --- a/addons/hearing/functions/fnc_updateHearingProtection.sqf +++ b/addons/hearing/functions/fnc_updateHearingProtection.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Updates the hearing protection and volume attenuation for player on earbuds/helmet change + * Updates the hearing protection and volume attenuation for player on earbuds/helmet change. * * Arguments: * None @@ -10,12 +10,12 @@ * None * * Example: - * [] call ace_hearing_fnc_updateHearingProtection + * call ace_hearing_fnc_updateHearingProtection * * Public: No */ -TRACE_1("params",_this); +LOG("updateHearingProtection"); if (isNull ACE_player) exitWith { GVAR(damageCoefficent) = 0; @@ -23,22 +23,32 @@ if (isNull ACE_player) exitWith { }; // Handle Earplugs -private _hasEarPlugsIn = [ACE_player] call FUNC(hasEarPlugsIn); +private _hasEarPlugsIn = ACE_player call FUNC(hasEarPlugsIn); GVAR(damageCoefficent) = [1, 0.25] select _hasEarPlugsIn; -GVAR(volumeAttenuation) = [1, GVAR(EarplugsVolume)] select _hasEarPlugsIn; +GVAR(volumeAttenuation) = [1, GVAR(earplugsVolume)] select _hasEarPlugsIn; // Handle Headgear -if (headgear ACE_player != "") then { - private _protection = getNumber (configFile >> "CfgWeapons" >> headgear ACE_player >> QGVAR(protection)) min 1; +private _headgear = headgear ACE_player; + +if (_headgear != "") then { + private _heargearConfig = configFile >> "CfgWeapons" >> _headgear; + + private _protection = getNumber (_heargearConfig >> QGVAR(protection)) min 1; GVAR(damageCoefficent) = GVAR(damageCoefficent) * (1 - _protection); - private _attenuation = getNumber (configFile >> "CfgWeapons" >> headgear ACE_player >> QGVAR(lowerVolume)) min 1; + + private _attenuation = getNumber (_heargearConfig >> QGVAR(lowerVolume)) min 1; GVAR(volumeAttenuation) = GVAR(volumeAttenuation) * (1 - _attenuation); }; // Handle Goggles -if (goggles ACE_player != "") then { - private _protection = getNumber (configFile >> "CfgGlasses" >> goggles ACE_player >> QGVAR(protection)) min 1; +private _goggles = goggles ACE_player; + +if (_goggles != "") then { + private _gogglesConfig = configFile >> "CfgGlasses" >> _goggles; + + private _protection = getNumber (_gogglesConfig >> QGVAR(protection)) min 1; GVAR(damageCoefficent) = GVAR(damageCoefficent) * (1 - _protection); - private _attenuation = getNumber (configFile >> "CfgGlasses" >> goggles ACE_player >> QGVAR(lowerVolume)) min 1; + + private _attenuation = getNumber (_gogglesConfig >> QGVAR(lowerVolume)) min 1; GVAR(volumeAttenuation) = GVAR(volumeAttenuation) * (1 - _attenuation); }; diff --git a/addons/hearing/functions/fnc_updatePlayerVehAttenuation.sqf b/addons/hearing/functions/fnc_updatePlayerVehAttenuation.sqf index 207c0f07a3a..856b694a3f6 100644 --- a/addons/hearing/functions/fnc_updatePlayerVehAttenuation.sqf +++ b/addons/hearing/functions/fnc_updatePlayerVehAttenuation.sqf @@ -7,10 +7,10 @@ * None * * Return Value: - * Ammount that unit can hear outside + * Amount that unit can hear outside * * Example: - * [] call ace_hearing_fnc_updatePlayerVehAttenuation + * call ace_hearing_fnc_updatePlayerVehAttenuation * * Public: No */ @@ -20,12 +20,14 @@ private _vehicle = vehicle ACE_player; if (isNull _vehicle) exitWith {}; private _newAttenuation = 1; + if (ACE_player != _vehicle) then { - private _turretPath = [ACE_player] call EFUNC(common,getTurretIndex); - private _effectType = getText (configOf _vehicle >> "attenuationEffectType"); + private _vehicleConfig = configOf _vehicle; + private _turretPath = _vehicle unitTurret ACE_player; + private _effectType = getText (_vehicleConfig >> "attenuationEffectType"); if (_turretPath isNotEqualTo []) then { - private _turretConfig = [(configOf _vehicle), _turretPath] call EFUNC(common,getTurretConfigPath); + private _turretConfig = [_vehicleConfig, _turretPath] call EFUNC(common,getTurretConfigPath); if ((getNumber (_turretConfig >> "disableSoundAttenuation")) == 1) then { _effectType = ""; @@ -40,7 +42,7 @@ if (ACE_player != _vehicle) then { case (_effectType == ""): {1}; case (_effectType == "CarAttenuation"); case (_effectType == "RHS_CarAttenuation"): { // Increase protection for armored cars - private _armor = getNumber (configOf _vehicle >> "HitPoints" >> "HitBody" >> "armor"); + private _armor = getNumber (_vehicleConfig >> "HitPoints" >> "HitBody" >> "armor"); linearConversion [2, 8, _armor, 0.5, 0.3, true];}; case (_effectType == "OpenCarAttenuation"): {1}; case (_effectType == "TankAttenuation"): {0.1}; diff --git a/addons/hearing/functions/fnc_updateVolume.sqf b/addons/hearing/functions/fnc_updateVolume.sqf index 0029cdc4de2..bb1d57e3c14 100644 --- a/addons/hearing/functions/fnc_updateVolume.sqf +++ b/addons/hearing/functions/fnc_updateVolume.sqf @@ -1,55 +1,61 @@ #include "..\script_component.hpp" /* - * Author: commy2 and esteldunedain and Ruthberg + * Author: commy2, esteldunedain, Ruthberg * Updates and applies the current deafness. Called every 1 sec from a PFEH. * * Arguments: - * 0: Args - * - 0: Just update volume (skip ringing/recovery) (default: false) + * 0: Update volume only (skip ringing/recovery) (default: false) * * Return Value: * None * * Example: - * [] call ace_hearing_fnc_updateVolume + * call ace_hearing_fnc_updateVolume * * Public: No */ +if (isGamePaused) exitWith {}; + if (!alive ACE_player) exitWith { - if (missionNameSpace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {}; + if (missionNamespace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {}; + TRACE_1("dead - removing hearing effects",ACE_player); + [QUOTE(ADDON), 1, true] call EFUNC(common,setHearingCapability); }; -(_this select 0) params [["_justUpdateVolume", false]]; +params [["_updateVolumeOnly", false]]; GVAR(deafnessDV) = (GVAR(deafnessDV) min 20) max 0; GVAR(volume) = (1 - (GVAR(deafnessDV) / 20)) max 0.05; + TRACE_3("",GVAR(volume),GVAR(deafnessDV),GVAR(deafnessDV) - GVAR(deafnessPrior)); -if (!_justUpdateVolume) then { +if (!_updateVolumeOnly) then { // Ring if we got a big increase in the last second or enough accumulated damage if (GVAR(deafnessDV) - GVAR(deafnessPrior) > 1 || GVAR(deafnessDV) > 10) then { if (CBA_missionTime - GVAR(time3) < 3) exitWith {}; + if (!isGameFocused) exitWith {}; // prevent audio from stacking when tabbed out + GVAR(time3) = CBA_missionTime; - if (!isGameFocused) exitWith {}; if (GVAR(deafnessDV) > 19.75) then { - playSound (["ACE_Combat_Deafness_Heavy", "ACE_Combat_Deafness_Heavy_NoRing"] select GVAR(DisableEarRinging)); + playSound (["ACE_Combat_Deafness_Heavy", "ACE_Combat_Deafness_Heavy_NoRing"] select GVAR(disableEarRinging)); } else { - playSound (["ACE_Combat_Deafness_Medium", "ACE_Combat_Deafness_Medium_NoRing"] select GVAR(DisableEarRinging)); + playSound (["ACE_Combat_Deafness_Medium", "ACE_Combat_Deafness_Medium_NoRing"] select GVAR(disableEarRinging)); }; }; + GVAR(deafnessPrior) = GVAR(deafnessDV); // Hearing takes longer to return to normal after it hits rock bottom - GVAR(deafnessDV) = (GVAR(deafnessDV) - (0.5 * (GVAR(volume) max 0.1))) max 0; + GVAR(deafnessDV) = (GVAR(deafnessDV) - (0.5 * (GVAR(volume) max 0.1))) max 0; }; -if (missionNameSpace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {}; +if (missionNamespace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {}; private _volume = GVAR(volume); @@ -57,8 +63,8 @@ private _volume = GVAR(volume); _volume = _volume min GVAR(volumeAttenuation); // Reduce volume if player is unconscious -if (ACE_player getVariable ["ACE_isUnconscious", false]) then { - _volume = _volume min GVAR(UnconsciousnessVolume); +if (lifeState ACE_player == "INCAPACITATED") then { + _volume = _volume min GVAR(unconsciousnessVolume); }; [QUOTE(ADDON), _volume, true] call EFUNC(common,setHearingCapability); diff --git a/addons/hearing/initKeybinds.inc.sqf b/addons/hearing/initKeybinds.inc.sqf index 22cf132add6..d1299661986 100644 --- a/addons/hearing/initKeybinds.inc.sqf +++ b/addons/hearing/initKeybinds.inc.sqf @@ -2,14 +2,17 @@ // Conditions: specific if !([ACE_player, objNull, ["isNotSwimming", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; - if (GVAR(EnableCombatDeafness) && {!([ACE_player] call FUNC(hasEarPlugsIn))} && {[ACE_player, "ACE_EarPlugs"] call EFUNC(common,hasItem)}) exitWith { + if (GVAR(enableCombatDeafness) && {!(ACE_player call FUNC(hasEarPlugsIn))} && {[ACE_player, "ACE_EarPlugs"] call EFUNC(common,hasItem)}) exitWith { [ACE_player, true] call FUNC(putInEarPlugs); - true + + true // return }; - if (GVAR(EnableCombatDeafness) && {[ACE_player] call FUNC(hasEarPlugsIn)}) exitWith { + + if (GVAR(enableCombatDeafness) && {ACE_player call FUNC(hasEarPlugsIn)}) exitWith { [ACE_player, true] call FUNC(removeEarPlugs); - true + + true // return }; - - false + + false // return }] call CBA_fnc_addKeybind; // UNBOUND diff --git a/addons/hearing/initSettings.inc.sqf b/addons/hearing/initSettings.inc.sqf index 61b6d239c58..adc6c6def75 100644 --- a/addons/hearing/initSettings.inc.sqf +++ b/addons/hearing/initSettings.inc.sqf @@ -1,7 +1,8 @@ -private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; +private _category = format ["ACE %1", LLSTRING(Module_DisplayName)]; [ - QGVAR(enableCombatDeafness), "CHECKBOX", + QGVAR(enableCombatDeafness), + "CHECKBOX", [LSTRING(EnableCombatDeafness_DisplayName), LSTRING(EnableCombatDeafness_Description)], _category, true, @@ -11,7 +12,8 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; ] call CBA_fnc_addSetting; [ - QGVAR(earplugsVolume), "SLIDER", + QGVAR(earplugsVolume), + "SLIDER", [LSTRING(earplugsVolume_DisplayName), LSTRING(earplugsVolume_Description)], _category, [0, 1, 0.5, 1], @@ -19,7 +21,8 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; ] call CBA_fnc_addSetting; [ - QGVAR(unconsciousnessVolume), "SLIDER", + QGVAR(unconsciousnessVolume), + "SLIDER", [LSTRING(unconsciousnessVolume_DisplayName), LSTRING(unconsciousnessVolume_Description)], _category, [0, 1, 0.4, 1], @@ -27,15 +30,16 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; ] call CBA_fnc_addSetting; [ - QGVAR(disableEarRinging), "CHECKBOX", + QGVAR(disableEarRinging), + "CHECKBOX", [LSTRING(DisableEarRinging_DisplayName), LSTRING(DisableEarRinging_Description)], _category, - false, - 0 + false ] call CBA_fnc_addSetting; [ - QGVAR(enabledForZeusUnits), "CHECKBOX", + QGVAR(enabledForZeusUnits), + "CHECKBOX", [LSTRING(enabledForZeusUnits_DisplayName), LSTRING(enabledForZeusUnits_Description)], _category, true, @@ -43,7 +47,8 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; ] call CBA_fnc_addSetting; [ - QGVAR(autoAddEarplugsToUnits), "LIST", + QGVAR(autoAddEarplugsToUnits), + "LIST", [LSTRING(autoAddEarplugsToUnits_DisplayName), LSTRING(autoAddEarplugsToUnits_Description)], _category, [[0, 1, 2], [ELSTRING(common,Disabled), LSTRING(heavyWeaponUnits), ELSTRING(common,Enabled)], 1], diff --git a/addons/hearing/stringtable.xml b/addons/hearing/stringtable.xml index 12654786398..5b7c3da0635 100644 --- a/addons/hearing/stringtable.xml +++ b/addons/hearing/stringtable.xml @@ -370,12 +370,17 @@ Metti/Togli tappi 귀마개 토글 Mettre/enlever les bouchons + Ohrstöpsel einsetzen/herausnehmen + Poner/quitar tapones Only units with heavy weapons Uniquement les unités dotées d'armes lourdes Только юниты с тяжелым вооружением + Nur Einheiten mit schweren Waffen 重火器を装備したユニットのみ + Sólo unidades con armas pesadas + Solo a unità con armi pesanti diff --git a/addons/hellfire/functions/fnc_setupVehicle.sqf b/addons/hellfire/functions/fnc_setupVehicle.sqf index 49eefd82746..ce3961d77af 100644 --- a/addons/hellfire/functions/fnc_setupVehicle.sqf +++ b/addons/hellfire/functions/fnc_setupVehicle.sqf @@ -46,7 +46,7 @@ if ((getNumber (configOf _vehicle >> QGVAR(addLaserDesignator))) == 1) then { params ["_vehicle", "_turretPath"]; TRACE_3("checking for laser",_vehicle,_turretPath,_vehicle turretLocal _turretPath); if (!alive _vehicle) exitWith {}; - if (!(_vehicle turretLocal _turretPath)) then {WARNING("Turret not local");}; + if !(_vehicle turretLocal _turretPath) then {WARNING("Turret not local");}; private _hasLaser = false; { // Most addons just use "Laserdesignator_mounted", but this should cover custom ones diff --git a/addons/hitreactions/ACE_Settings.hpp b/addons/hitreactions/ACE_Settings.hpp index 90c1445eba7..78a510a1419 100644 --- a/addons/hitreactions/ACE_Settings.hpp +++ b/addons/hitreactions/ACE_Settings.hpp @@ -1,4 +1,3 @@ - class ACE_Settings { class GVAR(minDamageToTrigger) { movedToSQF = 1; diff --git a/addons/hitreactions/CfgEventHandlers.hpp b/addons/hitreactions/CfgEventHandlers.hpp index eecf08c69da..b737b7bcbfc 100644 --- a/addons/hitreactions/CfgEventHandlers.hpp +++ b/addons/hitreactions/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); @@ -11,6 +10,12 @@ class Extended_PreInit_EventHandlers { }; }; +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; + class Extended_Hit_EventHandlers { class CAManBase { class ADDON { diff --git a/addons/hitreactions/XEH_PREP.hpp b/addons/hitreactions/XEH_PREP.hpp index 7701b8ef19b..eea48dcaa8b 100644 --- a/addons/hitreactions/XEH_PREP.hpp +++ b/addons/hitreactions/XEH_PREP.hpp @@ -1,3 +1,3 @@ - +PREP(checkWeaponDrop); PREP(fallDown); PREP(getRandomAnimation); diff --git a/addons/hitreactions/XEH_postInit.sqf b/addons/hitreactions/XEH_postInit.sqf new file mode 100644 index 00000000000..2750ae11592 --- /dev/null +++ b/addons/hitreactions/XEH_postInit.sqf @@ -0,0 +1,94 @@ +#include "script_component.hpp" + + +[QGVAR(updateFiredEHs), { + TRACE_2("updateFiredEH",GVAR(weaponDropChanceArmHitPlayer),GVAR(weaponDropChanceArmHitAI)); + if (GVAR(weaponDropChanceArmHitPlayer) + GVAR(weaponDropChanceArmHitAI) == 0) then { + if (isNil QGVAR(firedEHs)) exitWith {}; + { + _x call CBA_fnc_removeEventHandler; + } forEach GVAR(firedEHs); + GVAR(firedEHs) = nil; + TRACE_1("removed EHs",GVAR(firedEHs)); + } else { + if (!isNil QGVAR(firedEHs)) exitWith {}; + private _firedEH = { + if (!local (_this select 0)) exitWith {}; + (_this select 6) addEventHandler ["HitPart", { + params ["", "_entity", "", "", "", "", "_selections"]; + [_entity, _selections] call FUNC(checkWeaponDrop); + }]; + }; + GVAR(firedEHs) = []; + { + GVAR(firedEHs) pushBack [_x, [_x, _firedEH] call CBA_fnc_addEventHandler]; + } forEach ["ace_firedNonPlayer", "ace_firedPlayer"]; + TRACE_1("added EHs",GVAR(firedEHs)); + }; +}] call CBA_fnc_addEventHandler; + +[QGVAR(dropWeapon), { + params ["_unit"]; + TRACE_1("dropWeaponEH",_unit); + + if !(_unit getVariable [QGVAR(canDropWeapon), true]) exitWith {}; + + // Prevents AI from losing both primary and pistol when being shot with their pistol out + _unit setVariable [QGVAR(canDropWeapon), false]; + + private _weapon = currentWeapon _unit; + private _thrownWeapon = _unit call EFUNC(common,throwWeapon); + + [{ + params ["_unit"]; + + _unit setVariable [QGVAR(canDropWeapon), nil]; + }, _unit, 0.5] call CBA_fnc_waitAndExecute; + + if (_unit call EFUNC(common,isPlayer)) exitWith {}; // Don't make players pick their own weapons up + + // Wait before executing, as otherwise the unit would pick up the weapon immediately + [{ + [{ + (_this select 0) params ["_unit", "_weapon", "_thrownWeapon", "_timeout"]; + + // If the unit has been deleted or dead, if the weapon doesn't exist anymore or if it's been too long, stop + if (!alive _unit || {!local _unit} || {isNull _thrownWeapon} || {CBA_missionTime >= _timeout}) exitWith { + (_this select 1) call CBA_fnc_removePerFrameHandler; + }; + + // Don't pick up weapon when unit is unconscious + if (lifeState _unit == "INCAPACITATED") exitWith {}; + + // If the unit has no essential weapons, force them to get their weapon, otherwise wait until no enemies are present + if !( + (primaryWeapon _unit == "" && {handgunWeapon _unit == ""}) || + {(_unit distance (_unit findNearestEnemy _unit)) > missionNamespace getVariable [QGVAR(safePickupDistance), DEFAULT_PICKUP_DISTANCE]} + ) exitWith {}; + + // If the unit is too far away, make them move closer + if (_unit distance _thrownWeapon >= 4) exitWith { + private _pos = getPosATL _thrownWeapon; + + _unit setDestination [_pos, "LEADER PLANNED", true]; + _unit doMove _pos; + }; + + (_this select 1) call CBA_fnc_removePerFrameHandler; + + _unit action ["TakeWeapon", _thrownWeapon, _weapon]; + + // Make the unit switch weapons + [{ + (_this select 0) hasWeapon (_this select 1) + }, { + params ["_unit", "_weapon"]; + + if (!alive _unit || {!local _unit} || {primaryWeapon _unit != _weapon}) exitWith {}; + + // Switch to the primary weapon, if it was picked up + _unit selectWeapon _weapon; + }, [_unit, _weapon], 5] call CBA_fnc_waitUntilAndExecute; + }, 5, _this] call CBA_fnc_addPerFrameHandler; + }, [_unit, _weapon, _thrownWeapon, CBA_missionTime + 300], random [2, 3, 4]] call CBA_fnc_waitAndExecute; +}] call CBA_fnc_addEventHandler; diff --git a/addons/hitreactions/XEH_preInit.sqf b/addons/hitreactions/XEH_preInit.sqf index 894773534a4..296279c7ebe 100644 --- a/addons/hitreactions/XEH_preInit.sqf +++ b/addons/hitreactions/XEH_preInit.sqf @@ -8,4 +8,16 @@ PREP_RECOMPILE_END; #include "initSettings.inc.sqf" +GVAR(armSelections) = [ + "leftshoulder", + "rightshoulder", + "lefthand", + "leftforearm", + "leftarmroll", + "rightforearm", + "rightarmroll", + "righthand", + "rightarm" +]; + ADDON = true; diff --git a/addons/hitreactions/functions/fnc_checkWeaponDrop.sqf b/addons/hitreactions/functions/fnc_checkWeaponDrop.sqf new file mode 100644 index 00000000000..ad4e7c4a417 --- /dev/null +++ b/addons/hitreactions/functions/fnc_checkWeaponDrop.sqf @@ -0,0 +1,33 @@ +#include "..\script_component.hpp" +/* + * Author: KJW + * Checks if an entity should drop their weapon based on projectile hit info. + * + * Arguments: + * 0: Entity that was hit + * 1: Selection names that were hit + * + * Return Value: + * None + * + * Example: + * [player, []] call ace_hitreactions_fnc_checkWeaponDrop + * + * Public: No + */ + +params ["_entity", "_selections"]; + +// Make sure entity is a unit +if !(_entity isKindOf "CAManBase") exitWith {}; + +// Don't throw weapon if unit is unconscious or dead +if !(lifeState _entity in ["HEALTHY", "INJURED"]) exitWith {}; + +if (random 1 >= ([GVAR(weaponDropChanceArmHitAI), GVAR(weaponDropChanceArmHitPlayer)] select (_entity call EFUNC(common,isPlayer)))) exitWith {}; + +if (_selections findAny GVAR(armSelections) == -1) exitWith {}; + +if (getNumber ((currentWeapon _entity) call CBA_fnc_getItemConfig >> QGVAR(undroppable)) == 1) exitWith {}; + +[QGVAR(dropWeapon), _entity, _entity] call CBA_fnc_targetEvent; diff --git a/addons/hitreactions/initSettings.inc.sqf b/addons/hitreactions/initSettings.inc.sqf index 2ca4ceaeacd..820f6647670 100644 --- a/addons/hitreactions/initSettings.inc.sqf +++ b/addons/hitreactions/initSettings.inc.sqf @@ -1,9 +1,30 @@ private _category = [LELSTRING(common,categoryUncategorized), QUOTE(COMPONENT_BEAUTIFIED)]; [ - QGVAR(minDamageToTrigger), "SLIDER", + QGVAR(minDamageToTrigger), + "SLIDER", LSTRING(minDamageToTrigger_displayName), _category, [-1, 1, 0.1, 1], 1 ] call CBA_fnc_addSetting; + +[ + QGVAR(weaponDropChanceArmHitPlayer), + "SLIDER", + LSTRING(weaponDropChanceArmHitPlayer_displayName), + _category, + [0, 1, 0, 2, true], + 1, + {[QGVAR(updateFiredEHs)] call CBA_fnc_localEvent} +] call CBA_fnc_addSetting; + +[ + QGVAR(weaponDropChanceArmHitAI), + "SLIDER", + LSTRING(weaponDropChanceArmHitAI_displayName), + _category, + [0, 1, 0, 2, true], + 1, + {[QGVAR(updateFiredEHs)] call CBA_fnc_localEvent} +] call CBA_fnc_addSetting; diff --git a/addons/hitreactions/script_component.hpp b/addons/hitreactions/script_component.hpp index dccbef24f74..dd407a914b3 100644 --- a/addons/hitreactions/script_component.hpp +++ b/addons/hitreactions/script_component.hpp @@ -15,3 +15,5 @@ #endif #include "\z\ace\addons\main\script_macros.hpp" + +#define DEFAULT_PICKUP_DISTANCE 8 diff --git a/addons/hitreactions/stringtable.xml b/addons/hitreactions/stringtable.xml index b07e9be9a03..421f806e32e 100644 --- a/addons/hitreactions/stringtable.xml +++ b/addons/hitreactions/stringtable.xml @@ -6,7 +6,7 @@ Danno Minimo per far cadere 觸發倒下前最低需受到多少傷害 触发倒下前最低需受到多少伤害 - 崩れ落ちるまでの最低損傷値 + 転倒が発生するダメージの最低値 넘어질 때 발생하는 최소 피해량 Mindestschaden, um Sturz auszulösen Minimalne obrażenie, żeby aktywować spadanie @@ -17,5 +17,15 @@ Düşmeyi tetikleyen min hasar Daño mínimo para provocar la caída + + Player Weapon Drop Chance (Arm Hit) + プレイヤーが武器を落とす確率 (腕部への被弾) + Шанс выпадения оружия у игрока (попадание в руку) + + + AI Weapon Drop Chance (Arm Hit) + AIが武器を落とす確率 (腕部への被弾) + Шанс выпадения оружия у ИИ (попадание в руку) + diff --git a/addons/interact_menu/XEH_clientInit.sqf b/addons/interact_menu/XEH_clientInit.sqf index 5c9a2ecae08..d0c6d93940e 100644 --- a/addons/interact_menu/XEH_clientInit.sqf +++ b/addons/interact_menu/XEH_clientInit.sqf @@ -3,16 +3,16 @@ if (!hasInterface) exitWith {}; // Wait until player controls (man,vehicle or uav) a thing before compiling the menu -GVAR(controllableSelfActionsAdded) = [] call CBA_fnc_createNamespace; +GVAR(controllableSelfActionsAdded) = createHashMap; DFUNC(newControllableObject) = { params ["_object"]; private _type = typeOf _object; TRACE_2("newControllableObject",_object,_type); if (_type == "") exitWith {}; - if (!(GVAR(controllableSelfActionsAdded) getVariable [_type, false])) then { + if !(_type in GVAR(controllableSelfActionsAdded)) then { [_type] call FUNC(compileMenuSelfAction); - GVAR(controllableSelfActionsAdded) setVariable [_type, true]; + GVAR(controllableSelfActionsAdded) set [_type, nil]; [{ TRACE_1("sending newControllableObject event",_this); // event for other systems to add self actions, running addActionToClass before this will cause compiling @@ -27,8 +27,7 @@ DFUNC(newControllableObject) = { GVAR(blockDefaultActions) = []; -GVAR(cachedBuildingTypes) = []; -GVAR(cachedBuildingActionPairs) = []; +GVAR(cachedBuildingTypes) = createHashMap; GVAR(ParsedTextCached) = []; diff --git a/addons/interact_menu/XEH_preInit.sqf b/addons/interact_menu/XEH_preInit.sqf index bf3278f0a3b..88269bcc04d 100644 --- a/addons/interact_menu/XEH_preInit.sqf +++ b/addons/interact_menu/XEH_preInit.sqf @@ -12,12 +12,12 @@ if (!hasInterface) exitWith { ADDON = true; }; ["All", "init", LINKFUNC(compileMenu)] call CBA_fnc_addClassEventHandler; -GVAR(ActNamespace) = [] call CBA_fnc_createNamespace; -GVAR(ActSelfNamespace) = [] call CBA_fnc_createNamespace; +GVAR(ActNamespace) = createHashMap; +GVAR(ActSelfNamespace) = createHashMap; // Compile actions for CAManBase now and use for all mans types ["CAManBase"] call FUNC(compileMenu); -GVAR(cacheManActions) = +(GVAR(ActNamespace) getVariable ["CAManBase", []]); // copy +GVAR(cacheManActions) = +(GVAR(ActNamespace) getOrDefault ["CAManBase" call EFUNC(common,getConfigName), []]); // copy // Event handlers for all interact menu controls DFUNC(handleMouseMovement) = { diff --git a/addons/interact_menu/functions/fnc_addActionToClass.sqf b/addons/interact_menu/functions/fnc_addActionToClass.sqf index 93d54c991c2..ccea8c4654d 100644 --- a/addons/interact_menu/functions/fnc_addActionToClass.sqf +++ b/addons/interact_menu/functions/fnc_addActionToClass.sqf @@ -48,6 +48,8 @@ if (param [4, false, [false]]) exitwith { (_parentPath + [_action select 0]) }; +_objectType = _objectType call EFUNC(common,getConfigName); + // Ensure the config menu was compiled first if (_typeNum == 0) then { [_objectType] call FUNC(compileMenu); @@ -56,18 +58,14 @@ if (_typeNum == 0) then { }; private _namespace = [GVAR(ActNamespace), GVAR(ActSelfNamespace)] select _typeNum; -private _actionTrees = _namespace getVariable _objectType; -if (isNil "_actionTrees") then { - _actionTrees = []; - _namespace setVariable [_objectType, _actionTrees]; -}; +private _actionTrees = _namespace getOrDefault [_objectType, [], true]; if (_parentPath isEqualTo ["ACE_MainActions"]) then { [_objectType, _typeNum] call FUNC(addMainAction); }; private _parentNode = [_actionTrees, _parentPath] call FUNC(findActionNode); -if (isNil {_parentNode}) exitWith { +if (isNil "_parentNode") exitWith { ERROR_4("Failed to add action - action (%1) to parent %2 on object %3 [%4]",(_action select 0),_parentPath,_objectType,_typeNum); [] }; diff --git a/addons/interact_menu/functions/fnc_addMainAction.sqf b/addons/interact_menu/functions/fnc_addMainAction.sqf index 83349c21b39..beb02997b9e 100644 --- a/addons/interact_menu/functions/fnc_addMainAction.sqf +++ b/addons/interact_menu/functions/fnc_addMainAction.sqf @@ -19,14 +19,10 @@ params ["_objectType", "_typeNum"]; private _namespace = [GVAR(ActNamespace), GVAR(ActSelfNamespace)] select _typeNum; -private _actionTrees = _namespace getVariable _objectType; -if (isNil "_actionTrees") then { - _actionTrees = []; -}; - +private _actionTrees = _namespace getOrDefault [_objectType, []]; private _parentNode = [_actionTrees, ["ACE_MainActions"]] call FUNC(findActionNode); -if (isNil {_parentNode}) then { +if (isNil "_parentNode") then { TRACE_2("No Main Action on object",_objectType,_typeNum); private _mainAction = ["ACE_MainActions", localize ELSTRING(interaction,MainAction), "", {}, {true}] call FUNC(createAction); [_objectType, _typeNum, [], _mainAction] call EFUNC(interact_menu,addActionToClass); diff --git a/addons/interact_menu/functions/fnc_compileMenu.sqf b/addons/interact_menu/functions/fnc_compileMenu.sqf index 75d759465c2..8c5d3c5fa1a 100644 --- a/addons/interact_menu/functions/fnc_compileMenu.sqf +++ b/addons/interact_menu/functions/fnc_compileMenu.sqf @@ -17,22 +17,22 @@ params ["_target"]; -private _objectType = _target; -if (_target isEqualType objNull) then { - _objectType = typeOf _target; +private _objectType = if (_target isEqualType objNull) then { + typeOf _target +} else { + _target call EFUNC(common,getConfigName) }; -private _namespace = GVAR(ActNamespace); // Exit if the action menu is already compiled for this class -if (!isNil {_namespace getVariable _objectType}) exitWith {}; +if (_objectType in GVAR(ActNamespace)) exitWith {}; if (_objectType isKindOf "VirtualMan_F") exitWith { // these have config: isPlayableLogic = 1 TRACE_1("skipping playable logic",_objectType); - _namespace setVariable [_objectType, []]; + GVAR(ActNamespace) set [_objectType, []]; }; if ((_objectType isKindOf "CAManBase") && {!isNil QGVAR(cacheManActions)}) exitWith { - _namespace setVariable [_objectType, +GVAR(cacheManActions)]; // copy + GVAR(ActNamespace) set [_objectType, +GVAR(cacheManActions)]; // copy }; private _recurseFnc = { @@ -139,7 +139,7 @@ if (_objectType isKindOf "CAManBase") then { }; }; -_namespace setVariable [_objectType, _actions]; +GVAR(ActNamespace) set [_objectType, _actions]; /* [ diff --git a/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf b/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf index ed3a02dd143..8f19dfabbec 100644 --- a/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf +++ b/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf @@ -17,15 +17,14 @@ params ["_target"]; -private _objectType = _target; -if (_target isEqualType objNull) then { - _objectType = typeOf _target; +private _objectType = if (_target isEqualType objNull) then { + typeOf _target +} else { + _target call EFUNC(common,getConfigName) }; -private _namespace = GVAR(ActSelfNamespace); // Exit if the action menu is already compiled for this class -if (!isNil {_namespace getVariable _objectType}) exitWith {}; - +if (_objectType in GVAR(actSelfNamespace)) exitWith {}; private _recurseFnc = { params ["_actionsCfg"]; @@ -131,4 +130,4 @@ private _actions = [ ] ]; -_namespace setVariable [_objectType, _actions]; +GVAR(ActSelfNamespace) set [_objectType, _actions]; diff --git a/addons/interact_menu/functions/fnc_initMenuReorder.sqf b/addons/interact_menu/functions/fnc_initMenuReorder.sqf index 48445b3fa02..d55f2f06ea6 100644 --- a/addons/interact_menu/functions/fnc_initMenuReorder.sqf +++ b/addons/interact_menu/functions/fnc_initMenuReorder.sqf @@ -17,7 +17,7 @@ params ["_class"]; -private _actionTrees = GVAR(ActSelfNamespace) getVariable _class; +private _actionTrees = GVAR(ActSelfNamespace) get _class; private _rootNode = [_actionTrees, ["ACE_SelfActions"]] call FUNC(findActionNode); private _rootActions = _rootNode select 1; private _settingCategoryPrefix = format ["ACE %1 - ", LELSTRING(Interaction,InteractionMenuSelf)]; diff --git a/addons/interact_menu/functions/fnc_keyDown.sqf b/addons/interact_menu/functions/fnc_keyDown.sqf index 5bce40d0a8e..9cb638bcea4 100644 --- a/addons/interact_menu/functions/fnc_keyDown.sqf +++ b/addons/interact_menu/functions/fnc_keyDown.sqf @@ -116,7 +116,7 @@ GVAR(selfMenuOffset) = (AGLtoASL (positionCameraToWorld [0, 0, 2])) vectorDiff ( //Auto expand the first level when self, mounted vehicle or zeus (skips the first animation as there is only one choice) if (GVAR(openedMenuType) == 0) then { if (isNull curatorCamera) then { - if (!(isNull (ACE_controlledUAV select 0))) then { + if !(isNull (ACE_controlledUAV select 0)) then { GVAR(menuDepthPath) = [["ACE_SelfActions", (ACE_controlledUAV select 0)]]; GVAR(expanded) = true; GVAR(expandedTime) = diag_tickTime; diff --git a/addons/interact_menu/functions/fnc_removeActionFromClass.sqf b/addons/interact_menu/functions/fnc_removeActionFromClass.sqf index 6772b61c547..7585616ef6a 100644 --- a/addons/interact_menu/functions/fnc_removeActionFromClass.sqf +++ b/addons/interact_menu/functions/fnc_removeActionFromClass.sqf @@ -19,17 +19,16 @@ params ["_objectType", "_typeNum", "_fullPath"]; +_objectType = _objectType call EFUNC(common,getConfigName); + private _res = _fullPath call FUNC(splitPath); _res params ["_parentPath", "_actionName"]; private _namespace = [GVAR(ActNamespace), GVAR(ActSelfNamespace)] select _typeNum; -private _actionTrees = _namespace getVariable _objectType; -if (isNil "_actionTrees") then { - _actionTrees = []; -}; +private _actionTrees = _namespace getOrDefault [_objectType, []]; private _parentNode = [_actionTrees, _parentPath] call FUNC(findActionNode); -if (isNil {_parentNode}) exitWith {}; +if (isNil "_parentNode") exitWith {}; // Iterate through children of the father private _found = false; diff --git a/addons/interact_menu/functions/fnc_renderActionPoints.sqf b/addons/interact_menu/functions/fnc_renderActionPoints.sqf index 058b5ed8462..62d29be91f4 100644 --- a/addons/interact_menu/functions/fnc_renderActionPoints.sqf +++ b/addons/interact_menu/functions/fnc_renderActionPoints.sqf @@ -61,7 +61,7 @@ private _fnc_renderNearbyActions = { } forEach GVAR(objectActionList); // Iterate through base level class actions and render them if appropiate - private _classActions = GVAR(ActNamespace) getVariable [typeOf _target, []]; + private _classActions = GVAR(ActNamespace) getOrDefault [typeOf _target, []]; { private _action = _x; // Try to render the menu @@ -95,8 +95,7 @@ private _fnc_renderSelfActions = { GVAR(objectActionList) = _target getVariable [QGVAR(selfActions), []]; // Iterate through base level class actions and render them if appropiate - private _namespace = GVAR(ActSelfNamespace); - private _classActions = _namespace getVariable typeOf _target; + private _classActions = GVAR(ActSelfNamespace) get typeOf _target; private _pos = if !(GVAR(useCursorMenu)) then { //Convert to ASL, add offset and then convert back to AGL (handles waves when over water) @@ -124,7 +123,7 @@ GVAR(collectedActionPoints) resize 0; // Render nearby actions, unit self actions or vehicle self actions as appropiate if (GVAR(openedMenuType) == 0) then { if (isNull curatorCamera) then { - if (!(isNull (ACE_controlledUAV select 0))) then { + if !(isNull (ACE_controlledUAV select 0)) then { // Render UAV self actions when in control of UAV AI (ACE_controlledUAV select 0) call _fnc_renderSelfActions; } else { diff --git a/addons/interact_menu/functions/fnc_splitPath.sqf b/addons/interact_menu/functions/fnc_splitPath.sqf index 8c0856d118b..8fabaca5a56 100644 --- a/addons/interact_menu/functions/fnc_splitPath.sqf +++ b/addons/interact_menu/functions/fnc_splitPath.sqf @@ -17,11 +17,13 @@ */ private _parentPath = []; -for [{private _i = 0},{_i < (count _this) - 1},{_i = _i + 1}] do { - _parentPath pushBack (_this select _i); -}; -private _actionName = if (count _this > 0) then { - _this select ((count _this) - 1); + +_parentPath append _this; + +private _count = count _this; + +private _actionName = if (_count > 0) then { + _parentPath deleteAt (_count - 1) // TODO: replace with _parentPath deleteAt [-1] and drop _count in 2.18 } else { "" }; diff --git a/addons/interact_menu/functions/fnc_userActions_getHouseActions.sqf b/addons/interact_menu/functions/fnc_userActions_getHouseActions.sqf index c11da0c2710..8f289508401 100644 --- a/addons/interact_menu/functions/fnc_userActions_getHouseActions.sqf +++ b/addons/interact_menu/functions/fnc_userActions_getHouseActions.sqf @@ -17,8 +17,9 @@ params ["_typeOfBuilding"]; -private _searchIndex = GVAR(cachedBuildingTypes) find _typeOfBuilding; -if (_searchIndex != -1) exitWith {GVAR(cachedBuildingActionPairs) select _searchIndex}; +private _cachedMemPoints = GVAR(cachedBuildingTypes) get _typeOfBuilding; + +if (!isNil "_cachedMemPoints") exitWith {_cachedMemPoints}; private _memPoints = []; private _memPointsActions = []; @@ -148,8 +149,6 @@ private _ladders = getArray (configFile >> "CfgVehicles" >> _typeOfBuilding >> " } forEach _ladders; -GVAR(cachedBuildingTypes) pushBack _typeOfBuilding; -GVAR(cachedBuildingActionPairs) pushBack [_memPoints, _memPointsActions]; - +GVAR(cachedBuildingTypes) set [_typeOfBuilding, [_memPoints, _memPointsActions]]; [_memPoints, _memPointsActions] diff --git a/addons/interact_menu/initSettings.inc.sqf b/addons/interact_menu/initSettings.inc.sqf index 22287189c33..c175bd17c2c 100644 --- a/addons/interact_menu/initSettings.inc.sqf +++ b/addons/interact_menu/initSettings.inc.sqf @@ -46,9 +46,7 @@ private _categoryColors = [_category, format ["| %1 |", LELSTRING(common,subcate QGVAR(textSize), "LIST", LSTRING(textSize), _category, - [[0, 1, 2, 3, 4], ["str_very_small", "str_small", "str_medium", "str_large", "str_very_large"], 2], - 0, - {[QGVAR(textSize), _this] call EFUNC(common,cbaSettings_settingChanged)} + [[0, 1, 2, 3, 4], ["str_very_small", "str_small", "str_medium", "str_large", "str_very_large"], 2] ] call CBA_fnc_addSetting; [ diff --git a/addons/interaction/functions/fnc_addPassengerActions.sqf b/addons/interaction/functions/fnc_addPassengerActions.sqf index a3d8c2eff07..9b8981bfd0d 100644 --- a/addons/interaction/functions/fnc_addPassengerActions.sqf +++ b/addons/interaction/functions/fnc_addPassengerActions.sqf @@ -20,11 +20,7 @@ params ["", "", "_parameters"]; _parameters params ["_unit"]; -private _namespace = EGVAR(interact_menu,ActNamespace); -private _actionTrees = _namespace getVariable typeOf _unit; -if (isNil "_actionTrees") then { - _actionTrees = []; -}; +private _actionTrees = EGVAR(interact_menu,ActNamespace) getOrDefault [typeOf _unit, []]; private _actions = []; diff --git a/addons/interaction/functions/fnc_canPullOutBody.sqf b/addons/interaction/functions/fnc_canPullOutBody.sqf index 167d09ecdb7..2676bfc203c 100644 --- a/addons/interaction/functions/fnc_canPullOutBody.sqf +++ b/addons/interaction/functions/fnc_canPullOutBody.sqf @@ -19,7 +19,7 @@ params ["_body", "_unit"]; // Defer to ACE Medical's unload patient if present -if (["ace_medical"] call EFUNC(common,isModLoaded)) exitWith {false}; +if (GETEGVAR(medical,enabled,false)) exitWith {false}; private _vehicle = objectParent _body; diff --git a/addons/interaction/initSettings.inc.sqf b/addons/interaction/initSettings.inc.sqf index b502ed36b00..2cefb162a76 100644 --- a/addons/interaction/initSettings.inc.sqf +++ b/addons/interaction/initSettings.inc.sqf @@ -20,7 +20,7 @@ false, true, {[QGVAR(disableNegativeRating), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ diff --git a/addons/irlight/stringtable.xml b/addons/irlight/stringtable.xml index 5423a8a8a0f..506e9deb9da 100644 --- a/addons/irlight/stringtable.xml +++ b/addons/irlight/stringtable.xml @@ -11,6 +11,7 @@ DBAL-A3 (vermelho) DBAL-A3 (赤) DBAL-A3 (красный) + DBAL-A3 (rojo) DBAL-A3 (green) @@ -22,6 +23,7 @@ DBAL-A3 (Verde) DBAL-A3 (緑) DBAL-A3 (зеленый) + DBAL-A3 (verde) <t color='#9cf953'>Use: </t>Turn Laser ON/OFF<br>Double click to switch mode @@ -33,6 +35,7 @@ <t color='#9cf953'>Uso: </t>Ligar/Desligar Laser<br>Duplo clique para mudar o modo <t color='#9cf953'>使用方法: </t>レーザーのオン/オフ切り替え<br>ダブルクリックでモード切り替え <t color='#9cf953'>Использование: </t>Включение / выключение лазера <br>Двойной щелчок для переключения режима + <t color='#9cf953'>Uso: </t>Alternar Láser ON/OFF<br>Doble click para cambiar estado Dual Beam Aiming Laser @@ -44,6 +47,7 @@ Laser de Pontaria de Duplo Feixe 複合ビーム照準レーザー Двухлучевой прицельный лазер + Láser de Apuntado de Doble Haz Visible Laser @@ -55,6 +59,7 @@ Laser Visível 可視光レーザー Видимый лазер + Láser Visible IR Laser @@ -66,6 +71,7 @@ Laser IR IRレーザー ИК-лазер + Láser IR IR Illuminator @@ -77,6 +83,7 @@ Iluminador IR IRイルミネーター ИК-осветитель + Iluminador IR IR Laser and Illuminator @@ -88,6 +95,7 @@ Laser e Iluminador IR IRレーザーとイルミネーター ИК-лазер и осветитель + Láser e Iluminador IR Wide Beam @@ -99,6 +107,7 @@ Feixe Largo 広角ビーム Широкий луч + Haz Ancho Medium Beam @@ -110,6 +119,7 @@ Feixe Médio 標準ビーム Средний луч + Haz Medio Narrow Beam @@ -121,6 +131,7 @@ Feixe Estreito 狭角ビーム Узкий луч + Haz Estrecho <t color='#9cf953'>Use: </t>Turn Light ON/OFF<br>Double click to switch mode @@ -132,6 +143,7 @@ <t color='#9cf953'>Uso: </t>Ligar/Desligar Iluminador<br>Duplo clique para mudar o modo <t color='#9cf953'>使用方法: </t>ライトのオン/オフ<br>ダブルクリックでモード切り替え <t color='#9cf953'>Использование: </t>Включение / выключение освещения <br>Двойной щелчок для переключения режима + <t color='#9cf953'>Uso: </t>Alternar Luz ON/OFF<br>Doble click para cambiar estado Special Purpose IR LED Illuminator @@ -143,6 +155,7 @@ Iluminador LED IR de Uso Especial 特殊用途のIR LEDイルミネーター ИК-светодиодный осветитель специального назначения + Iluminador LED IR de Propósito Especial Illuminator / Laser Momentary Switch @@ -154,6 +167,7 @@ Interruptor Momentâneo Iluminador/Laser イルミネーター/レーザーモーメンタリースイッチ Мгновенный переключатель осветителя/лазера + Conmutador Momentáneo Iluminador / Láser diff --git a/addons/killtracker/XEH_postInit.sqf b/addons/killtracker/XEH_postInit.sqf index c5adc266924..35050d1dc30 100644 --- a/addons/killtracker/XEH_postInit.sqf +++ b/addons/killtracker/XEH_postInit.sqf @@ -19,7 +19,8 @@ if ((getText (missionconfigfile >> "CfgDebriefingSections" >> QUOTE(XADDON) >> "variable")) != QXGVAR(outputText)) exitWith { TRACE_1("no mission debriefing config",_this); }; -if (!(["ace_medical"] call EFUNC(common,isModLoaded))) exitWith { + +if !(GETEGVAR(medical,enabled,false)) exitWith { WARNING("No ACE-Medical"); XGVAR(outputText) = "No ACE-Medical"; }; @@ -64,7 +65,7 @@ GVAR(killCount) = 0; private _killInfo = []; if (!isNull _killer) then { - if (!(_killer isKindof "CAManBase")) then { // If killer is a vehicle log the vehicle type + if !(_killer isKindof "CAManBase") then { // If killer is a vehicle log the vehicle type _killInfo pushBack format [LLSTRING(Vehicle), getText ((configOf _killer) >> "displayName")]; }; if (isNull _instigator) then { @@ -73,11 +74,11 @@ GVAR(killCount) = 0; }; }; private _unitIsPlayer = hasInterface && {_unit in [player, ace_player]}; // isPlayer check will fail at this point - private _killerIsPlayer = (!isNull _instigator) && {_unit != _instigator} && {[_instigator] call EFUNC(common,isPlayer)}; - TRACE_2("",_unitIsPlayer,_killerIsPlayer); + private _instigatorIsPlayer = (!isNull _instigator) && {_unit != _instigator} && {[_instigator] call EFUNC(common,isPlayer)}; + TRACE_2("",_unitIsPlayer,_instigatorIsPlayer); // Don't do anything if neither are players - if (!(_unitIsPlayer || _killerIsPlayer)) exitWith {}; + if !(_unitIsPlayer || _instigatorIsPlayer) exitWith {}; // Log firendly fire private _fnc_getSideFromConfig = { @@ -89,7 +90,7 @@ GVAR(killCount) = 0; default {civilian}; }; }; - if ((!isNull _instigator) && {_unit != _instigator} && {_instigator isKindOf "CAManBase"}) then { + if (!isNull _instigator && {_unit != _instigator} && {_instigator isKindOf "CAManBase"}) then { // Because of unconscious group switching/captives it's probably best to just use unit's config side private _unitSide = [_unit] call _fnc_getSideFromConfig; private _killerSide = [_instigator] call _fnc_getSideFromConfig; @@ -110,23 +111,23 @@ GVAR(killCount) = 0; // If unit was player then send event to self if (_unitIsPlayer) then { - private _killerName = "Self?"; - if ((!isNull _killer) && {_unit != _killer}) then { - if (_killerIsPlayer) then { - _killerName = [_killer, true, false] call EFUNC(common,getName); + private _instigatorName = "Self?"; + if ((!isNull _instigator) && {_unit != _instigator}) then { + if (_instigatorIsPlayer) then { + _instigatorName = [_instigator, true, false] call EFUNC(common,getName); } else { - _killerName = _killer getVariable [QGVAR(aiName), ""]; // allow setting a custom AI name (e.g. VIP Target) - if (_killerName == "") then { - _killerName = format ["*AI* - %1", getText ((configOf _killer) >> "displayName")]; + _instigatorName = _instigator getVariable [QGVAR(aiName), ""]; // allow setting a custom AI name (e.g. VIP Target) + if (_instigatorName == "") then { + _instigatorName = format ["*AI* - %1", getText ((configOf _instigator) >> "displayName")]; }; }; }; - TRACE_3("send death event",_unit,_killerName,_killInfo); - [QGVAR(death), [_killerName, _killInfo]] call CBA_fnc_localEvent; + TRACE_3("send death event",_unit,_instigatorName,_killInfo); + [QGVAR(death), [_instigatorName, _killInfo]] call CBA_fnc_localEvent; }; - // If killer was player then send event to killer - if (_killerIsPlayer) then { + // If shooter was player then send event to them (and optionally the whole crew) + if (_instigatorIsPlayer && {_unitIsPlayer || GVAR(trackAI)}) then { private _unitName = ""; if (_unitIsPlayer) then { _unitName = [_unit, true, false] call EFUNC(common,getName); // should be same as profileName @@ -136,9 +137,18 @@ GVAR(killCount) = 0; _unitName = format ["*AI* - %1", getText ((configOf _unit) >> "displayName")]; }; }; - if (_unitIsPlayer || GVAR(trackAI)) then { - TRACE_3("send kill event",_killer,_unitName,_killInfo); - [QGVAR(kill), [_unitName, _killInfo], _killer] call CBA_fnc_targetEvent; + TRACE_3("send kill event",_instigator,_unitName,_killInfo); + [QGVAR(kill), [_unitName, _killInfo], _instigator] call CBA_fnc_targetEvent; + + if (GVAR(showCrewKills) && {!(_killer isKindOf "CAManBase")}) then { + private _crew = [driver _killer, gunner _killer, commander _killer] - [_instigator]; + _crew = _crew select {[_x] call EFUNC(common,isPlayer)}; + _crew = _crew arrayIntersect _crew; + TRACE_1("showCrewKills",_crew); + _killInfo = format [" - [%1, %2", localize "str_a3_rscdisplaygarage_tab_crew", _killInfo select [4]]; + { + [QGVAR(kill), [_unitName, _killInfo], _x] call CBA_fnc_targetEvent; + } forEach _crew; }; }; }] call CBA_fnc_addEventHandler; diff --git a/addons/killtracker/initSettings.inc.sqf b/addons/killtracker/initSettings.inc.sqf index ebe1e55ccb2..9e4775bd7f7 100644 --- a/addons/killtracker/initSettings.inc.sqf +++ b/addons/killtracker/initSettings.inc.sqf @@ -6,3 +6,12 @@ true, 1 ] call CBA_fnc_addSetting; + +[ + QGVAR(showCrewKills), + "CHECKBOX", + [LSTRING(showCrewKills_DisplayName), LSTRING(showCrewKills_Description)], + LSTRING(Category), + false, + 1 +] call CBA_fnc_addSetting; diff --git a/addons/killtracker/stringtable.xml b/addons/killtracker/stringtable.xml index 24c7bcdd56c..916dac68777 100644 --- a/addons/killtracker/stringtable.xml +++ b/addons/killtracker/stringtable.xml @@ -9,11 +9,13 @@ ACE キルトラッカー ACE 킬트래커 ACE Suivi des morts + ACE Abschüsse + ACE Contador de Muertes ACE Killed Events ACE キルイベント - ACE Abgeschossene Ereignisse + ACE Abschusszähler ACE Eventi di Morte ACE Licznik Zabójstw ACE 击杀事件 @@ -103,6 +105,8 @@ プレイヤーに殺害されたAIユニットを追跡 플레이어가 죽인 AI 트래킹 Suivi de l'IA tuée par les joueurs + Zähle vom Spieler getöteten KI-Einheiten + Cuenta las unidades de IA matadas por el jugador Defines if killed AIs will be shown in the kill tracker during mission debriefing. @@ -112,6 +116,14 @@ ミッションデブリーフィングのキルトラッカーに殺害されたAIが表示されるかどうかを定義します。 사후강평 중 살해된 AI가 킬트래킹에 표시되는지 여부를 정의합니다. Définit si les IA tuées seront affichées dans le tracker pendant le débriefing de la mission. + Legt fest, ob getötete KIs während des Endbildschirms der Mission in den Abschüssen angezeigt werden. + Define si las IAs matadas se mostrarán en el contador de muertes en el debiefring de la misión. + + + Show vehicle kills to other crew members + + + Show kills from a vehicle to driver, gunner and commander diff --git a/addons/laser/functions/fnc_seekerFindLaserSpot.sqf b/addons/laser/functions/fnc_seekerFindLaserSpot.sqf index aa3e43d35a7..4ceb15d8148 100644 --- a/addons/laser/functions/fnc_seekerFindLaserSpot.sqf +++ b/addons/laser/functions/fnc_seekerFindLaserSpot.sqf @@ -115,7 +115,7 @@ if (_spots isNotEqualTo []) then { while { count(_spots) != count(_excludes) && _c < (count _spots) } do { scopeName "mainSearch"; { - if (!(_forEachIndex in _excludes)) then { + if !(_forEachIndex in _excludes) then { private _index = _buckets pushBack [_x, [_x]]; _excludes pushBack _forEachIndex; _bucketPos = _x select 0; @@ -124,7 +124,7 @@ if (_spots isNotEqualTo []) then { }; } forEach _spots; { - if (!(_forEachIndex in _excludes)) then { + if !(_forEachIndex in _excludes) then { private _testPos = (_x select 0); if ((_testPos vectorDistanceSqr _bucketPos) <= 100) then { _bucketList pushBack _x; diff --git a/addons/laser/stringtable.xml b/addons/laser/stringtable.xml index f0977c84f79..c6bf7cfc25e 100644 --- a/addons/laser/stringtable.xml +++ b/addons/laser/stringtable.xml @@ -129,6 +129,7 @@ Traqueur laser : activé Rastreador a Laser: Ligado Лазерный точечный трекер: Включен + Rastreador del Puntero Láser: On Laser Spot Tracker: Off @@ -140,6 +141,7 @@ Traqueur laser : désactivé Rastreador a Laser: Desligado Лазерный точечный трекер: выключен + Rastreador del Puntero Láser: Off Draw Laser on Map diff --git a/addons/logistics_uavbattery/functions/fnc_refuelUAV.sqf b/addons/logistics_uavbattery/functions/fnc_refuelUAV.sqf index 8c73052c453..a471e82cbf7 100644 --- a/addons/logistics_uavbattery/functions/fnc_refuelUAV.sqf +++ b/addons/logistics_uavbattery/functions/fnc_refuelUAV.sqf @@ -17,7 +17,7 @@ */ params ["_caller", "_target"]; -if (!(_this call FUNC(canRefuelUAV))) exitWith {}; +if !(_this call FUNC(canRefuelUAV)) exitWith {}; private _onFinish = { (_this select 0) params ["_caller", "_target"]; diff --git a/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf b/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf index 9383089d284..c2785c5fadb 100644 --- a/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf +++ b/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf @@ -25,7 +25,7 @@ _args params ["_magazineClassname", "_lastAmmoCount"]; private _fullMagazineCount = getNumber (configFile >> "CfgMagazines" >> _magazineClassname >> "count"); // Don't show anything if player can't interact -if (!([ACE_player, objNull, ["isNotInside", "isNotSitting", "isNotSwimming"]] call EFUNC(common,canInteractWith))) exitWith {}; +if !([ACE_player, objNull, ["isNotInside", "isNotSitting", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {}; // Count mags private _fullMags = 0; diff --git a/addons/main/script_version.hpp b/addons/main/script_version.hpp index 501b3095dc8..75b323ede34 100644 --- a/addons/main/script_version.hpp +++ b/addons/main/script_version.hpp @@ -1,4 +1,4 @@ #define MAJOR 3 #define MINOR 17 -#define PATCHLVL 0 -#define BUILD 83 +#define PATCHLVL 1 +#define BUILD 86 diff --git a/addons/map/XEH_postInitClient.sqf b/addons/map/XEH_postInitClient.sqf index ea3ce194647..534b37da8bd 100644 --- a/addons/map/XEH_postInitClient.sqf +++ b/addons/map/XEH_postInitClient.sqf @@ -8,7 +8,7 @@ LOG(MSG_INIT); // Calculate the maximum zoom allowed for this map call FUNC(determineZoom); -GVAR(flashlights) = [] call CBA_fnc_createNamespace; +GVAR(flashlights) = createHashMap; ["CBA_settingsInitialized", { if (isMultiplayer && {GVAR(DefaultChannel) != -1}) then { diff --git a/addons/map/functions/fnc_isFlashlight.sqf b/addons/map/functions/fnc_isFlashlight.sqf index e563d741145..ae26b41569d 100644 --- a/addons/map/functions/fnc_isFlashlight.sqf +++ b/addons/map/functions/fnc_isFlashlight.sqf @@ -17,14 +17,12 @@ params [["_class", "", [""]]]; -private _isFlashlight = GVAR(flashlights) getVariable _class; - -if (isNil "_isFlashlight") then { +GVAR(flashlights) getOrDefaultCall [_class, { private _items = ([_class] + (_class call CBA_fnc_switchableAttachments)); private _cfgWeapons = configFile >> "CfgWeapons"; // if this item or any of the switchable items is a flashlight - _isFlashlight = _items findIf { + _items findIf { private _weaponConfig = _cfgWeapons >> _x; [ @@ -34,10 +32,5 @@ if (isNil "_isFlashlight") then { isText (_x >> "ACE_Flashlight_Colour") || {!(getArray (_x >> "ambient") in [[], [0,0,0]]) && {getNumber (_x >> "irLight") == 0}} } != -1 // return - } != -1; - - // cache value - GVAR(flashlights) setVariable [_class, _isFlashlight]; -}; - -_isFlashlight // return + } != -1 // return +}, true] // return diff --git a/addons/map/initSettings.inc.sqf b/addons/map/initSettings.inc.sqf index 8de301eaa16..20665b5a71f 100644 --- a/addons/map/initSettings.inc.sqf +++ b/addons/map/initSettings.inc.sqf @@ -67,14 +67,11 @@ false, true, { - [QGVAR(BFT_Enabled), _this] call EFUNC(common,cbaSettings_settingChanged); - if (GVAR(BFT_Enabled) && {isNil QGVAR(BFT_markers)}) then { GVAR(BFT_markers) = []; [LINKFUNC(blueForceTrackingUpdate), GVAR(BFT_Interval), []] call CBA_fnc_addPerFrameHandler; }; - }, - false + } ] call CBA_fnc_addSetting; [ @@ -94,9 +91,7 @@ [localize LSTRING(BFT_ShowPlayerNames_DisplayName), localize LSTRING(BFT_ShowPlayerNames_Description)], [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize LSTRING(BFT_Module_DisplayName)], false, - true, - {[QGVAR(BFT_ShowPlayerNames), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false + true ] call CBA_fnc_addSetting; [ @@ -105,7 +100,5 @@ [localize LSTRING(BFT_HideAiGroups_DisplayName), localize LSTRING(BFT_HideAiGroups_Description)], [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize LSTRING(BFT_Module_DisplayName)], false, - true, - {[QGVAR(BFT_HideAiGroups), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false + true ] call CBA_fnc_addSetting; diff --git a/addons/map_gestures/XEH_preInit.sqf b/addons/map_gestures/XEH_preInit.sqf index e603e5398a1..42090ac7240 100644 --- a/addons/map_gestures/XEH_preInit.sqf +++ b/addons/map_gestures/XEH_preInit.sqf @@ -8,6 +8,6 @@ PREP_RECOMPILE_END; #include "initSettings.inc.sqf" -GVAR(GroupColorCfgMappingNew) = call CBA_fnc_createNamespace; +GVAR(GroupColorCfgMappingNew) = createHashMap; ADDON = true; diff --git a/addons/map_gestures/functions/fnc_addGroupColorMapping.sqf b/addons/map_gestures/functions/fnc_addGroupColorMapping.sqf index 17a8ffbb045..f533f9df345 100644 --- a/addons/map_gestures/functions/fnc_addGroupColorMapping.sqf +++ b/addons/map_gestures/functions/fnc_addGroupColorMapping.sqf @@ -25,7 +25,7 @@ TRACE_3("params",_group,_leadColor,_unitColor); if (_group isEqualType grpNull) then {_group = groupID _group}; if (_group == "") exitWith {ERROR("Group ID is blank, which is not valid.")}; -if (!([_leadColor] call FUNC(isValidColorArray))) exitWith {ERROR("leadColor is not a valid color array.")}; -if (!([_unitColor] call FUNC(isValidColorArray))) exitWith {ERROR("color is not a valid color array.")}; +if !([_leadColor] call FUNC(isValidColorArray)) exitWith {ERROR("leadColor is not a valid color array.")}; +if !([_unitColor] call FUNC(isValidColorArray)) exitWith {ERROR("color is not a valid color array.")}; -GVAR(GroupColorCfgMappingNew) setVariable [_group, [_leadColor, _unitColor]]; +GVAR(GroupColorCfgMappingNew) set [toLower _group, [_leadColor, _unitColor]]; diff --git a/addons/map_gestures/functions/fnc_drawMapGestures.sqf b/addons/map_gestures/functions/fnc_drawMapGestures.sqf index 2f0c80de3ea..0a69c1924b8 100644 --- a/addons/map_gestures/functions/fnc_drawMapGestures.sqf +++ b/addons/map_gestures/functions/fnc_drawMapGestures.sqf @@ -41,7 +41,7 @@ private _players = [_positions, FUNC(getProximityPlayers), missionNamespace, QGV }; // If color settings for the group exist, then use those, otherwise fall back to the default colors - private _colorMap = GVAR(GroupColorCfgMappingNew) getVariable [(groupID (group _x)), [GVAR(defaultLeadColor), GVAR(defaultColor)]]; + private _colorMap = GVAR(GroupColorCfgMappingNew) getOrDefault [toLower groupID (group _x), [GVAR(defaultLeadColor), GVAR(defaultColor)]]; private _color = _colorMap select (_x != leader _x); TRACE_2("",_colorMap,_color); diff --git a/addons/map_gestures/functions/fnc_isValidColorArray.sqf b/addons/map_gestures/functions/fnc_isValidColorArray.sqf index 7cc9335800b..bcd5fea38cd 100644 --- a/addons/map_gestures/functions/fnc_isValidColorArray.sqf +++ b/addons/map_gestures/functions/fnc_isValidColorArray.sqf @@ -20,7 +20,7 @@ scopeName "main"; params ["_colorArray"]; if (isNil "_colorArray") exitWith {false}; -if (!(_colorArray isEqualType [])) exitWith {false}; +if !(_colorArray isEqualType []) exitWith {false}; if (count _colorArray != 4) exitWith {false}; { diff --git a/addons/map_gestures/functions/fnc_moduleGroupSettings.sqf b/addons/map_gestures/functions/fnc_moduleGroupSettings.sqf index 07be21fc907..36bef695d51 100644 --- a/addons/map_gestures/functions/fnc_moduleGroupSettings.sqf +++ b/addons/map_gestures/functions/fnc_moduleGroupSettings.sqf @@ -24,9 +24,10 @@ if (!_activated) exitWith {}; // Transcode string setting into usable array. Example: "1,1,1,1" -> [1, 1, 1, 1] private _leadColor = call compile ("[" + (_logic getVariable ["leadColor", ""]) + "]"); -if (!([_leadColor] call FUNC(isValidColorArray))) exitWith {ERROR("leadColor is not a valid color array.")}; +if !([_leadColor] call FUNC(isValidColorArray)) exitWith {ERROR("leadColor is not a valid color array.")}; + private _color = call compile ("[" + (_logic getVariable ["color", ""]) + "]"); -if (!([_color] call FUNC(isValidColorArray))) exitWith {ERROR("color is not a valid color array.")}; +if !([_color] call FUNC(isValidColorArray)) exitWith {ERROR("color is not a valid color array.")}; // Add all synchronized groups and reference custom configuration for them { diff --git a/addons/map_gestures/functions/fnc_moduleSettings.sqf b/addons/map_gestures/functions/fnc_moduleSettings.sqf index b637997af75..22913dceef2 100644 --- a/addons/map_gestures/functions/fnc_moduleSettings.sqf +++ b/addons/map_gestures/functions/fnc_moduleSettings.sqf @@ -29,14 +29,14 @@ if (!_activated) exitWith {}; private _defaultLeadColor = _logic getVariable ["defaultLeadColor", ""]; if (_defaultLeadColor != "") then { _defaultLeadColor = call compile ("[" + _defaultLeadColor + "]"); - if (!([_defaultLeadColor] call FUNC(isValidColorArray))) exitWith {ERROR("defaultLeadColor is not a valid color array.")}; + if !([_defaultLeadColor] call FUNC(isValidColorArray)) exitWith {ERROR("defaultLeadColor is not a valid color array.")}; ["CBA_settings_setSettingMission", [QGVAR(defaultLeadColor), _defaultLeadColor, true]] call CBA_fnc_localEvent; }; private _defaultColor = _logic getVariable ["defaultColor", ""]; if (_defaultColor != "") then { _defaultColor = call compile ("[" + _defaultColor + "]"); - if (!([_defaultColor] call FUNC(isValidColorArray))) exitWith {ERROR("defaultColor is not a valid color array.")}; + if !([_defaultColor] call FUNC(isValidColorArray)) exitWith {ERROR("defaultColor is not a valid color array.")}; ["CBA_settings_setSettingMission", [QGVAR(defaultColor), _defaultColor, true]] call CBA_fnc_localEvent; }; diff --git a/addons/maptools/functions/fnc_canUseMapGPS.sqf b/addons/maptools/functions/fnc_canUseMapGPS.sqf index 0bdd0d0ea64..e9ca813288a 100644 --- a/addons/maptools/functions/fnc_canUseMapGPS.sqf +++ b/addons/maptools/functions/fnc_canUseMapGPS.sqf @@ -17,8 +17,7 @@ if (!visibleMap || {!alive ACE_player}) exitWith {false}; -private _gpsOpened = visibleGPS; -private _gpsAvailable = openGPS true; -if (!_gpsOpened) then {openGPS false}; +private _panels = flatten (ACE_player infoPanelComponents "left"); +private _index = _panels find "MinimapDisplayComponent"; -_gpsAvailable // return +_index != -1 && {_panels select (_index + 1)} diff --git a/addons/maptools/stringtable.xml b/addons/maptools/stringtable.xml index bb0782f22be..7e1d0cee97f 100644 --- a/addons/maptools/stringtable.xml +++ b/addons/maptools/stringtable.xml @@ -42,6 +42,8 @@ Tavola di calcolo Графическая доска Planche traçante + Wurfparabel Kartenwerkzeug + Tablero de Trazado The Plotting Board is a map tool designed for use in the directing of short range indirect fires. @@ -50,6 +52,8 @@ La tavola di calcolo è uno strumento utilizzato per dirigere fuoco di artiglieria a corto raggio. Графическая доска - это картографический инструмент, предназначенный для использования при ведении непрямого огня с малой дистанции. Une planche traçante est un outil cartographique conçu pour diriger des tirs indirects à courte distance. + Das Wurfparabel-Kartenwerkzeug ist ein Werkzeug, das für die Steuerung indirekten Feuers auf kurze Distanz entwickelt wurde. + El Tablero de Trazado es una herramienta de mapa utilizada para dirigir fuego indirecto de corto alcance. Map Tools @@ -275,6 +279,8 @@ Canali ammessi su tavola di calcolo Разрешить создание каналов на миллиметровой доске. Canaux autorisés sur la planche traçante + Wurfparabel Kartenwerkzeug erlaubte Kanäle + Permitir Canales de Dibujado de Tablero de Trazado Channels in which plotting board drawing is enabled. @@ -283,6 +289,8 @@ Canali in cui si può disegnare sulla tavola di calcolo. Каналы, в которых включено рисование на миллиметровой доске. Canaux dans lesquels vous pouvez dessiner sur le planche traçante + Kanäle, in denen das Zeichnen mit dem Wurfparabel-Kartenwerkzeug auf der Karte erlaubt ist. + Canales en los que el tablero de trazado está habilitado. Allow Direct Comms Only (Polylines Only) @@ -291,6 +299,8 @@ Comunicazioni Dirette (solo linee) Разрешать только прямую связь (только полилинии) Communications directes uniquement (lignes uniquement) + Nur direkte Kommunikation zulassen (nur Polylinien) + Permitir Sólo Comunicaciones Directas (Sólo Polylineas) Allow Direct/Group Comms (Polylines and Group Markers) @@ -299,6 +309,8 @@ Comunicazioni dirette/gruppo (linee e marker) Разрешить прямую/групповую связь (полилинии и групповые маркеры) Autoriser les communications directes/de groupe (polylignes et marqueurs de groupe) + Direkte/Gruppenkommunikation zulassen (Polylinien und Gruppenmarkierungen) + Permitir Comunicaciones Directas/Grupales (Polylineas y Marcadores de Grupo) Plotting Board @@ -307,6 +319,8 @@ Tavola di calcolo Миллиметровая доска Planche traçante + Wurfparabel Kartenwerkzeug + Tablero de Trazado Plotting Board Acrylic @@ -315,6 +329,8 @@ Acrilico tavola di calcolo Миллиметровая доска акрилловая Planche traçante Acrylique + Wurfparabel Kartenwerkzeug Acryl + Tablero de Trazado Acrílico Plotting Board Ruler @@ -323,6 +339,8 @@ Righello tavola di calcolo Линейка для миллиметровой доски Règle de la planche traçante + Wurfparabel Kartenwerkzeug Lineal + Regla de Tablero de Trazado To Plotting Board @@ -331,6 +349,8 @@ Su tavola di calcolo К миллиметровой доске. Sur la planche traçante + Zum Wurfparabel Kartenwerkzeug + A Tablero de Trazado To Plotting Board Acrylic @@ -339,6 +359,8 @@ Su acrilico tavola di calcolo К миллиметровой доске акрилловой Sur la planche traçante Acrylique + Zum Wurfparabel Kartenwerkzeug Acryl + A Tablero de Trazado Acrílico To Plotting Board Ruler @@ -347,6 +369,8 @@ Su righello tavola di calcolo К линейке миллиметровой доски. Sur la règle de la planche traçante + Zum Wurfparabel Kartenwerkzeug Lineal + A Regla de Tablero de Trazado Wipe all markers off Plotting Board @@ -355,6 +379,8 @@ Cancella tutti i disegni dalla tavola Сотрите все маркеры с миллиметровой доски. Effacer tous les dessins de la planche traçante + Alle Markierungen vom Wurfparabel Kartenwerkzeug entfernen + Borrar todas las marcas del Tablero de Trazado Show Plotting Board @@ -363,6 +389,8 @@ Mostra tavola di calcolo Показать миллиметровую доску. Afficher la planche traçante + Zeige Wurfparabel Kartenwerkzeug + Mostrar Tablero de Trazado Hide Plotting Board @@ -371,6 +399,8 @@ Nascondi tavola di calcolo Скрыть миллиметровую доску. Masquer la planche traçante + Verstecke Wurfparabel Kartenwerkzeug + Ocultar Tablero de Trazado Toggle Plotting Board Ruler @@ -379,6 +409,8 @@ Mostra/Nascondi Righello Переключить линейку миллиметровой доски. Afficher/masquer la règle + Schalte das Lineal des Wurfparabel-Kartenwerkzeuges um + Alternar Regla de Tablero de Trazado Align @@ -429,6 +461,8 @@ Su Вверх Monter + Nach oben + Arriba To Maptool @@ -437,6 +471,8 @@ Su strumento cartografico К инструментам карты Outil cartographique + Zum Kartenwerkzeug + A Herramienta de Mapa diff --git a/addons/markers/functions/fnc_removeTimestamp.sqf b/addons/markers/functions/fnc_removeTimestamp.sqf index 073d9ce6132..5d2c7c3c1f3 100644 --- a/addons/markers/functions/fnc_removeTimestamp.sqf +++ b/addons/markers/functions/fnc_removeTimestamp.sqf @@ -43,8 +43,8 @@ private _index = 1; private _keepCheckingDigits = true; private _validTimestamp = true; while {_keepCheckingDigits} do { - if (!(_string select [_index, 1] in DIGITS)) exitWith { _validTimestamp = false; }; - if (!(_string select [_index+1, 1] in DIGITS)) exitWith { _validTimestamp = false; }; + if !(_string select [_index, 1] in DIGITS) exitWith { _validTimestamp = false; }; + if !(_string select [_index+1, 1] in DIGITS) exitWith { _validTimestamp = false; }; switch (_string select [_index+2, 1]) do { case (":"): { _index = _index + 3; @@ -54,7 +54,7 @@ while {_keepCheckingDigits} do { }; case (" "): { _keepCheckingDigits = false; - if (!(_string select [_index+3, 3] in ["am]", "pm]"])) then {_validTimestamp = false; }; + if !(_string select [_index+3, 3] in ["am]", "pm]"]) then {_validTimestamp = false; }; }; default { _keepCheckingDigits = false; diff --git a/addons/markers/stringtable.xml b/addons/markers/stringtable.xml index a0c0be17f72..2c9dc1531ba 100644 --- a/addons/markers/stringtable.xml +++ b/addons/markers/stringtable.xml @@ -421,6 +421,7 @@ "MS" - 밀리초 (0부터 59까지) "MM" - ミリ秒 (0から59) "ММ" - миллисекунды (от 0 до 59) + "MM" - Milisegundos (de 0 a 59) "mmm" - Milliseconds (from 0 to 999) @@ -431,6 +432,7 @@ "mmm" - 밀리초 (0부터 999까지) "mmm" - ミリ秒 (0から599) "ммм" - миллисекунды (от 0 до 999) + "mmm" - Milisegundos (de 0 a 999) Timestamp Hour Format diff --git a/addons/medical/dev/test_hitpointConfigs.sqf b/addons/medical/dev/test_hitpointConfigs.sqf index 9de5c5e6868..7bdeb189c23 100644 --- a/addons/medical/dev/test_hitpointConfigs.sqf +++ b/addons/medical/dev/test_hitpointConfigs.sqf @@ -21,23 +21,16 @@ INFO_1("Checking uniforms for correct medical hitpoints [%1 units]",count _units private _testPass = true; { private _typeOf = configName _x; - private _hitpoints = (configProperties [_x >> "HitPoints", "isClass _x", true]) apply {configName _x}; - - // _typeOf createUnit [position player, group player, "z = this"]; - // deleteVehicle z; - - private _lastHitpoint = (_hitpoints param [(count _hitpoints) - 1, "#array"]); - if (_lastHitpoint != "ACE_HDBracket") then { - WARNING_2("%1 has bad last hitpoint: %2",_typeOf,_hitpoints); + private _hitpoints = (configProperties [_x >> "HitPoints", "isClass _x", true]) apply {toLowerANSI configName _x}; + private _expectedHitPoints = ["hitleftarm","hitrightarm","hitleftleg","hitrightleg","hithead","hitbody"]; + private _missingHitPoints = _expectedHitPoints select {!(_x in _hitpoints)}; + if (_missingHitPoints isNotEqualTo []) then { + WARNING_3("%1 missing ace hitpoints: %2 - class hitpoints: %3",_typeOf,_missingHitPoints,_hitpoints); _testPass = false; }; - if (((_hitpoints findIf {_x == "HitLeftArm"}) == -1) || {(_hitpoints findIf {_x == "HitRightArm"}) == -1} - || {(_hitpoints findIf {_x == "HitLeftLeg"}) == -1} || {(_hitpoints findIf {_x == "HitRightLeg"}) == -1} - || {(_hitpoints findIf {_x == "HitHead"}) == -1} || {(_hitpoints findIf {_x == "HitBody"}) == -1}) then { - WARNING_2("%1 missing ace hitpoints: %2",_typeOf,_hitpoints); - _testPass = false; - }; + // _typeOf createUnit [position player, group player, "z = this"]; + // deleteVehicle z; } forEach _units; _testPass diff --git a/addons/medical/dev/watchVariable.sqf b/addons/medical/dev/watchVariable.sqf index 05cb094ba8a..a0e064595ab 100644 --- a/addons/medical/dev/watchVariable.sqf +++ b/addons/medical/dev/watchVariable.sqf @@ -10,10 +10,10 @@ GVAR(dev_watchVariableRunning) = true; if (!isNull _display) exitWith {"Paused"}; private _unit = cursorTarget; - if (!(_unit isKindOf "CAManBase")) then {_unit = cursorObject}; - if (!(_unit isKindOf "CAManBase")) then {_unit = ACE_player}; + if !(_unit isKindOf "CAManBase") then {_unit = cursorObject}; + if !(_unit isKindOf "CAManBase") then {_unit = ACE_player}; if ((_unit != ACE_player) && {IS_UNCONSCIOUS(ACE_player)}) then {_unit = ACE_player}; - if (!(_unit isKindOf "CAManBase")) exitWith {"No Unit?"}; + if !(_unit isKindOf "CAManBase") exitWith {"No Unit?"}; private _return = []; diff --git a/addons/medical_ai/stringtable.xml b/addons/medical_ai/stringtable.xml index 5081a09d962..54f0c2714cc 100644 --- a/addons/medical_ai/stringtable.xml +++ b/addons/medical_ai/stringtable.xml @@ -58,6 +58,7 @@ Exigir Itens アイテムを要求 Требуемые предметы + Requerir Objetos AI will only perform medical treatment if they have the necessary items in their inventory. @@ -69,6 +70,7 @@ A IA só irá realizar tratamento médico se tiver os itens necessários em seu inventário. AIのインベントリに必要なアイテムがある場合にのみ治療を実行します。 Искусственный интеллект будет оказывать медицинскую помощь только в том случае, если в его инвентаре есть необходимые предметы. + La IA sólo realizará el tratamiento médico en caso de que dispongan de los objetos necesarios en su inventario. Auto Convert Items for AI @@ -80,6 +82,7 @@ Conversão automática de itens para IA AIのアイテムを自動変換 Автоматическое преобразование элементов для ИИ + Auto Convertir Objetos para la IA diff --git a/addons/medical_blood/XEH_postInit.sqf b/addons/medical_blood/XEH_postInit.sqf index daf45955843..b08921b441e 100644 --- a/addons/medical_blood/XEH_postInit.sqf +++ b/addons/medical_blood/XEH_postInit.sqf @@ -1,7 +1,5 @@ #include "script_component.hpp" -GVAR(useAceMedical) = ["ace_medical"] call EFUNC(common,isModLoaded); - // To support public API regardless of component settings [QGVAR(spurt), LINKFUNC(spurt)] call CBA_fnc_addEventHandler; diff --git a/addons/medical_blood/XEH_preInit.sqf b/addons/medical_blood/XEH_preInit.sqf index 852b4dbe73e..93da039be54 100644 --- a/addons/medical_blood/XEH_preInit.sqf +++ b/addons/medical_blood/XEH_preInit.sqf @@ -8,22 +8,8 @@ PREP_RECOMPILE_END; #include "initSettings.inc.sqf" -// Damage types which do not cause blood spurts -GVAR(noBloodDamageTypes) = createHashMapFromArray (call (uiNamespace getVariable QGVAR(noBloodDamageTypes))); - // blood object model namespace -GVAR(models) = [] call CBA_fnc_createNamespace; - -{ - _x params ["_name", "_model"]; - - // createSimpleObject expects a path without the leading slash - if ((_model select [0,1]) isEqualTo "\") then { - _model = _model select [1]; - }; - - GVAR(models) setVariable [_name, _model]; -} forEach [ +GVAR(models) = createHashMapFromArray [ // higher number means bigger model ["blooddrop_1", QPATHTOF(data\ace_drop_1.p3d)], ["blooddrop_2", QPATHTOF(data\ace_drop_2.p3d)], diff --git a/addons/medical_blood/XEH_preStart.sqf b/addons/medical_blood/XEH_preStart.sqf index d051879f3c7..e2683ff5867 100644 --- a/addons/medical_blood/XEH_preStart.sqf +++ b/addons/medical_blood/XEH_preStart.sqf @@ -4,7 +4,4 @@ // Damage types which do not cause blood spurts private _noBloodDamageTypes = "getNumber (_x >> 'noBlood') == 1" configClasses (configFile >> "ACE_Medical_Injuries" >> "damageTypes"); -uiNamespace setVariable [ - QGVAR(noBloodDamageTypes), - compileFinal str (_noBloodDamageTypes apply {[configName _x, nil]}) -]; +uiNamespace setVariable [QGVAR(noBloodDamageTypes), compileFinal (_noBloodDamageTypes createHashMapFromArray [])]; diff --git a/addons/medical_blood/functions/fnc_createBlood.sqf b/addons/medical_blood/functions/fnc_createBlood.sqf index e6740ef459e..fbff6cc3c66 100644 --- a/addons/medical_blood/functions/fnc_createBlood.sqf +++ b/addons/medical_blood/functions/fnc_createBlood.sqf @@ -21,7 +21,7 @@ params ["_type", "_position", "_source"]; TRACE_3("Creating blood",_type,_position,_source); -private _model = GVAR(models) getVariable _type; +private _model = GVAR(models) get _type; private _bloodDrop = createSimpleObject [_model, [0, 0, 0]]; _bloodDrop setDir random 360; diff --git a/addons/medical_blood/functions/fnc_handleWoundReceived.sqf b/addons/medical_blood/functions/fnc_handleWoundReceived.sqf index 8b46233af26..53d5d2361bf 100644 --- a/addons/medical_blood/functions/fnc_handleWoundReceived.sqf +++ b/addons/medical_blood/functions/fnc_handleWoundReceived.sqf @@ -22,7 +22,7 @@ params ["_unit", "_allDamages", "_shooter", "_damageType"]; (_allDamages select 0) params ["_damage"]; // Don't bleed if damage type does not cause bleeding -if (_damageType in GVAR(noBloodDamageTypes)) exitWith {}; +if (_damageType in (uiNamespace getVariable QGVAR(noBloodDamageTypes))) exitWith {}; // Don't bleed when players only and a non-player unit is wounded if (GVAR(enabledFor) == BLOOD_ONLY_PLAYERS && {!isPlayer _unit && {_unit != ACE_player}}) exitWith {}; diff --git a/addons/medical_blood/functions/fnc_isBleeding.sqf b/addons/medical_blood/functions/fnc_isBleeding.sqf index 2d57dcf73b3..a21a50913ae 100644 --- a/addons/medical_blood/functions/fnc_isBleeding.sqf +++ b/addons/medical_blood/functions/fnc_isBleeding.sqf @@ -17,7 +17,7 @@ params ["_unit"]; -if (GVAR(useAceMedical)) exitWith { +if (GETEGVAR(medical,enabled,false)) exitWith { IS_BLEEDING(_unit); }; diff --git a/addons/medical_blood/functions/fnc_onBleeding.sqf b/addons/medical_blood/functions/fnc_onBleeding.sqf index 02ddd93fd08..4963aaa21d4 100644 --- a/addons/medical_blood/functions/fnc_onBleeding.sqf +++ b/addons/medical_blood/functions/fnc_onBleeding.sqf @@ -25,7 +25,7 @@ if !(_unit call FUNC(isBleeding)) exitWith {}; if (!isNull objectParent _unit && {!(vehicle _unit isKindOf "StaticWeapon")}) exitWith {}; if (CBA_missionTime > (_unit getVariable [QGVAR(nextTime), -10])) then { - private _bloodLoss = (if (GVAR(useAceMedical)) then {GET_BLOOD_LOSS(_unit) * 2.5} else {getDammage _unit * 2}) min 6; + private _bloodLoss = ([damage _unit * 2, GET_BLOOD_LOSS(_unit) * 2.5] select GETEGVAR(medical,enabled,false)) min 6; _unit setVariable [QGVAR(nextTime), CBA_missionTime + 8 + random 2 - _bloodLoss]; TRACE_2("Creating blood drop for bleeding unit",_unit,_bloodLoss); diff --git a/addons/medical_damage/stringtable.xml b/addons/medical_damage/stringtable.xml index 626826117db..3f274dd37a4 100644 --- a/addons/medical_damage/stringtable.xml +++ b/addons/medical_damage/stringtable.xml @@ -803,6 +803,7 @@ Schmerz-Bewusstlosigkeit-Grenze 고통 기절 한계점 Limite de Dor Antes da Inconsciência + Umbral de Dolor de Inconsciencia Sets the threshold for severe pain, above which a person can fall unconscious upon receiving damage. @@ -814,6 +815,7 @@ Legt die Grenze für starke Schmerzen fest, oberhalb derer eine Person bei erlittenem Schaden bewusstlos werden kann. 사람이 데미지를 입었을 때 의식불명 상태가 될 수 있는 심각한 고통의 한계점을 설정합니다. Define o limite para dor severa, acima do qual uma pessoa pode ficar inconsciente ao receber dano. + Establece el umbral para dolor severo, sobre el cual una persona puede caer inconsciente una vez reciba daño. Fatal Injury Death Chance diff --git a/addons/medical_engine/XEH_postInit.sqf b/addons/medical_engine/XEH_postInit.sqf index 2514c62254f..ed660914984 100644 --- a/addons/medical_engine/XEH_postInit.sqf +++ b/addons/medical_engine/XEH_postInit.sqf @@ -6,27 +6,23 @@ [_new] call FUNC(updateDamageEffects); // Run on new controlled unit to update QGVAR(aimFracture) }, true] call CBA_fnc_addPlayerEventHandler; - ["CAManBase", "init", { params ["_unit"]; - // Check if last hit point is our dummy. - private _allHitPoints = getAllHitPointsDamage _unit param [0, []]; - reverse _allHitPoints; - while {(_allHitPoints param [0, ""]) select [0,1] == "#"} do { WARNING_1("Ignoring Reflector hitpoint %1",_allHitPoints deleteAt 0); }; + if (unitIsUAV _unit) exitWith {TRACE_1("ignore UAV AI",typeOf _unit);}; + if (getNumber (configOf _unit >> "isPlayableLogic") == 1) exitWith {TRACE_1("ignore logic unit",typeOf _unit);}; - if (_allHitPoints param [0, ""] != "ACE_HDBracket") then { - if (unitIsUAV _unit) exitWith {TRACE_1("ignore UAV AI",typeOf _unit);}; - if (getNumber ((configOf _unit) >> "isPlayableLogic") == 1) exitWith {TRACE_1("ignore logic unit",typeOf _unit)}; + private _allHitPoints = getAllHitPointsDamage _unit param [0, []]; + if ((GVAR(customHitpoints) arrayIntersect _allHitPoints) isNotEqualTo GVAR(customHitpoints)) exitWith { ERROR_1("Bad hitpoints for unit type ""%1""",typeOf _unit); - } else { - // Calling this function inside curly brackets allows the usage of - // "exitWith", which would be broken with "HandleDamage" otherwise. - _unit setVariable [ - QEGVAR(medical,HandleDamageEHID), - _unit addEventHandler ["HandleDamage", {_this call FUNC(handleDamage)}] - ]; }; + + // Calling this function inside curly brackets allows the usage of + // "exitWith", which would be broken with "HandleDamage" otherwise. + _unit setVariable [ + QEGVAR(medical,HandleDamageEHID), + _unit addEventHandler ["HandleDamage", {_this call FUNC(handleDamage)}] + ]; }, nil, [IGNORE_BASE_UAVPILOTS], true] call CBA_fnc_addClassEventHandler; #ifdef DEBUG_MODE_FULL @@ -88,7 +84,7 @@ }; }] call CBA_fnc_addEventHandler; -["CAManBase", "deleted", { +["CAManBase", "Deleted", { params ["_unit"]; TRACE_3("unit deleted",_unit,objectParent _unit,local _unit); if ((!isNull objectParent _unit) && {local objectParent _unit}) then { diff --git a/addons/medical_engine/XEH_preInit.sqf b/addons/medical_engine/XEH_preInit.sqf index b0304f167f1..035b9f4b052 100644 --- a/addons/medical_engine/XEH_preInit.sqf +++ b/addons/medical_engine/XEH_preInit.sqf @@ -40,11 +40,14 @@ GVAR(armorCache) = createHashMap; // with handle damage not returning full results. GVAR(fixedStatics) = []; -GVAR(animations) = [] call CBA_fnc_createNamespace; -GVAR(animations) setVariable [QUNCON_ANIM(faceUp), [QUNCON_ANIM(2),QUNCON_ANIM(2_1),QUNCON_ANIM(7_1),QUNCON_ANIM(8_1),QUNCON_ANIM(5_1),QUNCON_ANIM(6_1)]]; -GVAR(animations) setVariable [QUNCON_ANIM(faceDown), [QUNCON_ANIM(1),QUNCON_ANIM(3),QUNCON_ANIM(4),"unconscious",QUNCON_ANIM(9),QUNCON_ANIM(3_1),QUNCON_ANIM(4_1)]]; -GVAR(animations) setVariable [QUNCON_ANIM(faceLeft), [QUNCON_ANIM(7),QUNCON_ANIM(8),QUNCON_ANIM(1_1),QUNCON_ANIM(7_1),QUNCON_ANIM(8_1)]]; -GVAR(animations) setVariable [QUNCON_ANIM(faceRight), [QUNCON_ANIM(5),QUNCON_ANIM(6),QUNCON_ANIM(10),QUNCON_ANIM(5_1),QUNCON_ANIM(6_1)]]; +GVAR(animations) = createHashMapFromArray [ + [toLowerANSI QUNCON_ANIM(faceUp), [QUNCON_ANIM(2),QUNCON_ANIM(2_1),QUNCON_ANIM(7_1),QUNCON_ANIM(8_1),QUNCON_ANIM(5_1),QUNCON_ANIM(6_1)]], + [toLowerANSI QUNCON_ANIM(faceDown), [QUNCON_ANIM(1),QUNCON_ANIM(3),QUNCON_ANIM(4),"unconscious",QUNCON_ANIM(9),QUNCON_ANIM(3_1),QUNCON_ANIM(4_1)]], + [toLowerANSI QUNCON_ANIM(faceLeft), [QUNCON_ANIM(7),QUNCON_ANIM(8),QUNCON_ANIM(1_1),QUNCON_ANIM(7_1),QUNCON_ANIM(8_1)]], + [toLowerANSI QUNCON_ANIM(faceRight), [QUNCON_ANIM(5),QUNCON_ANIM(6),QUNCON_ANIM(10),QUNCON_ANIM(5_1),QUNCON_ANIM(6_1)]] +]; + +GVAR(customHitpoints) = ["hitleftarm", "hitrightarm", "hitleftleg", "hitrightleg"]; private _fnc_fixStatic = { params ["_vehicle"]; @@ -84,4 +87,7 @@ addMissionEventHandler ["Loaded", { [] call FUNC(disableThirdParty); +// Future-proofing +EGVAR(medical,enabled) = true; // TODO: remove when medical enable setting is implemented + ADDON = true; diff --git a/addons/medical_engine/functions/fnc_applyAnimAfterRagdoll.sqf b/addons/medical_engine/functions/fnc_applyAnimAfterRagdoll.sqf index db522b2bf72..726a606344a 100644 --- a/addons/medical_engine/functions/fnc_applyAnimAfterRagdoll.sqf +++ b/addons/medical_engine/functions/fnc_applyAnimAfterRagdoll.sqf @@ -23,7 +23,7 @@ if !(IS_UNCONSCIOUS(_unit) && // do not run if unit is conscio {alive _unit && // do not run if unit is dead {isNull objectParent _unit}}) exitWith {}; // do not run if unit in any vehicle -private _animsArray = GVAR(animations) getVariable [_anim, [""]]; +private _animsArray = GVAR(animations) getOrDefault [toLowerANSI _anim, [""]]; private _random = (toArray (hashValue _unit)) param [0, 0]; private _index = _random % (count _animsArray); private _unconsciousAnimation = _animsArray select _index; diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index a60816222fb..168203366c2 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -1,9 +1,9 @@ #include "..\script_component.hpp" /* - * Author: commy2, kymckay + * Author: commy2, kymckay, LinkIsGrim * HandleDamage EH where wound events are raised based on incoming damage. * Be aware that for each source of damage, the EH can fire multiple times (once for each hitpoint). - * We store these incoming damages and compare them on our final hitpoint: "ace_hdbracket". + * We store these incoming damages and compare them on last iteration of the event (_context == 2). * * Arguments: * Handle damage EH @@ -13,15 +13,16 @@ * * Public: No */ -params ["_unit", "_selection", "_damage", "_shooter", "_ammo", "_hitPointIndex", "_instigator", "_hitpoint"]; +params ["_unit", "_selection", "_damage", "_shooter", "_ammo", "_hitPointIndex", "_instigator", "_hitpoint", "_directHit", "_context"]; // HD sometimes triggers for remote units - ignore. if !(local _unit) exitWith {nil}; // Get missing meta info private _oldDamage = 0; +private _structuralDamage = _context == 0; -if (_hitPoint isEqualTo "") then { +if (_structuralDamage) then { _hitPoint = "#structural"; _oldDamage = damage _unit; } else { @@ -33,26 +34,29 @@ if !(isDamageAllowed _unit && {_unit getVariable [QEGVAR(medical,allowDamage), t private _newDamage = _damage - _oldDamage; -// Happens occasionally for vehiclehit events (see line 80 onwards) -// Just exit early to save some frametime -if (_newDamage == 0 && {_hitpoint isNotEqualTo "ace_hdbracket"}) exitWith {_oldDamage}; +// _newDamage == 0 happens occasionally for vehiclehit events (see line 80 onwards), just exit early to save some frametime +// context 4 is engine "bleeding". For us, it's just a duplicate event for #structural which we can ignore without any issues +if (_context != 2 && {_context == 4 || _newDamage == 0}) exitWith { + TRACE_4("Skipping engine bleeding or zero damage",_ammo,_newDamage,_directHit,_context); + _oldDamage +}; // Get scaled armor value of hitpoint and calculate damage before armor // We scale using passThrough to handle explosive-resistant armor properly (#9063) // We need realDamage to determine which limb was hit correctly [_unit, _hitpoint] call FUNC(getHitpointArmor) params ["_armor", "_armorScaled"]; private _realDamage = _newDamage * _armor; -if (_hitPoint isNotEqualTo "#structural") then { +if (!_structuralDamage) then { private _armorCoef = _armor/_armorScaled; private _damageCoef = linearConversion [0, 1, GVAR(damagePassThroughEffect), 1, _armorCoef]; _newDamage = _newDamage * _damageCoef; }; -TRACE_4("Received hit",_hitpoint,_ammo,_newDamage,_realDamage); +TRACE_6("Received hit",_hitpoint,_ammo,_newDamage,_realDamage,_directHit,_context); -// Drowning doesn't fire the EH for each hitpoint so the "ace_hdbracket" code never runs +// Drowning doesn't fire the EH for each hitpoint and never triggers _context=2 (LastHitPoint) // Damage occurs in consistent increments if ( - _hitPoint isEqualTo "#structural" && + _structuralDamage && {getOxygenRemaining _unit <= 0.5} && {_damage isEqualTo (_oldDamage + 0.005)} ) exitWith { @@ -64,14 +68,14 @@ if ( // Faster than (vehicle _unit), also handles dead units private _vehicle = objectParent _unit; +private _inVehicle = !isNull _vehicle; +private _environmentDamage = _ammo == ""; -// Crashing a vehicle doesn't fire the EH for each hitpoint so the "ace_hdbracket" code never runs +// Crashing a vehicle doesn't fire the EH for each hitpoint and never triggers _context=2 (LastHitPoint) // It does fire the EH multiple times, but this seems to scale with the intensity of the crash if ( EGVAR(medical,enableVehicleCrashes) && - {_hitPoint isEqualTo "#structural"} && - {_ammo isEqualTo ""} && - {!isNull _vehicle} && + {_environmentDamage && _inVehicle && _structuralDamage} && {vectorMagnitude (velocity _vehicle) > 5} // todo: no way to detect if stationary and another vehicle hits you ) exitWith { @@ -83,11 +87,8 @@ if ( // Receiving explosive damage inside a vehicle doesn't trigger for each hitpoint // This is the case for mines, explosives, artillery, and catasthrophic vehicle explosions -// Triggers twice, but that doesn't matter as damage is low if ( - _hitPoint isEqualTo "#structural" && - {!isNull _vehicle} && - {_ammo isNotEqualTo ""} && + (!_environmentDamage && _inVehicle && _structuralDamage) && { private _ammoCfg = configFile >> "CfgAmmo" >> _ammo; GET_NUMBER(_ammoCfg >> "explosive",0) > 0 || @@ -104,9 +105,13 @@ if ( 0 }; -// This hitpoint is set to trigger last, evaluate all the stored damage values -// to determine where wounds are applied -if (_hitPoint isEqualTo "ace_hdbracket") exitWith { +// Damages are stored for last iteration of the HandleDamage event (_context == 2) +_unit setVariable [format [QGVAR($%1), _hitPoint], [_realDamage, _newDamage]]; + +// Ref https://community.bistudio.com/wiki/Arma_3:_Event_Handlers#HandleDamage +// Context 2 means this is the last iteration of HandleDamage, so figure out which hitpoint took the most real damage and send wound event +// Don't exit, as the last iteration can be one of the hitpoints that we need to keep _oldDamage for +if (_context == 2) then { _unit setVariable [QEGVAR(medical,lastDamageSource), _shooter]; _unit setVariable [QEGVAR(medical,lastInstigator), _instigator]; @@ -157,7 +162,7 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { // Environmental damage sources all have empty ammo string // No explicit source given, we infer from differences between them - if (_ammo isEqualTo "") then { + if (_environmentDamage) then { // Any collision with terrain/vehicle/object has a shooter // Check this first because burning can happen at any velocity if !(isNull _shooter) then { @@ -199,16 +204,9 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { QGVAR($HitLeftArm),QGVAR($HitRightArm),QGVAR($HitLeftLeg),QGVAR($HitRightLeg), QGVAR($#structural) ]; - - 0 }; -// Damages are stored for "ace_hdbracket" event triggered last -_unit setVariable [format [QGVAR($%1), _hitPoint], [_realDamage, _newDamage]]; - // Engine damage to these hitpoints controls blood visuals, limping, weapon sway // Handled in fnc_damageBodyPart, persist here -if (_hitPoint in ["hithead", "hitbody", "hithands", "hitlegs"]) exitWith {_oldDamage}; - -// We store our own damage values so engine damage is unnecessary -0 +// For all other hitpoints, we store our own damage values, so engine damage is unnecessary +[0, _oldDamage] select (_hitPoint in ["hithead", "hitbody", "hithands", "hitlegs"]) diff --git a/addons/medical_engine/script_macros_config.hpp b/addons/medical_engine/script_macros_config.hpp index 611a8ad3569..4c276d7b186 100644 --- a/addons/medical_engine/script_macros_config.hpp +++ b/addons/medical_engine/script_macros_config.hpp @@ -20,13 +20,6 @@ // This used to take the armor values as parameters; it now inherits the values // of `armor`, `passThrough` and `explosionShielding` from the existing hitpoints // for vanilla consistency. -// "ACE_HDBracket" is a special hit point. It is designed in a way where the -// "HandleDamage" event handler will compute it at the end of every damage -// calculation step. This way we can figure out which hit point took the most -// damage from one projectile and should be receiving the ACE medical wound. -// the hit point itself should not take any damage -// It is important that the "ACE_HDBracket" hit point is the last in the config, -// but has the same selection as the first one (always "HitHead" for soldiers). #define ADD_ACE_HITPOINTS\ class HitLeftArm: HitHands {\ material = -1;\ @@ -47,15 +40,4 @@ };\ class HitRightLeg: HitLeftLeg {\ name = "leg_r";\ - };\ - class ACE_HDBracket {\ - armor = 1;\ - material = -1;\ - name = "head";\ - passThrough = 0;\ - radius = 1;\ - explosionShielding = 1;\ - visual = "";\ - minimalHit = 0;\ - depends = "HitHead";\ } diff --git a/addons/medical_engine/stringtable.xml b/addons/medical_engine/stringtable.xml index 1765df0d39d..cf197132029 100644 --- a/addons/medical_engine/stringtable.xml +++ b/addons/medical_engine/stringtable.xml @@ -37,6 +37,7 @@ Efeito de Penetração de Blindagem 装甲貫通効果 Эффект сквозного прохождения брони + Efecto de Atravesar Armadura Controls effect of armor 'passThrough' on final damage. Makes high armor values, like ones used in GL rigs, less effective.\nUse 0% for pre 3.16.0 armor behavior.\nOnly touch this if you know what you're doing! @@ -48,6 +49,7 @@ Controla o efeito de penetração (passThrough) da blindagem no dano final. Torna valores de blindagem altos, como os usados em coletes GL, menos eficazes.\nUse 0% para o comportamento de blindagem anterior à versão 3.16.0.\nSó mexa nisso se souber o que está fazendo! ボディアーマーの'passThrough'値が最終的な身体ダメージに与える影響を調整します。擲弾兵リグで使用されるような高い装甲値では効果が低くなります。\n3.16.0以前の挙動にするには0%にしてください。\nこれが何かわからない場合は変更しないことをお勧めします。 Контролирует эффект `passThrough` при нанесении конечного урона. Делает высокие значения брони, подобные тем, которые используются в GL rigs, менее эффективными.\nИспользуйте 0% для поведения брони до версии 3.16.0.n\Прикасайтесь к этому, только если знаете, что делаете! + Controla el efecto de 'passThrough' de armadura en el daño final. Hace que los valores altos de armadura, como los usados en los chalecos GL, sean menos efectivos.\nUsar 0% para comportamiento de armadura en versiones anteriores a 3.16.0.\nSólo modifica esto si sabes lo que estás haciendo! diff --git a/addons/medical_gui/XEH_postInit.sqf b/addons/medical_gui/XEH_postInit.sqf index 5ff49d21676..2b7fb8ce523 100644 --- a/addons/medical_gui/XEH_postInit.sqf +++ b/addons/medical_gui/XEH_postInit.sqf @@ -21,7 +21,7 @@ GVAR(selfInteractionActions) = []; [QEGVAR(interact_menu,newControllableObject), { params ["_type"]; // string of the object's classname - if (!(_type isKindOf "CAManBase")) exitWith {}; + if !(_type isKindOf "CAManBase") exitWith {}; { _x set [0, _type]; _x call EFUNC(interact_menu,addActionToClass); diff --git a/addons/medical_gui/stringtable.xml b/addons/medical_gui/stringtable.xml index 71388bfb41b..b88d9cbbf16 100644 --- a/addons/medical_gui/stringtable.xml +++ b/addons/medical_gui/stringtable.xml @@ -293,6 +293,7 @@ Medizinische Info anzeigen 医療情報一時表示 Просмотр медицинской информации + Ojear Información Médica Medical Peek Duration @@ -303,6 +304,7 @@ Dauer zum Anzeigen der medizinischen Info 医療情報一時表示の表示時間 Продолжительность медицинского осмотра + Duración del Ojear Información Médica How long the medical info peek remains open after releasing the key. @@ -313,6 +315,7 @@ Durata di visualizzazione delle Info Mediche dopo aver rilasciato il tasto. 医療情報一時表示キーを放してからどれだけ長く情報表示するか。 Как долго окно просмотра медицинской информации остается открытым после отпускания клавиши. + Durante cuánto tiempo la información médica ojeada permanece abierta una ves se deje de apretar la tecla. Load Patient @@ -566,6 +569,7 @@ Passa a te stesso 自分に切り替え Переключиться на себя + Cambiar a uno mismo Switch to target @@ -576,6 +580,7 @@ Passa al paziente 相手に切り替え Переключиться на цель + Cambiar al objetivo Head @@ -1002,6 +1007,7 @@ Nessuna emorragia 出血はしていない Кровотечения нет + Sin sangrado Slow bleeding @@ -1012,6 +1018,7 @@ Debole emorragia 出血は穏やか Медленное кровотечение + Sangrado lento Moderate bleeding @@ -1022,6 +1029,7 @@ Emorraggia moderata 出血はそこそこ速い Умеренное кровотечение + Sangrado moderado Severe bleeding @@ -1032,6 +1040,7 @@ Forte emorragia 出血は激しい Сильное кровотечение + Sangrado severo Massive bleeding @@ -1042,6 +1051,7 @@ Gravissima emorragia 出血は酷く多い Огромное кровотечение + Sangrado masivo in Pain @@ -1116,6 +1126,7 @@ Nessuna perdita di sangue 失血なし Потери крови нет + Sin pérdida de sangre @@ -1400,6 +1411,7 @@ Zeige medizinische Info beim Treffer an 被弾時の医療情報一時表示 Показать медицинскую информацию о попадании + Ojear Información Médica en Impacto Temporarily show medical info when injured. @@ -1411,6 +1423,7 @@ Bei Verletzungen vorübergehend medizinische Info anzeigen. 被弾時に医療情報を一時的に表示します。 Временно показывать медицинскую информацию при травме. + Temporalmente muestra la información médica cuando es herido. Medical Peek Duration on Hit @@ -1422,6 +1435,7 @@ Dauer der Anzeige bei einem Treffer. 被弾時の医療情報一時表示の表示時間 Продолжительность медицинского осмотра при попадании + Duración de Ojear la Información Médica cuando hay Impacto How long the medical info peek remains open after being injured. @@ -1433,6 +1447,7 @@ Wie lange die medizinische Info nach einer Verletzung angezeigt wird. 被弾時の医療情報の一時表示をどれだけ長く表示するか。 Как долго окно просмотра медицинской информации остается открытым после получения травмы. + Durante cuánto tiempo la información médica ojeada permanece abierta una tras haber sido herido. Show Trauma Sustained @@ -1445,6 +1460,7 @@ 显示遭受的创伤 Afficher les traumatismes subis Показать полученную травму + Mostrar Trauma Sostenido Show trauma sustained in the injury list. @@ -1457,6 +1473,7 @@ 在伤情表上显示创伤 Afficher les traumatismes subis dans la liste des blessures. Показать полученную травму в списке травм. + Mostrar trauma sostenido en la lista de heridas Body Part Outline Color @@ -1468,6 +1485,7 @@ Umrissfarbe des Körperteils 身体部位の輪郭表示の色 Цвет контура части тела + Color de Contorno de las Partes del Cuerpo Color of outline around selected body part. @@ -1479,6 +1497,7 @@ Farbe des Umrisses um das ausgewählten Körperteil. 選択した身体部位の輪郭表示の色。 Цвет контура вокруг выбранной части тела. + Color del contorno alrededor de la parte del cuerpo seleccionada. Minor Trauma @@ -1491,6 +1510,7 @@ 轻微创伤 Traumatisme mineur Незначительная травма + Trauma Menor Major Trauma @@ -1503,6 +1523,7 @@ 中度创伤 Traumatisme majeur Серьезная травма + Trauma mayor Severe Trauma @@ -1515,6 +1536,7 @@ 重度创伤 Traumatisme grave Тяжелая травма + Trauma Severo Chronic Trauma @@ -1527,6 +1549,7 @@ 慢性创伤 Traumatisme chronique Хроническая травма + Trauma Crónico L @@ -1538,6 +1561,7 @@ L Лево + I R @@ -1549,6 +1573,7 @@ R Право + D in your inventory @@ -1560,6 +1585,7 @@ im Inventar 個あなたが保有 в вашем инвентаре + en tu inventario in patient's inventory @@ -1571,6 +1597,7 @@ im Inventar des Patienten 個患者が保有 в инвентаре пациента + en el inventario del paciente in vehicle's inventory @@ -1582,6 +1609,7 @@ Nell'inventario del veicolo 個車両内に保有 в инвентаре транспорта + en el inventario del vehículo No effect until tourniquet removed @@ -1592,6 +1620,7 @@ Nessun effetto fino alla rimozione del laccio emostatico 止血帯を外すまで効果を発揮しません Никакого эффекта до тех пор, пока жгут не будет снят + Sin efecto hasta que se quita el torniquete Show Tourniquet Warning @@ -1602,6 +1631,7 @@ Mostra avviso di laccio emostatico 止血帯の警告を表示 Показать предупреждение о наложении жгута + Mostrar Advertencia de Torniquete Show a warning tooltip when a tourniquet will interfere with a medical action. @@ -1612,6 +1642,7 @@ Mostra un avviso se un laccio emostatico impedisce un trattamento medico. 止血帯が医療行為を妨げる場合には、警告ツールチップを表示します。 Показать всплывающую подсказку с предупреждением, когда жгут помешает медицинскому вмешательству. + Muestra un mensaje de advertencia cuando un torniquete interfiera con una acción médica. diff --git a/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf b/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf index 537c3566519..8be1d358df4 100644 --- a/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf +++ b/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf @@ -25,6 +25,7 @@ if (isNull _unit || {!isNil {_unit getVariable QEGVAR(medical,causeOfDeath)}}) e TRACE_4("enteredStateDeath",_this,_thisOrigin,_thisTransition,CBA_missionTime); private _causeOfDeath = format ["%1:%2", _thisOrigin, _thisTransition]; +private _source = _unit getVariable [QEGVAR(medical,lastDamageSource), objNull]; private _instigator = _unit getVariable [QEGVAR(medical,lastInstigator), objNull]; -[_unit, _causeOfDeath, _instigator] call EFUNC(medical_status,setDead); +[_unit, _causeOfDeath, _source, _instigator] call EFUNC(medical_status,setDead); diff --git a/addons/medical_status/functions/fnc_setDead.sqf b/addons/medical_status/functions/fnc_setDead.sqf index cb1e1f1d6f8..138948c0386 100644 --- a/addons/medical_status/functions/fnc_setDead.sqf +++ b/addons/medical_status/functions/fnc_setDead.sqf @@ -7,6 +7,7 @@ * 0: The unit * 1: Reason for death * 2: Killer + * 3: Instigator * * Return Value: * None @@ -14,9 +15,8 @@ * Public: No */ -params ["_unit", ["_reason", "#setDead"], ["_instigator", objNull]]; -TRACE_3("setDead",_unit,_reason,_instigator); - +params ["_unit", ["_reason", "#setDead"], ["_source", objNull], ["_instigator", objNull]]; +TRACE_4("setDead",_unit,_reason,_source,_instigator); // No heart rate or blood pressure to measure when dead _unit setVariable [VAR_HEART_RATE, 0, true]; @@ -38,7 +38,7 @@ if (_unitState isNotEqualTo "Dead") then { // (#8803) Reenable damage if disabled to prevent having live units in dead state // Keep this after death event for compatibility with third party hooks -if !(isDamageAllowed _unit) then { +if (!isDamageAllowed _unit) then { WARNING_1("setDead executed on unit with damage blocked - %1",_this); _unit allowDamage true; }; @@ -46,6 +46,6 @@ if !(isDamageAllowed _unit) then { // Kill the unit without changing visual apperance private _prevDamage = _unit getHitPointDamage "HitHead"; -_unit setHitPointDamage ["HitHead", 1, true, _instigator]; +_unit setHitPointDamage ["HitHead", 1, true, _source, _instigator]; -_unit setHitPointDamage ["HitHead", _prevDamage]; +_unit setHitPointDamage ["HitHead", _prevDamage, true, _source, _instigator]; diff --git a/addons/medical_status/stringtable.xml b/addons/medical_status/stringtable.xml index f6f51b55338..ea3f77429b2 100644 --- a/addons/medical_status/stringtable.xml +++ b/addons/medical_status/stringtable.xml @@ -126,6 +126,7 @@ Risque de perte d'arme 武器を落とす確率 Шанс выпадения оружия + Probabilidad de Soltar Arma Chance for a player to drop their weapon when going unconscious.\nHas no effect on AI. @@ -136,6 +137,7 @@ Pourcentage de chances pour un joueur de lâcher son arme lorsqu'il perd connaissance.\nAucun effet sur les IA. プレーヤーが意識を失ったときに武器を落とす可能性。\nAI には影響しません。 Шанс для игрока выронить свое оружие, когда он теряет сознание.\nНе влияет на ИИ + Probabilidad del jugador de soltar su arma cuando quedan inconscientes.\nNo tiene efecto sobre la IA. diff --git a/addons/medical_treatment/XEH_preInit.sqf b/addons/medical_treatment/XEH_preInit.sqf index bc01e267c1b..e6210a73729 100644 --- a/addons/medical_treatment/XEH_preInit.sqf +++ b/addons/medical_treatment/XEH_preInit.sqf @@ -14,27 +14,23 @@ PREP_RECOMPILE_END; // adjusting these is trail and error // if the animation is cut of ingame, increase these values // if the unit idles too much, decrease them -GVAR(animDurations) = [] call CBA_fnc_createNamespace; - -{ - GVAR(animDurations) setVariable _x; -} forEach [ - ["AinvPknlMstpSlayWnonDnon_medic", 7.5], - ["AinvPpneMstpSlayWnonDnon_medic", 7], - ["AinvPknlMstpSlayWrflDnon_medic", 7], - ["AinvPpneMstpSlayWrflDnon_medic", 9.5], - ["AinvPknlMstpSlayWlnrDnon_medic", 9], - ["AinvPknlMstpSlayWpstDnon_medic", 9.5], - ["AinvPpneMstpSlayWpstDnon_medic", 10], - ["AinvPknlMstpSlayWnonDnon_medicOther", 8.5], - ["AinvPpneMstpSlayWnonDnon_medicOther", 8.5], - ["AinvPknlMstpSlayWrflDnon_medicOther", 7], - ["AinvPpneMstpSlayWrflDnon_medicOther", 9], - ["AinvPknlMstpSlayWlnrDnon_medicOther", 9], - ["AinvPknlMstpSlayWpstDnon_medicOther", 10], - ["AinvPpneMstpSlayWpstDnon_medicOther", 8.5], - ["AinvPknlMstpSnonWnonDnon_medic1", 10], - ["AinvPknlMstpSnonWnonDr_medic0", 12] +GVAR(animDurations) = createHashMapFromArray [ + ["ainvpknlmstpslaywnondnon_medic", 7.5], + ["ainvppnemstpslaywnondnon_medic", 7], + ["ainvpknlmstpslaywrfldnon_medic", 7], + ["ainvppnemstpslaywrfldnon_medic", 9.5], + ["ainvpknlmstpslaywlnrdnon_medic", 9], + ["ainvpknlmstpslaywpstdnon_medic", 9.5], + ["ainvppnemstpslaywpstdnon_medic", 10], + ["ainvpknlmstpslaywnondnon_medicother", 8.5], + ["ainvppnemstpslaywnondnon_medicother", 8.5], + ["ainvpknlmstpslaywrfldnon_medicother", 7], + ["ainvppnemstpslaywrfldnon_medicother", 9], + ["ainvpknlmstpslaywlnrdnon_medicother", 9], + ["ainvpknlmstpslaywpstdnon_medicother", 10], + ["ainvppnemstpslaywpstdnon_medicother", 8.5], + ["ainvpknlmstpsnonwnondnon_medic1", 10], + ["ainvpknlmstpsnonwnondr_medic0", 12] ]; // class names of medical facilities (config case) diff --git a/addons/medical_treatment/functions/fnc_checkPulseLocal.sqf b/addons/medical_treatment/functions/fnc_checkPulseLocal.sqf index 3798e64eb4f..bb3efedc221 100644 --- a/addons/medical_treatment/functions/fnc_checkPulseLocal.sqf +++ b/addons/medical_treatment/functions/fnc_checkPulseLocal.sqf @@ -21,7 +21,7 @@ params ["_medic", "_patient", "_bodyPart"]; private _heartRate = 0; -if (!([_patient, _bodyPart] call FUNC(hasTourniquetAppliedTo))) then { +if !([_patient, _bodyPart] call FUNC(hasTourniquetAppliedTo)) then { _heartRate = switch (true) do { case (alive _patient): { GET_HEART_RATE(_patient) diff --git a/addons/medical_treatment/functions/fnc_checkResponse.sqf b/addons/medical_treatment/functions/fnc_checkResponse.sqf index dc76b1dbfbe..ca95fcb1d16 100644 --- a/addons/medical_treatment/functions/fnc_checkResponse.sqf +++ b/addons/medical_treatment/functions/fnc_checkResponse.sqf @@ -22,6 +22,11 @@ params ["_medic", "_patient"]; private _output = if (_patient call EFUNC(common,isAwake)) then { LSTRING(Check_Response_Responsive) } else { + if (GVAR(advancedDiagnose) == 3) exitWith { + if (IN_CRDC_ARRST(_patient)) exitWith { LSTRING(Check_Response_CardiacArrestDirect) }; + if (!alive _patient) exitWith { LSTRING(Check_Response_DeadDirect) }; + LSTRING(Check_Response_UnresponsiveDirect) + }; if ((GVAR(advancedDiagnose) == 2) && {IN_CRDC_ARRST(_patient)}) exitWith { LSTRING(Check_Response_CardiacArrest) }; if ((GVAR(advancedDiagnose) == 2) && {!alive _patient}) exitWith { LSTRING(Check_Response_Dead) }; LSTRING(Check_Response_Unresponsive) diff --git a/addons/medical_treatment/functions/fnc_cprLocal.sqf b/addons/medical_treatment/functions/fnc_cprLocal.sqf index 228774b2f63..e6b12990270 100644 --- a/addons/medical_treatment/functions/fnc_cprLocal.sqf +++ b/addons/medical_treatment/functions/fnc_cprLocal.sqf @@ -24,9 +24,14 @@ TRACE_2("cprLocal",_medic,_patient); private _bloodVolume = GET_BLOOD_VOLUME(_patient); private _successChance = linearConversion [BLOOD_VOLUME_CLASS_4_HEMORRHAGE, BLOOD_VOLUME_CLASS_2_HEMORRHAGE, _bloodVolume, GVAR(cprSuccessChanceMin), GVAR(cprSuccessChanceMax), true]; if ((random 1) < _successChance) then { + // If SpO2 is too low, it will make HR skyrocket to the point where patient goes back into CA + // Allow 3rd party mods to disable this mechanic + if (missionNamespace getVariable [QGVAR(setSpO2UponCPRSuccess), true] && {GET_SPO2(_patient) < DEFAULT_SPO2 / 2}) then { + _patient setVariable [VAR_SPO2, DEFAULT_SPO2 / 2, true]; + }; + TRACE_2("CPR random success",_bloodVolume,_successChance); [QEGVAR(medical,CPRSucceeded), _patient] call CBA_fnc_localEvent; } else { TRACE_2("CPR random fail",_bloodVolume,_successChance); }; - diff --git a/addons/medical_treatment/functions/fnc_fullHealLocal.sqf b/addons/medical_treatment/functions/fnc_fullHealLocal.sqf index dc95c44185a..42c5866a9af 100644 --- a/addons/medical_treatment/functions/fnc_fullHealLocal.sqf +++ b/addons/medical_treatment/functions/fnc_fullHealLocal.sqf @@ -77,12 +77,12 @@ _patient setVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0], true]; // wakeup needs to be done after achieving stable vitals, but before manually reseting unconc var if IS_UNCONSCIOUS(_patient) then { - if (!([_patient] call EFUNC(medical_status,hasStableVitals))) then { ERROR_2("fullheal [unit %1][state %2] did not restore stable vitals",_patient,_state); }; + if !([_patient] call EFUNC(medical_status,hasStableVitals)) then {ERROR_2("fullheal [unit %1][state %2] did not restore stable vitals",_patient,_state);}; TRACE_1("Waking up",_patient); [QEGVAR(medical,WakeUp), _patient] call CBA_fnc_localEvent; _state = GET_SM_STATE(_patient); TRACE_1("after WakeUp",_state); - if IS_UNCONSCIOUS(_patient) then { ERROR_2("fullheal [unit %1][state %2] failed to wake up patient",_patient,_state); }; + if IS_UNCONSCIOUS(_patient) then {ERROR_2("fullheal [unit %1][state %2] failed to wake up patient",_patient,_state);}; }; // Generic medical admin diff --git a/addons/medical_treatment/functions/fnc_treatment.sqf b/addons/medical_treatment/functions/fnc_treatment.sqf index c524fd7ebb1..5f6df40e31c 100644 --- a/addons/medical_treatment/functions/fnc_treatment.sqf +++ b/addons/medical_treatment/functions/fnc_treatment.sqf @@ -76,7 +76,7 @@ if (_medic isNotEqualTo player || {!_isInZeus}) then { }; // Determine the animation length - private _animDuration = GVAR(animDurations) getVariable _medicAnim; + private _animDuration = GVAR(animDurations) get toLowerANSI _medicAnim; if (isNil "_animDuration") then { WARNING_2("animation [%1] for [%2] has no duration defined",_medicAnim,_classname); _animDuration = 10; diff --git a/addons/medical_treatment/initSettings.inc.sqf b/addons/medical_treatment/initSettings.inc.sqf index fbb1b170c81..d080965eb9e 100644 --- a/addons/medical_treatment/initSettings.inc.sqf +++ b/addons/medical_treatment/initSettings.inc.sqf @@ -3,7 +3,7 @@ "LIST", [LSTRING(AdvancedDiagnose_DisplayName), LSTRING(AdvancedDiagnose_Description)], [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], - [[0, 1, 2], [ELSTRING(common,Disabled), ELSTRING(common,Enabled), LSTRING(AdvancedDiagnose_DiagnoseCardiacArrest)], 1], + [[0, 1, 2, 3], [ELSTRING(common,Disabled), ELSTRING(common,Enabled), LSTRING(AdvancedDiagnose_DiagnoseCardiacArrest), LSTRING(AdvancedDiagnose_DiagnoseCardiacArrestDirect)], 1], true ] call CBA_fnc_addSetting; diff --git a/addons/medical_treatment/stringtable.xml b/addons/medical_treatment/stringtable.xml index 29774efb3ca..8b8cc640ebf 100644 --- a/addons/medical_treatment/stringtable.xml +++ b/addons/medical_treatment/stringtable.xml @@ -77,6 +77,10 @@ Habilitado y poder diagnosticar Muerte/Parada cardíaca Abilitato e può diagnosticare Morte/Arresto Cardiaco + + Enabled & Can Diagnose Death/Cardiac Arrest [Directly] + 有効 & 死亡/心停止状態を診断可能 [直接的に] + Advanced Medication Erweiterte Medikation @@ -439,6 +443,7 @@ Tempo di scavo tomba 墓掘りの所要時間 Время рытья могилы + Tiempo de Cavado de Tumba Time, in seconds, required to dig a grave for a body. @@ -449,6 +454,7 @@ Tempo in secondi richiesto per seppellire un morto. 遺体の墓を掘るのに掛かる時間。 (秒単位) Время в секундах, необходимое для того, чтобы выкопать могилу для тела. + Tiempo, en segundos, requerido para cavar una tumba para un cuerpo. Allow Epinephrine @@ -3506,6 +3512,7 @@ Kein Schmerz 痛みはない Нет боли + Sin dolor In mild pain @@ -3627,6 +3634,7 @@ Kein IV IV なし Нет капельницы + Sin IV Blood Pressure @@ -4149,6 +4157,11 @@ %1 沒有反應 %1 tepki vermiyor + + %1 is unconscious + %1 は意識がない + %1 находится без сознания + %1 is not responsive, taking shallow gasps and convulsing %1 est inconscient, respire par intermittence et convulse. @@ -4161,6 +4174,11 @@ %1 не реагирует на раздражители, поверхностно дышит, в конвульсиях %1 no responde, dando pequeñas bocanadas y convulsionando + + %1 is in cardiac arrest + %1 は心停止している + У %1 произошла остановка сердца + %1 is not responsive, motionless and cold %1 est inconscient, inanimé et froid. @@ -4173,6 +4191,11 @@ %1 не реагирует на раздражители, не шевелится и холодный %1 no responde, sin movimiento y frío + + %1 is dead + %1 は死亡している + %1 мертв + You checked %1 Вы осмотрели раненого %1 @@ -4657,6 +4680,7 @@ Scava tomba per cadavere 墓を掘る Выкопать могилу для тела + Cavar tumba para cuerpo Digging grave for body... @@ -4667,6 +4691,7 @@ Scavando tomba per cadavere... 墓を掘っています Рытьё могилы для тела... + Cavando tumba para cuerpo... %1 has bandaged patient @@ -4919,6 +4944,7 @@ Controlla nome sulla lapide 墓石の名前を確認 Проверьте имя на надгробии + Comprobar nombre en la lápida Bandage Rollover @@ -4929,6 +4955,7 @@ Srotolamento Bendaggi 包帯の繰り越し Перевязка множественных ран + Vendaje múltiple If enabled, bandages can close different types of wounds on the same body part.\nBandaging multiple injuries will scale bandaging time accordingly. @@ -4939,6 +4966,7 @@ Se attivo, un singolo bendaggio potrà chiudere più ferite sulla stessa parte del corpo.\nBendare più ferite di conseguenza richiederà più tempo. 有効にすると、体の同じ部分にある別の種類の傷を一つの包帯で閉じることができます。\n複数の傷に包帯を巻くと、それに応じて包帯時間が変動します。 Если эта функция включена, бинты могут закрывать различные типы ран на одной и той же части тела.\nПри перевязке нескольких повреждений время перевязки будет увеличено соответствующим образом. + Si se habilita, las vendas pueden cerrar diferentes tipos de heridas en la misma parte del cuerpo.n\Vendar múltiples heridas escala el tiempo de vendado acorde. Bandage Effectiveness Coefficient @@ -4949,6 +4977,7 @@ Coefficiente di efficacia bendaggi 包帯有効性係数 Коэффициент эффективности повязки + Coeficiente de Efectividad de Vendado Determines how effective bandages are at closing wounds. @@ -4959,6 +4988,7 @@ Determina quanto i bendaggi sono efficaci nel chiudere le ferite. 包帯が傷をふさぐのにどれだけ効果的かを定義します。 Определяет, насколько эффективны бинты при закрытии ран. + Determina como de efectivos son los vendajes cerrando heridas. Medical Items @@ -4982,6 +5012,7 @@ 제우스 치료 시간 계수 Коэффициент времени обработки Zeus Coeff. de temps + Coeficiente de Tiempo del Tratamiento de Zeus Multiply all treatment times with this coefficient when in Zeus. @@ -4991,6 +5022,7 @@ 제우스일 때 모든 치료 시간에 이 계수를 곱합니다. Умножьте все время лечения на этот коэффициент, когда вы находитесь в Zeus. Coefficient de temps de traitement Zeus + Multiplica los tiempos de tratamientos por este coeficiente cuando se está en Zeus Painkillers @@ -5015,6 +5047,8 @@ 鎮痛剤を投与 진통제 투여 Administrer des analgésiques + Verabreiche Schmerztabletten + Administrar Analgésicos Administering Painkillers... @@ -5023,6 +5057,8 @@ 鎮痛剤を投与しています・・・ 진통제 투여 중... Administration d'analgésiques... + Verabreiche Schmerztablette... + Administrando Analgésicos... Over-the-counter analgesic used to combat light to moderate pain experiences. @@ -5031,6 +5067,8 @@ 軽度から中程度の痛みに対処するために使用される市販の鎮痛薬。 가벼운 통증부터 중간 정도의 통증을 퇴치하는 데 사용되는 일반의약품 진통제입니다. Analgésique sans ordonnance utilisé pour lutter contre les douleurs légères à modérées. + Rezeptfreies Analgetikum zur Bekämpfung leichter bis mittelschwerer Schmerzen. + Analgésico sin receta médica usado para aplacar dolores de ligeros a moderados. Over-the-counter analgesic used to combat light to moderate pain experiences. @@ -5039,6 +5077,8 @@ 軽度から中程度の痛みに対処するために使用される市販の鎮痛薬。 가벼운 통증부터 중간 정도의 통증을 퇴치하는 데 사용되는 일반의약품 진통제입니다. Analgésique sans ordonnance utilisé pour lutter contre les douleurs légères à modérées. + Rezeptfreies Analgetikum zur Bekämpfung leichter bis mittelschwerer Schmerzen. + Analgésico sin receta médica usado para aplacar dolores de ligeros a moderados. diff --git a/addons/medical_vitals/stringtable.xml b/addons/medical_vitals/stringtable.xml index eb0080bd078..2fe7336dc08 100644 --- a/addons/medical_vitals/stringtable.xml +++ b/addons/medical_vitals/stringtable.xml @@ -9,6 +9,8 @@ バイタル 생명 Paramètres vitaux + Vitalwerte + Vitales Enable SpO2 Simulation @@ -17,6 +19,8 @@ SpO2シミュレーションを有効化 산소포화도 시뮬레이션 활성화 Activer la simulation de la SpO2 + SpO2-Simulation aktivieren + Habilitar Simulación SpO2 Enables oxygen saturation simulation, providing variable heart rate and oxygen demand based on physical activity and altitude. Required for Airway Management. @@ -25,6 +29,8 @@ 酸素飽和度シミュレーションを有効にし、身体活動や標高に基づいて変動する心拍数と酸素要求量の機能を提供します。 気道管理に必要です。 산소포화도 시뮬레이션을 활성화하여 신체 활동과 고도에 따라 다양한 심박수와 산소 요구량을 제공합니다. 기도 관리에 필요합니다. Permet de simuler la saturation en oxygène, de modifier la fréquence cardiaque et la consommation d'oxygène en fonction de l'activité physique et de l'altitude. Nécessaire pour la gestion des voies respiratoires. + Aktiviert die Simulation der Sauerstoffsättigung und bietet variable Herzfrequenz und Sauerstoffbedarf basierend auf körperlicher Aktivität und Geländehöhe. Erforderlich für das Atemwegsmanagement. + Habilita la saturación de oxígeno, utilizando la demanda de oxígeno y ritmo cardíaco basado en la actividad física y la altitud. Requerido para el Manejo de las Vías Aéreas. diff --git a/addons/microdagr/initSettings.inc.sqf b/addons/microdagr/initSettings.inc.sqf index 8810939302d..aacc5fd24bc 100644 --- a/addons/microdagr/initSettings.inc.sqf +++ b/addons/microdagr/initSettings.inc.sqf @@ -15,7 +15,5 @@ private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(itemName) [LSTRING(WaypointPrecision_DisplayName), LSTRING(WaypointPrecision_Description)], _category, [[1, 2, 3], [LSTRING(WaypointPrecision_medium), LSTRING(WaypointPrecision_close), LSTRING(WaypointPrecision_exact)], 2], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(waypointPrecision), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // require mission restart + true // isGlobal ] call CBA_fnc_addSetting; diff --git a/addons/minedetector/XEH_postInit.sqf b/addons/minedetector/XEH_postInit.sqf index 77f2f6761c8..f5f5de0ca8a 100644 --- a/addons/minedetector/XEH_postInit.sqf +++ b/addons/minedetector/XEH_postInit.sqf @@ -1,16 +1,7 @@ #include "script_component.hpp" // Create a dictionary to store detector configs -GVAR(detectorConfigs) = call CBA_fnc_createNamespace; - -// Create a dictionary of detectable classnames -GVAR(detectableClasses) = call CBA_fnc_createNamespace; - -private _detectableClasses = call (uiNamespace getVariable [QGVAR(detectableClasses), {[]}]); //See XEH_preStart.sqf -{ - GVAR(detectableClasses) setVariable [_x, true]; -} forEach _detectableClasses; -TRACE_1("built cache",count allVariables GVAR(detectableClasses)); +GVAR(detectorConfigs) = createHashMap; [QGVAR(enableDetector), LINKFUNC(enableDetector)] call CBA_fnc_addEventHandler; [QGVAR(disableDetector), LINKFUNC(disableDetector)] call CBA_fnc_addEventHandler; diff --git a/addons/minedetector/XEH_preStart.sqf b/addons/minedetector/XEH_preStart.sqf index 48f003d08e3..046c0373640 100644 --- a/addons/minedetector/XEH_preStart.sqf +++ b/addons/minedetector/XEH_preStart.sqf @@ -15,5 +15,5 @@ private _detectableClasses = []; }; } forEach (configProperties [configFile >> "CfgAmmo", "isClass _x", true]); -TRACE_1("compiled",count _detectableClasses); -uiNamespace setVariable [QGVAR(detectableClasses), compileFinal str _detectableClasses]; +TRACE_1("built cache",count _detectableClasses); +uiNamespace setVariable [QGVAR(detectableClasses), compileFinal (_detectableClasses createHashMapFromArray [])]; diff --git a/addons/minedetector/functions/fnc_getDetectedObject.sqf b/addons/minedetector/functions/fnc_getDetectedObject.sqf index 810e4d4ff46..7811b3eaaa8 100644 --- a/addons/minedetector/functions/fnc_getDetectedObject.sqf +++ b/addons/minedetector/functions/fnc_getDetectedObject.sqf @@ -38,15 +38,13 @@ private _mine = objNull; private _distance = -1; { - private _objectType = typeOf _x; - - _isDetectable = GVAR(detectableClasses) getVariable _objectType; - if (isNil "_isDetectable" || {(getModelInfo _x) select 0 == "empty.p3d"}) then { - _isDetectable = false; + if ((getModelInfo _x) select 0 == "empty.p3d") then { + continue; }; - // If a nun-null object was detected exit the search - if (_isDetectable && {!isNull _x}) exitWith { + // If an object was detected, exit the search + if ((typeOf _x) in (uiNamespace getVariable QGVAR(detectableClasses))) exitWith { + _isDetectable = true; _distance = _detectorPointAGL distance _x; _mine = _x; TRACE_3("return",_isDetectable,_mine,_distance); diff --git a/addons/minedetector/functions/fnc_getDetectorConfig.sqf b/addons/minedetector/functions/fnc_getDetectorConfig.sqf index fe7a888ebf3..a5566cbfbfc 100644 --- a/addons/minedetector/functions/fnc_getDetectorConfig.sqf +++ b/addons/minedetector/functions/fnc_getDetectorConfig.sqf @@ -19,18 +19,15 @@ params ["_detectorType"]; if (_detectorType isEqualTo "") exitWith {[]}; -private _detectorConfig = GVAR(detectorConfigs) getVariable _detectorType; -if (isNil "_detectorConfig") then { +GVAR(detectorConfigs) getOrDefaultCall [_detectorType, { private _cfgEntry = (configFile >> "ACE_detector" >> "detectors" >> _detectorType); if (isClass _cfgEntry) then { - _detectorConfig = [ + [ _detectorType, getNumber (_cfgEntry >> "radius"), getArray (_cfgEntry >> "sounds") ]; } else { - _detectorConfig = []; + [] }; - GVAR(detectorConfigs) setVariable [_detectorType, _detectorConfig]; -}; -_detectorConfig +}, true] diff --git a/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf b/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf index d25d2bc2b78..2263716724a 100644 --- a/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf +++ b/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf @@ -18,7 +18,7 @@ TRACE_1("cycle fire mode",_this); if (!alive ACE_player) exitWith {}; -if (!([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith))) exitWith {}; +if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {}; private _currentShooter = objNull; diff --git a/addons/missileguidance/functions/fnc_onFired.sqf b/addons/missileguidance/functions/fnc_onFired.sqf index 18eaf2a7c70..1d63d120a9a 100644 --- a/addons/missileguidance/functions/fnc_onFired.sqf +++ b/addons/missileguidance/functions/fnc_onFired.sqf @@ -20,7 +20,7 @@ params ["_shooter","_weapon","","_mode","_ammo","","_projectile"]; // Bail on not missile -if (!(_ammo isKindOf "MissileBase")) exitWith {}; +if !(_ammo isKindOf "MissileBase") exitWith {}; // Bail if guidance is disabled for this ammo if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "enabled")) != 1) exitWith {}; diff --git a/addons/mk6mortar/functions/fnc_handleFired.sqf b/addons/mk6mortar/functions/fnc_handleFired.sqf index f2979d0e4e8..8ea2984b794 100644 --- a/addons/mk6mortar/functions/fnc_handleFired.sqf +++ b/addons/mk6mortar/functions/fnc_handleFired.sqf @@ -28,7 +28,7 @@ if (_vehicle distance ACE_player > 8000) exitWith {}; //AI will have no clue how to use: private _shooterMan = gunner _vehicle; -if (!([_shooterMan] call EFUNC(common,isPlayer))) exitWith {}; +if !([_shooterMan] call EFUNC(common,isPlayer)) exitWith {}; //Calculate air density: private _altitude = (getPosASL _vehicle) select 2; diff --git a/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf b/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf index 216bab43bc8..d721b0e4ae8 100644 --- a/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf +++ b/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf @@ -19,7 +19,7 @@ params ["_player", "_newVehicle"]; if (isNull _newVehicle) exitWith {}; -if (!(_newVehicle isKindOf "Mortar_01_base_F")) exitWith {}; +if !(_newVehicle isKindOf "Mortar_01_base_F") exitWith {}; private _tubeWeaponName = (weapons _newVehicle) select 0; private _fireModes = getArray (configFile >> "CfgWeapons" >> _tubeWeaponName >> "modes"); diff --git a/addons/mk6mortar/stringtable.xml b/addons/mk6mortar/stringtable.xml index a0d8612aa58..41955799988 100644 --- a/addons/mk6mortar/stringtable.xml +++ b/addons/mk6mortar/stringtable.xml @@ -163,7 +163,7 @@ A távmérő és számítógép megjelenítése (ezeket el KELL távolítani ha a légellenállás engedélyezve van) Показывает компьютер и дальномер (это НУЖНО отключить, если вы включаете сопротивление воздуха) Consenti l'utilizzo del Computer Balistico e del Telemetro (questi DEVONO essere disabilitati se vuoi abilitare la resistenza dell'aria) - 砲撃コンピュータと距離計を表示します (空気抵抗を仕様する場合は必ず無効化する必要があります) + 砲撃コンピュータと距離計を表示します (空気抵抗を有効化する場合はこれらを取り除く必要があります) 탄도계산컴퓨터와 거리측정기를 보여줍니다(공기저항을 활성화했을 경우 이 항목은 비활성화 되어야 합니다) 显示弹道计算机和测距仪(如果有启用空气阻力功能时,须停用此项功能) 顯示射控電腦和測距儀 (如果有啟用空氣阻力功能時,須停用此項功能) @@ -241,7 +241,7 @@ Rimuove i caricatori di colpi dal mortaio. Un operatore dovrà caricare proiettili singoli prima di poter fare fuoco. Non viene applicato su operatori IA. Elimina os carregadores do morteiro, requerendo que o atirador ou carregador utilize de forma individual a munição. Não afeta os morteiros controlados pela IA. Удаляет артиллерийские магазины, требует загрузку отдельных снарядов стрелком или заряжающим. Не влияет на артиллерию ИИ. - 迫撃砲から弾薬を除去します。射手か装填手により予め装填されている必要があります。AI迫撃砲へ影響を与えません。 + 迫撃砲から弾倉を除去します。一発ずつ射手か装填手によって装填される必要があります。AIの迫撃砲には影響を与えません。 박격포 탄창을 제거합니다, 사수나 장전수가 개별적으로 탄환을 넣어줘야 합니다. 인공지능은 영향을 받지 않습니다. 开启此功能时。迫击炮的弹药需由炮手与装填手共同合作来进行装填。此功能并不影响由 AI 射击的迫击炮 開啟此功能時。迫擊砲的彈藥需由砲手與裝填手共同合作來進行裝填。此功能並不影響由AI射擊的迫擊砲 @@ -257,7 +257,7 @@ Odstranit náboj Remover munição Извлечь снаряд - 弾薬を除去 + 砲弾を取り除く 탄약 제거 卸除弹头 卸除彈頭 @@ -273,7 +273,7 @@ Nabít minomet Carregar morteiro Зарядить миномет - 弾薬を装填 + 砲弾を装填 탄약 장전 装载弹头 裝載彈頭 @@ -288,7 +288,7 @@ Togliendo Proiettile Descarregar munição Извлечение снаряда - 弾薬を除去しています + 砲弾を取り除いています 탄약 제거 중 正在卸除弹头 卸除彈頭中 @@ -305,7 +305,7 @@ Připavuji náboj Preparar munição Подготовка снаряда - 砲弾を事前装填 + 砲弾を準備 탄약 준비 중 正在准备弹头 準備彈頭中 @@ -544,7 +544,7 @@ [ACE] Bedna se standardní 82mm municí [ACE] Caixa de Munição 82mm Padrão [ACE] Ящик снарядов 82мм (стандартный) - [ACE] 82mm 保管箱 + [ACE] 82mm 標準砲弾セット入り弾薬箱 [ACE] 82mm 기본 장비 상자 [ACE] 82 mm 预设弹药箱 [ACE] 82毫米預設彈藥箱 diff --git a/addons/nametags/XEH_postInit.sqf b/addons/nametags/XEH_postInit.sqf index 85115690b48..a3fb7307f2e 100644 --- a/addons/nametags/XEH_postInit.sqf +++ b/addons/nametags/XEH_postInit.sqf @@ -50,7 +50,7 @@ if (missionNamespace getVariable [QGVAR(useFactionIcons), true]) then { { if (isArray (_x >> QGVAR(rankIcons))) then { private _faction = configName _x; - if (!isNil {GVAR(factionRanks) getVariable _faction}) exitWith {}; // don't overwrite if already set + if (_faction in GVAR(factionRanks)) exitWith {}; // don't overwrite if already set private _icons = getArray (_x >> QGVAR(rankIcons)); [_faction, _icons] call FUNC(setFactionRankIcons); }; diff --git a/addons/nametags/functions/fnc_drawNameTagIcon.sqf b/addons/nametags/functions/fnc_drawNameTagIcon.sqf index 428cf037d5b..efe0c6bf157 100644 --- a/addons/nametags/functions/fnc_drawNameTagIcon.sqf +++ b/addons/nametags/functions/fnc_drawNameTagIcon.sqf @@ -42,7 +42,7 @@ _fnc_parameters = { default { private _targetFaction = _target getVariable [QGVAR(faction), faction _target]; - private _customRankIcons = GVAR(factionRanks) getVariable _targetFaction; + private _customRankIcons = GVAR(factionRanks) get _targetFaction; if (!isNil "_customRankIcons") then { _customRankIcons param [ALL_RANKS find rank _target, ""] // return diff --git a/addons/nametags/functions/fnc_setFactionRankIcons.sqf b/addons/nametags/functions/fnc_setFactionRankIcons.sqf index 88fd8808333..42d3ed40cbc 100644 --- a/addons/nametags/functions/fnc_setFactionRankIcons.sqf +++ b/addons/nametags/functions/fnc_setFactionRankIcons.sqf @@ -25,7 +25,7 @@ */ if (isNil QGVAR(factionRanks)) then { - GVAR(factionRanks) = [] call CBA_fnc_createNamespace; + GVAR(factionRanks) = createHashMap; }; params [["_faction", "", [""]], ["_icons", [], [[]], [7]]]; @@ -33,6 +33,11 @@ TRACE_2("setFactionRankIcons",_faction,_icons); if !(_faction != "" && {_icons isEqualTypeAll ""}) exitWith {false}; -GVAR(factionRanks) setVariable [_faction, _icons]; +_faction = configName (configFile >> "CfgFactionClasses" >> _faction); + +// Faction doesn't exist +if (_faction == "") exitWith {false}; + +GVAR(factionRanks) set [_faction, _icons]; true diff --git a/addons/nightvision/XEH_postInit.sqf b/addons/nightvision/XEH_postInit.sqf index 9bfee4d166c..5a1aa19b82e 100644 --- a/addons/nightvision/XEH_postInit.sqf +++ b/addons/nightvision/XEH_postInit.sqf @@ -61,7 +61,7 @@ if (!isNil QGVAR(serverPriorFog)) then {[] call FUNC(nonDedicatedFix);}; // If v if !([ACE_player, objNull, ["isNotEscorting", "isNotInside", "isNotSitting", "isNotRefueling"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if ((currentVisionMode ACE_player != 1)) exitWith {false}; - if (!(missionNamespace getVariable [QGVAR(allowBrightnessControl), true])) exitWith {false}; // just a mission setVar (not ace_setting) + if !(missionNamespace getVariable [QGVAR(allowBrightnessControl), true]) exitWith {false}; // just a mission setVar (not ace_setting) // Statement [ACE_player, 1] call FUNC(changeNVGBrightness); @@ -73,7 +73,7 @@ if (!isNil QGVAR(serverPriorFog)) then {[] call FUNC(nonDedicatedFix);}; // If v if !([ACE_player, objNull, ["isNotEscorting", "isNotInside", "isNotSitting", "isNotRefueling"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if ((currentVisionMode ACE_player != 1)) exitWith {false}; - if (!(missionNamespace getVariable [QGVAR(allowBrightnessControl), true])) exitWith {false}; // just a mission setVar (not ace_setting) + if !(missionNamespace getVariable [QGVAR(allowBrightnessControl), true]) exitWith {false}; // just a mission setVar (not ace_setting) // Statement [ACE_player, -1] call FUNC(changeNVGBrightness); diff --git a/addons/nightvision/stringtable.xml b/addons/nightvision/stringtable.xml index e1345ec44ec..1c1cd61ba7a 100644 --- a/addons/nightvision/stringtable.xml +++ b/addons/nightvision/stringtable.xml @@ -132,6 +132,7 @@ 야투경 (3세대, 갈색, 백색광) JVN (Gen3, marron, WP) ПНВ (Gen3, Коричневый, БФ) + Gafas de visión nocturna (Gen3, Marrón, FB) Night Vision Goggles, White Phosphor @@ -142,6 +143,7 @@ 백색광 야투경 Jumelles Vision Nocturne, Phosphore blanc Очки ночного видения, белый фосфор + Gafas de Visión Nocturna, Fósforo Blanco NV Goggles (Gen3, Green) @@ -169,6 +171,7 @@ 야투경 (3세대, 녹색, 백색광) JVN (Gen3, vertes, WP) ПНВ (Gen3, Зелёный, БФ) + Gafas de visión nocturna (Gen3, Verde, FB) NV Goggles (Gen3, Black) @@ -196,6 +199,7 @@ 야투경 (3세대, 검정, 백색광) JVN (Gen3, noires, WP) ПНВ (Gen3, Чёрный, БФ) + Gafas de visión nocturna (Gen3, Negro, FB) NV Goggles (Gen4, Brown) @@ -218,6 +222,7 @@ 야투경 (4세대, 갈색, 백색광) JVN (Gen4, marron, WP) ПНВ (Gen4, Коричневый, БФ) + Gafas de visión nocturna (Gen4, Marrón, FB) NV Goggles (Gen4, Black) @@ -240,6 +245,7 @@ 야투경 (4세대, 검정, 백색광) JVN (Gen4, noires, WP) ПНВ (Gen4, Чёрный, БФ) + Gafas de visión nocturna (Gen4, Negro, FB) NV Goggles (Gen4, Green) @@ -262,6 +268,7 @@ 야투경 (4세대, 녹색, 백색광) JVN (Gen4, vertes, WP) ПНВ (Gen4, Зелёный, БФ) + Gafas de visión nocturna (Gen4, Verde, FB) NV Goggles (Wide, Brown) @@ -284,6 +291,7 @@ 야투경 (넓음, 갈색, 백색광) JVN (Large, marron, WP) ПНВ (Широкий, Коричневый, БФ) + Gafas de visión nocturna (Panorámicas, Marrón, FB) NV Goggles (Wide, Black) @@ -306,6 +314,7 @@ 야투경 (넓음, 검정, 백색광) JVN (Large, noires, WP) ПНВ (Широкий, Чёрный, БФ) + Gafas de visión nocturna (Panorámicas, Negro, FB) NV Goggles (Wide, Green) @@ -328,6 +337,7 @@ 야투경 (넓음, 녹색, 백색광) JVN (Large, vertes, WP) ПНВ (Широкий, Зелёный, БФ) + Gafas de visión nocturna (Panorámicas, Verde, FB) Brightness: %1 @@ -587,6 +597,7 @@ 야투경 세대 Génération de jumelles de vision nocturne Генерация ночного видения + Generación de Visión Nocturna Gen %1 @@ -597,6 +608,7 @@ %1세대 Gen %1 Генерация %1 + Gen %1 diff --git a/addons/nlaw/functions/fnc_keyDown.sqf b/addons/nlaw/functions/fnc_keyDown.sqf index 60ac4bf3d8f..5b75c721406 100644 --- a/addons/nlaw/functions/fnc_keyDown.sqf +++ b/addons/nlaw/functions/fnc_keyDown.sqf @@ -19,8 +19,8 @@ TRACE_1("lock key down",GVAR(isLockKeyDown)); if (!alive ACE_player) exitWith {}; -if (!([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith))) exitWith {}; -if (!(ACE_player call CBA_fnc_canUseWeapon)) exitWith {}; +if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {}; +if !(ACE_player call CBA_fnc_canUseWeapon) exitWith {}; if ((getNumber (configFile >> "CfgWeapons" >> (currentWeapon ACE_player) >> QGVAR(enabled))) == 0) exitWith {}; if (GVAR(isLockKeyDown)) exitWith {ERROR("already running?");}; diff --git a/addons/overheating/stringtable.xml b/addons/overheating/stringtable.xml index 48399b443c3..ef20ae9e81d 100644 --- a/addons/overheating/stringtable.xml +++ b/addons/overheating/stringtable.xml @@ -882,6 +882,8 @@ 노리쇠 방식 Тип болта Type d'obturateur + Art des Verschlusses + Tipo de Cerrojo Open Bolt @@ -890,6 +892,8 @@ 오픈 볼트 Открыть болт Obturateur ouvert + Offener Verschluss + Cerrojo Abierto Closed Bolt @@ -898,6 +902,8 @@ 클로즈드 볼트 Закрыть болт Obturateur fermé + Geschlossener Verschluss + Cerrojo Cerrado Barrel Type @@ -906,6 +912,8 @@ 총열 방식 Тип ствола Type de canon + Lauftyp + Tipo de Cañón Non-Removeable @@ -914,6 +922,8 @@ 제거 불가 Несъемный Inamovible + Nicht entfernbar + No-Desmontable Quick Change @@ -922,6 +932,8 @@ 신속 교체 Быстросъемный Changement rapide + Schnellwechsel + Cambiado Rápido diff --git a/addons/overpressure/functions/fnc_firedEHBB.sqf b/addons/overpressure/functions/fnc_firedEHBB.sqf index 2ef48bf4d99..a0277859402 100644 --- a/addons/overpressure/functions/fnc_firedEHBB.sqf +++ b/addons/overpressure/functions/fnc_firedEHBB.sqf @@ -53,7 +53,7 @@ if (_distance < _backblastRange) then { [_damage * 100] call BIS_fnc_bloodEffect; - if (["ace_medical"] call EFUNC(common,isModLoaded)) then { + if (GETEGVAR(medical,enabled,false)) then { [_unit, _damage, "body", "backblast", _unit] call EFUNC(medical,addDamageToUnit); } else { _unit setDamage (damage _unit + _damage); diff --git a/addons/overpressure/functions/fnc_overpressureDamage.sqf b/addons/overpressure/functions/fnc_overpressureDamage.sqf index 812a2ab7ea2..12b7a820cab 100644 --- a/addons/overpressure/functions/fnc_overpressureDamage.sqf +++ b/addons/overpressure/functions/fnc_overpressureDamage.sqf @@ -57,7 +57,7 @@ TRACE_3("cache",_overpressureAngle,_overpressureRange,_overpressureDamage); [_damage * 100] call BIS_fnc_bloodEffect; }; - if (["ace_medical"] call EFUNC(common,isModLoaded)) then { + if (GETEGVAR(medical,enabled,false)) then { [_x, _damage, "body", "backblast", _firer] call EFUNC(medical,addDamageToUnit); } else { _x setDamage (damage _x + _damage); diff --git a/addons/parachute/CfgVehicles.hpp b/addons/parachute/CfgVehicles.hpp index f764494224d..545d9a37053 100644 --- a/addons/parachute/CfgVehicles.hpp +++ b/addons/parachute/CfgVehicles.hpp @@ -101,4 +101,36 @@ class CfgVehicles { class B_Soldier_05_f; class B_Pilot_F: B_Soldier_05_f {backpack = "ACE_NonSteerableParachute";}; class I_Soldier_04_F; class I_pilot_F: I_Soldier_04_F {backpack = "ACE_NonSteerableParachute";}; class O_helipilot_F; class O_Pilot_F: O_helipilot_F {backpack = "ACE_NonSteerableParachute";}; + + class Plane_Base_F; + class Plane_CAS_01_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_CAS_02_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_Fighter_01_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_Fighter_02_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_Fighter_03_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_Fighter_04_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; }; diff --git a/addons/parachute/initSettings.inc.sqf b/addons/parachute/initSettings.inc.sqf index 0cfc3f8ca05..0c6804cff79 100644 --- a/addons/parachute/initSettings.inc.sqf +++ b/addons/parachute/initSettings.inc.sqf @@ -5,9 +5,7 @@ private _category = [LELSTRING(common,categoryUncategorized), localize "str_dn_p "CHECKBOX", [LSTRING(HideAltimeter), LSTRING(HideAltimeter_tooltip)], _category, - true, - false, - {[QGVAR(hideAltimeter), _this, false] call EFUNC(common,cbaSettings_settingChanged)} + true ] call CBA_fnc_addSetting; [ diff --git a/addons/pylons/functions/fnc_showDialog.sqf b/addons/pylons/functions/fnc_showDialog.sqf index a06cb6f1142..9c0faab52d0 100644 --- a/addons/pylons/functions/fnc_showDialog.sqf +++ b/addons/pylons/functions/fnc_showDialog.sqf @@ -107,7 +107,7 @@ GVAR(comboBoxes) = []; private _mirroredIndex = getNumber (_x >> "mirroredMissilePos"); private _button = controlNull; - if (count allTurrets [_aircraft, false] > 0) then { + if ((allTurrets [_aircraft, false]) isNotEqualTo []) then { _button = _display ctrlCreate ["ctrlButtonPictureKeepAspect", -1]; private _turret = [_aircraft, _forEachIndex] call EFUNC(common,getPylonTurret); [_button, false, _turret] call FUNC(onButtonTurret); diff --git a/addons/realisticnames/Attachments.hpp b/addons/realisticnames/Attachments.hpp new file mode 100644 index 00000000000..a861bb4a043 --- /dev/null +++ b/addons/realisticnames/Attachments.hpp @@ -0,0 +1,174 @@ +//attachments + +class ItemCore; + +class acc_flashlight: ItemCore { + displayName = CSTRING(flashlight_Name); +}; + +class optic_MRD: ItemCore { + displayName = CSTRING(optic_mrd_Name); +}; +class optic_MRD_black: optic_MRD { + displayName = CSTRING(optic_mrd_black_Name); +}; + +class optic_Hamr: ItemCore { + displayName = CSTRING(optic_hamr); +}; +class optic_Hamr_khk_F: optic_Hamr { + displayName = CSTRING(optic_hamr_khk); +}; +class ACE_optic_Hamr_2D: optic_Hamr { + displayName = CSTRING(optic_hamr_2d); +}; +class ACE_optic_Hamr_PIP: ACE_optic_Hamr_2D { + displayName = CSTRING(optic_hamr_pip); +}; + +class optic_Arco: ItemCore { + displayName = CSTRING(optic_arco); +}; +class optic_Arco_blk_F: optic_Arco { + displayName = CSTRING(optic_arco_blk); +}; +class optic_Arco_ghex_F: optic_Arco { + displayName = CSTRING(optic_arco_ghex); +}; +class ACE_optic_Arco_2D: optic_Arco { + displayName = CSTRING(optic_arco_2d); +}; +class ACE_optic_Arco_PIP: ACE_optic_Arco_2D { + displayName = CSTRING(optic_arco_pip); +}; +class optic_Arco_lush_F: optic_Arco { + displayName = CSTRING(optic_arco_lush); +}; +class optic_Arco_arid_F: optic_Arco { + displayName = CSTRING(optic_arco_arid); +}; +class optic_Arco_AK_blk_F: optic_Arco_blk_F { + displayName = CSTRING(optic_arco_ak_blk); +}; +class optic_Arco_AK_lush_F: optic_Arco_lush_F { + displayName = CSTRING(optic_arco_ak_lush); +}; +class optic_Arco_AK_arid_F: optic_Arco_arid_F { + displayName = CSTRING(optic_arco_ak_arid); +}; + +class optic_ERCO_blk_f: optic_Arco { + displayName = CSTRING(optic_erco_blk); +}; +class optic_ERCO_khk_f: optic_ERCO_blk_f { + displayName = CSTRING(optic_erco_khk); +}; +class optic_ERCO_snd_f: optic_ERCO_blk_f { + displayName = CSTRING(optic_erco_snd); +}; + +class optic_LRPS: ItemCore { + displayName = CSTRING(optic_lrps); +}; +class optic_LRPS_ghex_F: optic_LRPS { + displayName = CSTRING(optic_lrps_ghex); +}; +class optic_LRPS_tna_F: optic_LRPS { + displayName = CSTRING(optic_lrps_tna); +}; +class ACE_optic_LRPS_2D: optic_LRPS { + displayName = CSTRING(optic_lrps_2d); +}; +class ACE_optic_LRPS_PIP: ACE_optic_LRPS_2D { + displayName = CSTRING(optic_lrps_pip); +}; + +class optic_AMS_base; +class optic_AMS: optic_AMS_base { + displayName = CSTRING(optic_ams); +}; +class optic_AMS_khk: optic_AMS { + displayName = CSTRING(optic_ams_khk); +}; +class optic_AMS_snd: optic_AMS { + displayName = CSTRING(optic_ams_snd); +}; + +class optic_KHS_base; +class optic_KHS_blk: optic_KHS_base { + displayName = CSTRING(optic_khs_blk); +}; +class optic_KHS_hex: optic_KHS_blk { + displayName = CSTRING(optic_khs_hex); +}; +class optic_KHS_old: ItemCore { + displayName = CSTRING(optic_khs_old); +}; +class optic_KHS_tan: optic_KHS_blk { + displayName = CSTRING(optic_khs_tan); +}; + +class optic_DMS: ItemCore { + displayName = CSTRING(optic_dms); +}; +class optic_DMS_ghex_F: optic_DMS { + displayName = CSTRING(optic_dms_ghex); +}; +class optic_DMS_weathered_F: optic_DMS { + displayName = CSTRING(optic_dms_weathered); +}; +class optic_DMS_weathered_Kir_F: optic_DMS_weathered_F { + displayName = CSTRING(optic_dms_weathered_kir); +}; + +class optic_holosight: ItemCore { + displayName = CSTRING(optic_holosight); +}; +class optic_Holosight_blk_F: optic_holosight { + displayName = CSTRING(optic_holosight_blk); +}; +class optic_Holosight_khk_F: optic_holosight { + displayName = CSTRING(optic_holosight_khk); +}; +class optic_Holosight_lush_F: optic_holosight { + displayName = CSTRING(optic_holosight_lush); +}; +class optic_Holosight_arid_F: optic_holosight { + displayName = CSTRING(optic_holosight_arid); +}; +class optic_Holosight_smg: ItemCore { + displayName = CSTRING(optic_holosight_smg); +}; +class optic_Holosight_smg_blk_F: optic_Holosight_smg { + displayName = CSTRING(optic_holosight_smg_blk); +}; +class optic_Holosight_smg_khk_F: optic_Holosight_smg { + displayName = CSTRING(optic_holosight_smg_khk); +}; + +class optic_MRCO: ItemCore { + displayName = CSTRING(optic_MRCO); +}; +class ACE_optic_MRCO_2D: optic_MRCO { + displayName = CSTRING(optic_MRCO_2d); +}; +class ACE_optic_MRCO_PIP: ACE_optic_MRCO_2D { + displayName = CSTRING(optic_MRCO_pip); +}; + +class optic_Yorris: ItemCore { + displayName = CSTRING(optic_Yorris); +}; + +class optic_ACO: ItemCore { + displayName = CSTRING(optic_ACO); +}; +class optic_ACO_grn: ItemCore { + displayName = CSTRING(optic_ACO_grn); +}; +class optic_ACO_smg: ItemCore { + displayName = CSTRING(optic_ACO_smg); +}; +class optic_ACO_grn_smg: ItemCore { + displayName = CSTRING(optic_ACO_grn_smg); +}; diff --git a/addons/realisticnames/CfgVehicles.hpp b/addons/realisticnames/CfgVehicles.hpp index 8d4d0c2f4a1..29ac412957f 100644 --- a/addons/realisticnames/CfgVehicles.hpp +++ b/addons/realisticnames/CfgVehicles.hpp @@ -249,6 +249,10 @@ class CfgVehicles { class O_Truck_02_medical_F: Truck_02_medical_base_F { displayName = CSTRING(Truck_02_medical_Name); }; + class Truck_02_water_base_F; + class C_IDAP_Truck_02_water_F: Truck_02_water_base_F { + displayName = CSTRING(Truck_02_water_Name); + }; class I_Truck_02_transport_F: Truck_02_transport_base_F { displayName = CSTRING(Truck_02_transport_Name); }; @@ -283,6 +287,12 @@ class CfgVehicles { class C_Truck_02_box_F: Truck_02_box_base_F { displayName = CSTRING(Truck_02_box_Name); }; + class C_IDAP_Truck_02_transport_F: Truck_02_transport_base_F { + displayName = CSTRING(Truck_02_transport_Name); + }; + class C_IDAP_Truck_02_F: Truck_02_base_F { + displayName = CSTRING(Truck_02_covered_Name); + }; class Truck_03_base_F; class O_Truck_03_transport_F: Truck_03_base_F { @@ -384,6 +394,9 @@ class CfgVehicles { class I_Heli_Transport_02_F: Heli_Transport_02_base_F { displayName = CSTRING(Heli_Transport_02_Name); }; + class C_IDAP_Heli_Transport_02_F: Heli_Transport_02_base_F { + displayName = CSTRING(Heli_Transport_02_Name); + }; // planes class Plane_CAS_01_base_F; diff --git a/addons/realisticnames/CfgWeapons.hpp b/addons/realisticnames/CfgWeapons.hpp index 953f981051e..5b0e33e98c9 100644 --- a/addons/realisticnames/CfgWeapons.hpp +++ b/addons/realisticnames/CfgWeapons.hpp @@ -2,6 +2,7 @@ class Mode_SemiAuto; class Mode_FullAuto; class CfgWeapons { + #include "Attachments.hpp" // assault rifles // MX @@ -707,175 +708,19 @@ class CfgWeapons { }; }; - //attachments - - class ItemCore; - - class acc_flashlight: ItemCore { - displayName = "UTG Defender 126"; - }; - - class optic_Hamr: ItemCore { - displayName = CSTRING(optic_hamr); - }; - class optic_Hamr_khk_F: optic_Hamr { - displayName = CSTRING(optic_hamr_khk); - }; - class ACE_optic_Hamr_2D: optic_Hamr { - displayName = CSTRING(optic_hamr_2d); - }; - class ACE_optic_Hamr_PIP: ACE_optic_Hamr_2D { - displayName = CSTRING(optic_hamr_pip); - }; - - class optic_Arco: ItemCore { - displayName = CSTRING(optic_arco); - }; - class optic_Arco_blk_F: optic_Arco { - displayName = CSTRING(optic_arco_blk); - }; - class optic_Arco_ghex_F: optic_Arco { - displayName = CSTRING(optic_arco_ghex); - }; - class ACE_optic_Arco_2D: optic_Arco { - displayName = CSTRING(optic_arco_2d); - }; - class ACE_optic_Arco_PIP: ACE_optic_Arco_2D { - displayName = CSTRING(optic_arco_pip); - }; - class optic_Arco_lush_F: optic_Arco { - displayName = CSTRING(optic_arco_lush); - }; - class optic_Arco_arid_F: optic_Arco { - displayName = CSTRING(optic_arco_arid); - }; - class optic_Arco_AK_blk_F: optic_Arco_blk_F { - displayName = CSTRING(optic_arco_ak_blk); - }; - class optic_Arco_AK_lush_F: optic_Arco_lush_F { - displayName = CSTRING(optic_arco_ak_lush); - }; - class optic_Arco_AK_arid_F: optic_Arco_arid_F { - displayName = CSTRING(optic_arco_ak_arid); - }; - - class optic_ERCO_blk_f: optic_Arco { - displayName = CSTRING(optic_erco_blk); - }; - class optic_ERCO_khk_f: optic_ERCO_blk_f { - displayName = CSTRING(optic_erco_khk); - }; - class optic_ERCO_snd_f: optic_ERCO_blk_f { - displayName = CSTRING(optic_erco_snd); - }; - - class optic_LRPS: ItemCore { - displayName = CSTRING(optic_lrps); - }; - class optic_LRPS_ghex_F: optic_LRPS { - displayName = CSTRING(optic_lrps_ghex); - }; - class optic_LRPS_tna_F: optic_LRPS { - displayName = CSTRING(optic_lrps_tna); - }; - class ACE_optic_LRPS_2D: optic_LRPS { - displayName = CSTRING(optic_lrps_2d); - }; - class ACE_optic_LRPS_PIP: ACE_optic_LRPS_2D { - displayName = CSTRING(optic_lrps_pip); - }; - - class optic_AMS_base; - class optic_AMS: optic_AMS_base { - displayName = CSTRING(optic_ams); - }; - class optic_AMS_khk: optic_AMS { - displayName = CSTRING(optic_ams_khk); - }; - class optic_AMS_snd: optic_AMS { - displayName = CSTRING(optic_ams_snd); - }; - - class optic_KHS_base; - class optic_KHS_blk: optic_KHS_base { - displayName = CSTRING(optic_khs_blk); - }; - class optic_KHS_hex: optic_KHS_blk { - displayName = CSTRING(optic_khs_hex); - }; - class optic_KHS_old: ItemCore { - displayName = CSTRING(optic_khs_old); - }; - class optic_KHS_tan: optic_KHS_blk { - displayName = CSTRING(optic_khs_tan); - }; - - class optic_DMS: ItemCore { - displayName = CSTRING(optic_dms); - }; - class optic_DMS_ghex_F: optic_DMS { - displayName = CSTRING(optic_dms_ghex); - }; - class optic_DMS_weathered_F: optic_DMS { - displayName = CSTRING(optic_dms_weathered); - }; - class optic_DMS_weathered_Kir_F: optic_DMS_weathered_F { - displayName = CSTRING(optic_dms_weathered_kir); - }; - - class optic_holosight: ItemCore { - displayName = CSTRING(optic_holosight); - }; - class optic_Holosight_blk_F: optic_holosight { - displayName = CSTRING(optic_holosight_blk); - }; - class optic_Holosight_khk_F: optic_holosight { - displayName = CSTRING(optic_holosight_khk); - }; - class optic_Holosight_lush_F: optic_holosight { - displayName = CSTRING(optic_holosight_lush); - }; - class optic_Holosight_arid_F: optic_holosight { - displayName = CSTRING(optic_holosight_arid); - }; - class optic_Holosight_smg: ItemCore { - displayName = CSTRING(optic_holosight_smg); - }; - class optic_Holosight_smg_blk_F: optic_Holosight_smg { - displayName = CSTRING(optic_holosight_smg_blk); - }; - class optic_Holosight_smg_khk_F: optic_Holosight_smg { - displayName = CSTRING(optic_holosight_smg_khk); - }; - - class optic_MRCO: ItemCore { - displayName = CSTRING(optic_MRCO); - }; - class ACE_optic_MRCO_2D: optic_MRCO { - displayName = CSTRING(optic_MRCO_2d); - }; - class ACE_optic_MRCO_PIP: ACE_optic_MRCO_2D { - displayName = CSTRING(optic_MRCO_pip); - }; - - class optic_Yorris: ItemCore { - displayName = CSTRING(optic_Yorris); - }; + // APEX/Tanoa - class optic_ACO: ItemCore { - displayName = CSTRING(optic_ACO); + // Type 115 + class arifle_ARX_base_F; + class arifle_ARX_blk_F: arifle_ARX_base_F { + displayName = CSTRING(arifle_arx_blk_Name); }; - class optic_ACO_grn: ItemCore { - displayName = CSTRING(optic_ACO_grn); + class arifle_ARX_ghex_F: arifle_ARX_base_F { + displayName = CSTRING(arifle_arx_ghex_Name); }; - class optic_ACO_smg: ItemCore { - displayName = CSTRING(optic_ACO_smg); + class arifle_ARX_hex_F: arifle_ARX_base_F { + displayName = CSTRING(arifle_arx_hex_Name); }; - class optic_ACO_grn_smg: ItemCore { - displayName = CSTRING(optic_ACO_grn_smg); - }; - - // APEX/Tanoa // QBZ-95 and variants class arifle_CTAR_base_F; @@ -1018,6 +863,16 @@ class CfgWeapons { // Contact/Livonia + // CZ 581 Shotgun + class sgun_HunterShotgun_01_base_F; + class sgun_HunterShotgun_01_F: sgun_HunterShotgun_01_base_F { + displayName = CSTRING(sgun_huntershotgun_01_Name); + }; + class sgun_HunterShotgun_01_sawedoff_base_F; + class sgun_HunterShotgun_01_sawedoff_F: sgun_HunterShotgun_01_sawedoff_base_F { + displayName = CSTRING(sgun_huntershotgun_sawedoff_01_Name); + }; + // FNX-45 (Green) class hgun_Pistol_heavy_01_green_F: hgun_Pistol_heavy_01_F { displayName = CSTRING(hgun_Pistol_heavy_01_green_Name); diff --git a/addons/realisticnames/stringtable.xml b/addons/realisticnames/stringtable.xml index 6130f6aaf4e..833c83db946 100644 --- a/addons/realisticnames/stringtable.xml +++ b/addons/realisticnames/stringtable.xml @@ -46,7 +46,7 @@ XM312 (Alta) XM312 (Magasított) XM312 (Alto) - XM312 (高) + XM312 (ハイマウント) XM312 (높음) XM312重機槍 (高射腳架) XM312(高) @@ -97,7 +97,7 @@ XM307 (Alta) XM307 (Magasított) XM307 (Alto) - XM307 (高) + XM307 (ハイマウント) XM307 (높음) XM307榴彈機槍 (高射腳架) XM307(高) @@ -556,7 +556,7 @@ Leopard 2SG Leopard 2SG Leopard 2SG - レオパルト 2SG + レオパルト2SG 레오파르트 2SG "豹2型新加坡版"主戰坦克 "豹"2 新加坡版 @@ -698,6 +698,12 @@ "卡玛兹"(医疗) KamAZ Medikal + + KamAZ Water + KamAZ Água + KamAZ 給水 + КамАЗ (водоноситель) + KamAZ MRL KamAS MRL @@ -1655,6 +1661,18 @@ FNX-45戰術型手槍 FNX-45 战术型 + + CZ 581 + CZ 581 + CZ 581 + CZ 581 + + + CZ 581 (Sawed-Off) + CZ 581 (Cano serrado) + CZ 581 (ソードオフ) + CZ 581 (Sawed-Off) + FNX-45 Tactical (Green) FNX-45 Tactical (Grün) @@ -2321,7 +2339,7 @@ Scorpion Evo 3 A1 Scorpion Evo 3 A1 Scorpion Evo 3 A1 - スコーピオン エボ 3 A1 + スコーピオン Evo 3 A1 스콜피온 에보 3 A1 "蠍式"Evo 3 A1衝鋒槍 Evo 3 A1 "蝎" @@ -2372,7 +2390,7 @@ Stoner 99 LMG Stoner 99 LMG Stoner 99 LMG - ストーナー 99 LMG + ストーナー99 LMG 스토너 99 LMG 斯通納99輕機槍 斯通纳 99 @@ -3056,6 +3074,24 @@ "柏拉格" 战斗无人机 Burraq UCAV + + Type 115 (Black) + Type 115 (Preto) + Type 115 (ブラック) + Type 115 (чёрный) + + + Type 115 (Green Hex) + Type 115 (Verde Hex) + Type 115 (緑六角形迷彩) + Type 115 (зелёный гекс) + + + Type 115 (Hex) + Type 115 (Hex) + Type 115 (六角形迷彩) + Type 115 (гекс) + QBZ-95-1 (Black) QBZ-95-1 (Černá) @@ -3651,7 +3687,7 @@ Polaris DAGOR (light) Polaris DAGOR (leicht) - ポラリス DAGOR (軽) + ポラリス DAGOR (軽装) "北極星"先進佈署越野車 (輕型) "北极星"(轻型) Polaris DAGOR (leggero) @@ -3840,6 +3876,24 @@ Wiesel 2 RFCV (Radar) 비젤 2 RFCV (레이더) + + UTG Defender 126 + UTG Defender 126 + UTG ディフェンダー 126 + UTG Defender 126 + + + EOTech MRDS + EOTech MRDS + EOTech MRDS + EOTech MRDS + + + EOTech MRDS (Black) + EOTech MRDS (Preto) + EOTech MRDS (ブラック) + EOTech MRDS (чёрный) + Leupold Mark 4 HAMR Leupold Mark 4 HAMR @@ -4272,7 +4326,7 @@ KAHLES Helia (Tan) KAHLES Helia (Tan) KAHLES Helia(沙色) - KAHLES Helia (タン) + KAHLES ヘリア (タン) KAHLES Helia (Tan) KAHLES Helia (Marroncino) KAHLES Helia (пустынный) diff --git a/addons/rearm/XEH_postInit.sqf b/addons/rearm/XEH_postInit.sqf index f156fb71d64..61ec35b8dec 100644 --- a/addons/rearm/XEH_postInit.sqf +++ b/addons/rearm/XEH_postInit.sqf @@ -1,9 +1,8 @@ #include "script_component.hpp" -GVAR(hardpointGroupsCache) = [] call CBA_fnc_createNamespace; GVAR(configTypesAdded) = []; -GVAR(magazineNameCache) = [] call CBA_fnc_createNamespace; -GVAR(originalMagazineNames) = []; +GVAR(magazineNameCache) = createHashMap; +GVAR(usedMagazineNames) = createHashMap; [QGVAR(initSupplyVehicle), { TRACE_1("initSupplyVehicle EH",_this); // Warning: this can run before settings are init diff --git a/addons/rearm/XEH_preStart.sqf b/addons/rearm/XEH_preStart.sqf index b092699f9b9..b013b04b860 100644 --- a/addons/rearm/XEH_preStart.sqf +++ b/addons/rearm/XEH_preStart.sqf @@ -4,6 +4,6 @@ // Test binarization one time at startup - ref https://github.com/acemod/ACE3/pull/8093 private _test = getText (configFile >> "Cfg3DEN" >> "Object" >> "AttributeCategories" >> "ace_attributes" >> "Attributes" >> "ace_rearm_rearmCargo" >> "defaultValue"); -if (!("else {" in _test)) then { +if !("else {" in _test) then { ERROR("3den attribute has ERROR [check binarization]"); }; diff --git a/addons/rearm/functions/fnc_getMagazineName.sqf b/addons/rearm/functions/fnc_getMagazineName.sqf index 2ee4a988ed9..e961831c8c4 100644 --- a/addons/rearm/functions/fnc_getMagazineName.sqf +++ b/addons/rearm/functions/fnc_getMagazineName.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* - * Author: PabstMirror - * Gets a non-ambigious display name for a magazine using displayNameShort (AP/HE) + * Author: PabstMirror, johnb43 + * Gets a non-ambigious display name for a magazine using displayNameShort (AP/HE). * * Arguments: * 0: Magazine Classname @@ -10,7 +10,7 @@ * Display Name * * Example: - * ["B_20mm_AP"] call ace_rearm_fnc_getMagazineName + * "60Rnd_20mm_AP_shells" call ace_rearm_fnc_getMagazineName * * Public: No */ @@ -18,31 +18,31 @@ params ["_className"]; TRACE_1("getMagazineName",_className); -private _magName = GVAR(magazineNameCache) getVariable _className; -if (isNil "_magName") then { - private _displayName = getText(configFile >> "CfgMagazines" >> _className >> "displayName"); +GVAR(magazineNameCache) getOrDefaultCall [_className, { + private _cfgMagazines = configFile >> "CfgMagazines"; + private _displayName = getText (_cfgMagazines >> _className >> "displayName"); + if (_displayName == "") then { _displayName = _className; WARNING_1("Magazine is missing display name [%1]",_className); }; - if ((_displayName select [0,6]) == "[CSW] ") then { _displayName = _displayName select [6]; }; + // [CSW] prefix is localised + if (["ace_csw"] call EFUNC(common,isModLoaded)) then { + _displayName = trim (_displayName regexReplace [LELSTRING(csw,regex), ""]); + }; - GVAR(magazineNameCache) setVariable [_className, _displayName]; - GVAR(originalMagazineNames) pushBack _displayName; - TRACE_2("Adding to cache",_className,_displayName); + // If the display name exists already, add displayNameShort to the existing entry + private _existingClassname = GVAR(usedMagazineNames) get _displayName; - // go through all existing cache entries and update if there now are duplicates - { - private _xMagName = GVAR(magazineNameCache) getVariable _x; - if ((_xMagName == _displayName) && {({_xMagName == _x} count GVAR(originalMagazineNames)) > 1}) then { - private _xMagName = format ["%1: %2", _displayName, getText(configFile >> "CfgMagazines" >> _x >> "displayNameShort")]; - GVAR(magazineNameCache) setVariable [_x, _xMagName]; - TRACE_2("Using unique name",_x,_xMagName); - }; - } forEach (allVariables GVAR(magazineNameCache)); + if (!isNil "_existingClassname") then { + GVAR(magazineNameCache) set [_existingClassname, format ["%1: %2", _displayName, getText (_cfgMagazines >> _existingClassname >> "displayNameShort")]]; - _magName = GVAR(magazineNameCache) getVariable _className; -}; + _displayName = format ["%1: %2", _displayName, getText (_cfgMagazines >> _className >> "displayNameShort")]; + }; + + GVAR(usedMagazineNames) set [_displayName, _className]; + TRACE_2("Adding to cache",_className,_displayName); -_magName + _displayName +}, true] // return diff --git a/addons/rearm/initSettings.inc.sqf b/addons/rearm/initSettings.inc.sqf index 37535d8d90e..6489bd9326c 100644 --- a/addons/rearm/initSettings.inc.sqf +++ b/addons/rearm/initSettings.inc.sqf @@ -7,7 +7,7 @@ private _category = [ELSTRING(main,Category_Logistics), LLSTRING(DisplayName)]; true, true, {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -15,8 +15,7 @@ private _category = [ELSTRING(main,Category_Logistics), LLSTRING(DisplayName)]; [LSTRING(RearmSettings_level_DisplayName), LSTRING(RearmSettings_level_Description)], _category, [[0,1,2],[LSTRING(RearmSettings_vehicle), LSTRING(RearmSettings_magazine), LSTRING(RearmSettings_caliber)],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(level), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -24,8 +23,7 @@ private _category = [ELSTRING(main,Category_Logistics), LLSTRING(DisplayName)]; [LSTRING(RearmSettings_supply_DisplayName), LSTRING(RearmSettings_supply_Description)], _category, [[0,1,2],[LSTRING(RearmSettings_unlimited), LSTRING(RearmSettings_limited), LSTRING(RearmSettings_magazineSupply)],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(supply), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -33,6 +31,5 @@ private _category = [ELSTRING(main,Category_Logistics), LLSTRING(DisplayName)]; [LLSTRING(RearmSettings_distance_DisplayName), LLSTRING(RearmSettings_distance_Description)], _category, [10, 50, 20, 0], - true, // isGlobal - {[QGVAR(supply), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; diff --git a/addons/refuel/ACE_Refuel_Positions.hpp b/addons/refuel/ACE_Refuel_Positions.hpp new file mode 100644 index 00000000000..78af5b6d48d --- /dev/null +++ b/addons/refuel/ACE_Refuel_Positions.hpp @@ -0,0 +1,96 @@ +class GVAR(positions) { + Altis[] = { /* Altis */ {"Land_fs_feed_F", {{3757,13478,0},{4001,12592,0},{5023,14430,0},{5769,20086,0},{6199,15081,0},{6798,15561,0},{8482,18261,0},{9026,15729,0},{9206,12112,0},{11832,14156,0},{12025,15830,0},{14173,16542,0},{14221,18303,0},{15297,17566,0},{15781,17453,0},{16751,12513,0},{16875,15469,0},{17417,13937,0},{19961,11454,0},{20785,16666,0},{21231,7117,0},{23379,19799,0},{25701,21373,0}}}}; + Stratis[] = { /* Stratis */ {"Land_FuelStation_Feed_F", {{2708,5788,0}}}}; + VR[] = {}; + Malden[] = { /* Malden 2035 */ + {"Land_fs_feed_F", {{3227,6291,0},{5111,9062,0},{5504,3500,0},{6633,8807,0},{7047,7052,0}}}, + {"Land_FuelStation_01_pump_malevil_F", {{7224,7772,0},{8047,4023,0}}}, + {"Land_FuelStation_Feed_F", {{10063,3988,0},{11600,4477,0}}} + }; + Tanoa[] = { /* Tanoa */ + {"Land_fs_feed_F", {{2132,3360,0},{2452,7435,0},{3030,11316,0},{5174,8806,0},{5380,4093,0},{5594,12508,0},{7978,7419,0},{8319,9709,0},{8494,12432,0},{8954,13678,0},{8970,10332,0},{10827,6490,0},{10941,9855,0},{11146,5152,0},{11631,2999,0},{14261,11513,0},{14365,8743,0}}}, + {"Land_FuelStation_01_pump_F", {{1865,12128,0},{5409,9905,0},{5682,10165,0},{5776,4222,0},{5793,10825,0},{6592,13080,0},{6887,7491,0},{7359,7998,0},{9954,13467,0},{11635,13047,0},{11694,2271,0},{12613,7583,0}}} + }; + Enoch[] = { /* Livonia */ + {"Land_FuelStation_03_pump_F", {{2008,7365,0},{6259,3949,0}}}, + {"Land_FuelStation_Feed_F", {{10208,2173,0}}} + }; + + Bootcamp_ACR[] = { /* CUP Bukovina */ {"Land_A_FuelStation_Feed", {{652,473,0},{2849,1612,0}}}}; + Woodland_ACR[] = { /* CUP Bystrica */ {"Land_A_FuelStation_Feed", {{447,1381,0},{1302,2185,0},{1855,6852,0},{4102,1195,0},{4755,4499,0}}}}; + chernarus[] = { /* CUP Chernarus (Autumn) */ {"Land_A_FuelStation_Feed", {{2021,2242,0},{2692,5602,0},{2997,7471,0},{3648,8968,0},{4733,6381,0},{5847,2191,0},{5849,10112,0},{6705,2996,0},{7255,7662,0},{9502,2005,0},{10154,5300,0},{10446,8866,0},{10726,10786,0},{12988,10076,0},{13385,6603,0}}}}; + chernarus_summer[] = { /* CUP Chernarus (Summer) */ {"Land_A_FuelStation_Feed", {{2021,2242,0},{2685,5606,0},{2998,7473,0},{3652,8973,0},{4733,6381,0},{5854,2193,0},{5849,10112,0},{6702,2995,0},{7255,7662,0},{9502,2005,0},{10154,5300,0},{10452,8869,0},{10726,10786,0},{13001,10074,0},{13398,6606,0}}}}; + Chernarus_Winter[] = { /* CUP Chernarus (Winter) */ {"Land_A_FuelStation_Feed", {{2021,2242,0},{2685,5604,0},{2997,7471,0},{3657,8979,0},{4733,6381,0},{5854,2193,0},{5849,10112,0},{6702,2995,0},{7255,7662,0},{9503,2019,0},{10155,5309,0},{10452,8869,0},{10726,10786,0},{12994,10075,0},{13385,6603,0}}}}; + cup_chernarus_A3[] = { /* CUP Chernarus 2020 */ + {"Land_fs_feed_F", {{2511,5279,0}}}, + {"Land_FuelStation_03_pump_F", {{313,9385,0},{1129,2400,0},{2021,2242,0},{2692,5602,0},{2991,7471,1},{3007,12654,0},{3648,8968,0},{4328,13081,0},{4733,6381,0},{5847,2191,0},{5849,10112,0},{6699,3001,0},{7255,7662,0},{7494,12662,0},{9502,2005,0},{10155,5309,0},{10452,8869,0},{10726,10786,0},{13001,10074,0},{13398,6606,0},{13569,13329,0}}} + }; + Desert_E[] = { /* CUP Desert */ }; + porto[] = { /* CUP Porto */ }; + ProvingGrounds_PMC[] = { /* CUP Proving Grounds */ {"Land_FuelStation_Feed_PMC", {{698,1208,0}}}}; + intro[] = { /* CUP Rahmadi */ }; + sara[] = { /* CUP Sahrani */ + {"Land_Benzina_schnell", {{8473,9423,0},{9227,5840,0},{9433,5187,0},{10168,6423,0},{10932,9475,0},{11233,6114,0},{11756,10227,0},{12289,6833,0}}}, + {"Land_Fuelstation_army", {{9568,9819,0},{19294,13879,0}}} + }; + sara_dbe1[] = { /* CUP United Sahrani */ + {"Land_Benzina_schnell", {{8473,9423,0},{9227,5840,0},{9433,5187,0},{10168,6423,0},{10932,9475,0},{11233,6114,0},{11756,10227,0},{12289,6833,0}}}, + {"Land_Fuelstation_army", {{9568,9819,0},{19294,13879,0}}} + }; + saralite[] = { /* CUP Southern Sahrani */ + {"Land_Benzina_schnell", {{3593,6663,0},{4347,3080,0},{4553,2427,0},{5288,3663,0},{6052,6715,0},{6353,3354,0},{6876,7467,0},{7409,4073,0}}}, + {"Land_Fuelstation_army", {{4688,7059,0}}} + }; + Shapur_BAF[] = { /* CUP Shapur */ {"Land_Ind_FuelStation_Feed_EP1", {{1512,1298,0}}}}; + takistan[] = { /* CUP Takistan */ {"Land_Ind_FuelStation_Feed_EP1", {{2004,11720,0},{3081,9848,0},{3549,4197,0},{5538,9284,0},{5836,5771,0},{7497,1818,0},{8248,7800,0},{10422,6328,0},{10647,11021,0}}}}; + Mountains_ACR[] = { /* CUP Takistan Mountains */ {"Land_Ind_FuelStation_Feed_EP1", {{2962,4197,0},{5249,5771,0}}}}; + utes[] = { /* CUP Utes */ }; + zargabad[] = { /* CUP Zargabad */ {"Land_Ind_FuelStation_Feed_EP1", {{3736,2784,0},{3867,4208,0},{3871,5980,0},{5027,1906,0}}}}; + + pja310[] = { /* G.O.S Al Rayak */ {"Land_Ind_FuelStation_Feed_EP1", {{887,18588,0},{964,18356,0},{1196,18463,0},{1872,8754,0},{2051,8437,0},{2125,8238,0},{2240,8584,0},{2310,8566,0},{2366,3901,0},{2879,13142,0},{3880,10361,0},{4056,13261,0},{4122,13487,0},{4302,13628,0},{4475,13377,0},{4556,13742,0},{6461,3372,0},{7216,6059,0},{7228,6344,0},{7416,6099,0},{7472,6838,0},{7591,6081,0},{11650,3536,0},{14863,7292,0},{16466,18897,0},{16476,19116,0},{16642,18994,0},{16676,19199,0},{16858,10558,0},{16908,9959,0},{17120,3706,0},{17100,4375,0},{18056,4133,0},{18229,4066,0},{18235,4571,0},{18814,5010,0}}}}; + australia[] = { /* Aussie Australia v5.09 */ + {"Land_fs_feed_F", {{4614,16978,0},{5509,19273,0},{5487,19276,0},{5508,19330,0},{5540,19357,0},{5564,19377,0},{5623,19376,0},{5643,19352,0},{6355,17860,0},{12811,27772,0},{15837,33438,0},{16335,33436,0},{16367,33436,0},{17127,33902,0},{20754,12737,0},{20874,12793,0},{20901,12793,1},{22127,25635,0},{22127,25666,0},{22162,25712,0},{22194,25712,0},{22213,25630,0},{22315,19235,0},{22595,24757,0},{24909,13855,0},{25050,12786,0},{25071,12786,0},{26085,11260,1},{26212,11174,0},{26824,28005,0},{27719,17108,0},{27757,12033,0},{28473,35132,0},{30707,11879,0},{31091,5370,0},{31096,10918,0},{31096,10945,0},{31165,10914,0},{31165,10958,0},{31313,16763,0},{31515,9673,0},{31515,9652,0},{31758,4861,0},{32224,2736,0},{33919,13364,0},{33936,13350,0},{34789,26383,0},{35274,26021,2},{35786,12148,0},{35765,12170,0},{35835,12145,0},{35833,12188,0},{35812,12210,0},{36199,16479,0},{36399,13140,0},{36593,12065,0},{36574,13089,0},{36595,13089,0},{36597,13282,0},{38153,14544,0},{38520,18891,0},{38515,20173,0},{38535,20198,0},{38565,20198,0}}}, + {"Land_FuelStation_01_pump_F", {{5495,18693,0},{32067,29608,0},{32087,29611,0},{33215,4147,0},{37293,13172,0},{37293,13193,0}}}, + {"Land_FuelStation_Feed_F", {{19303,16449,0},{31064,20116,0}}} + }; + Farabad[] = { /* Farabad */ + {"Land_Benzina_schnell", {{592,7505,0},{804,1445,0},{3132,3129,0}}}, + {"Land_fs_feed_F", {{1920,4960,0},{5052,4703,1},{9456,9277,0}}}, + {"Land_FuelStation_01_pump_F", {{2378,6248,0},{7092,534,0}}}, + {"Land_Ind_FuelStation_Feed_EP1", {{4788,5525,0}}} + }; + IslaPera[] = { /* Isla Pera */ + {"Land_fs_feed_F", {{1855,2866,0}}}, + {"Land_FuelStation_01_pump_malevil_F", {{3981,2065,0},{5306,8796,0},{9236,4287,0}}} + }; + VTF_Lybor[] = { /* Lybor */ + {"Land_FuelStation_03_pump_F", {{3879,3823,0}}}, + {"Land_FuelStation_Feed_F", {{1831,2694,0},{2175,3323,0},{3304,2981,0},{4271,3024,0}}} + }; + rof_mok[] = { /* Mull of Kintyre, Scotland */ + {"Land_A_FuelStation_Feed", {{12837,5124,1},{15271,17533,0},{19453,21896,0}}}, + {"Land_fs_feed_F", {{7492,17369,0}}}, + {"Land_Fuelstation", {{10284,18679,0}}}, + {"Land_Ind_FuelStation_Feed_EP1", {{9762,16325,0}}} + }; + pulau[] = { /* Pulau */ + {"Land_fs_feed_F", {{2368,3128,0},{4891,7168,0},{7358,7368,0}}}, + {"Land_FuelStation_Feed_F", {{5994,5789,0}}} + }; + WL_Rosche[] = { /* Rosche, Germany (2.0) */ + {"Land_fs_feed_F", {{693,4803,0},{12059,6700,0},{13320,14822,0}}}, + {"Land_FuelStation_01_pump_F", {{447,6859,0}}}, + {"Land_Ind_FuelStation_Feed_EP1", {{1437,5455,0}}} + }; + Kapaulio[] = { /* Saint Kapaulio */ + {"Land_fs_feed_F", {{931,7647,0},{958,6796,0},{2034,9426,0},{2563,9427,0},{3500,8110,0},{3602,6082,0},{4222,6308,0},{4561,693,0},{8077,5906,0},{8434,13145,0},{8525,17299,0},{9265,7155,0},{10527,18267,0},{12078,1846,0},{12833,6464,0},{13433,6327,0},{14084,6308,0},{14172,7786,0},{14831,4649,0},{16080,14743,0},{17356,2312,0},{18047,5254,0},{18318,5042,0}}}, + {"Land_FuelStation_01_pump_malevil_F", {{18039,18139,0}}}, + {"Land_FuelStation_Feed_F", {{756,12133,0},{1239,7346,0},{1726,17469,0},{3113,10070,0},{3828,8362,0},{5668,16967,0},{7435,14185,0},{7543,12107,0},{8366,6086,0},{9672,9586,0},{11749,12255,0},{12802,10022,0},{13989,3591,0},{15198,10900,0},{19063,1654,0},{19378,18517,0}}} + }; + pabst_yellowstone[] = { /* Yellowstone */ + {"Land_fs_feed_F", {{3075,7426,0},{7060,3626,0},{7950,4060,0},{7974,4072,0}}}, + {"Land_FuelStation_01_pump_F", {{4565,1953,0}}}, + {"Land_FuelStation_01_pump_malevil_F", {{7072,3676,0}}}, + {"Land_FuelStation_Feed_F", {{4678,3971,0},{6391,5174,0}}} + }; +}; diff --git a/addons/refuel/Cfg3DEN.hpp b/addons/refuel/Cfg3DEN.hpp index 33831079955..00d5453d955 100644 --- a/addons/refuel/Cfg3DEN.hpp +++ b/addons/refuel/Cfg3DEN.hpp @@ -1,7 +1,4 @@ -#define GET_NUMBER(config,default) (if (isNumber (config)) then {getNumber (config)} else {default}) #define GET_1ST_ARRAY(config) (if (isArray (config)) then {getArray (config) select 0} else {[ARR_3(0,0,0)]}) - -#define DEFAULT_FUELCARGO GET_NUMBER(configOf _this >> QQGVAR(fuelCargo),REFUEL_DISABLED_FUEL) #define DEFAULT_HOOKS GET_1ST_ARRAY(configOf _this >> QQGVAR(hooks)) class Cfg3DEN { @@ -14,8 +11,8 @@ class Cfg3DEN { tooltip = CSTRING(fuelCargo_edenDesc); property = QGVAR(fuelCargo); control = "EditShort"; - expression = QUOTE(if (_value != DEFAULT_FUELCARGO) then {[ARR_2(_this,_value)] call DFUNC(makeSource)}); - defaultValue = QUOTE(DEFAULT_FUELCARGO); + expression = QUOTE(if (_value != (_this call FUNC(getFuelCargo))) then {[ARR_2(_this,_value)] call FUNC(makeSource)}); + defaultValue = QUOTE(_this call FUNC(getFuelCargo)); validate = "number"; condition = "(1-objectBrain)*(1-objectAgent)"; typeName = "NUMBER"; diff --git a/addons/refuel/CfgVehicles.hpp b/addons/refuel/CfgVehicles.hpp index 5fba3369434..44575a141d7 100644 --- a/addons/refuel/CfgVehicles.hpp +++ b/addons/refuel/CfgVehicles.hpp @@ -1,3 +1,5 @@ +#define XEH_INHERITED class EventHandlers {class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {};} + class CBA_Extended_EventHandlers; class CfgNonAIVehicles { @@ -45,9 +47,7 @@ class CfgVehicles { class ThingX; class GVAR(fuelNozzle): ThingX { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; + XEH_INHERITED; displayName = QGVAR(fuelNozzle); scope = 1; @@ -275,12 +275,6 @@ class CfgVehicles { GVAR(hooks)[] = {{0.38,-3.17,-0.7},{-0.41,-3.17,-0.7}}; GVAR(fuelCargo) = 2000; }; - class C_Van_01_fuel_F: Van_01_fuel_base_F { - transportFuel = 0; //1k - }; - class I_G_Van_01_fuel_F: Van_01_fuel_base_F { - transportFuel = 0; //1k - }; class Tank_F: Tank { GVAR(fuelCapacity) = 1200; @@ -295,7 +289,6 @@ class CfgVehicles { class B_APC_Tracked_01_base_F: APC_Tracked_01_base_F {}; class B_APC_Tracked_01_CRV_F: B_APC_Tracked_01_base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{-1.08,-4.81,-0.8}}; GVAR(fuelCargo) = 1000; }; @@ -407,7 +400,6 @@ class CfgVehicles { // Vanilla fuel vehicles class Truck_02_fuel_base_F: Truck_02_base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{0.99,-3.47,-0.67},{-1.04,-3.47,-0.67}}; GVAR(fuelCargo) = 10000; }; @@ -416,13 +408,11 @@ class CfgVehicles { }; class B_Truck_01_fuel_F: B_Truck_01_mover_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{0.28,-4.99,-0.3},{-0.25,-4.99,-0.3}}; GVAR(fuelCargo) = 10000; }; class O_Truck_03_fuel_F: Truck_03_base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{1.3,-1.59,-0.62},{-1.16,-1.59,-0.62}}; GVAR(fuelCargo) = 10000; }; @@ -436,20 +426,17 @@ class CfgVehicles { class Pod_Heli_Transport_04_base_F: Slingload_base_F {}; class Land_Pod_Heli_Transport_04_fuel_F: Pod_Heli_Transport_04_base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{-1.49,1.41,-0.3}}; GVAR(fuelCargo) = 10000; }; class Slingload_01_Base_F: Slingload_base_F {}; class B_Slingload_01_Fuel_F: Slingload_01_Base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{0.55,3.02,-0.5},{-0.52,3.02,-0.5}}; GVAR(fuelCargo) = 10000; }; class O_Heli_Transport_04_fuel_F: Heli_Transport_04_base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{-1.52,1.14,-1.18}}; GVAR(fuelCargo) = 10000; }; @@ -466,11 +453,7 @@ class CfgVehicles { }; }; class Land_StorageBladder_01_F: StorageBladder_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - - transportFuel = 0; //60k + XEH_INHERITED; GVAR(hooks)[] = {{-3.35,2.45,0.17}}; GVAR(fuelCargo) = 60000; }; @@ -486,36 +469,35 @@ class CfgVehicles { }; }; class Land_FlexibleTank_01_F: FlexibleTank_base_F { - transportFuel = 0; //300 GVAR(hooks)[] = {{0, 0, 0.5}}; GVAR(fuelCargo) = 300; }; // Vanilla buildings class Land_Fuelstation_Feed_F: House_Small_F { - transportFuel = 0; //50k + XEH_INHERITED; GVAR(hooks)[] = {{0,0,-0.5}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_fs_feed_F: House_Small_F { - transportFuel = 0; //50k + XEH_INHERITED; GVAR(hooks)[] = {{-0.4,0.022,-0.23}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_FuelStation_01_pump_F: House_F { - transportFuel = 0; //50k + XEH_INHERITED; GVAR(hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_FuelStation_01_pump_malevil_F: House_F { - transportFuel = 0; //50k + XEH_INHERITED; GVAR(hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_FuelStation_03_pump_F: House_F { // Enoch - transportFuel = 0; //50k + XEH_INHERITED; GVAR(hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; diff --git a/addons/refuel/XEH_PREP.hpp b/addons/refuel/XEH_PREP.hpp index 077c8f1aed7..cb9279500bc 100644 --- a/addons/refuel/XEH_PREP.hpp +++ b/addons/refuel/XEH_PREP.hpp @@ -11,6 +11,7 @@ PREP(disconnect); PREP(dropNozzle); PREP(getCapacity); PREP(getFuel); +PREP(getFuelCargo); PREP(handleDisconnect); PREP(handleRespawn); PREP(initSource); diff --git a/addons/refuel/XEH_postInit.sqf b/addons/refuel/XEH_postInit.sqf index c826efd3d45..f6f5a7d7b36 100644 --- a/addons/refuel/XEH_postInit.sqf +++ b/addons/refuel/XEH_postInit.sqf @@ -1,95 +1,151 @@ #include "script_component.hpp" -if (isServer) then { - addMissionEventHandler ["HandleDisconnect", {call FUNC(handleDisconnect)}]; -}; +["CBA_settingsInitialized", { + if (!GVAR(enabled)) exitWith {}; -[QGVAR(initSource), LINKFUNC(initSource)] call CBA_fnc_addEventHandler; + ["All", "InitPost", { + params ["_vehicle"]; + if (getFuelCargo _vehicle <= 0) exitWith {}; + TRACE_1("initPost",_vehicle); -if (!hasInterface) exitWith {}; + if (local _vehicle) then { + _vehicle setFuelCargo 0; + LOG("initPost setFuelCargo"); + }; + }, true, ["Man"], true] call CBA_fnc_addClassEventHandler; -["isNotRefueling", {!((_this select 0) getVariable [QGVAR(isRefueling), false])}] call EFUNC(common,addCanInteractWithCondition); + if (isServer) then { + addMissionEventHandler ["HandleDisconnect", {call FUNC(handleDisconnect)}]; + }; -["MouseButtonDown", LINKFUNC(onMouseButtonDown)] call CBA_fnc_addDisplayHandler; + private _cfgPositions = configFile >> QGVAR(positions) >> worldName; + if (isArray _cfgPositions) then { + { + _x params ["_class", "_positions"]; + { + private _objects = _x nearObjects [_class, 30]; + if (_objects isEqualTo []) then { + WARNING_3("no pumps %1 found near %2 %3",_class,worldName,_x); + } else { + { + // terrain fuel pumps don't trigger init and must setFuelCargo on each client + _x setFuelCargo 0; + } forEach _objects; + }; + } forEach _positions; + } forEach getArray _cfgPositions; -GVAR(mainAction) = [ - QGVAR(Refuel), - localize LSTRING(Refuel), - QPATHTOF(ui\icon_refuel_interact.paa), - {}, - { - alive _target - && {[_player, _target, [INTERACT_EXCEPTIONS]] call EFUNC(common,canInteractWith)} - && {REFUEL_DISABLED_FUEL != ([_target] call FUNC(getCapacity))} - }, - {}, [], [0,0,0], - REFUEL_ACTION_DISTANCE -] call EFUNC(interact_menu,createAction); - -GVAR(actions) = [ - [QGVAR(TakeNozzle), - localize LSTRING(TakeNozzle), - QPATHTOF(ui\icon_refuel_interact.paa), - {[_player, _target] call FUNC(TakeNozzle)}, - {[_player, _target] call FUNC(canTakeNozzle)}, - {}, [], [0,0,0], - REFUEL_ACTION_DISTANCE - ] call EFUNC(interact_menu,createAction), - [QGVAR(CheckFuelCounter), - localize LSTRING(CheckFuelCounter), - QPATHTOF(ui\icon_refuel_interact.paa), - {[_player, _target] call FUNC(readFuelCounter)}, - {true}, - {}, [], [0,0,0], - REFUEL_ACTION_DISTANCE - ] call EFUNC(interact_menu,createAction), - [QGVAR(CheckFuel), - localize LSTRING(CheckFuel), - QPATHTOF(ui\icon_refuel_interact.paa), - {[_player, _target] call FUNC(checkFuel)}, - {[_player, _target] call FUNC(canCheckFuel)}, - {}, [], [0,0,0], - REFUEL_ACTION_DISTANCE - ] call EFUNC(interact_menu,createAction), - [QGVAR(Return), - localize LSTRING(Return), + // placed in editor static objects don't trigger init but synchronize fuel cargo + // placed in editor vehicles both trigger init and synchronize fuel cargo + { + if (getFuelCargo _x > 0 && {local _x}) then { + TRACE_1("allMissionObjects",_x); + _x setFuelCargo 0; + }; + } forEach allMissionObjects ""; + } else { + // here are both terrain and editor static objects + WARNING_2("World %1: %2 is not configured; can load slower",worldName,QGVAR(positions)); + private _halfWorldSize = worldSize / 2; + private _worldCenter = [_halfWorldSize, _halfWorldSize]; + _halfWorldSize = _halfWorldSize * sqrt 2; + private _refuelMissionObjects = allMissionObjects "" select {getFuelCargo _x > 0}; + private _baseStaticClasses = keys (uiNamespace getVariable QGVAR(cacheRefuelClassesBaseStatic)); + + { + { + _x setFuelCargo 0; + } forEach (_worldCenter nearObjects [_x, _halfWorldSize]); + } forEach _baseStaticClasses; + }; + + [QGVAR(initSource), LINKFUNC(initSource)] call CBA_fnc_addEventHandler; + + if (!hasInterface) exitWith {}; + + ["isNotRefueling", {!((_this select 0) getVariable [QGVAR(isRefueling), false])}] call EFUNC(common,addCanInteractWithCondition); + + ["MouseButtonDown", LINKFUNC(onMouseButtonDown)] call CBA_fnc_addDisplayHandler; + + GVAR(mainAction) = [ + QGVAR(Refuel), + localize LSTRING(Refuel), QPATHTOF(ui\icon_refuel_interact.paa), - {[_player, _target] call FUNC(returnNozzle)}, - {[_player, _target] call FUNC(canReturnNozzle)}, + {}, + { + alive _target + && {[_player, _target, [INTERACT_EXCEPTIONS]] call EFUNC(common,canInteractWith)} + && {REFUEL_DISABLED_FUEL != ([_target] call FUNC(getCapacity))} + }, {}, [], [0,0,0], REFUEL_ACTION_DISTANCE - ] call EFUNC(interact_menu,createAction) -]; + ] call EFUNC(interact_menu,createAction); -// init menu for config refuel vehicles -private _cacheRefuelClasses = call (uiNamespace getVariable [QGVAR(cacheRefuelClasses), {[[],[]]}]); -_cacheRefuelClasses params [["_staticClasses", [], [[]]], ["_dynamicClasses", [], [[]]]]; + GVAR(actions) = [ + [QGVAR(TakeNozzle), + localize LSTRING(TakeNozzle), + QPATHTOF(ui\icon_refuel_interact.paa), + {[_player, _target] call FUNC(TakeNozzle)}, + {[_player, _target] call FUNC(canTakeNozzle)}, + {}, [], [0,0,0], + REFUEL_ACTION_DISTANCE + ] call EFUNC(interact_menu,createAction), + [QGVAR(CheckFuelCounter), + localize LSTRING(CheckFuelCounter), + QPATHTOF(ui\icon_refuel_interact.paa), + {[_player, _target] call FUNC(readFuelCounter)}, + {true}, + {}, [], [0,0,0], + REFUEL_ACTION_DISTANCE + ] call EFUNC(interact_menu,createAction), + [QGVAR(CheckFuel), + localize LSTRING(CheckFuel), + QPATHTOF(ui\icon_refuel_interact.paa), + {[_player, _target] call FUNC(checkFuel)}, + {[_player, _target] call FUNC(canCheckFuel)}, + {}, [], [0,0,0], + REFUEL_ACTION_DISTANCE + ] call EFUNC(interact_menu,createAction), + [QGVAR(Return), + localize LSTRING(Return), + QPATHTOF(ui\icon_refuel_interact.paa), + {[_player, _target] call FUNC(returnNozzle)}, + {[_player, _target] call FUNC(canReturnNozzle)}, + {}, [], [0,0,0], + REFUEL_ACTION_DISTANCE + ] call EFUNC(interact_menu,createAction) + ]; -{ - private _className = _x; - [_className, 0, ["ACE_MainActions"], GVAR(mainAction)] call EFUNC(interact_menu,addActionToClass); - { - [_className, 0, ["ACE_MainActions", QGVAR(Refuel)], _x] call EFUNC(interact_menu,addActionToClass); - } forEach GVAR(actions); - TRACE_1("add menu to static",_x); -} forEach _staticClasses; - -{ - private _className = _x; - [_className, 0, ["ACE_MainActions"], GVAR(mainAction), true] call EFUNC(interact_menu,addActionToClass); + private _staticClasses = keys (uiNamespace getVariable QGVAR(cacheRefuelClassesStatic)); + private _baseDynamicClasses = keys (uiNamespace getVariable QGVAR(cacheRefuelClassesBaseDynamic)); + + // init menu for config refuel vehicles { - [_className, 0, ["ACE_MainActions", QGVAR(Refuel)], _x, true] call EFUNC(interact_menu,addActionToClass); - } forEach GVAR(actions); - TRACE_1("add menu to dynamic",_x); -} forEach _dynamicClasses; - -#ifdef DRAW_HOOKS_POS -addMissionEventHandler ["Draw3D", { - private _source = cursorObject; - private _cfgPos = getArray (configOf _source >> QGVAR(hooks)); - private _dynPos = _source getVariable [QGVAR(hooks), []]; + private _className = _x; + [_className, 0, ["ACE_MainActions"], GVAR(mainAction)] call EFUNC(interact_menu,addActionToClass); + { + [_className, 0, ["ACE_MainActions", QGVAR(Refuel)], _x] call EFUNC(interact_menu,addActionToClass); + } forEach GVAR(actions); + TRACE_1("add menu to static",_x); + } forEach _staticClasses; + { - drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", [1,1,1,1], _source modelToWorldVisual _x, 1, 1, 0, format ["Hook %1", _forEachIndex]]; - } forEach ([_dynPos, _cfgPos] select (_dynPos isEqualTo [])); -}]; -#endif + private _className = _x; + [_className, 0, ["ACE_MainActions"], GVAR(mainAction), true] call EFUNC(interact_menu,addActionToClass); + { + [_className, 0, ["ACE_MainActions", QGVAR(Refuel)], _x, true] call EFUNC(interact_menu,addActionToClass); + } forEach GVAR(actions); + TRACE_1("add menu to dynamic",_x); + } forEach _baseDynamicClasses; + + #ifdef DRAW_HOOKS_POS + addMissionEventHandler ["Draw3D", { + private _source = cursorObject; + private _cfgPos = getArray (configOf _source >> QGVAR(hooks)); + private _dynPos = _source getVariable [QGVAR(hooks), _cfgPos]; + { + drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", [1,1,1,1], _source modelToWorldVisual _x, 1, 1, 0, format ["Hook %1", _forEachIndex]]; + } forEach _dynPos; + }]; + #endif +}] call CBA_fnc_addEventHandler; diff --git a/addons/refuel/XEH_preStart.sqf b/addons/refuel/XEH_preStart.sqf index fa5fe4acda1..308ca30a9b9 100644 --- a/addons/refuel/XEH_preStart.sqf +++ b/addons/refuel/XEH_preStart.sqf @@ -4,27 +4,44 @@ // cache refuel vehicles, see XEH_postInit.sqf private _staticClasses = []; -private _dynamicClasses = []; +private _baseStaticClasses = []; +private _baseDynamicClasses = []; +private _cacheRefuelCargo = createHashMap; { - private _fuelCargo = getNumber (_x >> QGVAR(fuelCargo)); + private _transportFuel = getNumber (_x >> "transportFuel"); + private _fuelCargo = [_x >> QGVAR(fuelCargo), "NUMBER", _transportFuel] call CBA_fnc_getConfigEntry; if (_fuelCargo > 0 || {_fuelCargo == REFUEL_INFINITE_FUEL}) then { private _sourceClass = configName _x; + private _noXEH = !isText (_x >> "EventHandlers" >> "CBA_Extended_EventHandlers" >> "init"); + private _isPublic = getNumber (_x >> "scope") == 2; // check if we can use actions with inheritance if ( - !isText (_x >> "EventHandlers" >> "CBA_Extended_EventHandlers" >> "init") // addActionToClass relies on XEH init - || {configName _x isKindOf "Static"} // CBA_fnc_addClassEventHandler doesn't support "Static" class + _noXEH // addActionToClass relies on XEH init + || {_sourceClass isKindOf "Static"} // CBA_fnc_addClassEventHandler doesn't support "Static" class ) then { - if (2 == getNumber (_x >> "scope")) then { - _staticClasses pushBackUnique _sourceClass; + if (_isPublic) then { + if (_noXEH) then { + WARNING_3("Class %1: %2 [%3] needs XEH",_sourceClass,configName inheritsFrom _x,configSourceMod _x); + }; + _staticClasses pushBack _sourceClass; + if (_baseStaticClasses findIf {_sourceClass isKindOf _x} == -1) then { + _baseStaticClasses pushBack _sourceClass; + }; }; } else { - if (-1 == _dynamicClasses findIf {_sourceClass isKindOf _x}) then { - _dynamicClasses pushBackUnique _sourceClass; + if (_baseDynamicClasses findIf {_sourceClass isKindOf _x} == -1) then { + _baseDynamicClasses pushBack _sourceClass; }; }; + if (_isPublic) then { + _cacheRefuelCargo set [_sourceClass, _fuelCargo]; + }; }; -} forEach ('true' configClasses (configFile >> "CfgVehicles")); +} forEach ("true" configClasses (configFile >> "CfgVehicles")); -TRACE_2("compiled",count _staticClasses,count _dynamicClasses); -uiNamespace setVariable [QGVAR(cacheRefuelClasses), compileFinal str [_staticClasses, _dynamicClasses]]; +TRACE_3("found",count _staticClasses,count _baseStaticClasses,count _baseDynamicClasses); +uiNamespace setVariable [QGVAR(cacheRefuelClassesStatic), compileFinal (_staticClasses createHashMapFromArray [])]; +uiNamespace setVariable [QGVAR(cacheRefuelClassesBaseStatic), compileFinal (_baseStaticClasses createHashMapFromArray [])]; +uiNamespace setVariable [QGVAR(cacheRefuelClassesBaseDynamic), compileFinal (_baseDynamicClasses createHashMapFromArray [])]; +uiNamespace setVariable [QGVAR(cacheRefuelCargo), compileFinal _cacheRefuelCargo]; diff --git a/addons/refuel/config.cpp b/addons/refuel/config.cpp index b39b6650594..79b97994f17 100644 --- a/addons/refuel/config.cpp +++ b/addons/refuel/config.cpp @@ -14,6 +14,7 @@ class CfgPatches { }; }; +#include "ACE_Refuel_Positions.hpp" #include "ACE_Settings.hpp" #include "Cfg3DEN.hpp" #include "CfgEventHandlers.hpp" diff --git a/addons/refuel/dev/exportTerrainRefuelPositions.sqf b/addons/refuel/dev/exportTerrainRefuelPositions.sqf new file mode 100644 index 00000000000..c7f9abfb2fd --- /dev/null +++ b/addons/refuel/dev/exportTerrainRefuelPositions.sqf @@ -0,0 +1,95 @@ +// call compileScript ["z\ace\addons\refuel\dev\exportTerrainRefuelPositions.sqf"] +// can be run in Eden Editor console + +#include "\z\ace\addons\refuel\script_component.hpp" + +{ + if (!isArray (configFile >> QGVAR(positions) >> configName _x)) then { + WARNING_1("need configs on [%1]",configName _x); + }; +} forEach ("true" configClasses (configFile >> "CfgWorldList")); + + + +private _basePumps = []; +private _totalCount = 0; +private _posCount = 0; +private _message = ""; +private _halfWorldSize = worldSize / 2; +private _worldCenter = [_halfWorldSize, _halfWorldSize]; +_halfWorldSize = _halfWorldSize * sqrt 2; + +private _baseStaticClasses = keys (uiNamespace getVariable QGVAR(cacheRefuelClassesBaseStatic)); +private _class = ""; +private _objects = []; +private _positions = []; +private _object = objNull; +private _pos = []; + +{ + _class = _x; + _objects = _worldCenter nearObjects [_class, _halfWorldSize]; + if (_objects isEqualTo []) then { + continue; + }; + ADD(_totalCount,count _objects); + _positions = []; + { + _object = _x; + _pos = ASLToAGL getPosASL _object; + if (-1 < _positions findIf {60 > _x distance _pos && {20 < _x distance _pos}}) then { + _message = "INCREASE DISTANCE " + str _pos; + }; + if (-1 == _positions findIf {20 > _x distance _pos}) then { + _positions pushBack (_pos apply {round _x}); + INC(_posCount); + }; + } forEach _objects; + _positions sort true; // sort positions by smallest first + _basePumps pushBack [_class, _positions]; +} forEach _baseStaticClasses; + +_basePumps sort true; // sort pump classes alphabetically + +// check final array as it's calculated in postInit +private _checkCount = 0; +{ + _x params ["_class", "_positions"]; + private _pumps = []; + { + _pumps append (_x nearObjects [_class, 30]); + } forEach _positions; + _pumps = _pumps arrayIntersect _pumps; + _checkCount = _checkCount + count _pumps; +} forEach _basePumps; +if (_checkCount != _totalCount) then { + _message = "WRONG COUNT " + str _checkCount; +}; + +// export text +private _nl = toString [10]; +private _multipleBasePumps = 1 < count _basePumps; +private _output = [format [" %1[] = { /* %2 */", worldName, getText (configfile >> "CfgWorlds" >> worldName >> "description")]]; +{ + if (_forEachIndex > 0) then {_output pushBack ","}; + _x params ["_class", "_positions"]; + if (_multipleBasePumps) then { + _output pushBack (_nl + " "); + } else { + _output pushBack " "; + }; + _output pushBack format ["{""%1"", {", _class]; + { + if (_forEachIndex > 0) then {_output pushBack ","}; + _output pushBack format ["{%1,%2,%3}", _x#0, _x#1, _x#2]; + } forEach _positions; + _output pushBack "}}"; +} forEach _basePumps; +if (_multipleBasePumps) then {_output pushBack (_nl + " ")}; +if (_basePumps isEqualTo []) then {_output pushBack " "}; +_output pushBack ("};" + _nl); + +_output = _output joinString ""; + +copyToClipboard _output; +[_totalCount, _posCount, _message, _output] diff --git a/addons/refuel/dev/test_debugConfigs.sqf b/addons/refuel/dev/test_debugConfigs.sqf index f427f07d28c..52ff8a962ae 100644 --- a/addons/refuel/dev/test_debugConfigs.sqf +++ b/addons/refuel/dev/test_debugConfigs.sqf @@ -5,14 +5,14 @@ private _testPass = true; -diag_log text format ["[ACE-refuel] Showing CfgVehicles with vanilla transportFuel"]; -private _fuelTrucks = configProperties [configFile >> "CfgVehicles", "(isClass _x) && {(getNumber (_x >> 'transportFuel')) > 0}", true]; +INFO("Showing CfgVehicles with transportFuel and without XEH"); +private _badCfgVehicles = ' + 2 == getNumber (_x >> "scope") + && {0 < getNumber (_x >> "transportFuel")} + && {!isText (_x >> "EventHandlers" >> "CBA_Extended_EventHandlers" >> "init")} +' configClasses (configFile >> "CfgVehicles"); { - if ((configName _x) isKindOf "Car") then { - diag_log text format ["Car [%1] needs config [transportFuel: %2]", configName _x, getNumber (_x >> 'transportFuel')]; - } else { - diag_log text format ["Non-car? [%1] needs config [transportFuel: %2]", configName _x, getNumber (_x >> 'transportFuel')]; - }; -} forEach _fuelTrucks; + diag_log text format ["Class %1: %2 [%3] needs XEH", configName _x, configName inheritsFrom _x, configSourceMod _x]; +} forEach _badCfgVehicles; _testPass diff --git a/addons/refuel/functions/fnc_getFuelCargo.sqf b/addons/refuel/functions/fnc_getFuelCargo.sqf new file mode 100644 index 00000000000..360679013e4 --- /dev/null +++ b/addons/refuel/functions/fnc_getFuelCargo.sqf @@ -0,0 +1,20 @@ +#include "..\script_component.hpp" +/* + * Author: Dystopian + * Returns vehicle fuel amount from config (cached). + * + * Arguments: + * 0: Fuel Source + * + * Return Value: + * Fuel amount from config + * + * Example: + * cursorObject call ace_refuel_fnc_getFuelCargo + * + * Public: No + */ + +params ["_source"]; + +(uiNamespace getVariable QGVAR(cacheRefuelCargo)) getOrDefault [typeOf _source, REFUEL_DISABLED_FUEL] diff --git a/addons/refuel/functions/fnc_makeJerryCan.sqf b/addons/refuel/functions/fnc_makeJerryCan.sqf index 4b807756c9e..31a91a30d7b 100644 --- a/addons/refuel/functions/fnc_makeJerryCan.sqf +++ b/addons/refuel/functions/fnc_makeJerryCan.sqf @@ -16,6 +16,13 @@ * Public: Yes */ +// Only run this after the settings are initialized +if !(EGVAR(common,settingsInitFinished)) exitWith { + EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(makeJerryCan), _this]; +}; + +if (!GVAR(enabled)) exitWith {}; + params [["_target", objNull, [objNull]], ["_fuelAmount", 20, [0]]]; if (isNull _target || diff --git a/addons/refuel/functions/fnc_makeSource.sqf b/addons/refuel/functions/fnc_makeSource.sqf index 38b2d8a2618..9d76635849f 100644 --- a/addons/refuel/functions/fnc_makeSource.sqf +++ b/addons/refuel/functions/fnc_makeSource.sqf @@ -25,21 +25,39 @@ if !(EGVAR(common,settingsInitFinished)) exitWith { EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(makeSource), _this]; }; +if (!GVAR(enabled)) exitWith {}; + params [ ["_source", objNull, [objNull]], ["_fuelCargo", 0, [0]], ["_hooks", nil, [[]]] ]; -TRACE_3("makeSource",_source,_fuelCargo,_hooks); -private _fuelCargoConfig = getNumber (configOf _source >> QGVAR(fuelCargo)); +private _fuelCargoConfig = _source call FUNC(getFuelCargo); + +TRACE_4("makeSource",_source,_fuelCargo,_hooks,_fuelCargoConfig); if ( isNull _source || {_fuelCargo < 0 && {!(_fuelCargo in [REFUEL_INFINITE_FUEL, REFUEL_DISABLED_FUEL])}} - || {_fuelCargo != 0 && {_fuelCargo == _fuelCargoConfig}} ) exitWith {}; +// We might be removing fuel from an object that in config doesn't have fuel, but was given fuel via this function prior +if (_fuelCargo == REFUEL_DISABLED_FUEL && {_fuelCargoConfig == REFUEL_DISABLED_FUEL}) exitWith { + if (isNil {_source getVariable QGVAR(currentFuelCargo)}) exitWith {}; + + _source setVariable [QGVAR(currentFuelCargo), nil, true]; + _source setVariable [QGVAR(capacity), REFUEL_DISABLED_FUEL, true]; + + private _jipID = _source getVariable QGVAR(initSource_jipID); + + if (isNil "_jipID") exitWith {}; + + _jipID call CBA_fnc_removeGlobalEventJIP; + + _source setVariable [QGVAR(initSource_jipID), nil]; +}; + private _capacity = if (_fuelCargo < 0) then {_fuelCargo} else {_fuelCargoConfig max _fuelCargo}; _source setVariable [QGVAR(capacity), _capacity, true]; @@ -57,10 +75,10 @@ if ( }; // only add if menu doesn't already exist -if (!(_fuelCargoConfig != 0 && {!isNil {_source getVariable QGVAR(initSource_jipID)}})) then { - private _jipID = [QGVAR(initSource), [_source]] call CBA_fnc_globalEventJIP; - [_jipID, _source] call CBA_fnc_removeGlobalEventJIP; - _source setVariable [QGVAR(initSource_jipID), _jipID]; -}; +if (_fuelCargoConfig != REFUEL_DISABLED_FUEL || {!isNil {_source getVariable QGVAR(initSource_jipID)}}) exitWith {}; + +private _jipID = [QGVAR(initSource), [_source]] call CBA_fnc_globalEventJIP; +[_jipID, _source] call CBA_fnc_removeGlobalEventJIP; +_source setVariable [QGVAR(initSource_jipID), _jipID]; [QGVAR(sourceInitialized), [_source]] call CBA_fnc_globalEvent; diff --git a/addons/refuel/initSettings.inc.sqf b/addons/refuel/initSettings.inc.sqf index f3744697a44..2888ad190ce 100644 --- a/addons/refuel/initSettings.inc.sqf +++ b/addons/refuel/initSettings.inc.sqf @@ -1,12 +1,21 @@ private _category = [ELSTRING(main,Category_Logistics), "str_state_refuel"]; +[ + QGVAR(enabled), "CHECKBOX", + ELSTRING(common,Enabled), + _category, + true, + 1, + {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + [ QGVAR(rate), "SLIDER", [LSTRING(RefuelSettings_speed_DisplayName), LSTRING(RefuelSettings_speed_Description)], _category, [0,25,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(rate), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -14,8 +23,7 @@ private _category = [ELSTRING(main,Category_Logistics), "str_state_refuel"]; [LSTRING(RefuelSettings_speedCargo_DisplayName), LSTRING(RefuelSettings_speedCargo_Description)], _category, [0,250,10,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(cargoRate), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -23,8 +31,7 @@ private _category = [ELSTRING(main,Category_Logistics), "str_state_refuel"]; [LSTRING(RefuelSettings_hoseLength_DisplayName)], _category, [0,50,12,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(hoseLength), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -32,6 +39,5 @@ private _category = [ELSTRING(main,Category_Logistics), "str_state_refuel"]; [LSTRING(RefuelSettings_progressDuration_DisplayName), LSTRING(RefuelSettings_progressDuration_Description)], _category, [0, 10, 2], // [min, max, default value] - true, // isGlobal - {[QGVAR(progressDuration), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; diff --git a/addons/refuel/stringtable.xml b/addons/refuel/stringtable.xml index 909a3f4587e..648ee38c6da 100644 --- a/addons/refuel/stringtable.xml +++ b/addons/refuel/stringtable.xml @@ -506,6 +506,7 @@ 연료통 집어들기 Взять канистру с топливом Ramasser le réservoir de carburant + Coger garrafa de combustible Picking fuel canister up... @@ -515,6 +516,7 @@ 연료통 집어드는 중... Поднимаю канистру с топливом... Ramasser les bidons de carburant... + Cogiendo garrafa de combustible... Connect fuel canister @@ -524,6 +526,7 @@ 연료통 꽂기 Подсоединить канистру с топливом Raccorder le réservoir de carburant + Conectar garrafa de combustible Connecting fuel canister... @@ -533,6 +536,7 @@ 연료통 꽂는 중... Подсоединение топливной канистры... Raccorder le réservoir de carburant... + Conectando garrafa de combustible... Disconnect fuel canister @@ -542,6 +546,7 @@ 연료통 빼기 Отсоединить канистру с топливом Débrancher le réservoir de carburant + Desconectar garrafa de combustible Refuel hose length diff --git a/addons/reload/stringtable.xml b/addons/reload/stringtable.xml index e081834e29b..2c4bbcab769 100644 --- a/addons/reload/stringtable.xml +++ b/addons/reload/stringtable.xml @@ -138,6 +138,7 @@ Taśma została połączona 탄띠가 연결되었습니다 Ремень был пристегнут + Cinta enganchada Belt could not be linked @@ -148,6 +149,7 @@ Taśma nie mogła być połączona 탄띠를 연결할 수 없습니다 Ремень не удалось пристегнуть + La cinta no ha podido ser enganchada diff --git a/addons/reloadlaunchers/stringtable.xml b/addons/reloadlaunchers/stringtable.xml index ac42ef4d99e..b55ccde1705 100644 --- a/addons/reloadlaunchers/stringtable.xml +++ b/addons/reloadlaunchers/stringtable.xml @@ -10,6 +10,7 @@ 동료의 장전에 대한 알림 표시 Affichage de notifications lors d'une rechargement par un ami Отображает уведомления о загрузке помощника + Mostrar notificaciones para recarga de compañero Displays notifications when an assistant loads a gunner's launcher. @@ -20,6 +21,7 @@ 부사수가 사수의 발사기를 장전할 때 알림을 표시합니다. Affiche une notofication lorsqu'un assistant recharge l'arme du tireur. Отображает уведомления, когда помощник загружает пусковую установку стрелка. + Mostrar notificaciones cuando un asistente recarga el lanzador del tirador. Load launcher @@ -47,6 +49,7 @@ %1 ładuje twoją wyrzutnię %1이(가) 당신의 발사기를 장전했습니다. %1 загружает Вашу установку + %1 está cargando tu lanzador %1 stopped loading your launcher @@ -57,6 +60,7 @@ %1 przestał ładować twoją wyrzutnię %1이(가) 당신의 발사기 장전을 멈췄습니다. %1 прекратил загружать Вашу установку + %1 paró de cargar tu lanzador Loading launcher... @@ -118,6 +122,7 @@ Wyrzutnia nie mogła być załadowana 발사기를 장전할 수 없습니다. Не удалось загрузить пусковую установку + El lanzador no ha podido ser cargado Buddy Loading @@ -128,6 +133,7 @@ Nachladen durch Kamerad バディローディング Перезарядка помощником + Cargado de Compañero diff --git a/addons/repair/XEH_PREP.hpp b/addons/repair/XEH_PREP.hpp index 186ec0b310f..16e11b7476e 100644 --- a/addons/repair/XEH_PREP.hpp +++ b/addons/repair/XEH_PREP.hpp @@ -25,7 +25,6 @@ PREP(getSelectionsToIgnore); PREP(getPatchWheelTime); PREP(getPostRepairDamage); PREP(getRepairItems); -PREP(getWheelHitPointsWithSelections); PREP(hasItems); PREP(isEngineer); PREP(isInRepairFacility); diff --git a/addons/repair/dev/draw_showRepairInfo.sqf b/addons/repair/dev/draw_showRepairInfo.sqf index 20bf748e7fd..182b2f7a088 100644 --- a/addons/repair/dev/draw_showRepairInfo.sqf +++ b/addons/repair/dev/draw_showRepairInfo.sqf @@ -4,6 +4,7 @@ #include "..\script_component.hpp" addMissionEventHandler ["Draw3D", { + if (isGamePaused) exitWith {}; if !((cursorObject isKindOf "Car") || (cursorObject isKindOf "Tank") || (cursorObject isKindOf "Air")) exitWith {}; private _config = configOf cursorObject; @@ -11,7 +12,7 @@ addMissionEventHandler ["Draw3D", { private _hitpointGroups = getArray (_config >> QGVAR(hitpointGroups)); (getAllHitPointsDamage cursorObject) params [["_hitPoints", []], ["_hitSelections", []]]; - ([cursorObject] call FUNC(getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; + ([cursorObject] call EFUNC(common,getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; private _output = []; @@ -28,7 +29,7 @@ addMissionEventHandler ["Draw3D", { _info = _info + "[Wheel]"; _color = [0,1,0,1]; }; - if (!((getText (_config>> "HitPoints" >> _hitpoint >> "depends")) in ["", "0"])) then { + if !((getText (_config>> "HitPoints" >> _hitpoint >> "depends")) in ["", "0"]) then { _info = _info + format ["[depends: %1]", getText (_config>> "HitPoints" >> _hitpoint >> "depends")]; _color = [0,0,1,1] }; diff --git a/addons/repair/functions/fnc_addRepairActions.sqf b/addons/repair/functions/fnc_addRepairActions.sqf index 9dad1ecc311..16711d7b8a1 100644 --- a/addons/repair/functions/fnc_addRepairActions.sqf +++ b/addons/repair/functions/fnc_addRepairActions.sqf @@ -37,7 +37,7 @@ private _selectionsToIgnore = _vehicle call FUNC(getSelectionsToIgnore); (getAllHitPointsDamage _vehicle) params [["_hitPoints", []], ["_hitSelections", []]]; // Since 1.82 these are all lower case // get hitpoints of wheels with their selections -([_vehicle] call FUNC(getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; +([_vehicle] call EFUNC(common,getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; private _hitPointsAddedNames = []; private _hitPointsAddedStrings = []; diff --git a/addons/repair/functions/fnc_canRepair.sqf b/addons/repair/functions/fnc_canRepair.sqf index f1f4aa7b7c8..ff61450b12b 100644 --- a/addons/repair/functions/fnc_canRepair.sqf +++ b/addons/repair/functions/fnc_canRepair.sqf @@ -65,7 +65,7 @@ if (!_return) exitWith {false}; // if (_vehicleStateCondition == 1 && {!([_target] call FUNC(isInStableCondition))}) exitWith {false}; private _repairLocations = getArray (_config >> "repairLocations"); -if (!("All" in _repairLocations)) then { +if !("All" in _repairLocations) then { private _repairFacility = {([_caller] call FUNC(isInRepairFacility)) || ([_target] call FUNC(isInRepairFacility))}; private _repairVeh = {([_caller] call FUNC(isNearRepairVehicle)) || ([_target] call FUNC(isNearRepairVehicle))}; { diff --git a/addons/repair/functions/fnc_getSelectionsToIgnore.sqf b/addons/repair/functions/fnc_getSelectionsToIgnore.sqf index 08ca639a209..455b58c0405 100644 --- a/addons/repair/functions/fnc_getSelectionsToIgnore.sqf +++ b/addons/repair/functions/fnc_getSelectionsToIgnore.sqf @@ -28,7 +28,7 @@ private _turretPaths = ((fullCrew [_vehicle, "gunner", true]) + (fullCrew [_vehi (getAllHitPointsDamage _vehicle) params [["_hitPoints", []], ["_hitSelections", []]]; // get hitpoints of wheels with their selections -([_vehicle] call FUNC(getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; +([_vehicle] call EFUNC(common,getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; private _indexesToIgnore = []; private _processedSelections = []; @@ -117,7 +117,7 @@ private _processedSelections = []; continue }; - if (!(getText (_vehCfg >> "HitPoints" >> _hitpoint >> "depends") in ["", "0"])) then { // skip depends hitpoints, should be normalized by engine + if !(getText (_vehCfg >> "HitPoints" >> _hitpoint >> "depends") in ["", "0"]) then { // skip depends hitpoints, should be normalized by engine TRACE_3("Skipping depends hitpoint",_hitpoint,_forEachIndex,_selection); /*#ifdef DEBUG_MODE_FULL systemChat format ["Skipping depends hitpoint, hitpoint %1, index %2, selection %3", _hitpoint, _forEachIndex, _selection]; diff --git a/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf b/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf deleted file mode 100644 index 5d655887c65..00000000000 --- a/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf +++ /dev/null @@ -1,97 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: commy2 - * Returns the wheel hitpoints and their selections. - * - * Arguments: - * 0: Vehicle - * - * Return Value: - * 0: Wheel hitpoints - * 1: Wheel hitpoint selections in model coordinates - * - * Example: - * [car1] call ace_repair_fnc_getWheelHitPointsWithSelections - * - * Public: No - */ - -params ["_vehicle"]; -TRACE_1("params",_vehicle); - -// get the vehicles wheel config -private _wheels = configOf _vehicle >> "Wheels"; - -// exit with nothing if the vehicle has no wheels class -if !(isClass _wheels) exitWith {TRACE_1("No Wheels",_wheels); [[],[]]}; - -// get all hitpoints and selections -(getAllHitPointsDamage _vehicle) params ["_hitPoints", "_hitPointSelections"]; - -// get all wheels and read selections from config -_wheels = "true" configClasses _wheels; - -private _wheelHitPoints = []; -private _wheelHitPointSelections = []; - -{ - private _wheelName = configName _x; - private _wheelCenter = getText (_x >> "center"); - private _wheelBone = getText (_x >> "boneName"); - private _wheelBoneNameResized = _wheelBone select [0, 9]; //ount "wheel_X_Y"; // this is a requirement for physx. Should work for all addon vehicles. - - TRACE_4("",_wheelName,_wheelCenter,_wheelBone,_wheelBoneNameResized); - - private _wheelHitPoint = ""; - private _wheelHitPointSelection = ""; - - //Commy's orginal method - { - if ((_wheelBoneNameResized != "") && {_x find _wheelBoneNameResized == 0}) exitWith { // same as above. Requirement for physx. - _wheelHitPoint = _hitPoints select _forEachIndex; - _wheelHitPointSelection = _hitPointSelections select _forEachIndex; - TRACE_2("wheel found [Orginal]",_wheelName,_wheelHitPoint); - }; - } forEach _hitPointSelections; - - - if (_vehicle isKindOf "Car") then { - //Backup method, search for the closest hitpoint to the wheel's center selection pos. - //Ref #2742 - RHS's HMMWV - if (_wheelHitPoint == "") then { - private _wheelCenterPos = _vehicle selectionPosition _wheelCenter; - if (_wheelCenterPos isEqualTo [0,0,0]) exitWith {TRACE_1("no center?",_wheelCenter);}; - - - private _bestDist = 99; - private _bestIndex = -1; - { - if (_x != "") then { - //Filter out things that definitly aren't wheeels (#3759) - if ((toLowerANSI (_hitPoints select _forEachIndex)) in ["hitengine", "hitfuel", "hitbody"]) exitWith {TRACE_1("filter",_x)}; - private _xPos = _vehicle selectionPosition _x; - if (_xPos isEqualTo [0,0,0]) exitWith {}; - private _xDist = _wheelCenterPos distance _xPos; - if (_xDist < _bestDist) then { - _bestIndex = _forEachIndex; - _bestDist = _xDist; - }; - }; - } forEach _hitPointSelections; - - TRACE_2("closestPoint",_bestDist,_bestIndex); - if (_bestIndex != -1) then { - _wheelHitPoint = _hitPoints select _bestIndex; - _wheelHitPointSelection = _hitPointSelections select _bestIndex; - TRACE_2("wheel found [Backup]",_wheelName,_wheelHitPoint); - }; - }; - }; - - if ((_wheelHitPoint != "") && {_wheelHitPointSelection != ""}) then { - _wheelHitPoints pushBack _wheelHitPoint; - _wheelHitPointSelections pushBack _wheelHitPointSelection; - }; -} forEach _wheels; - -[_wheelHitPoints, _wheelHitPointSelections] diff --git a/addons/repair/functions/fnc_normalizeHitPoints.sqf b/addons/repair/functions/fnc_normalizeHitPoints.sqf index 5e61ef8c88a..97f34c22db6 100644 --- a/addons/repair/functions/fnc_normalizeHitPoints.sqf +++ b/addons/repair/functions/fnc_normalizeHitPoints.sqf @@ -33,7 +33,7 @@ private _dependentHitPointScripts = []; { if ((_x != "") && {isClass (_config >> _x)} && {!(_x in _realHitPoints)}) then { _realHitPoints pushBack _x; - if (!((getText (_config >> _x >> "depends")) in ["", "0"])) then { + if !((getText (_config >> _x >> "depends")) in ["", "0"]) then { _dependentHitPoints pushBack _x; _dependentHitPointScripts pushBack compile getText (_config >> _x >> "depends"); }; diff --git a/addons/repair/functions/fnc_repair.sqf b/addons/repair/functions/fnc_repair.sqf index 86ff191000a..526b2d506b6 100644 --- a/addons/repair/functions/fnc_repair.sqf +++ b/addons/repair/functions/fnc_repair.sqf @@ -70,7 +70,7 @@ if (!_return) exitWith {false}; // if (_vehicleStateCondition == 1 && {!([_target] call FUNC(isInStableCondition))}) exitWith {false}; private _repairLocations = getArray (_config >> "repairLocations"); -if (!("All" in _repairLocations)) then { +if !("All" in _repairLocations) then { private _repairFacility = {([_caller] call FUNC(isInRepairFacility)) || ([_target] call FUNC(isInRepairFacility))}; private _repairVeh = {([_caller] call FUNC(isNearRepairVehicle)) || ([_target] call FUNC(isNearRepairVehicle))}; { diff --git a/addons/repair/functions/fnc_repair_failure.sqf b/addons/repair/functions/fnc_repair_failure.sqf index c305c90b6bf..f9de2a8ae6e 100644 --- a/addons/repair/functions/fnc_repair_failure.sqf +++ b/addons/repair/functions/fnc_repair_failure.sqf @@ -65,7 +65,7 @@ if (isNil _callback) then { } else { _callback = missionNamespace getVariable _callback; }; -if (!(_callback isEqualType {})) then {_callback = {TRACE_1("callback was NOT code",_callback)};}; +if !(_callback isEqualType {}) then {_callback = {TRACE_1("callback was NOT code",_callback)};}; _args call _callback; diff --git a/addons/repair/functions/fnc_repair_success.sqf b/addons/repair/functions/fnc_repair_success.sqf index 271d662cd49..62480827791 100644 --- a/addons/repair/functions/fnc_repair_success.sqf +++ b/addons/repair/functions/fnc_repair_success.sqf @@ -60,7 +60,7 @@ if (isNil _callback) then { } else { _callback = missionNamespace getVariable _callback; }; -if (!(_callback isEqualType {})) then {_callback = {TRACE_1("callback was NOT code",_callback)};}; +if !(_callback isEqualType {}) then {_callback = {TRACE_1("callback was NOT code",_callback)};}; _args call _callback; diff --git a/addons/repair/initSettings.inc.sqf b/addons/repair/initSettings.inc.sqf index 26d502e757a..e39bb93a764 100644 --- a/addons/repair/initSettings.inc.sqf +++ b/addons/repair/initSettings.inc.sqf @@ -8,16 +8,14 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; true, true, {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ QGVAR(displayTextOnRepair), "CHECKBOX", [LSTRING(SettingDisplayTextName), LSTRING(SettingDisplayTextDesc)], _category, - true, // default value - false, // isGlobal - {[QGVAR(displayTextOnRepair), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // default value ] call CBA_fnc_addSetting; [ @@ -25,8 +23,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(engineerSetting_Repair_name), LSTRING(engineerSetting_Repair_description)], _category, [[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],1], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(engineerSetting_repair), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -34,8 +31,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(engineerSetting_Wheel_name), LSTRING(engineerSetting_Wheel_description)], _category, [[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(engineerSetting_wheel), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -69,8 +65,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(repairDamageThreshold_name), LSTRING(repairDamageThreshold_description)], _category, [0, 1, 0.6, 1, true], - true, // isGlobal - {[QGVAR(repairDamageThreshold), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -78,8 +73,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(repairDamageThreshold_Engineer_name), LSTRING(repairDamageThreshold_Engineer_description)], _category, [0, 1, 0.4, 1, true], - true, // isGlobal - {[QGVAR(repairDamageThreshold_engineer), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -87,8 +81,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(consumeItem_ToolKit_name), LSTRING(consumeItem_ToolKit_description)], _category, [[0,1],[ELSTRING(common,No), ELSTRING(common,Yes)],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(consumeItem_toolKit), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -105,8 +98,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(fullRepairLocation), LSTRING(fullRepairLocation_description)], _catFullRepair, [[0,1,2,3,4],[LSTRING(useAnywhere), LSTRING(repairVehicleOnly), LSTRING(repairFacilityOnly), LSTRING(vehicleAndFacility), ELSTRING(common,Disabled)],2], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(fullRepairLocation), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -114,8 +106,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(engineerSetting_fullRepair_name), LSTRING(engineerSetting_fullRepair_description)], _catFullRepair, [[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],2], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(engineerSetting_fullRepair), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -168,8 +159,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(autoShutOffEngineWhenStartingRepair_name), LSTRING(autoShutOffEngineWhenStartingRepair_description)], _category, false, // default value - true, // isGlobal - {[QGVAR(autoShutOffEngineWhenStartingRepair), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ diff --git a/addons/repair/stringtable.xml b/addons/repair/stringtable.xml index 775202ed3a6..850f9dee7f3 100644 --- a/addons/repair/stringtable.xml +++ b/addons/repair/stringtable.xml @@ -281,6 +281,7 @@ 전체 수리 시간 계수 Coefficient du temps de réparation complète Коэффициент времени полного ремонта + Coeficiente de Tiempo de Reparación Completa Modifies how long it takes to perform a Full Repair.\nThe repair time is based on the amount of repairs needed for each part, including those normally inaccessible. @@ -291,6 +292,7 @@ 전체적인 수리를 수행하는 데 걸리는 시간을 수정합니다.\n수리 시간은 일반적으로 접근할 수 없는 부품을 포함하여 각 부품에 필요한 수리 시간을 기준으로 합니다. Modifie la durée que prend une réparation complète.\nLe temps de réparation est basé sur la quantité de réparations requises pour chaque partie, incluant celles qui sont normalement inaccessibles. Изменяет время, необходимое для выполнения полного ремонта.\nВремя ремонта зависит от объема ремонтных работ, необходимых для каждой детали, включая те, которые обычно недоступны. + Modifica cuánto tiempo lleva realizar una Reparación Completa.\nEl tiempo de reparación está basado en la cantidad de reparaciones necesarias para cada parte, incluyendo aquellas que normalmente no son accesibles. Boost engineer training when in repair vehicles or facilities. Untrained becomes engineer, engineer becomes advanced engineer. @@ -1262,6 +1264,7 @@ タイヤ交換の許可 바퀴 교체 허용 Autoriser le remplacement des roues + Permitir Recambio de Rueda Who can remove and replace wheels? @@ -1287,6 +1290,7 @@ 바퀴 수리 허용 Autoriser le rafistolage des roues Разрешить починить колесо + Permitir Parcheo de Rueda Who can patch wheels? @@ -1297,6 +1301,7 @@ 누가 바퀴를 수리할 수 있습니까? Qui peut rafistoler les roues ? Кто может починить колеса? + Quién puede parchear ruedas? Allow Repair @@ -1957,6 +1962,7 @@ 바퀴 수리 아이템 필요 Exigences pour rafistoler une roue Требования для починки колеса + Requerimientos de Parcheo de Ruedas Items required to patch a wheel. @@ -1967,6 +1973,7 @@ 바퀴를 수리하기 위해 아이템이 필요합니다. Equipements requis pour rafistoler une roue. Предметы, необходимые для починки колеса. + Objetos requeridos para parchear una rueda. Misc Repair Requirements @@ -2142,6 +2149,7 @@ 부품 수리 시간 Temps de réparation des pièces Время ремонта детали + Tiempo de Reparación de Pieza Time in seconds to complete a repair. @@ -2152,6 +2160,7 @@ 수리를 완료하는 시간(초 단위) Durée en secondes pour terminer une réparation. Время завершения ремонта в секундах. + Tiempo en segundos para completar una reparación. Wheel Change Time @@ -2162,6 +2171,7 @@ 바퀴 교체 시간 Temps de changement d'une roue Время замены колеса + Tiempo de Cambio de Rueda Time in seconds to remove or change a wheel. @@ -2172,6 +2182,7 @@ 바퀴를 제거하거나 교체하는 데 걸리는 시간(초 단위) Durée en seconde pour enlever ou changer une roue. Время в секундах на снятие или замену колеса. + Tiempo en segundos para quitar o cambiar una rueda. Patch Wheel @@ -2182,6 +2193,7 @@ 바퀴 수리 Rafistoler la roue Чинить колесо + Parchear Rueda Patching Wheel... @@ -2192,6 +2204,7 @@ 바퀴 수리 중... Rafistolage de la roue... Починка колеса... + Parcheando Rueda... Wheel Patch Time @@ -2202,6 +2215,7 @@ 바퀴 수리 시간 Temps de rafistolage d'une roue Время починки полеса + Tiempo de Parcheo de Rueda Time it takes to patch a wheel by 5%. @@ -2212,6 +2226,7 @@ 바퀴를 5% 수리하는 데 걸리는 시간(초 단위) Durée pour rafistoler une roue de 5%. Время, необходимое для починки колеса, сокращается на 5%. + Tiempo que lleva parchear una rueda por cada 5%. Patch Wheel Threshold @@ -2222,6 +2237,7 @@ 바퀴 수리 한계점 Seuil de rafistolage d'une roue Порог починки колеса + Umbral de Parcheo de Rueda Maximum damage to which a wheel can be patched.\n0% means all damage can be repaired. @@ -2232,6 +2248,7 @@ 바퀴를 수리할 수 있는 최대 레벨입니다. Niveau maximum de dégâts jusqu'à laquelle une roue peut être réparée.\n0% signifie que la roue peut être reparée entièrement. Максимальный уровень, до которого колесо может быть починено. + Máximo daño que permite a una rueda ser parcheada.\n0% significa que todo el daño puede ser reparado. Wheel Patch Location @@ -2242,6 +2259,7 @@ 바퀴 수리 장소 Lieu de rafistolage des roues Место починки колеса + Localización para el Parcheo de Rueda Where the wheel can be patched. @@ -2252,6 +2270,7 @@ 바퀴를 수리할 수 있는 곳입니다. Lieu où les roues peuvent être rafistolées. Где колесо можно починить. + Dónde puede ser parcheada la rueda. On the ground @@ -2262,6 +2281,7 @@ 지면 위 Sur le terrain На земле + En el suelo On a vehicle @@ -2272,6 +2292,7 @@ 차량 Sur un véhicule На транспорте + En un vehículo diff --git a/addons/scopes/functions/fnc_adjustScope.sqf b/addons/scopes/functions/fnc_adjustScope.sqf index 0a9d7bd089b..a760065cdec 100644 --- a/addons/scopes/functions/fnc_adjustScope.sqf +++ b/addons/scopes/functions/fnc_adjustScope.sqf @@ -22,7 +22,7 @@ if (!GVAR(enabled)) exitWith {false}; params ["_unit", "_turretAndDirection", "_majorStep"]; TRACE_3("adjustScope",_unit,_turretAndDirection,_majorStep); -if (!(_unit isKindOf "Man")) exitWith {false}; +if !(_unit isKindOf "Man") exitWith {false}; if (currentMuzzle _unit != currentWeapon _unit) exitWith {false}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); diff --git a/addons/scopes/functions/fnc_canAdjustZero.sqf b/addons/scopes/functions/fnc_canAdjustZero.sqf index ca03ab41236..1461d91d204 100644 --- a/addons/scopes/functions/fnc_canAdjustZero.sqf +++ b/addons/scopes/functions/fnc_canAdjustZero.sqf @@ -20,7 +20,7 @@ params ["_unit"]; if (cameraView == "GUNNER") exitWith {false}; if (!isNull objectParent _unit) exitWith {false}; if (GVAR(simplifiedZeroing)) exitWith {false}; -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {false}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {false}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith {false}; diff --git a/addons/scopes/functions/fnc_canResetZero.sqf b/addons/scopes/functions/fnc_canResetZero.sqf index 79dae44be95..92bbda1a4dd 100644 --- a/addons/scopes/functions/fnc_canResetZero.sqf +++ b/addons/scopes/functions/fnc_canResetZero.sqf @@ -19,7 +19,7 @@ params ["_unit"]; if (cameraView == "GUNNER") exitWith {false}; if (!isNull objectParent _unit) exitWith {false}; -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {false}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {false}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith {false}; diff --git a/addons/scopes/functions/fnc_firedEH.sqf b/addons/scopes/functions/fnc_firedEH.sqf index f1b8e91bf4e..5ff78a44b70 100644 --- a/addons/scopes/functions/fnc_firedEH.sqf +++ b/addons/scopes/functions/fnc_firedEH.sqf @@ -18,7 +18,7 @@ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); -if (!(_ammo isKindOf "BulletBase")) exitWith {}; +if !(_ammo isKindOf "BulletBase") exitWith {}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith {}; diff --git a/addons/scopes/functions/fnc_getCurrentZeroRange.sqf b/addons/scopes/functions/fnc_getCurrentZeroRange.sqf index 001e5e8b79e..d1bc3b7790d 100644 --- a/addons/scopes/functions/fnc_getCurrentZeroRange.sqf +++ b/addons/scopes/functions/fnc_getCurrentZeroRange.sqf @@ -17,12 +17,12 @@ params ["_unit"]; -if (!GVAR(enabled)) exitWith { currentZeroing _unit }; +if (!GVAR(enabled)) exitWith {currentZeroing _unit}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith { currentZeroing _unit }; if (GVAR(simplifiedZeroing)) exitWith { - if (!(GVAR(canAdjustElevation) select _weaponIndex)) exitWith { currentZeroing _unit }; + if !(GVAR(canAdjustElevation) select _weaponIndex) exitWith {currentZeroing _unit}; private _adjustment = _unit getVariable [QGVAR(Adjustment), [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]; ((_adjustment select _weaponIndex) select 0) }; diff --git a/addons/scopes/functions/fnc_getOptics.sqf b/addons/scopes/functions/fnc_getOptics.sqf index 6be1952b6f8..d419d8d7f05 100644 --- a/addons/scopes/functions/fnc_getOptics.sqf +++ b/addons/scopes/functions/fnc_getOptics.sqf @@ -21,7 +21,7 @@ params ["_unit"]; private _optics = ["", "", ""]; -if (!(_unit isKindOf "CAManBase")) exitWith {_optics}; +if !(_unit isKindOf "CAManBase") exitWith {_optics}; { if (count _x >= 2) then { diff --git a/addons/scopes/initKeybinds.inc.sqf b/addons/scopes/initKeybinds.inc.sqf index a147b1b2157..0e8db972381 100644 --- a/addons/scopes/initKeybinds.inc.sqf +++ b/addons/scopes/initKeybinds.inc.sqf @@ -2,7 +2,7 @@ // Conditions: canInteract if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; [ACE_player] call FUNC(inventoryCheck); @@ -14,7 +14,7 @@ // Conditions: canInteract if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; [ACE_player] call FUNC(inventoryCheck); @@ -26,7 +26,7 @@ // Conditions: canInteract if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; [ACE_player] call FUNC(inventoryCheck); @@ -38,7 +38,7 @@ // Conditions: canInteract if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; [ACE_player] call FUNC(inventoryCheck); @@ -50,7 +50,7 @@ // Conditions: canInteract if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; [ACE_player] call FUNC(inventoryCheck); @@ -62,7 +62,7 @@ // Conditions: canInteract if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; [ACE_player] call FUNC(inventoryCheck); @@ -74,7 +74,7 @@ // Conditions: canInteract if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; [ACE_player] call FUNC(inventoryCheck); @@ -86,7 +86,7 @@ // Conditions: canInteract if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; [ACE_player] call FUNC(inventoryCheck); diff --git a/addons/sitting/functions/fnc_sit.sqf b/addons/sitting/functions/fnc_sit.sqf index 2d7cc999daa..70e028719b8 100644 --- a/addons/sitting/functions/fnc_sit.sqf +++ b/addons/sitting/functions/fnc_sit.sqf @@ -78,7 +78,7 @@ if (_seatsClaimed isEqualTo []) then { _seat setVariable [QGVAR(seatsClaimed), _seatsClaimed, true]; // Also prevent dragging/carrying -if (!([_seat] call EFUNC(common,owned))) then { +if !([_seat] call EFUNC(common,owned)) then { [_player, _seat] call EFUNC(common,claim); }; diff --git a/addons/sitting/initSettings.inc.sqf b/addons/sitting/initSettings.inc.sqf index 744c188e9fd..ee1af1ec8ef 100644 --- a/addons/sitting/initSettings.inc.sqf +++ b/addons/sitting/initSettings.inc.sqf @@ -6,5 +6,5 @@ true, true, {[QGVAR(enable), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; diff --git a/addons/slideshow/functions/fnc_mapImage_init.sqf b/addons/slideshow/functions/fnc_mapImage_init.sqf index 5235315bd0f..3fb6e4c7f89 100644 --- a/addons/slideshow/functions/fnc_mapImage_init.sqf +++ b/addons/slideshow/functions/fnc_mapImage_init.sqf @@ -50,7 +50,7 @@ ctrlMapAnimCommit _map; // add drawEH to draw markers next update (they will get drawn 3 times total) _map setVariable ["markers", _markers]; -_map ctrlAddEventHandler ["draw", { +_map ctrlAddEventHandler ["Draw", { params ["_map"]; private _markers = _map getVariable ["markers", []]; TRACE_2("drawing markers",_map,count _markers); diff --git a/addons/switchunits/functions/fnc_switchUnit.sqf b/addons/switchunits/functions/fnc_switchUnit.sqf index 135088d2430..9ce074eecbb 100644 --- a/addons/switchunits/functions/fnc_switchUnit.sqf +++ b/addons/switchunits/functions/fnc_switchUnit.sqf @@ -18,7 +18,7 @@ params ["_unit"]; // don't switch to original player units -if (!([_unit] call FUNC(isValidAi))) exitWith {}; +if !([_unit] call FUNC(isValidAi)) exitWith {}; // exit var private _leave = false; diff --git a/addons/tagging/XEH_postInit.sqf b/addons/tagging/XEH_postInit.sqf index dd46b7fb988..02e082648a7 100644 --- a/addons/tagging/XEH_postInit.sqf +++ b/addons/tagging/XEH_postInit.sqf @@ -1,14 +1,6 @@ // by esteldunedain #include "script_component.hpp" - -// Cache for static objects -GVAR(cacheStaticModels) = [false] call CBA_fnc_createNamespace; -private _cacheStaticModels = call (uiNamespace getVariable [QGVAR(cacheStaticModels), {[]}]); -{ - GVAR(cacheStaticModels) setVariable [_x, true]; -} forEach _cacheStaticModels; - if (hasInterface) then { // Compile and cache config tags call FUNC(compileConfigTags); diff --git a/addons/tagging/XEH_preStart.sqf b/addons/tagging/XEH_preStart.sqf index e1ac396c48f..eb8f7ab767a 100644 --- a/addons/tagging/XEH_preStart.sqf +++ b/addons/tagging/XEH_preStart.sqf @@ -26,9 +26,9 @@ private _cfgBase = configFile >> "CfgNonAIVehicles"; private _array = _model splitString "\"; _cacheStaticModels pushBackUnique toLowerANSI (_array select -1); }; -} forEach (_nonaivehicleClasses select {(configName _x) isKindOf ["Bridge_base_F", _cfgBase]}); +} forEach (_nonAIVehicleClasses select {(configName _x) isKindOf ["Bridge_base_F", _cfgBase]}); -uiNamespace setVariable [QGVAR(cacheStaticModels), compileFinal str _cacheStaticModels]; +uiNamespace setVariable [QGVAR(cacheStaticModels), compileFinal (_cacheStaticModels createHashMapFromArray [])]; TRACE_1("compiled",count _cacheStaticModels); // force preload of stencil texture to avoid error popup diff --git a/addons/tagging/functions/fnc_checkTaggable.sqf b/addons/tagging/functions/fnc_checkTaggable.sqf index 7eab60c1ba5..ef20062a32d 100644 --- a/addons/tagging/functions/fnc_checkTaggable.sqf +++ b/addons/tagging/functions/fnc_checkTaggable.sqf @@ -43,14 +43,14 @@ if (_object isKindOf "Static") exitWith {false}; // Taggable vehicle, do not exit - if (((_object getVariable [QGVAR(canTag), getNumber (configOf _object >> QGVAR(canTag))]) in [1, true]) + if (((_object getVariable [QGVAR(canTag), getNumber (configOf _object >> QGVAR(canTag))]) in [1, true]) && {getText (configOf _object >> "selectionClan") in selectionNames _object}) exitWith { false }; // If the class is not categorized correctly search the cache - private _modelName = (getModelInfo _object) select 0; - private _isStatic = GVAR(cacheStaticModels) getVariable [_modelName, false]; + private _modelName = toLowerANSI ((getModelInfo _object) select 0); + private _isStatic = _modelName in (uiNamespace getVariable QGVAR(cacheStaticModels)); TRACE_2("Object:",_modelName,_isStatic); // If the class in not on the cache, exit (!_isStatic) diff --git a/addons/tagging/functions/fnc_generateStencilTexture.sqf b/addons/tagging/functions/fnc_generateStencilTexture.sqf index 1870d671141..6d8dffdc551 100644 --- a/addons/tagging/functions/fnc_generateStencilTexture.sqf +++ b/addons/tagging/functions/fnc_generateStencilTexture.sqf @@ -29,10 +29,10 @@ params [ ["_dimension", 512, [0]] ]; -if (_textColor select [0, 1] == "#") then { _textColor = _textColor select [1]; }; -if (_backgroundColor select [0, 1] == "#") then { _backgroundColor = _backgroundColor select [1]; }; -if (!((count _textColor) in [6,8])) exitWith { ERROR_1("bad Tcolor %1",_textColor); "" }; -if (!((count _backgroundColor) in [6,8])) exitWith { ERROR_1("bad Bcolor %1",_textColor); "" }; +if (_textColor select [0, 1] == "#") then {_textColor = _textColor select [1];}; +if (_backgroundColor select [0, 1] == "#") then {_backgroundColor = _backgroundColor select [1];}; +if !((count _textColor) in [6,8]) exitWith {ERROR_1("bad Tcolor %1",_textColor); ""}; +if !((count _backgroundColor) in [6,8]) exitWith {ERROR_1("bad Bcolor %1",_textColor); ""}; if (_autoMultiline) then { private _magicWidth = 0.75; diff --git a/addons/tagging/functions/fnc_stencilVehicle.sqf b/addons/tagging/functions/fnc_stencilVehicle.sqf index b2ee99c2413..1dfd86a2f95 100644 --- a/addons/tagging/functions/fnc_stencilVehicle.sqf +++ b/addons/tagging/functions/fnc_stencilVehicle.sqf @@ -29,7 +29,7 @@ TRACE_2("",_vehicle,_text); if (!isServer) exitWith {}; if (_text == "") exitWith {}; private _clanSel = getText (configOf _vehicle >> "selectionClan"); -if (!(_clanSel in selectionNames _vehicle)) exitWith { TRACE_1("no tag",_clanSel); }; +if !(_clanSel in selectionNames _vehicle) exitWith {TRACE_1("no tag",_clanSel);}; private _texture = [_text, _textSize, _textColor, "00000000", true] call FUNC(generateStencilTexture); TRACE_1("",_texture); diff --git a/addons/tagging/functions/fnc_tag.sqf b/addons/tagging/functions/fnc_tag.sqf index aa0ba9fac97..f130e1322b3 100644 --- a/addons/tagging/functions/fnc_tag.sqf +++ b/addons/tagging/functions/fnc_tag.sqf @@ -60,8 +60,8 @@ if ((!isNull _object) && { }; // If the class is not categorized correctly search the cache - private _modelName = (getModelInfo _object) select 0; - private _isStatic = GVAR(cacheStaticModels) getVariable [_modelName, false]; + private _modelName = toLowerANSI ((getModelInfo _object) select 0); + private _isStatic = _modelName in (uiNamespace getVariable QGVAR(cacheStaticModels)); TRACE_2("Object:",_modelName,_isStatic); // If the class in not on the cache, exit (!_isStatic) diff --git a/addons/tagging/initSettings.inc.sqf b/addons/tagging/initSettings.inc.sqf index 4fc35b83d1b..e05146c0819 100644 --- a/addons/tagging/initSettings.inc.sqf +++ b/addons/tagging/initSettings.inc.sqf @@ -4,8 +4,5 @@ private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(Tagging)] QGVAR(quickTag), "LIST", [LLSTRING(QuickTag), LLSTRING(QuickTagDesc)], _category, - [[0,1,2,3], [LELSTRING(Common,Disabled), LLSTRING(LastUsed), LLSTRING(RandomX), LLSTRING(Random)], 1], // [values, titles, defaultIndex] - false, // isGlobal - {[QGVAR(quickTag), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart + [[0,1,2,3], [LELSTRING(Common,Disabled), LLSTRING(LastUsed), LLSTRING(RandomX), LLSTRING(Random)], 1] // [values, titles, defaultIndex] ] call CBA_fnc_addSetting; diff --git a/addons/tagging/stringtable.xml b/addons/tagging/stringtable.xml index 4d32fac6d66..fa54b56b542 100644 --- a/addons/tagging/stringtable.xml +++ b/addons/tagging/stringtable.xml @@ -384,6 +384,7 @@ 차량 ID 마킹 Marquage ID des véhicules Идентификационная маркировка транспортного средства + Marcado Identificativo de Vehículo Replaces clan tag with stenciled text @@ -394,6 +395,7 @@ 클랜 태그를 스텐실 텍스트로 바꿉니다. Remplace le tag du clan par un texte au pochoir Заменяет тег клана трафаретным текстом + Reemplaza marca del clan con un texto serigrafiado diff --git a/addons/ui/XEH_PREP.hpp b/addons/ui/XEH_PREP.hpp index f7edabcc3fa..436e59361c5 100644 --- a/addons/ui/XEH_PREP.hpp +++ b/addons/ui/XEH_PREP.hpp @@ -1,5 +1,4 @@ PREP(compileConfigUI); -PREP(handlePlayerChanged); PREP(handleSpeedIndicator); PREP(moduleInit); PREP(onAnimChanged); diff --git a/addons/ui/XEH_clientInit.sqf b/addons/ui/XEH_clientInit.sqf index 1ef328b1769..2c8cd3e4b49 100644 --- a/addons/ui/XEH_clientInit.sqf +++ b/addons/ui/XEH_clientInit.sqf @@ -4,11 +4,11 @@ if (!hasInterface) exitWith {}; // Compile and cache config UI -GVAR(configCache) = call CBA_fnc_createNamespace; +GVAR(configCache) = createHashMap; call FUNC(compileConfigUI); // Scripted API namespace -GVAR(elementsSet) = call CBA_fnc_createNamespace; +GVAR(elementsSet) = createHashMap; // Attach all event handlers where UI has to be updated ["CBA_settingsInitialized", { @@ -21,7 +21,7 @@ GVAR(elementsSet) = call CBA_fnc_createNamespace; // Defaults must be set in this EH to make sure controls are activated and advanced settings can be modified { [_x, missionNamespace getVariable (format [QGVAR(%1), _x]), false, !GVAR(allowSelectiveUI)] call FUNC(setAdvancedElement); - } forEach (allVariables GVAR(configCache)); + } forEach (keys GVAR(configCache)); // Execute local event for when it's safe to modify UI through this API // infoDisplayChanged can execute multiple times, make sure it only happens once @@ -40,12 +40,11 @@ GVAR(elementsSet) = call CBA_fnc_createNamespace; [true] call FUNC(setElements); } else { private _nameNoPrefix = toLowerANSI (_name select [7]); - private _cachedElement = GVAR(configCache) getVariable _nameNoPrefix; - if (!isNil "_cachedElement") then { + if (_nameNoPrefix in GVAR(configCache)) then { [_nameNoPrefix, _value, true] call FUNC(setAdvancedElement); }; }; }] call CBA_fnc_addEventHandler; }] call CBA_fnc_addEventHandler; -["unit", LINKFUNC(handlePlayerChanged), true] call CBA_fnc_addPlayerEventHandler; +[QUOTE(ADDON), "AnimChanged", LINKFUNC(onAnimChanged)] call EFUNC(common,addPlayerEH); diff --git a/addons/ui/functions/fnc_compileConfigUI.sqf b/addons/ui/functions/fnc_compileConfigUI.sqf index ef6ec1026a4..960db9aed45 100644 --- a/addons/ui/functions/fnc_compileConfigUI.sqf +++ b/addons/ui/functions/fnc_compileConfigUI.sqf @@ -40,6 +40,6 @@ TRACE_1("Caching Condition",_x); } forEach (configProperties [_x >> "conditions"]); - GVAR(configCache) setVariable [_class, [_idd, _elements, _location, _conditions]]; + GVAR(configCache) set [_class, [_idd, _elements, _location, _conditions]]; }; } forEach ("true" configClasses (configFile >> "ACE_UI")); diff --git a/addons/ui/functions/fnc_handlePlayerChanged.sqf b/addons/ui/functions/fnc_handlePlayerChanged.sqf deleted file mode 100644 index 94f317a18cd..00000000000 --- a/addons/ui/functions/fnc_handlePlayerChanged.sqf +++ /dev/null @@ -1,32 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: veteran29 - * Handles switching units. - * - * Arguments: - * 0: New Unit - * 1: Old Unit - * - * Return Value: - * None - * - * Example: - * [newbob, oldbob] call ace_ui_fnc_handlePlayerChanged - * - * Public: No - */ -params ["_newUnit", "_oldUnit"]; -TRACE_2("unit changed",_newUnit,_oldUnit); - -if (!isNull _oldUnit) then { - _oldUnit removeEventHandler ["AnimChanged", _oldUnit getVariable [QGVAR(animHandler), -1]]; - _oldUnit setVariable [QGVAR(animHandler), nil]; - TRACE_1("remove old",_oldUnit getVariable QGVAR(animHandler)); -}; - -// Don't add a new EH if the unit respawned -if (_newUnit getVariable [QGVAR(animHandler), -1] == -1) then { - private _animHandler = _newUnit addEventHandler ["AnimChanged", LINKFUNC(onAnimChanged)]; - TRACE_1("add new",_animHandler); - _newUnit setVariable [QGVAR(animHandler), _animHandler]; -}; diff --git a/addons/ui/functions/fnc_setAdvancedElement.sqf b/addons/ui/functions/fnc_setAdvancedElement.sqf index 6751d9700c3..86a11348020 100644 --- a/addons/ui/functions/fnc_setAdvancedElement.sqf +++ b/addons/ui/functions/fnc_setAdvancedElement.sqf @@ -20,7 +20,9 @@ params ["_element", "_show", ["_showHint", false, [true]], ["_force", false, [true]]]; -private _cachedElement = GVAR(configCache) getVariable _element; +_element = toLowerANSI _element; + +private _cachedElement = GVAR(configCache) get _element; if (isNil "_cachedElement") exitWith {TRACE_1("nil element",_this)}; if (!_force && {!GVAR(allowSelectiveUI)}) exitWith { @@ -56,7 +58,7 @@ if ( // Get setting from scripted API if (!_force) then { - private _setElement = GVAR(elementsSet) getVariable _element; + private _setElement = GVAR(elementsSet) get _element; if (!isNil "_setElement") then { _setElement params ["_sourceSet", "_showSet"]; if (_showHint) then { diff --git a/addons/ui/functions/fnc_setElementVisibility.sqf b/addons/ui/functions/fnc_setElementVisibility.sqf index f7f8dccd0c8..938fb2da7de 100644 --- a/addons/ui/functions/fnc_setElementVisibility.sqf +++ b/addons/ui/functions/fnc_setElementVisibility.sqf @@ -32,12 +32,11 @@ if (_source == "" || {_element == ""}) exitWith { _element = toLowerANSI _element; // Verify element is bound -private _cachedElement = GVAR(configCache) getVariable _element; -if (isNil "_cachedElement") exitWith { +if !(_element in GVAR(configCache)) exitWith { WARNING_2("Element '%1' does not exist - modification by '%2' failed.",_element,_source); }; -private _setElement = GVAR(elementsSet) getVariable _element; +private _setElement = GVAR(elementsSet) get _element; private _return = false; if (isNil "_setElement") then { @@ -45,7 +44,7 @@ if (isNil "_setElement") then { private _success = [_element, _show, false, true] call FUNC(setAdvancedElement); if (_success) then { - GVAR(elementsSet) setVariable [_element, [_source, _show]]; + GVAR(elementsSet) set [_element, [_source, _show]]; _return = true; }; } else { @@ -57,7 +56,7 @@ if (isNil "_setElement") then { }; } else { TRACE_3("Unsetting element",_sourceSet,_element,_show); - GVAR(elementsSet) setVariable [_element, nil]; + GVAR(elementsSet) set [_element, nil]; [_element, _show, false, true] call FUNC(setAdvancedElement); _return = true; diff --git a/addons/vector/functions/fnc_onKeyHold.sqf b/addons/vector/functions/fnc_onKeyHold.sqf index 60a38ba96da..f19039851b6 100644 --- a/addons/vector/functions/fnc_onKeyHold.sqf +++ b/addons/vector/functions/fnc_onKeyHold.sqf @@ -16,7 +16,7 @@ * Public: No */ -if (!((currentWeapon ACE_player) isKindOf ["ACE_Vector", configFile >> "CfgWeapons"])) exitWith { +if !((currentWeapon ACE_player) isKindOf ["ACE_Vector", configFile >> "CfgWeapons"]) exitWith { [_this select 1] call CBA_fnc_removePerFrameHandler; GVAR(currentMode) = ""; diff --git a/addons/vehicle_damage/XEH_PREP.hpp b/addons/vehicle_damage/XEH_PREP.hpp index 524fe6ea9dd..a7eb5198811 100644 --- a/addons/vehicle_damage/XEH_PREP.hpp +++ b/addons/vehicle_damage/XEH_PREP.hpp @@ -11,3 +11,4 @@ PREP(knockOut); PREP(addDamage); PREP(handleDamageEjectIfDestroyed); PREP(blowOffTurret); +PREP(medicalDamage); diff --git a/addons/vehicle_damage/XEH_postInit.sqf b/addons/vehicle_damage/XEH_postInit.sqf index ce563302e3d..43050086d81 100644 --- a/addons/vehicle_damage/XEH_postInit.sqf +++ b/addons/vehicle_damage/XEH_postInit.sqf @@ -3,12 +3,14 @@ ["ace_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 (isPlayer _crewman) exitWith {}; - if (!alive _crewman || { !( [_crewman] call EFUNC(common,isAwake))} ) exitWith {}; + if (!alive _crewman || {!([_crewman] call EFUNC(common,isAwake))}) exitWith {}; unassignVehicle _crewman; _crewman leaveVehicle _vehicle; diff --git a/addons/vehicle_damage/functions/fnc_abandon.sqf b/addons/vehicle_damage/functions/fnc_abandon.sqf index 6a9d4eeb296..83b06a80df1 100644 --- a/addons/vehicle_damage/functions/fnc_abandon.sqf +++ b/addons/vehicle_damage/functions/fnc_abandon.sqf @@ -18,6 +18,8 @@ params ["_vehicle"]; TRACE_2("abandon",_vehicle,(crew _vehicle) select {alive _x}); +if (_vehicle getVariable [QGVAR(allowCrewInImmobile), false]) exitWith {}; // check for API + [{ params ["_vehicle"]; _vehicle allowCrewInImmobile false; diff --git a/addons/vehicle_damage/functions/fnc_addDamage.sqf b/addons/vehicle_damage/functions/fnc_addDamage.sqf index 75d72da3406..35475bd36cb 100644 --- a/addons/vehicle_damage/functions/fnc_addDamage.sqf +++ b/addons/vehicle_damage/functions/fnc_addDamage.sqf @@ -37,6 +37,6 @@ if (_hitIndex >= 0) then { _vehicle setHitPointDamage [_hitPoint, _damage, true]; }; -if (_hitPoint isEqualTo "hitengine" && { _damage > 0.9 }) then { - _vehicle call EFUNC(cookoff,engineFire); +if (_hitPoint == "hitengine" && {_damage > 0.9}) then { + [QEGVAR(cookoff,engineFireServer), _vehicle] call CBA_fnc_serverEvent; }; diff --git a/addons/vehicle_damage/functions/fnc_detonate.sqf b/addons/vehicle_damage/functions/fnc_detonate.sqf index 67d64da442b..7f0dce28c93 100644 --- a/addons/vehicle_damage/functions/fnc_detonate.sqf +++ b/addons/vehicle_damage/functions/fnc_detonate.sqf @@ -6,7 +6,6 @@ * Arguments: * 0: The vehicle * 1: Person who caused detonation (default: objNull) - * 2: An array of vehicle ammo in vehicle (default: []) * * Return Value: * None @@ -17,19 +16,12 @@ * Public: No */ -params ["_vehicle", ["_injurer", objNull], ["_vehicleAmmo", []]]; +params ["_vehicle", ["_injurer", objNull]]; -if (_vehicleAmmo isEqualTo []) then { - _vehicleAmmo = [_vehicle] call EFUNC(cookoff,getVehicleAmmo); -}; - -([_vehicle] + _vehicleAmmo) call EFUNC(cookoff,detonateAmmunition); - -if ((_vehicleAmmo select 1) > 0) then { +if (((_vehicle call EFUNC(cookoff,getVehicleAmmo)) select 1) > 0) then { { - // random amount of injuries - for "_i" from 0 to random 5 do { - [_x, random 1 , selectRandom ["Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg"], selectRandom ["bullet", "shell", "explosive"], _injurer] call EFUNC(medical,addDamageToUnit); - }; - } forEach crew _vehicle; + [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_handleCookoff.sqf b/addons/vehicle_damage/functions/fnc_handleCookoff.sqf index 7cf63377960..3e7b83ebb61 100644 --- a/addons/vehicle_damage/functions/fnc_handleCookoff.sqf +++ b/addons/vehicle_damage/functions/fnc_handleCookoff.sqf @@ -23,9 +23,12 @@ params ["_vehicle", "_chanceOfFire", "_intensity", ["_injurer", objNull], ["_hitPart", ""], ["_canRing", false], ["_canJet", true]]; -private _alreadyCookingOff = _vehicle getVariable [QGVAR(cookingOff), false]; +// Ignore if the vehicle is already cooking off +if (_vehicle getVariable [QEGVAR(cookoff,isCookingOff), false]) exitWith {true}; -if (!_alreadyCookingOff && { _chanceOfFire >= random 1 }) exitWith { +_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 { @@ -44,28 +47,13 @@ if (!_alreadyCookingOff && { _chanceOfFire >= random 1 }) exitWith { _source = ["hit_engine_point", "HitPoints"]; }; - // sending nil for _maxIntensity (9th param) to use default value in ace_cookoff_fnc_cookOff - [QEGVAR(cookOff,cookOff), [_vehicle, _intensity, _injurer, _delayWithSmoke, _fireDetonateChance, _detonateAfterCookoff, _source, _canRing, nil, _canJet]] call CBA_fnc_localEvent; - _vehicle setVariable [QGVAR(cookingOff), true]; + [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); - // cant setVehicleAmmo 0 here because it removes FFV unit's ammo - if (GVAR(removeAmmoDuringCookoff)) then { - private _ammo = [_vehicle] call EFUNC(cookoff,getVehicleAmmo); - _ammo params ["_magazines"]; - TRACE_1("removing magazines",_magazines); - { - _x params ["_magazine"]; - _vehicle removeMagazines _magazine; - } forEach _magazines; - }; true }; -// Avoid RPT spam -if (_alreadyCookingOff) exitWith { true }; - LOG_2("[%1] No Cook-off - Chance of fire [%2]",_vehicle,_chanceOfFire); false diff --git a/addons/vehicle_damage/functions/fnc_handleDetonation.sqf b/addons/vehicle_damage/functions/fnc_handleDetonation.sqf index 9556cea424d..8f317323fa7 100644 --- a/addons/vehicle_damage/functions/fnc_handleDetonation.sqf +++ b/addons/vehicle_damage/functions/fnc_handleDetonation.sqf @@ -21,18 +21,17 @@ */ params ["_vehicle", "_chanceOfDetonate", "_vehicleAmmo", "_explosiveAmmoCount", "_nonExplosiveAmmoCount", ["_injurer", objNull]]; -private _alreadyDetonating = _vehicle getVariable [QGVAR(detonating), false]; + private _isKnockedOut = _explosiveAmmoCount > 0; -if (!_alreadyDetonating && { _chanceOfDetonate >= random 1 }) exitWith { +// Ignore if the vehicle is already detonating ammo +if (_vehicle getVariable [QEGVAR(cookoff,isAmmoDetonating), false]) exitWith {_isKnockedOut}; + +if (_chanceOfDetonate >= random 1) exitWith { [_vehicle, _injurer, _vehicleAmmo] call FUNC(detonate); LOG_2("Detonating [%1] with a chance-to-detonate [%2]",_vehicle,_chanceOfDetonate); - _vehicle setVariable [QGVAR(detonating), true]; _isKnockedOut }; -// Avoid RPT spam -if (_alreadyDetonating) exitWith { _isKnockedOut }; - LOG_2("[%1] No Detonation - Chance of detonation [%2]",_vehicle,_chanceOfDetonate); false diff --git a/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf b/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf index e18d8a38149..02033b83be7 100644 --- a/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf +++ b/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf @@ -28,7 +28,7 @@ TRACE_6("handleVehicleDamage",_vehicle,_hitPoint,_hitIndex,_injurer,_oldDamage,_ if !(alive _vehicle) exitWith { private _eventHandler = _vehicle getVariable[QGVAR(handleDamage), nil]; if !(isNil "_eventHandler") then { - _vehicle removeEventHandler ["handleDamage", _eventHandler]; + _vehicle removeEventHandler ["HandleDamage", _eventHandler]; }; LOG_1("Vehicle [%1] no longer alive",_vehicle); true diff --git a/addons/vehicle_damage/functions/fnc_medicalDamage.sqf b/addons/vehicle_damage/functions/fnc_medicalDamage.sqf new file mode 100644 index 00000000000..c5234cf1c12 --- /dev/null +++ b/addons/vehicle_damage/functions/fnc_medicalDamage.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Applies medical damage to a unit. + * + * Arguments: + * 0: Target + * 1: Source + * 2: Instigator + * 3: Guarantee death? (default: false) + * + * Return Value: + * None + * + * Example: + * [cursorObject, player, player] call ace_vehicle_damage_fnc_medicalDamage; + * + * Public: No + */ + +params ["_unit", "_source", "_instigator", ["_guaranteeDeath", false]]; + +// Check if unit is invulnerable +if !(isDamageAllowed _unit && {_unit getVariable [QEGVAR(medical,allowDamage), true]}) exitWith {}; + +if (GETEGVAR(medical,enabled,false)) then { + for "_i" from 0 to floor (4 + random 3) do { + [_unit, random [0, 0.66, 1], selectRandom ["Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg"], selectRandom ["bullet", "shell", "explosive"], _instigator] call EFUNC(medical,addDamageToUnit); + }; +} else { + { + _unit setHitPointDamage [_x, (_unit getHitPointDamage _x) + random [0, 0.66, 1], true, _source, _instigator]; + } forEach ["HitFace", "HitNeck", "HitHead", "HitPelvis", "HitAbdomen", "HitDiaphragm", "HitChest", "HitBody", "HitArms", "HitHands", "HitLegs"]; +}; + +// If guaranteed death is wished +if (_guaranteeDeath && {alive _unit}) then { + [_unit, QGVAR(medicalDamage), _source, _instigator] call EFUNC(common,setDead); +}; diff --git a/addons/vehicle_damage/functions/fnc_processHit.sqf b/addons/vehicle_damage/functions/fnc_processHit.sqf index 73e70bbf577..2402df7fc25 100644 --- a/addons/vehicle_damage/functions/fnc_processHit.sqf +++ b/addons/vehicle_damage/functions/fnc_processHit.sqf @@ -37,12 +37,10 @@ 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 + // Kill everyone inside for very insane damage { - _x setDamage 1; - _x setVariable [QEGVAR(medical,lastDamageSource), _injurer]; - _x setVariable [QEGVAR(medical,lastInstigator), _injurer]; - } forEach crew _vehicle; + [QGVAR(medicalDamage), [_x, _injurer, _injurer, true], _x] call CBA_fnc_targetEvent; + } forEach (crew _vehicle); _vehicle setDamage 1; _return = false; _return @@ -119,7 +117,7 @@ if (_isCar) then { _ammoEffectiveness = (_ammoEffectiveness + (_ammoEffectiveness * 0.5)) min 1; }; -private _currentVehicleAmmo = [_vehicle] call EFUNC(cookoff,getVehicleAmmo); +private _currentVehicleAmmo = _vehicle call EFUNC(cookoff,getVehicleAmmo); private _chanceOfDetonation = 0; private _explosiveAmmoCount = 0; private _nonExplosiveAmmoCount = 0; @@ -163,7 +161,7 @@ switch (_hitArea) do { _chanceOfFire = 0; // no cookoff for cars }; - if ([_vehicle, _chanceToDetonate, _currentVehicleAmmo, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { + if ([_vehicle, _chanceToDetonate, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { [_vehicle] call FUNC(knockOut); }; @@ -191,7 +189,7 @@ switch (_hitArea) do { _chanceOfFire = 0; // no cookoff for cars }; - if ([_vehicle, _chanceToDetonate, _currentVehicleAmmo, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { + if ([_vehicle, _chanceToDetonate, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { [_vehicle, _hitIndex, _hitpointName, 0.89 * _penChance] call FUNC(addDamage); [_vehicle] call FUNC(knockOut); }; @@ -265,7 +263,7 @@ switch (_hitArea) do { _chanceOfFire = 0; // no cookoff for cars }; - if ([_vehicle, _chanceToDetonate, _currentVehicleAmmo, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { + if ([_vehicle, _chanceToDetonate, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { [_vehicle] call FUNC(knockOut); }; diff --git a/addons/vehicle_damage/initSettings.inc.sqf b/addons/vehicle_damage/initSettings.inc.sqf index ae322a6fd88..0d3f324af2f 100644 --- a/addons/vehicle_damage/initSettings.inc.sqf +++ b/addons/vehicle_damage/initSettings.inc.sqf @@ -8,16 +8,6 @@ true // Needs mission restart ] call CBA_settings_fnc_init; -[ - QGVAR(removeAmmoDuringCookoff), "CHECKBOX", - [LSTRING(removeAmmoAfterCookoff_setting_enable), LSTRING(removeAmmoAfterCookoff_setting_description)], - LSTRING(category_displayName), - true, // default value - true, // isGlobal - {[QGVAR(removeAmmoDuringCookoff), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart -] call CBA_settings_fnc_init; - [ QGVAR(enableCarDamage), "CHECKBOX", [LSTRING(carDamage_setting_enable), LSTRING(carDamage_setting_description)], diff --git a/addons/vehicle_damage/stringtable.xml b/addons/vehicle_damage/stringtable.xml index 5581408f745..4a8fdb42643 100644 --- a/addons/vehicle_damage/stringtable.xml +++ b/addons/vehicle_damage/stringtable.xml @@ -49,30 +49,6 @@ Продвинутое повреждение машин Habilitar/Deshabilitar daño avanzado de coche (Experimental) - - Removes all vehicle ammo after cook-off - 誘爆後に車両から全ての弾薬を削除 - Retire toutes les munitions des véhicules après une auto-inflammation. - Entfernt die gesamte Munition nach dem Durchzünden der Munition eines Fahrzeuges. - Rimuove tutte le munizioni dal veicolo dopo l'esplosione delle stesse - Usuwa całą amunicję z pojazdu po samozapłonie - 殉爆后移除所有车辆弹药 - 쿡오프 현상 후 차량에서 모든 탄약을 제거합니다. - Удалять все боеприпасы из техники после их детонации - Elimina toda la munición del vehículo despues ser inducida a detonar por calor - - - Enable/Disable Ammo Removal During Cook-Off - 誘爆中の弾薬除去を有効/無効にする - Retirer les munitions durant l'auto-inflammation - Aktiviert/Deaktiviert Entfernung der Munition beim Durchzünden - Abilita rimozione munizioni dopo l'esplosione - Włącz/Wyłącz usuwanie amunicji podczas samozapłonu - 启用/禁用殉爆过程中的弹药移除功能 - 쿡오프시 탄약 제거 활성화/비활성화 - Удалять боеприпасы из-за детонации - Habilita/Deshabilita ka eliminación de munición durante la detonación inducida por calor - Wreck (Turret) Épave (tourelle) diff --git a/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf b/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf index 6461e7fca28..4d0f065c06a 100644 --- a/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf +++ b/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf @@ -23,8 +23,12 @@ if (!params [["_unit", objNull, [objNull]], ["_veh", objNull, [objNull]], ["_use }; TRACE_3("params",_unit,_veh,_useCustom); -if (isNull _unit) exitWith {ERROR("null unit");}; -if (isNull _veh) exitWith {ERROR("null vehicle");}; +if (isNull _unit) exitWith { + ERROR("null unit"); +}; +if (isNull _veh) exitWith { + ERROR("null vehicle"); +}; if (_useCustom) then { private _previousMags = magazinesDetail _unit; diff --git a/addons/vehiclelock/functions/fnc_lockpick.sqf b/addons/vehiclelock/functions/fnc_lockpick.sqf index 4ef3289b458..7bb29395f0e 100644 --- a/addons/vehiclelock/functions/fnc_lockpick.sqf +++ b/addons/vehiclelock/functions/fnc_lockpick.sqf @@ -33,7 +33,10 @@ if ((locked _veh) == 0) exitWith {false}; if !("ACE_key_lockpick" in (_unit call EFUNC(common,uniqueItems))) exitWith {false}; private _vehLockpickStrength = _veh getVariable[QGVAR(lockpickStrength), GVAR(DefaultLockpickStrength)]; -if (!(_vehLockpickStrength isEqualType 0)) exitWith {ERROR("ACE_vehicleLock_LockpickStrength invalid"); false}; +if !(_vehLockpickStrength isEqualType 0) exitWith { + ERROR("ACE_vehicleLock_LockpickStrength invalid"); + false +}; //-1 indicates unpickable lock if (_vehLockpickStrength < 0) exitWith {false}; @@ -45,7 +48,7 @@ private _condition = { ((_unit distance _veh) < 5) && {(speed _veh) < 0.1} }; -if (!([[_unit, _veh]] call _condition)) exitWith {false}; +if !([[_unit, _veh]] call _condition) exitWith {false}; private _returnValue = _funcType in ["canLockpick", "startLockpick", "finishLockpick"]; switch (_funcType) do { diff --git a/addons/vehiclelock/functions/fnc_moduleSync.sqf b/addons/vehiclelock/functions/fnc_moduleSync.sqf index c29c7a06d29..a269fbd6e54 100644 --- a/addons/vehiclelock/functions/fnc_moduleSync.sqf +++ b/addons/vehiclelock/functions/fnc_moduleSync.sqf @@ -22,7 +22,7 @@ if (!isServer) exitWith {}; params ["_logic", "_syncedObjects", "_activated"]; TRACE_3("params",_logic,_syncedObjects,_activated); -if !(_activated) exitWith {WARNING("Vehicle Lock Sync Module - placed but not active");}; +if (!_activated) exitWith {WARNING("Vehicle Lock Sync Module - placed but not active");}; [{ params ["_syncedObjects"]; diff --git a/addons/vehiclelock/initSettings.inc.sqf b/addons/vehiclelock/initSettings.inc.sqf index 9f68c77e7c3..dcb520e7e21 100644 --- a/addons/vehiclelock/initSettings.inc.sqf +++ b/addons/vehiclelock/initSettings.inc.sqf @@ -3,8 +3,7 @@ [LSTRING(DefaultLockpickStrength_DisplayName), LSTRING(DefaultLockpickStrength_Description)], LSTRING(DisplayName), [-1,60,10,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(defaultLockpickStrength), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ diff --git a/addons/viewports/functions/fnc_eachFrame.sqf b/addons/viewports/functions/fnc_eachFrame.sqf index 068a5edcf5c..21f2f09dc8d 100644 --- a/addons/viewports/functions/fnc_eachFrame.sqf +++ b/addons/viewports/functions/fnc_eachFrame.sqf @@ -27,7 +27,7 @@ private _newIndex = -1; if (cba_events_control) then { if (cameraView != "INTERNAL") exitWith {}; if (isTurnedOut _player) exitWith {}; - if (!([_player, _vehicle, []] call EFUNC(common,canInteractWith))) exitWith {}; + if !([_player, _vehicle, []] call EFUNC(common,canInteractWith)) exitWith {}; BEGIN_COUNTER(newIndex); if ((_shownIndex > -1) && {currentVisionMode _player != _lastVisionMode}) then { diff --git a/addons/viewports/functions/fnc_getSeatInfo.sqf b/addons/viewports/functions/fnc_getSeatInfo.sqf index 86dccebdd19..01c71c3cfeb 100644 --- a/addons/viewports/functions/fnc_getSeatInfo.sqf +++ b/addons/viewports/functions/fnc_getSeatInfo.sqf @@ -41,6 +41,6 @@ private _compartment = switch (_role) do { }; }; -if (!(_compartment isEqualType "")) then { _compartment = format ["Compartment%1",_compartment] }; +if !(_compartment isEqualType "") then {_compartment = format ["Compartment%1",_compartment]}; [_role, _cargoIndex, _turretPath, _compartment] diff --git a/addons/viewrestriction/functions/fnc_changeCamera.sqf b/addons/viewrestriction/functions/fnc_changeCamera.sqf index 6a1f7d03ff6..eb6907386a4 100644 --- a/addons/viewrestriction/functions/fnc_changeCamera.sqf +++ b/addons/viewrestriction/functions/fnc_changeCamera.sqf @@ -18,7 +18,7 @@ params ["_newCameraView", "_cameraOn"]; -if (! ([_newCameraView, _cameraOn] call FUNC(canChangeCamera))) exitWith {}; +if !([_newCameraView, _cameraOn] call FUNC(canChangeCamera)) exitWith {}; TRACE_1("View Restricted",XGVAR(mode)); diff --git a/addons/viewrestriction/initSettings.inc.sqf b/addons/viewrestriction/initSettings.inc.sqf index 3ed47c10efb..80382f5b198 100644 --- a/addons/viewrestriction/initSettings.inc.sqf +++ b/addons/viewrestriction/initSettings.inc.sqf @@ -6,7 +6,7 @@ [[0, 1, 2, 3], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson), LSTRING(Selective)], 0], true, {[QGVAR(mode), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -17,7 +17,7 @@ [[0, 1, 2], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson)], 0], true, {[QGVAR(modeSelectiveFoot), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -28,7 +28,7 @@ [[0, 1, 2], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson)], 0], true, {[QGVAR(modeSelectiveLand), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -39,7 +39,7 @@ [[0, 1, 2], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson)], 0], true, {[QGVAR(modeSelectiveAir), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -50,7 +50,7 @@ [[0, 1, 2], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson)], 0], true, {[QGVAR(modeSelectiveSea), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ diff --git a/addons/volume/initSettings.inc.sqf b/addons/volume/initSettings.inc.sqf index 8735f81527f..44bb464a1ee 100644 --- a/addons/volume/initSettings.inc.sqf +++ b/addons/volume/initSettings.inc.sqf @@ -3,9 +3,6 @@ "CHECKBOX", [ELSTRING(common,Enabled), LSTRING(KeybindDescription)], format ["ACE %1", LLSTRING(Name)], - false, - false, - {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, false ] call CBA_fnc_addSetting; @@ -14,10 +11,7 @@ "LIST", [LSTRING(Reduction), LSTRING(ReductionDescription)], format ["ACE %1", LLSTRING(Name)], - [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ["0%", "10%", "20%", "30%", "40%", "50%", "60%", "70%", "80%", "90%", "100%"], 5], - false, - {[QGVAR(reduction), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false + [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ["0%", "10%", "20%", "30%", "40%", "50%", "60%", "70%", "80%", "90%", "100%"], 5] ] call CBA_fnc_addSetting; [ @@ -25,10 +19,7 @@ "LIST", [LSTRING(FadeDelay), LSTRING(FadeDelayDescription)], format ["ACE %1", LLSTRING(Name)], - [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ["0s", "1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s", "10s"], 1], - false, - {[QGVAR(fadeDelay), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false + [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ["0s", "1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s", "10s"], 1] ] call CBA_fnc_addSetting; [ @@ -36,9 +27,6 @@ "CHECKBOX", [LSTRING(LowerInVehicles), LSTRING(LowerInVehiclesDescription)], format ["ACE %1", LLSTRING(Name)], - false, - false, - {[QGVAR(lowerInVehicles), _this] call EFUNC(common,cbaSettings_settingChanged)}, false ] call CBA_fnc_addSetting; @@ -47,10 +35,7 @@ "CHECKBOX", [LSTRING(ShowNotification), LSTRING(ShowNotificationDescription)], format ["ACE %1", LLSTRING(Name)], - true, - false, - {[QGVAR(showNotification), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false + true ] call CBA_fnc_addSetting; [ @@ -58,8 +43,5 @@ "CHECKBOX", [LSTRING(RemindIfLowered), LSTRING(RemindIfLoweredDescription)], format ["ACE %1", LLSTRING(Name)], - false, - false, - {[QGVAR(remindIfLowered), _this] call EFUNC(common,cbaSettings_settingChanged)}, false ] call CBA_fnc_addSetting; diff --git a/addons/weaponselect/XEH_postInit.sqf b/addons/weaponselect/XEH_postInit.sqf index 77a2fc673b0..e9f05de8bbd 100644 --- a/addons/weaponselect/XEH_postInit.sqf +++ b/addons/weaponselect/XEH_postInit.sqf @@ -198,7 +198,7 @@ if (!hasInterface) exitWith {}; ["ACE3 Vehicles", QGVAR(CollisionLights), localize LSTRING(CollisionLights), { // Conditions: canInteract - if (!([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith))) exitWith {false}; + if !([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if ((ACE_player isEqualTo (vehicle ACE_player)) || {ACE_player != (driver (vehicle ACE_player))}) exitWith {false}; diff --git a/addons/weaponselect/XEH_preInit.sqf b/addons/weaponselect/XEH_preInit.sqf index 92ba1b06a60..e699f3d2f38 100644 --- a/addons/weaponselect/XEH_preInit.sqf +++ b/addons/weaponselect/XEH_preInit.sqf @@ -11,18 +11,22 @@ GVAR(GrenadesAll) = []; GVAR(GrenadesFrag) = []; GVAR(GrenadesNonFrag) = []; +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgAmmo = configFile >> "CfgAmmo"; +private _cfgThrow = configFile >> "CfgWeapons" >> "Throw"; + { - private _magazines = getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines"); + private _magazines = getArray (_cfgThrow >> _x >> "magazines"); GVAR(GrenadesAll) append _magazines; { - private _ammo = getText (configFile >> "CfgMagazines" >> _x >> "ammo"); - private _explosive = getNumber (configFile >> "CfgAmmo" >> _ammo >> "explosive"); + private _ammo = getText (_cfgMagazines >> _x >> "ammo"); + private _explosive = getNumber (_cfgAmmo >> _ammo >> "explosive"); ([GVAR(GrenadesFrag), GVAR(GrenadesNonFrag)] select (_explosive == 0)) pushBack _x; } forEach _magazines; -} forEach getArray (configFile >> "CfgWeapons" >> "Throw" >> "muzzles"); +} forEach getArray (_cfgThrow >> "muzzles"); #include "initSettings.inc.sqf" diff --git a/addons/weaponselect/functions/fnc_selectNextGrenade.sqf b/addons/weaponselect/functions/fnc_selectNextGrenade.sqf index ff111a93f6d..ad17c7f18d9 100644 --- a/addons/weaponselect/functions/fnc_selectNextGrenade.sqf +++ b/addons/weaponselect/functions/fnc_selectNextGrenade.sqf @@ -61,14 +61,14 @@ private _vestGrenades = vestItems _unit select {_x in GVAR(GrenadesAll) private _backpackGrenades = backpackItems _unit select {_x in GVAR(GrenadesAll) && {_x != _nextGrenade}}; // remove all grenades except those we are switching to --> this breaks the selector -{_unit removeItemFromUniform _x; false} count _uniformGrenades; -{_unit removeItemFromVest _x; false} count _vestGrenades; -{_unit removeItemFromBackpack _x; false} count _backpackGrenades; +{_unit removeItemFromUniform _x} forEach _uniformGrenades; +{_unit removeItemFromVest _x} forEach _vestGrenades; +{_unit removeItemFromBackpack _x} forEach _backpackGrenades; // readd grenades -{_unit addItemToUniform _x; false} count _uniformGrenades; -{_unit addItemToVest _x; false} count _vestGrenades; -{_unit addItemToBackpack _x; false} count _backpackGrenades; +{_unit addItemToUniform _x} forEach _uniformGrenades; +{_unit addItemToVest _x} forEach _vestGrenades; +{_unit addItemToBackpack _x} forEach _backpackGrenades; [_nextGrenade, {_x == _nextGrenade} count _magazines] call FUNC(displayGrenadeTypeAndNumber); diff --git a/addons/weaponselect/initSettings.inc.sqf b/addons/weaponselect/initSettings.inc.sqf index 029c5201cb6..f5695748b40 100644 --- a/addons/weaponselect/initSettings.inc.sqf +++ b/addons/weaponselect/initSettings.inc.sqf @@ -2,7 +2,5 @@ QGVAR(displayText), "CHECKBOX", [LSTRING(SettingDisplayTextName), LSTRING(SettingDisplayTextDesc)], ELSTRING(common,ACEKeybindCategoryWeapons), - true, // default value - false, // isGlobal - {[QGVAR(displayText), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // default value ] call CBA_fnc_addSetting; diff --git a/addons/weather/functions/fnc_calculateWindSpeed.sqf b/addons/weather/functions/fnc_calculateWindSpeed.sqf index cd73fac3588..d24322bef09 100644 --- a/addons/weather/functions/fnc_calculateWindSpeed.sqf +++ b/addons/weather/functions/fnc_calculateWindSpeed.sqf @@ -47,15 +47,15 @@ if (_terrainEffectEnabled) then { private _newWindSpeed = 0; { private _windSource = [100, _windDirAdjusted, _x] call _fnc_polar2vect; - if (!(terrainIntersectASL [_position, _position vectorAdd _windSource])) exitWith { + if !(terrainIntersectASL [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 9) * _windSpeed; }; _windSource = [100, _windDirAdjusted + _x, 0] call _fnc_polar2vect; - if (!(terrainIntersectASL [_position, _position vectorAdd _windSource])) exitWith { + if !(terrainIntersectASL [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 9) * _windSpeed; }; _windSource = [100, _windDirAdjusted - _x, 0] call _fnc_polar2vect; - if (!(terrainIntersectASL [_position, _position vectorAdd _windSource])) exitWith { + if !(terrainIntersectASL [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 9) * _windSpeed; }; } forEach [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; @@ -69,15 +69,15 @@ if (_obstacleEffectEnabled) then { private _newWindSpeed = 0; { private _windSource = [20, _windDirAdjusted, _x] call _fnc_polar2vect; - if (!(lineIntersects [_position, _position vectorAdd _windSource])) exitWith { + if !(lineIntersects [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 2) * _windSpeed; }; _windSource = [20, _windDirAdjusted + _x, 0] call _fnc_polar2vect; - if (!(lineIntersects [_position, _position vectorAdd _windSource])) exitWith { + if !(lineIntersects [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 2) * _windSpeed; }; _windSource = [20, _windDirAdjusted - _x, 0] call _fnc_polar2vect; - if (!(lineIntersects [_position, _position vectorAdd _windSource])) exitWith { + if !(lineIntersects [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 2) * _windSpeed; }; } forEach [0, 5, 10, 15, 20, 25, 30, 35, 40, 45]; diff --git a/addons/weather/init3DEN.sqf b/addons/weather/init3DEN.sqf index 34b7dc2d5bc..74af5fbaf1b 100644 --- a/addons/weather/init3DEN.sqf +++ b/addons/weather/init3DEN.sqf @@ -5,7 +5,7 @@ // cannot create checkboxes which have the default value "true" // 3den uses inverted checkboxes instead, but those only change in appearence // we have to auto set these settings manually - on mission creation -add3DENEventHandler ["onMissionNew", { +add3DENEventHandler ["OnMissionNew", { set3DENMissionAttributes [ ["Intel", "IntelWavesIsForced", true], ["Intel", "IntelWindIsForced", true] diff --git a/addons/weather/initSettings.inc.sqf b/addons/weather/initSettings.inc.sqf index fb11e31e753..26f44420840 100644 --- a/addons/weather/initSettings.inc.sqf +++ b/addons/weather/initSettings.inc.sqf @@ -34,6 +34,5 @@ private _category = [format ["ACE %1", LLSTRING(Module_DisplayName)]]; QGVAR(showCheckAirTemperature), "CHECKBOX", [LSTRING(showCheckAirTemperature_DisplayName), LELSTRING(common,showActionInSelfInteraction)], _category, - true, // default value - false // isGlobal + true // default value ] call CBA_fnc_addSetting; diff --git a/addons/xm157/functions/fnc_keyPress.sqf b/addons/xm157/functions/fnc_keyPress.sqf index c5e4760563e..3a9dd53a269 100644 --- a/addons/xm157/functions/fnc_keyPress.sqf +++ b/addons/xm157/functions/fnc_keyPress.sqf @@ -19,8 +19,8 @@ params ["_func", "_keyDown"]; if (!GVAR(shown)) exitWith { false }; // fast exit if not shown -if (!([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith))) exitWith { false }; -if (!(ACE_player call CBA_fnc_canUseWeapon)) exitWith { false }; +if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith { false }; +if !(ACE_player call CBA_fnc_canUseWeapon) exitWith { false }; if (currentMuzzle ACE_player != currentWeapon ACE_player) exitWith { false }; private _display = uinamespace getVariable [QGVAR(display), displayNull]; diff --git a/addons/zeus/CfgVehicles.hpp b/addons/zeus/CfgVehicles.hpp index 2a1f2611256..5fb4a4f61a5 100644 --- a/addons/zeus/CfgVehicles.hpp +++ b/addons/zeus/CfgVehicles.hpp @@ -256,6 +256,12 @@ class CfgVehicles { displayName = CSTRING(ModuleSimulation_DisplayName); function = QFUNC(moduleSimulation); }; + class GVAR(moduleSpectator): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(Utility); + displayName = ECSTRING(spectator,Module_DisplayName); + curatorInfoType = QGVAR(RscSpectator); + }; class GVAR(moduleSuicideBomber): GVAR(moduleBase) { curatorCanAttach = 1; category = QGVAR(AI); diff --git a/addons/zeus/XEH_PREP.hpp b/addons/zeus/XEH_PREP.hpp index 8de15147bd5..69dd7b18a63 100644 --- a/addons/zeus/XEH_PREP.hpp +++ b/addons/zeus/XEH_PREP.hpp @@ -34,6 +34,7 @@ PREP(moduleSetMedicalVehicle); PREP(moduleSetRepairFacility); PREP(moduleSetRepairVehicle); PREP(moduleSimulation); +PREP(moduleSpectator); PREP(moduleSuicideBomber); PREP(moduleSuppressiveFire); PREP(moduleSuppressiveFireLocal); @@ -56,6 +57,7 @@ PREP(ui_groupSide); PREP(ui_patrolArea); PREP(ui_searchArea); PREP(ui_setEngineer); +PREP(ui_spectator); PREP(ui_suicideBomber); PREP(ui_teleportPlayers); PREP(ui_toggleFlashlight); diff --git a/addons/zeus/XEH_postInit.sqf b/addons/zeus/XEH_postInit.sqf index b4d1302ab5b..15b4c15f769 100644 --- a/addons/zeus/XEH_postInit.sqf +++ b/addons/zeus/XEH_postInit.sqf @@ -11,6 +11,7 @@ QGVAR(GlobalSkillAI) addPublicVariableEventHandler FUNC(moduleGlobalSetSkill); [QGVAR(moduleSearchNearby), CBA_fnc_searchNearby] call CBA_fnc_addEventHandler; [QGVAR(moduleSearchArea), CBA_fnc_taskSearchArea] call CBA_fnc_addEventHandler; [QGVAR(suppressiveFire), LINKFUNC(moduleSuppressiveFireLocal)] call CBA_fnc_addEventHandler; +[QGVAR(moduleSpectator), LINKFUNC(moduleSpectator)] call CBA_fnc_addEventHandler; // Editable object commands must be ran on server, this events are used in the respective module if (isServer) then { diff --git a/addons/zeus/config.cpp b/addons/zeus/config.cpp index 2714c247b05..d90c9062949 100644 --- a/addons/zeus/config.cpp +++ b/addons/zeus/config.cpp @@ -99,6 +99,11 @@ class CfgPatches { QGVAR(moduleLayTrench) }; }; + class GVAR(spectator): ADDON { + units[] = { + QGVAR(moduleSpectator) + }; + }; }; class ACE_Curator { @@ -112,6 +117,7 @@ class ACE_Curator { GVAR(arsenal) = "ace_arsenal"; GVAR(fire) = "ace_fire"; GVAR(trenches) = "ace_trenches"; + GVAR(spectator) = "ace_spectator"; }; #include "CfgFactionClasses.hpp" diff --git a/addons/zeus/functions/fnc_addObjectToCurator.sqf b/addons/zeus/functions/fnc_addObjectToCurator.sqf index 9651630ccce..4b87904d0f6 100644 --- a/addons/zeus/functions/fnc_addObjectToCurator.sqf +++ b/addons/zeus/functions/fnc_addObjectToCurator.sqf @@ -17,7 +17,7 @@ params ["_object"]; -if (!(_object getVariable [QGVAR(addObject), GVAR(autoAddObjects)])) exitWith {}; +if !(_object getVariable [QGVAR(addObject), GVAR(autoAddObjects)]) exitWith {}; [{ TRACE_1("Delayed addCuratorEditableObjects",_this); diff --git a/addons/zeus/functions/fnc_bi_moduleCurator.sqf b/addons/zeus/functions/fnc_bi_moduleCurator.sqf index ec04a12d241..cdc4d35b648 100644 --- a/addons/zeus/functions/fnc_bi_moduleCurator.sqf +++ b/addons/zeus/functions/fnc_bi_moduleCurator.sqf @@ -23,13 +23,13 @@ params ["_logic", "_units", "_activated"]; if (_activated) then { - //--- Terminate when not created on the server - if (!isserver && local _logic && isnull (getassignedcuratorunit _logic)) exitwith { + // Terminate when not created on the server + if (!isServer && local _logic && isnull (getassignedcuratorunit _logic)) exitwith { [format ["%1 is trying to create curator logic ModuleCurator_F",profilename],"bis_fnc_error",false] call bis_fnc_mp; deletevehicle _logic; }; - //--- Get curator owner + // Get curator owner _ownerVar = _logic getvariable ["owner",""]; _ownerUID = parsenumber _ownerVar; if (cheatsenabled) then { @@ -46,13 +46,13 @@ if (_activated) then { }; _isAdmin = _ownerVar == "#adminLogged" || _ownerVar == "#adminVoted"; - //--- Wipe out the variable so clients can't access it + // Wipe out the variable so clients can't access it _logic setvariable ["owner",nil]; - //--- Server + // Server if (isserver) then { - //--- Prepare admin variable + // Prepare admin variable _adminVar = ""; if (_isAdmin) then { _letters = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]; @@ -61,12 +61,12 @@ if (_activated) then { _logic setvariable ["adminVar",_adminVar,true]; }; - //--- Get allowed addons + // Get allowed addons _addonsType = _logic getvariable ["Addons",2]; _addons = []; switch _addonsType do { - //--- All (including unofficial ones) + // All (including unofficial ones) case 3: { _cfgPatches = configfile >> "cfgpatches"; for "_i" from 0 to (count _cfgPatches - 1) do { @@ -79,10 +79,10 @@ if (_activated) then { _logic addcuratoraddons _addons; }; - //--- All active + // All active case 2: {}; - //--- All mission + // All mission case 1: { _addonsList = []; { @@ -92,13 +92,13 @@ if (_activated) then { _logic addcuratoraddons _addonsList; }; - //--- None + // None case 0: { removeallcuratoraddons _logic; }; }; - //--- Handle ownership + // Handle ownership [_logic,_ownerVar,_ownerUID,_adminVar] spawn { scriptname "BIS_fnc_moduleCurator: Owner"; @@ -110,16 +110,16 @@ if (_activated) then { _name = _logic getvariable ["name",""]; if (_name == "") then {_name = localize "STR_A3_curator";}; - //--- Wait until mission starts + // Wait until mission starts waitUntil {time > 0}; // NOTE: DO NOT CHANGE TO CBA_missionTime, IT BREAKS THE MODULE - //--- Refresh addon list, so it's broadcasted to clients + // Refresh addon list, so it's broadcasted to clients _addons = curatoraddons _logic; removeAllCuratorAddons _logic; _logic addcuratoraddons _addons; while {true} do { - //--- Wait for player to become Zeus + // Wait for player to become Zeus switch true do { case (_ownerUID > 0): { waituntil { @@ -133,7 +133,7 @@ if (_activated) then { }; if (isnull _logic) exitwith {}; - //--- Assign + // Assign _player = objnull; switch true do { case (_ownerUID > 0): { @@ -150,7 +150,7 @@ if (_activated) then { waituntil {_player assignCurator _logic; getassignedcuratorunit _logic == _player || isnull _logic}; if (isnull _logic) exitwith {}; - //--- Add radio channels + // Add radio channels { _x radiochanneladd [_player]; } foreach (_logic getvariable ["channels",[]]); @@ -159,7 +159,7 @@ if (_activated) then { private _msgCode = { params ["_logic","_player"]; - //--- Sent notification to all assigned players + // Sent notification to all assigned players if ((_logic getVariable ["showNotification",true]) && GVAR(zeusAscension)) then { { if (isplayer _x) then { @@ -181,7 +181,7 @@ if (_activated) then { // Added by ace_zeus [QGVAR(zeusUnitAssigned), [_logic,_player]] call CBA_fnc_globalEvent; - //--- Wait for player to stop being Zeus + // Wait for player to stop being Zeus switch true do { case (_ownerUID > 0): { waituntil { @@ -195,12 +195,12 @@ if (_activated) then { }; if (isnull _logic) exitwith {}; - //--- Add radio channels + // Add radio channels { _x radiochannelremove [_player]; } foreach (_logic getvariable ["channels",[]]); - //--- Unassign + // Unassign waituntil {unassigncurator _logic; isnull (getassignedcuratorunit _logic) || isnull _logic}; if (isnull _logic) exitwith {}; }; @@ -211,14 +211,14 @@ if (_activated) then { params ["_logic"]; if (GVAR(zeusBird)) then { - //--- Create bird + // Create bird _birdType = _logic getVariable ["birdType","eagle_f"]; if (_birdType != "") then { _bird = createvehicle [_birdType,[100,100,100],[],0,"none"]; _logic setVariable ["bird",_bird,true]; }; - //--- Locality changed + // Locality changed _logic addeventhandler [ "local", { @@ -237,7 +237,7 @@ if (_activated) then { [_logic] call _birdCode; }; - //--- Activated all future addons + // Activated all future addons _addons = []; { if (typeof _x == "ModuleCuratorAddAddons_F") then { @@ -254,12 +254,12 @@ if (_activated) then { if (time <= 0) then { _addons call bis_fnc_activateaddons; }; }; - //--- Player + // Player if (hasinterface) then { waituntil {local player}; _serverCommand = ["#kick", "#shutdown"] select (_ownerVar == "#adminLogged"); - //--- Black effect until the interface is open + // Black effect until the interface is open _forced = _logic getvariable ["forced",0] > 0; if (_forced) then { _isCurator = switch true do { @@ -279,15 +279,15 @@ if (_activated) then { }; }; - //--- Check if player is server admin + // Check if player is server admin if (_isAdmin) then { _adminVar = _logic getvariable ["adminVar",""]; _logic setvariable ["adminVar",nil]; if (isserver) then { - //--- Host + // Host missionnamespace setvariable [_adminVar,player]; } else { - //--- Client + // Client [_logic,_adminVar,_serverCommand] spawn { scriptname "BIS_fnc_moduleCurator: Admin check"; @@ -314,7 +314,7 @@ if (_activated) then { sleep 1; waituntil {alive player}; - //--- Show warning when Zeus key is not assigned + // Show warning when Zeus key is not assigned if (count (actionkeys "curatorInterface") == 0) then { [ format [ @@ -324,7 +324,7 @@ if (_activated) then { ] call bis_fnc_guiMessage; }; - //--- Show hint about pinging for players + // Show hint about pinging for players if ( isnil {profilenamespace getvariable "bis_fnc_curatorPinged_done"} && @@ -339,7 +339,7 @@ if (_activated) then { }; }; - //--- Add local event handlers + // Add local event handlers _logic addeventhandler ["curatorFeedbackMessage",{_this call bis_fnc_showCuratorFeedbackMessage;}]; _logic addeventhandler ["curatorPinged",{_this call bis_fnc_curatorPinged;}]; _logic addeventhandler ["curatorObjectPlaced",{_this call bis_fnc_curatorObjectPlaced;}]; diff --git a/addons/zeus/functions/fnc_getModuleDestination.sqf b/addons/zeus/functions/fnc_getModuleDestination.sqf index b328201d6ce..10d7acae9e0 100644 --- a/addons/zeus/functions/fnc_getModuleDestination.sqf +++ b/addons/zeus/functions/fnc_getModuleDestination.sqf @@ -113,9 +113,9 @@ GVAR(moduleDestination_mapDrawEH) = [((findDisplay 312) displayCtrl 50), "draw", } else { TRACE_4("cleaning up",_this select 1,GVAR(moduleDestination_displayEHMouse),GVAR(moduleDestination_displayEHKeyboard),GVAR(moduleDestination_mapDrawEH)); (_this select 1) call CBA_fnc_removePerFrameHandler; - (findDisplay 312) displayRemoveEventHandler ["mouseButtonDown", GVAR(moduleDestination_displayEHMouse)]; + (findDisplay 312) displayRemoveEventHandler ["MouseButtonDown", GVAR(moduleDestination_displayEHMouse)]; (findDisplay 312) displayRemoveEventHandler ["KeyDown", GVAR(moduleDestination_displayEHKeyboard)]; - ((findDisplay 312) displayCtrl 50) ctrlRemoveEventHandler ["draw", GVAR(moduleDestination_mapDrawEH)]; + ((findDisplay 312) displayCtrl 50) ctrlRemoveEventHandler ["Draw", GVAR(moduleDestination_mapDrawEH)]; GVAR(moduleDestination_displayEHMouse) = nil; GVAR(moduleDestination_displayEHKeyboard) = nil; GVAR(moduleDestination_mapDrawEH) = nil; diff --git a/addons/zeus/functions/fnc_moduleCargoParadrop.sqf b/addons/zeus/functions/fnc_moduleCargoParadrop.sqf index 69d90d310d6..2aaffb37964 100644 --- a/addons/zeus/functions/fnc_moduleCargoParadrop.sqf +++ b/addons/zeus/functions/fnc_moduleCargoParadrop.sqf @@ -30,13 +30,13 @@ TRACE_4("moduleCargoParadrop placed",_logic,typeOf _vehicle,_pilot,typeOf _pilot deleteVehicle _logic; // cleanup logic now, we just needed it to get the attached vehicle -if (!(missionNamespace getVariable [QEGVAR(cargo,enable), false])) exitWith { +if !(missionNamespace getVariable [QEGVAR(cargo,enable), false]) exitWith { [LSTRING(RequiresAddon)] call FUNC(showMessage); }; if (isNull _vehicle) exitWith { [LSTRING(NothingSelected)] call FUNC(showMessage); }; -if (!(_vehicle isKindOf "Air")) exitWith { +if !(_vehicle isKindOf "Air") exitWith { [format ["%1 %2", localize "str_dn_aircraft", localize "str_msg_no_veh_select"]] call FUNC(showMessage); }; if ((!alive _vehicle) || {!alive _pilot}) exitWith { diff --git a/addons/zeus/functions/fnc_moduleCargoParadropWaypoint.sqf b/addons/zeus/functions/fnc_moduleCargoParadropWaypoint.sqf index dded460710b..65706484999 100644 --- a/addons/zeus/functions/fnc_moduleCargoParadropWaypoint.sqf +++ b/addons/zeus/functions/fnc_moduleCargoParadropWaypoint.sqf @@ -22,7 +22,7 @@ TRACE_2("moduleCargoParadropWaypoint",_vehicleGroup,_wpPos); private _vehicle = vehicle leader _vehicleGroup; private _commander = driver _vehicle; private _cargo = _vehicle getVariable [QEGVAR(cargo,loaded), []]; -if (!(_vehicle isKindOf "Air")) exitWith {WARNING_1("not in a air vehicle",typeOf _vehicle); true}; +if !(_vehicle isKindOf "Air") exitWith {WARNING_1("not in a air vehicle",typeOf _vehicle); true}; if (_cargo isEqualTo []) exitWith {WARNING_1("no cargo",_cargo); true}; private _previousSpeedMode = speedMode _vehicleGroup; diff --git a/addons/zeus/functions/fnc_moduleHeal.sqf b/addons/zeus/functions/fnc_moduleHeal.sqf index 9a49375003d..4bf0525ea75 100644 --- a/addons/zeus/functions/fnc_moduleHeal.sqf +++ b/addons/zeus/functions/fnc_moduleHeal.sqf @@ -43,7 +43,7 @@ switch (false) do { }; // Heal validated target -if (["ace_medical"] call EFUNC(common,isModLoaded)) then { +if (GETEGVAR(medical,enabled,false)) then { TRACE_1("healing with ace_medical",_unit); [QEGVAR(medical_treatment,fullHealLocal), [_unit], _unit] call CBA_fnc_targetEvent; } else { diff --git a/addons/zeus/functions/fnc_moduleSetMedic.sqf b/addons/zeus/functions/fnc_moduleSetMedic.sqf index f66ca9132da..d44dd56e593 100644 --- a/addons/zeus/functions/fnc_moduleSetMedic.sqf +++ b/addons/zeus/functions/fnc_moduleSetMedic.sqf @@ -21,7 +21,7 @@ params ["_logic"]; if !(local _logic) exitWith {}; -if !(["ace_medical"] call EFUNC(common,isModLoaded)) then { +if !(GETEGVAR(medical,enabled,false)) then { [LSTRING(RequiresAddon)] call FUNC(showMessage); } else { private _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); diff --git a/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf b/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf index 1f982129357..b6742a25a44 100644 --- a/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf +++ b/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf @@ -21,7 +21,7 @@ params ["_logic"]; if !(local _logic) exitWith {}; -if !(["ace_medical"] call EFUNC(common,isModLoaded)) then { +if !(GETEGVAR(medical,enabled,false)) then { [LSTRING(RequiresAddon)] call FUNC(showMessage); } else { private _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); @@ -40,7 +40,7 @@ if !(["ace_medical"] call EFUNC(common,isModLoaded)) then { if (GETVAR(_unit,EGVAR(captives,isHandcuffed),false)) then { [LSTRING(OnlyNonCaptive)] call FUNC(showMessage); } else { - if (!(GETVAR(_unit,EGVAR(medical,isMedicalFacility),false))) then { + if !(GETVAR(_unit,EGVAR(medical,isMedicalFacility),false)) then { _unit setVariable [QEGVAR(medical,isMedicalFacility), true, true]; }; }; diff --git a/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf b/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf index e8189b377e6..26bb3fcfe95 100644 --- a/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf +++ b/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf @@ -21,7 +21,7 @@ params ["_logic"]; if !(local _logic) exitWith {}; -if !(["ace_medical"] call EFUNC(common,isModLoaded)) then { +if !(GETEGVAR(medical,enabled,false)) then { [LSTRING(RequiresAddon)] call FUNC(showMessage); } else { private _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); diff --git a/addons/zeus/functions/fnc_moduleSpectator.sqf b/addons/zeus/functions/fnc_moduleSpectator.sqf new file mode 100644 index 00000000000..fb9ca2a63b1 --- /dev/null +++ b/addons/zeus/functions/fnc_moduleSpectator.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Zeus module function to make the local player an ACE Spectator. + * + * Arguments: + * 0: Force interface + * 1: Hide player + * 2: Sides available to spectate + * 3: Camera modes available + * 4: Vision modes available + * + * Return Value: + * None + * + * Example: + * [true, true, [west], [0, 1, 2], [-2, -1, 0, 1]] call ace_zeus_fnc_moduleSpectator + * + * Public: No + */ + +params ["_force", "_hide", "_sides", "_modes", "_visions"]; +TRACE_1("params",_this); + +// Update sides available to spectate +[_sides, [west, east, independent, civilian] - _sides] call EFUNC(spectator,updateSides); + +// Update available camera modes +[_modes, [0, 1, 2] - _modes] call EFUNC(spectator,updateCameraModes); + +// Update available vision modes +[_visions, [-2, -1, 0, 1, 2, 3, 4, 5, 6, 7] - _visions] call EFUNC(spectator,updateVisionModes); + +// Make unit spectator (close Zeus camera if open) +if (!isNull curatorCamera) then { + (findDisplay 312) closeDisplay 2; +}; + +[true, _force, _hide] call EFUNC(spectator,setSpectator); diff --git a/addons/zeus/functions/fnc_moduleSuicideBomber.sqf b/addons/zeus/functions/fnc_moduleSuicideBomber.sqf index 8346eb42665..8425ff15485 100644 --- a/addons/zeus/functions/fnc_moduleSuicideBomber.sqf +++ b/addons/zeus/functions/fnc_moduleSuicideBomber.sqf @@ -57,7 +57,7 @@ if (_autoSeek) then { LOG("Unit deleted or killed, PFH removed"); }; - if (!([_unit] call EFUNC(common,isAwake))) exitWith {}; + if !([_unit] call EFUNC(common,isAwake)) exitWith {}; // Detonation private _nearObjects = (_unit nearObjects _activationRadius) select {side _x == _activationSide && {_x != _unit} && {alive _x}}; diff --git a/addons/zeus/functions/fnc_showMessage.sqf b/addons/zeus/functions/fnc_showMessage.sqf index 8bbd7d510dc..53094dbfb3f 100644 --- a/addons/zeus/functions/fnc_showMessage.sqf +++ b/addons/zeus/functions/fnc_showMessage.sqf @@ -18,7 +18,7 @@ * Public: Yes */ -if (!(_this isEqualTypeParams [""])) exitWith {ERROR_1("First arg must be string [%1]",_this);}; +if !(_this isEqualTypeParams [""]) exitWith {ERROR_1("First arg must be string [%1]",_this);}; private _message = _this apply {if ((_x isEqualType "") && {isLocalized _x}) then {localize _x} else {_x}}; [objNull, format _message] call BIS_fnc_showCuratorFeedbackMessage; diff --git a/addons/zeus/functions/fnc_ui_globalSetSkill.sqf b/addons/zeus/functions/fnc_ui_globalSetSkill.sqf index 31f41d76c6b..5a7c5fc5e03 100644 --- a/addons/zeus/functions/fnc_ui_globalSetSkill.sqf +++ b/addons/zeus/functions/fnc_ui_globalSetSkill.sqf @@ -24,7 +24,7 @@ private _ctrlButtonOK = _display displayCtrl 1; //IDC_OK private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); TRACE_1("logicObject",_logic); -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; //Specific on-load stuff: private _fnc_sliderMove = { @@ -74,5 +74,5 @@ private _fnc_onConfirm = { [QGVAR(GlobalSkillAI),GVAR(GlobalSkillAI)] call FUNC(moduleGlobalSetSkill); }; -_display displayAddEventHandler ["unload", _fnc_onUnload]; -_ctrlButtonOK ctrlAddEventHandler ["buttonclick", _fnc_onConfirm]; +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_groupSide.sqf b/addons/zeus/functions/fnc_ui_groupSide.sqf index 4dff592f621..110e2e302da 100644 --- a/addons/zeus/functions/fnc_ui_groupSide.sqf +++ b/addons/zeus/functions/fnc_ui_groupSide.sqf @@ -24,7 +24,7 @@ private _ctrlButtonOK = _display displayCtrl 1; //IDC_OK private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); TRACE_1("logicObject",_logic); -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; //Validate the module target: private _unit = effectiveCommander (attachedTo _logic); @@ -101,7 +101,7 @@ private _fnc_onSelection = { _ctrl ctrlSetTextColor _color; - _ctrl ctrlAddEventHandler ["buttonclick", _fnc_onSelection]; + _ctrl ctrlAddEventHandler ["ButtonClick", _fnc_onSelection]; } forEach IDCs; private _fnc_onUnload = { @@ -129,5 +129,5 @@ private _fnc_onConfirm = { deleteVehicle _logic; }; -_display displayAddEventHandler ["unload", _fnc_onUnload]; -_ctrlButtonOK ctrlAddEventHandler ["buttonClick", _fnc_onConfirm]; +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_setEngineer.sqf b/addons/zeus/functions/fnc_ui_setEngineer.sqf index b2515c311dd..3f008403cc7 100644 --- a/addons/zeus/functions/fnc_ui_setEngineer.sqf +++ b/addons/zeus/functions/fnc_ui_setEngineer.sqf @@ -23,7 +23,7 @@ private _ctrlButtonOK = _display displayCtrl 1; // IDC_OK private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); TRACE_1("logicObject",_logic); -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; // Validate module target private _unit = attachedTo _logic; diff --git a/addons/zeus/functions/fnc_ui_spectator.sqf b/addons/zeus/functions/fnc_ui_spectator.sqf new file mode 100644 index 00000000000..fe9b4a36687 --- /dev/null +++ b/addons/zeus/functions/fnc_ui_spectator.sqf @@ -0,0 +1,265 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Initializes the "Spectator" Zeus module display. + * + * Arguments: + * 0: spectator controls group + * + * Return Value: + * None + * + * Example: + * [CONTROL] call ace_zeus_fnc_ui_spectator + * + * Public: No + */ + +#define SIDE_IDCs [92540, 92541, 92542, 92543] +#define CAMERA_IDCs [92550, 92551, 92552] +#define VISION_IDCs [92558, 92559, 92560, 92561] + +params ["_control"]; + +private _display = ctrlParent _control; +private _ctrlButtonOK = _display displayCtrl 1; // IDC_OK +private _logic = missionNamespace getVariable ["BIS_fnc_initCuratorAttributes_target", objNull]; +TRACE_1("Logic Object",_logic); + +_control ctrlRemoveAllEventHandlers "SetFocus"; + +// Validate module target +private _unit = attachedTo _logic; +TRACE_1("Unit",_unit); + +scopeName "Main"; +private _fnc_errorAndClose = { + params ["_msg"]; + _display closeDisplay 0; + deleteVehicle _logic; + [_msg] call FUNC(showMessage); + breakOut "Main"; +}; + +switch (false) do { + case (["ace_spectator"] call EFUNC(common,isModLoaded)): { + [LSTRING(RequiresAddon)] call _fnc_errorAndClose; + }; + case (!isNull _unit): { + [LSTRING(NothingSelected)] call _fnc_errorAndClose; + }; + case (_unit isKindOf "CAManBase"): { + [LSTRING(OnlyInfantry)] call _fnc_errorAndClose; + }; + case (alive _unit): { + [LSTRING(OnlyAlive)] call _fnc_errorAndClose; + }; + case ([_unit, true] call EFUNC(common,isPlayer)): { + [LSTRING(OnlyPlayers)] call _fnc_errorAndClose; + }; +}; + +// Specific onLoad stuff +private _side = side _unit; + +// Spectate sides +private _fnc_onSideSelection = { + params ["_ctrl"]; + + private _display = ctrlParent _ctrl; + if (isNull _display) exitWith {}; + + private _color = _ctrl getVariable "color"; + private _scale = 1; + + private _sides = _display getVariable [QGVAR(spectateSides), []]; + private _selectedSide = (ctrlIDC _ctrl) - 92540; + + // Add or remove from spectatable sides and update color and scale + if (_selectedSide in _sides) then { + _display setVariable [QGVAR(spectateSides), _sides - [_selectedSide]]; + _color set [3, 0.5]; + } else { + _display setVariable [QGVAR(spectateSides), _sides + [_selectedSide]]; + _color set [3, 1]; + _scale = 1.2; + }; + + _ctrl ctrlSetTextColor _color; + [_ctrl, _scale, 0.1] call BIS_fnc_ctrlSetScale; +}; + +// Use the unit's side as default +private _activeSide = [east, west, independent, civilian] find _side; + +// Handle sides other than default four (sideEnemy) +if (_activeSide != -1) then { + _display setVariable [QGVAR(spectateSides), [_activeSide]]; +}; + +{ + private _ctrl = _display displayCtrl _x; + private _side = _x - 92540; + private _color = [_side] call BIS_fnc_sideColor; + _ctrl setVariable ["color", _color]; + _ctrl ctrlSetActiveColor _color; + _color set [3, 0.5]; + + if (_side == _activeSide) then { + [_ctrl, 1.2, 0] call BIS_fnc_ctrlSetScale; + _color set [3, 1]; + }; + + _ctrl ctrlSetTextColor _color; + + _ctrl ctrlAddEventHandler ["ButtonClick", _fnc_onSideSelection]; +} forEach SIDE_IDCs; + +// Camera modes +private _fnc_onModesSelection = { + params ["_ctrl"]; + + private _display = ctrlParent _ctrl; + if (isNull _display) exitWith {}; + + private _color = [1, 1, 1, 0.5]; + private _scale = 1; + + private _modes = _display getVariable [QGVAR(cameraModes), []]; + private _selectedMode = (ctrlIDC _ctrl) - 92550; + + // Add or remove from camera modes and update color and scale + if (_selectedMode in _modes) then { + _display setVariable [QGVAR(cameraModes), _modes - [_selectedMode]]; + } else { + _display setVariable [QGVAR(cameraModes), _modes + [_selectedMode]]; + _color set [3, 1]; + _scale = 1.2; + }; + + _ctrl ctrlSetTextColor _color; + [_ctrl, _scale, 0.1] call BIS_fnc_ctrlSetScale; +}; + +// Use setting as default since global variable will change +private _availableModes = [[0, 1, 2], [1, 2], [0], [1], [2]] select EGVAR(spectator,restrictModes); +_display setVariable [QGVAR(cameraModes), _availableModes]; + +{ + private _ctrl = _display displayCtrl _x; + private _color = [1, 1, 1, 0.5]; + + if ((_x - 92550) in _availableModes) then { + [_ctrl, 1.2, 0] call BIS_fnc_ctrlSetScale; + _color set [3, 1]; + }; + + _ctrl ctrlSetTextColor _color; + + _ctrl ctrlAddEventHandler ["ButtonClick", _fnc_onModesSelection]; +} forEach CAMERA_IDCs; + +// Vision Modes +private _fnc_onVisionSelection = { + params ["_ctrl", "_state"]; + + private _display = ctrlParent _ctrl; + if (isNull _display) exitwith {}; + + // Convert to boolean since EH returns state as 0 or 1 + private _state = [false, true] select _state; + + private _visions = _display getVariable [QGVAR(visionModes), []]; + private _selectedVision = (ctrlIDC _ctrl) - 92560; + + // Add or remove from vision modes + if (_state) then { + _display setVariable [QGVAR(visionModes), _visions + [_selectedVision]]; + } else { + _display setVariable [QGVAR(visionModes), _visions - [_selectedVision]]; + }; + + // Handle all checked/unchecked + private _allCheckboxes = VISION_IDCs apply {cbChecked (_display displayCtrl _x)}; + + if (_allCheckboxes isEqualTo [_state, _state, _state, _state]) then { + (_display displayCtrl 92557) cbSetChecked _state; + }; +}; + +// Use setting as default since global variable will change +private _availableVisions = [[-2,-1,0,1], [-2,-1], [-2,0,1], [-2]] select EGVAR(spectator,restrictVisions); +_display setVariable [QGVAR(visionModes), _availableVisions]; + +{ + private _ctrl = _display displayCtrl _x; + + if ((_x - 92560) in _availableVisions) then { + _ctrl cbSetChecked true; + }; + + _ctrl ctrlAddEventHandler ["CheckedChanged", _fnc_onVisionSelection]; +} forEach VISION_IDCs; + +// Init all visions checkbox +private _fnc_onVisionsAll = { + params ["_ctrl", "_state"]; + + private _display = ctrlParent _ctrl; + if (isNull _display) exitWith {}; + + // Convert to boolean since EH returns state as 0 or 1 + _state = _state == 1; + + // Set state of all checkboxes + { + (_display displayCtrl _x) cbSetChecked _state; + } forEach VISION_IDCs; + + // Store new visions mode setting + private _setting = [[], [-2, -1, 0, 1]] select _state; + _display setVariable [QGVAR(visionModes), _setting]; +}; + +private _allCheckbox = _display displayCtrl 92557; + +// Set to checked by default if setting is all vision modes +if (_availableVisions isEqualTo [-2, -1, 0, 1]) then { + _allCheckbox cbSetChecked true; +}; + +_allCheckbox ctrlAddEventHandler ["CheckedChanged", _fnc_onVisionsAll]; + +// Confirm and Cancel +private _fnc_onUnload = { + private _logic = missionNamespace getVariable ["BIS_fnc_initCuratorAttributes_target", objNull]; + if (isNull _logic) exitWith {}; + + deleteVehicle _logic; +}; + +private _fnc_onConfirm = { + params [["_ctrlButtonOK", controlNull, [controlNull]]]; + + private _display = ctrlParent _ctrlButtonOK; + if (isNull _display) exitWith {}; + + private _logic = missionNamespace getVariable ["BIS_fnc_initCuratorAttributes_target", objNull]; + if (isNull _logic) exitWith {}; + + private _unit = attachedTo _logic; + if (isNull _unit) exitWith {}; + + private _force = lbCurSel (_display displayCtrl 92531) > 0; + private _hide = lbCurSel (_display displayCtrl 92532) > 0; + private _sides = (_display getVariable [QGVAR(spectateSides), []]) apply {_x call BIS_fnc_sideType}; + private _modes = _display getVariable [QGVAR(cameraModes), []]; + private _visions = _display getVariable [QGVAR(visionModes), []]; + + [QGVAR(moduleSpectator), [_force, _hide, _sides, _modes, _visions], _unit] call CBA_fnc_targetEvent; + + deleteVehicle _logic; +}; + +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_teleportPlayers.sqf b/addons/zeus/functions/fnc_ui_teleportPlayers.sqf index 1becc040048..b7aab411268 100644 --- a/addons/zeus/functions/fnc_ui_teleportPlayers.sqf +++ b/addons/zeus/functions/fnc_ui_teleportPlayers.sqf @@ -23,7 +23,7 @@ private _ctrlButtonOK = _display displayCtrl 1; //IDC_OK private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); TRACE_1("logicObject",_logic); -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; //Specific on-load stuff: private _listbox = _display displayCtrl 16189; @@ -91,5 +91,5 @@ private _fnc_onConfirm = { }; _display displayAddEventHandler ["KeyUp", _fnc_onKeyUp]; -_display displayAddEventHandler ["unload", _fnc_onUnload]; -_ctrlButtonOK ctrlAddEventHandler ["buttonclick", _fnc_onConfirm]; +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/stringtable.xml b/addons/zeus/stringtable.xml index 8b3aaed92ca..e871ef85eff 100644 --- a/addons/zeus/stringtable.xml +++ b/addons/zeus/stringtable.xml @@ -1097,6 +1097,22 @@ 需要一個不存在的插件 현재 없는 애드온을 필요로 합니다 + + Only Players + プレイヤーのみ + Nur Spieler + 오직 플레이어만 + Tylko gracze + Joueurs seulement + Solo Giocatori + 仅玩家 + 只有玩家 + Только игроки + Apenas Jogadores + Pouze hráči + Solo jugadores + Sadece Oyuncular + None Keiner @@ -1322,6 +1338,7 @@ 화물 내리기 Выгрузить из отсека Décharger de la cargaison + Descargar de la carga Toggle NVGs @@ -1483,7 +1500,7 @@ Fill from top to bottom Von oben nach unten befüllen Remplir de haut en bas - 上から下まで占拠 + 上から下へと占拠 Riempi dall'alto al basso 由上而下進行填滿 由上而下进行填满 @@ -1968,6 +1985,7 @@ 의료 메뉴가 비활성화되었습니다 Медицинское меню отключено Le Menu médical est désactivé + El menú médico está deshabilitado Lay Trenchline @@ -1978,6 +1996,7 @@ Piazza Trincea 塹壕溝線を敷設 Проложить траншею + Poner una Trinchera +SHIFT to force (Can only lay N/S or E/W) @@ -1988,6 +2007,42 @@ +SHIFT per forzare (Può piazzare solo N/S o E/O +SHIFTキー で強制的に敷設 (北/南または東/西方向にのみ配置可能) +SHIFT на принудительное (может укладываться только на Север/Юг или Восток/Запад) + +SHIFT para forzar (Puede solo colocar en N/S or E/O) + + + Forces the spectator interface preventing the player from closing it with the Escape key + 観戦インターフェイスを強制し、ユーザーがEscキーでも閉じられないようにします。 + Активирует интерфейс spectator, не позволяя игроку закрыть его с помощью клавиши Escape. + + + Hide player + プレイヤーを隠す + Скрыть игрока + + + Hides the player by making them invisible, invulnerable, muted, and removing them from their group + 透明化、無敵化、ミュート、グループからの除外を行いプレーヤーを隠します + Скрывает игрока, делая его невидимым, неуязвимым, отключая звук и удаляя из группы. + + + Sets the sides that are available to spectate + 指定の陣営を観戦可能に設定します + Устанавливает стороны, доступные для режима spectator + + + White Hot + 白=熱源 + Белый + + + Black Hot + 黒=熱源 + Чёрный + + + Toggle All + 全てを切り替え + Выключить все diff --git a/addons/zeus/ui/RscAttributes.hpp b/addons/zeus/ui/RscAttributes.hpp index 0ff21b145f6..da3f53364fb 100644 --- a/addons/zeus/ui/RscAttributes.hpp +++ b/addons/zeus/ui/RscAttributes.hpp @@ -915,3 +915,231 @@ class GVAR(RscSuicideBomber): RscDisplayAttributes { class ButtonCancel: ButtonCancel {}; }; }; + +class GVAR(RscSpectator): RscDisplayAttributes { + onLoad = QUOTE([ARR_3('onLoad',_this,QQGVAR(RscSpectator))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload',_this,QQGVAR(RscSpectator))] call FUNC(zeusAttributes)); + class Controls: Controls { + class Background: Background {}; + class Title: Title {}; + class Content: Content { + class Controls { + class spectator: RscControlsGroupNoScrollbars { + onSetFocus = QUOTE(_this call FUNC(ui_spectator)); + idc = 92530; + x = 0; + y = 0; + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(10.7)); + class controls { + class ForceInterfaceLabel: RscText { + idc = -1; + text = "$STR_a3_cfgvehicles_modulecurator_f_arguments_forced"; + tooltip = CSTRING(ModuleSpectator_ForceInterface_Tooltip); + x = 0; + y = 0; + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(1)); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class ForceInterface: ctrlToolbox { + idc = 92531; + x = QUOTE(W_PART(10.1)); + y = 0; + w = QUOTE(W_PART(15.9)); + h = QUOTE(H_PART(1)); + rows = 1; + columns = 2; + strings[] = {ECSTRING(common,No), ECSTRING(common,Yes)}; + }; + class HidePlayerLabel: ForceInterfaceLabel { + text = CSTRING(ModuleSpectator_HidePlayer); + tooltip = CSTRING(ModuleSpectator_HidePlayer_Tooltip); + y = QUOTE(H_PART(1.1)); + }; + class HidePlayer: ForceInterface { + idc = 92532; + y = QUOTE(H_PART(1.1)); + }; + class SpectateSides: RscControlsGroupNoScrollbars { + idc = 92533; + x = 0; + y = QUOTE(H_PART(2.2)); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(2.5)); + class controls { + class Label: RscText { + idc = -1; + text = "$STR_A3_Spectator_Eden_WhitelistedSides_Name"; + tooltip = CSTRING(ModuleSpectator_SpectableSides_Tooltip); + x = 0; + y = 0; + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(2.5)); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class Background: RscText { + idc = -1; + x = QUOTE(W_PART(10)); + y = 0; + w = QUOTE(W_PART(16)); + h = QUOTE(H_PART(2.5)); + colorBackground[] = {1, 1, 1, 0.1}; + }; + class BLUFOR: RscActivePicture { + idc = 92541; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_west_ca.paa"; + x = QUOTE(W_PART(12.5)); + y = QUOTE(H_PART(0.25)); + w = QUOTE(W_PART(2)); + h = QUOTE(H_PART(2)); + tooltip = "$STR_WEST"; + }; + class OPFOR: BLUFOR { + idc = 92540; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_east_ca.paa"; + x = QUOTE(W_PART(15.5)); + tooltip = "$STR_EAST"; + }; + class Independent: BLUFOR { + idc = 92542; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_guer_ca.paa"; + x = QUOTE(W_PART(18.5)); + tooltip = "$STR_guerrila"; + }; + class Civilian: BLUFOR { + idc = 92543; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_civ_ca.paa"; + x = QUOTE(W_PART(21.5)); + tooltip = "$STR_Civilian"; + }; + }; + }; + class CameraModes: RscControlsGroupNoScrollbars { + idc = 92534; + x = 0; + y = QUOTE(H_PART(4.8)); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(2.5)); + class controls { + class Label: RscText { + idc = -1; + text = ECSTRING(spectator,modes_DisplayName); + tooltip = ECSTRING(spectator,modes_Description); + x = 0; + y = 0; + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(2.5)); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class Background: RscText { + idc = -1; + x =QUOTE(W_PART(10)); + y = 0; + w = QUOTE(W_PART(16)); + h = QUOTE(H_PART(2.5)); + colorBackground[] = {1, 1, 1, 0.1}; + }; + class Free: RscActivePicture { + idc = 92550; + text = "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\Free.paa"; + x = QUOTE(W_PART(13.375)); + y = QUOTE(H_PART(0.375)); + w = QUOTE(W_PART(1.75)); + h = QUOTE(H_PART(1.75)); + tooltip = "$STR_A3_Spectator_free_camera_tooltip"; + }; + class Follow: Free { + idc = 92552; + text = "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\Follow.paa"; + x = QUOTE(W_PART(17.125)); + tooltip = "$STR_A3_Spectator_3pp_camera_tooltip"; + }; + class FirstPerson: Free { + idc = 92551; + text = "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\Fps.paa"; + x = QUOTE(W_PART(20.875)); + tooltip = "$STR_A3_Spectator_1pp_camera_tooltip"; + }; + }; + }; + class VisionModes: RscControlsGroupNoScrollbars { + idc = 92535; + x = 0; + y = QUOTE(H_PART(7.4)); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(3.3)); + class controls { + class Label: RscText { + idc = -1; + text = ECSTRING(spectator,visions_DisplayName); + tooltip = ECSTRING(spectator,visions_Description); + x = 0; + y = 0; + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(1)); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class Background: RscText { + idc = -1; + x = 0; + y = QUOTE(H_PART(1)); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(2.3)); + colorBackground[] = {1, 1, 1, 0.1}; + }; + class AllCheckBox: RscCheckBox { + idc = 92557; + tooltip = CSTRING(ToggleAll); + x = QUOTE(W_PART(25)); + y = 0; + w = QUOTE(W_PART(1)); + h = QUOTE(H_PART(1)); + }; + class NormalLabel: Label { + text = "$STR_speed_normal"; + tooltip = ""; + x = QUOTE(W_PART(1)); + y = QUOTE(H_PART(1.1)); + w = QUOTE(W_PART(10.8)); + colorBackground[] = {0, 0, 0, 0.6}; + }; + class Normal: AllCheckBox { + idc = 92558; + x = QUOTE(W_PART(11.9)); + y = QUOTE(H_PART(1.1)); + }; + class NightVisionLabel: NormalLabel { + text = "$STR_usract_night_vision"; + y = QUOTE(H_PART(2.2)); + }; + class NightVision: Normal { + idc = 92559; + y = QUOTE(H_PART(2.2)); + }; + class WhiteHotLabel: NormalLabel { + text = CSTRING(ModuleSpectator_WhiteHot); + x = QUOTE(W_PART(13.1)); + }; + class WhiteHot: Normal { + idc = 92560; + x = QUOTE(W_PART(24)); + }; + class BlackHotLabel: WhiteHotLabel { + text = CSTRING(ModuleSpectator_BlackHot); + y = QUOTE(Y_PART(2.2)); + }; + class BlackHot: WhiteHot { + idc = 92561; + y = QUOTE(H_PART(2.2)); + }; + }; + }; + }; + }; + }; + }; + class ButtonOK: ButtonOK {}; + class ButtonCancel: ButtonCancel {}; + }; +}; diff --git a/docs/_config.yml b/docs/_config.yml index 66cd1141f7b..ee7822969d6 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -9,8 +9,8 @@ ace: version: major: 3 minor: 17 - patch: 0 - build: 82 + patch: 1 + build: 86 markdown: kramdown diff --git a/docs/_config_dev.yml b/docs/_config_dev.yml index e3c042e9c70..348e1aee441 100644 --- a/docs/_config_dev.yml +++ b/docs/_config_dev.yml @@ -9,8 +9,8 @@ ace: version: major: 3 minor: 17 - patch: 0 - build: 82 + patch: 1 + build: 86 markdown: kramdown diff --git a/docs/wiki/development/coding-guidelines.md b/docs/wiki/development/coding-guidelines.md index 786a5d74e89..fe9f0bfdf09 100644 --- a/docs/wiki/development/coding-guidelines.md +++ b/docs/wiki/development/coding-guidelines.md @@ -381,11 +381,19 @@ However the following is allowed: _value = (_array select 0) select 1; ``` -Any conditions in statements shall always be wrapped around brackets. +Any conditions in statements shall always be wrapped around brackets. Both uses of the `!` operator below are allowed. ```sqf -if (!_value) then {}; if (_value) then {}; +if (!_value) then {}; +if !(_value) then {}; +``` + +Use of the `!` operator on the lefthand-side of brackets can be more readable, particularly for more complex conditions or macros: + +```sqf +if !(_value && _otherValue && {_thirdValue call _something}) then {}; +if !(GETEGVAR(addon,globalVariableName,defaultValue)) then {}; ``` ### 5.6 Magic Numbers @@ -632,81 +640,6 @@ player addEventHandler ["Fired", FUNC(handleFired)]; // bad player addEventHandler ["Fired", {call FUNC(handleFired)}]; // good ``` -### 7.4 Hashes - -When a key value pair is required, make use of the hash implementation from ACE3. - -Hashes are a variable type that store key value pairs. They are not implemented natively in SQF, so there are a number of macros and functions for their usage in ACE3. If you are unfamiliar with the idea, they are similar in function to `setVariable`/`getVariable` but do not require an object to use. - -The following example is a simple usage using our macros which will be explained further below. - -```sqf -_hash = HASHCREATE; -HASH_SET(_hash,"key","value"); -if (HASH_HASKEY(_hash,"key")) then { - player sideChat format ["val: %1", HASH_GET(_hash,"key"); // will print out "val: value" -}; -HASH_REM(_hash,"key"); -if (HASH_HASKEY(_hash,"key")) then { - // this will never execute because we removed the hash key/val pair "key" -}; -``` - -A description of the above macros is below. - -| Macro | Use | -| ------|-------| -|`HASHCREATE` | Used to create an empty hash. | -|`HASH_SET(hash,key,val)` | Will set the hash key to that value, a key can be anything, even objects. | -|`HASH_GET(hash,key)` | Will return the value of that key (or nil if it doesn't exist). | -|`HASH_HASKEY(hash,key)` | Will return true/false if that key exists in the hash. | -|`HASH_REM(hash,key)` | Will remove that hash key. | - -#### 7.4.1 Hashlists - -A hashlist is an extension of a hash. It is a list of hashes! The reason for having this special type of storage container rather than using a normal array is that an array of normal hashes that are similar will duplicate a large amount of data in their storage of keys. A hashlist on the other hand uses a common list of keys and an array of unique value containers. The following will demonstrate its usage. - -```sqf -_defaultKeys = ["key1", "key2", "key3"]; -// create a new hashlist using the above keys as default -_hashList = HASHLIST_CREATELIST(_defaultKeys); - -//lets get a blank hash template out of this hashlist -_hash = HASHLIST_CREATEHASH(_hashList); - -//_hash is now a standard hash... -HASH_SET(_hash,"key1","1"); - -//to store it to the list we need to push it to the list -HASHLIST_PUSH(_hashList, _hash); - -//now lets get it out and store it in something else for fun -//it was pushed to an empty list, so it's index is 0 -_anotherHash = HASHLIST_SELECT(_hashList,0); - -// this should print "val: 1" -player sideChat format["val: %1", HASH_GET(_anotherHash,"key1")]; - -//Say we need to add a new key to the hashlist -//that we didn't initialize it with? We can simply -//set a new key using the standard HASH_SET macro -HASH_SET(_anotherHash,"anotherKey","another value"); -``` - -As you can see above working with hashlists are fairly simple, a more in depth explanation of the macros is below. - -| Macro | Use | -| -------|---------| -|`HASHLIST_CREATELIST(keys)` | Creates a new hashlist with the default keys, pass [] for no default keys. | -|`HASHLIST_CREATEHASH(hashlist)` | Returns a blank hash template from a hashlist. | -|`HASHLIST_PUSH(hashList, hash)` | Pushes a new hash onto the end of the list. | -|`HASHLIST_SELECT(hashlist, index)` | Returns the hash at that index in the list. | -|`HASHLIST_SET(hashlist, index, hash)` | Sets a specific index to that hash. | - -##### 7.4.1.1 A note on pass by reference and hashes - -Hashes and hashlists are implemented with SQF arrays, and as such they are passed by reference to other functions. Remember to make copies (using the `+` operator) if you intend for the hash or hashlist to be modified with out the need for changing the original value. - ## 8. Performance Considerations ### 8.1 Adding Elements to Arrays diff --git a/docs/wiki/feature/grenades.md b/docs/wiki/feature/grenades.md index 679b309b1ec..2b60c08d4ec 100644 --- a/docs/wiki/feature/grenades.md +++ b/docs/wiki/feature/grenades.md @@ -23,6 +23,8 @@ version: ### 1.1 Throw modes Provides different modes for throwing grenades (high throw, precision throw and drop mode). +A grenade is only rollable if the fuse time (`explosionTime`) is >= 1 second and the player isn't in a vehicle. + ### 1.2 Hand flares Adds throwable hand flares in the colors white, red, green and yellow. Additionally buffs existing flares by making them brighter and last longer. diff --git a/docs/wiki/feature/hitreactions.md b/docs/wiki/feature/hitreactions.md index 7d12c1cb12d..a84d1c0b78b 100644 --- a/docs/wiki/feature/hitreactions.md +++ b/docs/wiki/feature/hitreactions.md @@ -18,3 +18,6 @@ version: ### 1.1 Falling under fire If a unit is shot while running it falls to the ground in a prone position, the area where the shot lands does not matters. Note that the shot needs to inflict a certain amount of damage to make the unit fall, a small cut won't make the unit stumble. + +### 1.2 Weapon dropping +If a unit's arm is shot it will cause the gun to be dropped based on the chance set. The default is 0. diff --git a/docs/wiki/framework/cargo-framework.md b/docs/wiki/framework/cargo-framework.md index 68b28f7fa70..a1d810ce9c4 100644 --- a/docs/wiki/framework/cargo-framework.md +++ b/docs/wiki/framework/cargo-framework.md @@ -47,6 +47,24 @@ class CfgVehicles {

ace_cargo_hasCargo and ace_cargo_canLoad are only needed if you aren't inheriting from any of BI base classes or if you are trying to disable loading for a specific vehicle / object.

+### 1.3 Adding predefined cargo via config + +```cpp +class CfgVehicles { + class yourVehicleClass { + ace_cargo_space = 4; // Add if necessary + ace_cargo_hasCargo = 1; // Add if necessary + class ace_cargo { + class cargo { + class ACE_medicalSupplyCrate { // Doesn't have to have the same name as the item you're adding + type = "ACE_medicalSupplyCrate"; + amount = 1; + }; + }; + }; + }; +}; +``` ## 2. Events diff --git a/docs/wiki/framework/cookoff-framework.md b/docs/wiki/framework/cookoff-framework.md index b53fea2049c..81296991540 100644 --- a/docs/wiki/framework/cookoff-framework.md +++ b/docs/wiki/framework/cookoff-framework.md @@ -12,43 +12,22 @@ version: patch: 0 --- -## 1. Disabling / Enabling Cook off for individual vehicles +## 1. Disabling cook-off fire for individual vehicles -You can dynamically enable and/or disable vehicle cook off for individual vehicles by using `setVariable`: +Cook-off fire can be disabled for a specific vehicle (does not affect ammo cook-off): ``` -VEHICLE setVariable ["ace_cookoff_enable", true, true]; +_vehicle setVariable ["ace_cookoff_enable", false, true]; ``` -The above will enable cook off for that specific vehicle, no matter the mission settings. +Mission settings will always apply however, so you can't enable cook-off on a vehicle if the mission settings have cook-off for vehicles disabled. -Likewise, cook off can also be disabled for a specific vehicle: +## 2. Disabling ammunition cook-off for individual vehicles and boxes -``` -VEHICLE setVariable ["ace_cookoff_enable", false, true]; -``` - -## 2. Cook off probability - -You can set the probability of cook off for individual vehicle types by changing the `ace_cookoff_probability` value in the vehicle's config: +Ammunition cook-off can be disabled for a specific vehicle or box (does not affect cook-off fire): ``` -class MyVehicle { - ace_cookoff_probability = 0.6; -}; +_vehicleOrBox setVariable ["ace_cookoff_enableAmmoCookoff", false, true]; ``` -Global cook off probability can also be adjusted with the `ace_cookoff_probabilityCoef` mission setting. - -Higher values will make cook-off more probable, whilst lower values will make cook-off less probable. - -## 3. Ignore damage to turret - -For use on vehicles when damage to the main turret would not cause a vehicle cookoff. -e.g. RCWS turrets - -``` -class MyVehicle { - ace_vehicle_damage_turretFireProb = 0; -}; -``` +Mission settings will always apply however, so you can't enable ammunition cook-off on a vehicle or box if the mission settings have ammunition cook-off disabled. diff --git a/docs/wiki/framework/events-framework.md b/docs/wiki/framework/events-framework.md index bec6492c968..860cd900684 100644 --- a/docs/wiki/framework/events-framework.md +++ b/docs/wiki/framework/events-framework.md @@ -103,18 +103,17 @@ MenuType: 0 = Interaction, 1 = Self Interaction | Event Key | Parameters | Locality | Type | Description | |----------|---------|---------|---------|---------| -|`ace_refuel_started` | [_source, _target] | Local | Listen | Refueling has started | +|`ace_refuel_started` | [_source, _target] | Local | Listen | Refuelling has started | |`ace_refuel_tick` | [_source, _target, _amount] | Local | Listen | Amount of fuel transferred in a tick | -|`ace_refuel_stopped` | [_source, _target] | Local | Listen | Refueling has stopped | +|`ace_refuel_stopped` | [_source, _target] | Local | Listen | Refuelling has stopped | ### 2.10 Cook Off (`ace_cookoff`) | Event Key | Parameters | Locality | Type | Description | -|----------|---------|---------|---------|---------| -|`ace_cookoff_cookOff` | _vehicle | Global | Listen | Vehicle cook off has started -|`ace_cookoff_cookOffBox` | _box | Global | Listen | Ammo box cook off has started | -|`ace_cookoff_engineFire` | _vehicle | Global | Listen | Engine fire has started | - +|----------|---------|---------|---------|---------|---------| +|`ace_cookoff_cookOff` | [_vehicle, _intensity, _instigator, _smokeDelayEnabled, _ammoDetonationChance, _detonateAfterCookoff, _fireSource, _canRing, _maxIntensity, _canJet] | Global | Listen | Vehicle cook-off has started | +|`ace_cookoff_cookOffBox` | [_box, _source, _instigator, _delay] | Global | Listen | Ammo box cook-off has started | +|`ace_cookoff_engineFire` | [_vehicle] | Global | Listen | Engine fire has started | ### 2.11 Attach (`ace_attach`) @@ -156,9 +155,15 @@ MenuType: 0 = Interaction, 1 = Self Interaction | Event Key | Parameters | Locality | Type | Description | |---------- |------------|----------|------|-------------| -|---------- |------------|----------|------|-------------| | `ace_interaction_doorOpeningStarted` | [_house, _door, _animations] | Local | Listen | Called when local unit starts interacting with doors -| `ace_interaction_doorOpeningStopped` | [_house, _door, _animations] | Local | Listen | Called when local unit stopps interacting with doors +| `ace_interaction_doorOpeningStopped` | [_house, _door, _animations] | Local | Listen | Called when local unit stops interacting with doors + +### 2.17 Headless (`ace_headless`) + +| Event Key | Parameters | Locality | Type | Description | +|---------- |------------|----------|------|-------------| +| `ace_headless_groupTransferPre` | [_group, _HC (OBJECT), _previousOwner, _idHC] | Target | Listen | Called just before a group is transferred from any machine to a HC. Called where group currently is local and on the HC, where group is going to be local. +| `ace_headless_groupTransferPost` | [_group, _HC (OBJECT), _previousOwner, _idHC, _transferredSuccessfully] | Target | Listen | Called just after a group is transferred from a machine to a HC. Called where group was local and on the HC, where group is now local. `_transferredSuccessfully` is passed so mods can actually check if the locality was properly transferred, as ownership transfer is not guaranteed. ## 3. Usage Also Reference [CBA Events System](https://github.com/CBATeam/CBA_A3/wiki/Custom-Events-System){:target="_blank"} documentation. diff --git a/docs/wiki/framework/grenades-framework.md b/docs/wiki/framework/grenades-framework.md index fce3b480c2d..755773c1710 100644 --- a/docs/wiki/framework/grenades-framework.md +++ b/docs/wiki/framework/grenades-framework.md @@ -50,6 +50,10 @@ class CfgAmmo { ace_grenades_flashbangBangs = 6; // 6 bangs ace_grenades_flashbangInterval = 0.25; // 0.25 seconds between each subsequent bang ace_grenades_flashbangIntervalMaxDeviation = 0.05; // Deviation of up to ± 0.05 seconds on each fuse + ace_grenades_flashbangExplodeSound[] = { // Sound that is played upon detonation + {"A3\Sounds_F\arsenal\explosives\grenades\Explosion_HE_grenade_01.wss", 5, 1.2, 400}, // file path, volume, pitch, max distance + {"A3\Sounds_F\arsenal\explosives\grenades\Explosion_HE_grenade_02.wss", 5, 1.2, 400} + }; }; }; ``` @@ -70,6 +74,11 @@ The average amount of time in seconds, after `explosionTime` has passed, between The amount of randomness in the fuse time. +### 2.1.5 ace_grenades_flashbangExplodeSound + +The sounds that can be used when the flashbang detonates. It randomly selects an entry from this array (equal chances, there are no weights involved). +If not defined, `[format ["A3\Sounds_F\arsenal\explosives\grenades\Explosion_HE_grenade_0%1.wss", floor (random 4) + 1], 5, 1.2, 400]` is used as a default instead (4 sounds total). + ### 2.2 Incendiary Config Values ```cpp @@ -103,6 +112,12 @@ If set to zero or left undefined, the grenade is not treated as a flare. If it i Sets the color of the emitted light. The first 3 values of the array of the color, the last is the light intensity. +### 2.4 Grenade Rolling + +#### 2.4.1 ace_grenades_rollVectorDirAndUp + +Sets the `setVectorDirAndUp` of the grenade when the grenade is rolled. + ## 3. Events ### 3.1 Listenable diff --git a/docs/wiki/framework/headless-framework.md b/docs/wiki/framework/headless-framework.md index 6dbc83c5123..7a2a5a08221 100644 --- a/docs/wiki/framework/headless-framework.md +++ b/docs/wiki/framework/headless-framework.md @@ -30,14 +30,29 @@ As of ACEX v3.2.0 _(before merge into ACE3)_ this feature can also be enabled wi ## 2. Scripting -### 2.1 Disable Transferring for a Group +### 2.1 Manipulating HC Transfers of Groups via function -To prevent a group from transferring to a Headless Client use the following line on a group leader (or every unit in a group in case group leader may not spawn): +`ace_headless_fnc_blacklist` + + | Arguments | Type | Optional (default value) +---| --------- | ---- | ------------------------ +0 | Units | Object, Group or Array of both | Required +1 | Add (true) or remove (false) from blacklist | Bool | Optional (default: `true`) +2 | Owner to transfer units to | Number | Optional (default: `-1`) +3 | Rebalance (0 = no rebalance, 1 = rebalance, 2 = force rebalance) | Number | (default: `0`) +**R** | None | None | Return value + +`Force rebalance` means that all units, including the ones that are on the HCs, are rebalanced amongst the HCs, whereas `rebalance` means that newly spawned units are going to be evenly distributed amongst HCs. Therefore, `rebalance` does not guarantee that the HCs will have an equal amount of groups, whereas `force rebalance` does. + +### 2.2 Disable Transferring for a Group via variable + +To prevent a group from transferring to a Headless Client use the following line on a unit within a group: ```sqf this setVariable ["acex_headless_blacklist", true]; ``` +This variable can also be set on vehicles, disabling transferal of any groups having units in said vehicles. ## 3. Limitations @@ -48,3 +63,7 @@ Some Arma 3 features are incompatible, this is up to BI to add support. Disable Additionally, groups will not be transferred due to lack of support if they: - Have waypoints with synchronized triggers (waypoint would not change status based on trigger condition) (added in ACEX v3.2.0 - _before merge into ACE3_) + +Groups will not be transferred to avoid issues: +- If a player is within the group. +- If they contain UAVs. diff --git a/docs/wiki/framework/hitreactions-framework.md b/docs/wiki/framework/hitreactions-framework.md new file mode 100644 index 00000000000..ca3ff93f5bf --- /dev/null +++ b/docs/wiki/framework/hitreactions-framework.md @@ -0,0 +1,32 @@ +--- +layout: wiki +title: Hit Reactions Framework +description: Explains how to set-up weapons with ACE3 hit reactions system. +group: framework +order: 5 +parent: wiki +mod: ace +version: + major: 3 + minor: 18 + patch: 0 +--- + +## 1. Config Values + +```cpp +class CfgWeapons { + class MyWeapon { + ace_hitreactions_undroppable = 1; // Prevents weapon from being dropped + }; +}; +``` + +## 2. Mission Variables + +### 2.1 Safe pickup distance for AI + +Allows 3rd party mods to set the distance between AI and the nearest hostile that is considered safe to go pickup a dropped weapon. +```sqf +ace_hitreactions_safePickupDistance = 10; // default is 8 +``` diff --git a/docs/wiki/framework/medical-treatment-framework.md b/docs/wiki/framework/medical-treatment-framework.md index 736295804ae..52e661a516d 100644 --- a/docs/wiki/framework/medical-treatment-framework.md +++ b/docs/wiki/framework/medical-treatment-framework.md @@ -128,3 +128,10 @@ If a mission maker wishes to disable Zeus access to the medical menu, they can s ```sqf ace_medical_gui_enableZeusModule = false; // default is true ``` + +### 3.3 SpO2 Configuration + +If 3rd party mods want to disable SpO2 being set to a minimum upon successful CPR, they can set the variable below: +```sqf +ace_medical_treatment_setSpO2UponCPRSuccess = false; // default is true +``` diff --git a/docs/wiki/framework/nametags-framework.md b/docs/wiki/framework/nametags-framework.md new file mode 100644 index 00000000000..d27a358b170 --- /dev/null +++ b/docs/wiki/framework/nametags-framework.md @@ -0,0 +1,45 @@ +--- +layout: wiki +title: Nametags Framework +description: Explains how to implement rank icons for factions. +group: framework +order: 5 +parent: wiki +mod: ace +version: + major: 3 + minor: 13 + patch: 0 +--- + +## 1. Config Values + +### 1.1 Faction rank icons + +Defines the rank icons used by a faction. + +```cpp +class CfgFactionClasses { + class MyFaction { + ace_nametags_rankIcons[] = { + "\z\ace\addons\nametags\UI\icons_germany\private_gs.paa", // path to private rank icon + "\z\ace\addons\nametags\UI\icons_germany\corporal_gs.paa", // path to corporal rank icon + "\z\ace\addons\nametags\UI\icons_germany\sergeant_gs.paa", // path to sergeant rank icon + "\z\ace\addons\nametags\UI\icons_germany\lieutenant_gs.paa", // path to lieutenant rank icon + "\z\ace\addons\nametags\UI\icons_germany\captain_gs.paa", // path to captain rank icon + "\z\ace\addons\nametags\UI\icons_germany\major_gs.paa", // path to major rank icon + "\z\ace\addons\nametags\UI\icons_germany\colonel_gs.paa" // path to colonel rank icon + }; + }; +}; +``` + +## 2. Mission Variables + +### 2.1 Faction rank icon usage + +If disabled, it won't use the faction icons defined via the config entry listed above. +Needs to be set before postInit. +```sqf +ace_nametags_useFactionIcons = false; // by default true +``` diff --git a/docs/wiki/framework/refuel-framework.md b/docs/wiki/framework/refuel-framework.md index 325606a9707..3cf10d72053 100644 --- a/docs/wiki/framework/refuel-framework.md +++ b/docs/wiki/framework/refuel-framework.md @@ -134,5 +134,5 @@ The jerry can will now have a volume of 200 liters. | Name | Arguments | Global? | Added in | | ------------- | ------------- | ----- | ------------- | -| ace_refuel_sourceInitialized | Fuel source (OBJECT), items (BOOL or ARRAY) | Yes | 3.16.0 | +| ace_refuel_sourceInitialized | Fuel source (OBJECT) | Yes | 3.16.0 | | ace_refuel_jerryCanInitalized | Jerry can (OBJECT) | Yes | 3.16.0 | diff --git a/docs/wiki/framework/vehicledamage-framework.md b/docs/wiki/framework/vehicledamage-framework.md index 7e22bccf5db..0d4268bf5e8 100644 --- a/docs/wiki/framework/vehicledamage-framework.md +++ b/docs/wiki/framework/vehicledamage-framework.md @@ -47,7 +47,7 @@ Default: 0.5 #### 1.1.5 `ace_vehicle_damage_turretFireProb` -The probabilitiy for the vehicle to catch on fire upon its turret being penetrated +The probability for the vehicle to catch on fire upon its turret being penetrated Default: 0.2 @@ -126,3 +126,11 @@ Default ARMA config value. We assume that the warheads are vanilla strings, so o - `TandemHEAT` If no `ace_vehicle_damage_incendiary` defined, this value will be used to assume a default based on above table of common values (excluding `Incendiary Bullet` which is 0). + +## 3. Disabling crew bailing for individual vehicles + +Crew bailing when their vehicle is disabled (immobile or can't shoot) can be disabled for a specific vehicle: + +``` +_vehicle setVariable ["ace_vehicle_damage_allowCrewInImmobile", true, true]; +``` From a6cfcbf6979d0ea21dbf595a95a7fd1c22eebd53 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 16 Jul 2024 21:07:50 -0500 Subject: [PATCH 267/282] Removed event handlers --- addons/frag/CfgAmmo.hpp | 18 +---------- addons/frag/CfgAmmoBaseEH.hpp | 46 +++++++-------------------- addons/frag/CfgAmmoFragParameters.hpp | 25 +-------------- addons/frag/CfgAmmoFragSpawner.hpp | 2 +- addons/frag/CfgAmmoSpall.hpp | 2 +- 5 files changed, 15 insertions(+), 78 deletions(-) diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index d3d800cccba..d10e93ba856 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -1,22 +1,6 @@ #define BASE_DRAG -0.01 #define HD_MULT 5 #define BASE_DRAG_HD (BASE_DRAG * HD_MULT) -#define ACE_FRAG_INIT_CODE _this call FUNC(initRound) -#define ACE_FRAG_RM_EH class EventHandlers: EventHandlers {\ - class ADDON {\ - delete init;\ - };\ -} -#define ACE_FRAG_ADD_EH_BASE class EventHandlers {\ - class ADDON {\ - init = QUOTE(ACE_FRAG_INIT_CODE);\ - };\ -} -#define ACE_FRAG_ADD_EH class EventHandlers: EventHandlers {\ - class ADDON {\ - init = QUOTE(ACE_FRAG_INIT_CODE);\ - };\ -} class CfgAmmo { @@ -31,7 +15,7 @@ class CfgAmmo { typicalSpeed = 800; maxSpeed = 1500; deflecting = 65; - ACE_FRAG_RM_EH; + GVAR(skip) = 1; }; class GVAR(tiny): GVAR(base) { diff --git a/addons/frag/CfgAmmoBaseEH.hpp b/addons/frag/CfgAmmoBaseEH.hpp index c28855d92b3..a2992049f0f 100644 --- a/addons/frag/CfgAmmoBaseEH.hpp +++ b/addons/frag/CfgAmmoBaseEH.hpp @@ -1,38 +1,25 @@ // We need this since autocannons generally inherit from BulletBase class BulletCore; -class BulletBase: BulletCore { - ACE_FRAG_ADD_EH_BASE; -}; +class BulletBase: BulletCore; class GrenadeCore; -class GrenadeBase: GrenadeCore { - ACE_FRAG_ADD_EH_BASE; -}; +class GrenadeBase: GrenadeCore; class LaserBombCore; -class ammo_Bomb_LaserGuidedBase: LaserBombCore { - ACE_FRAG_ADD_EH_BASE; -}; +class ammo_Bomb_LaserGuidedBase: LaserBombCore; class MissileCore; -class MissileBase: MissileCore { - ACE_FRAG_ADD_EH_BASE; -}; +class MissileBase: MissileCore; class RocketCore; class RocketBase: RocketCore { - ACE_FRAG_ADD_EH_BASE; GVAR(skip) = 1; }; -class ArtilleryRocketCore: RocketCore { - ACE_FRAG_ADD_EH_BASE; -}; +class ArtilleryRocketCore: RocketCore; class ShellCore; -class ShellBase: ShellCore { - ACE_FRAG_ADD_EH_BASE; -}; +class ShellBase: ShellCore; class ShotDeployCore; class ShotDeployBase: ShotDeployCore { @@ -40,32 +27,21 @@ class ShotDeployBase: ShotDeployCore { }; class ShotgunCore; -class ShotgunBase: ShotgunCore { - ACE_FRAG_ADD_EH_BASE; -}; +class ShotgunBase: ShotgunCore; class SubmunitionCore; class SubmunitionBase: SubmunitionCore { - ACE_FRAG_ADD_EH_BASE; GVAR(skip) = 1; }; class BoundingMineCore; -class BoundingMineBase: BoundingMineCore { - ACE_FRAG_ADD_EH_BASE; -}; +class BoundingMineBase: BoundingMineCore; class PipeBombCore; -class PipeBombBase: PipeBombCore { - ACE_FRAG_ADD_EH_BASE; -}; +class PipeBombBase: PipeBombCore; class DirectionalBombCore; -class DirectionalBombBase: DirectionalBombCore { - ACE_FRAG_ADD_EH_BASE; -}; +class DirectionalBombBase: DirectionalBombCore; class MineCore; -class MineBase: MineCore { - ACE_FRAG_ADD_EH_BASE; -}; +class MineBase: MineCore; diff --git a/addons/frag/CfgAmmoFragParameters.hpp b/addons/frag/CfgAmmoFragParameters.hpp index 7425a7d9aa0..28d572bf040 100644 --- a/addons/frag/CfgAmmoFragParameters.hpp +++ b/addons/frag/CfgAmmoFragParameters.hpp @@ -111,7 +111,6 @@ class B_40mm_GPR: B_30mm_HE { GVAR(gurney_k) = "1/2"; }; class UnderwaterMine_Range_Ammo: MineBase { - ACE_FRAG_RM_EH; GVAR(skip) = 1; }; @@ -158,7 +157,6 @@ class ammo_Bomb_SmallDiameterBase: ammo_Bomb_LaserGuidedBase { class BombCore; class Bo_Mk82: BombCore { - ACE_FRAG_ADD_EH_BASE; GVAR(classes)[] = {QGVAR(large), QGVAR(large), QGVAR(large_HD), QGVAR(large), QGVAR(huge), QGVAR(huge_HD), QGVAR(huge)}; GVAR(fragCount) = 17500; GVAR(metal) = 140000; @@ -198,7 +196,6 @@ class Mo_cluster_Bomb_03_F: Mo_cluster_Bomb_01_F { // idk, @lambda.tiger on the // ~~~~ Grenades: class Grenade; class GrenadeHand: Grenade { - ACE_FRAG_ADD_EH_BASE; GVAR(skip) = 0; GVAR(force) = 1; /* @@ -219,11 +216,9 @@ class mini_Grenade: GrenadeHand { GVAR(charge) = 36; }; class GrenadeHand_stone: GrenadeHand { - ACE_FRAG_RM_EH; GVAR(skip) = 1; }; class SmokeShell: GrenadeHand { - ACE_FRAG_RM_EH; GVAR(skip) = 1; }; class G_40mm_HE: GrenadeBase { @@ -264,7 +259,6 @@ class ACE_G_40mm_HE: G_40mm_HE { class EventHandlers: EventHandlers {}; }; class ACE_G_40mm_Practice: ACE_G_40mm_HE { - ACE_FRAG_RM_EH; GVAR(skip) = 1; GVAR(force) = 0; EGVAR(vehicle_damage,incendiary) = 0; @@ -272,7 +266,6 @@ class ACE_G_40mm_Practice: ACE_G_40mm_HE { // ~~~~ Mines & UXO class ATMine_Range_Ammo: MineBase { - ACE_FRAG_RM_EH; GVAR(skip) = 1; }; @@ -304,7 +297,6 @@ class TrainingMine_Ammo: APERSMine_Range_Ammo { }; class SLAMDirectionalMine_Wire_Ammo: DirectionalBombBase { - ACE_FRAG_RM_EH; GVAR(skip) = 1; }; @@ -377,26 +369,20 @@ class UXO2_Ammo_Base_F: UXO1_Ammo_Base_F { }; class APERSMineDispenser_Mine_Ammo: APERSMine_Range_Ammo { - ACE_FRAG_RM_EH; GVAR(skip) = 1; }; -class UXO_deploy_base_f: SubmunitionBase { - ACE_FRAG_RM_EH; -}; +class UXO_deploy_base_f: SubmunitionBase; class ClaymoreDirectionalMine_Remote_Ammo: DirectionalBombBase { - ACE_FRAG_RM_EH; GVAR(skip) = 1; }; class SatchelCharge_Remote_Ammo: PipeBombBase { - ACE_FRAG_RM_EH; GVAR(skip) = 1; }; class DemoCharge_Remote_Ammo: PipeBombBase { - ACE_FRAG_RM_EH; GVAR(skip) = 1; }; @@ -409,7 +395,6 @@ class BombDemine_01_Ammo_F: BombCore { }; class BombDemine_01_SubAmmo_F: ShellBase { - ACE_FRAG_RM_EH; GVAR(skip) = 1; }; @@ -426,11 +411,9 @@ class R_PG7_F: RocketBase { }; class R_PG32V_F: RocketBase { - ACE_FRAG_RM_EH; GVAR(skip) = 1; }; class R_TBG32V_F: R_PG32V_F { // Thermobaric - ACE_FRAG_ADD_EH; GVAR(skip) = 0; GVAR(fragCount) = 200; GVAR(metal) = 400; @@ -635,7 +618,6 @@ class ammo_missile_cruise_01: ammo_Missile_CruiseBase { GVAR(gurney_k) = "3/5"; }; class ammo_Missile_Cruise_01_Cluster: ammo_missile_cruise_01 { - ACE_FRAG_RM_EH; }; class ammo_Missile_AntiRadiationBase: MissileBase { @@ -777,7 +759,6 @@ class M_127mm_Firefist_AT: RocketBase { // HOT missile }; class M_NLAW_AT_F: MissileBase { - ACE_FRAG_RM_EH; GVAR(skip) = 1; }; @@ -873,7 +854,6 @@ class ammo_Penetrator_Base: ShellBase { // ~~~~ Special class ProbingBeam_01_F: BulletBase { - ACE_FRAG_RM_EH; GVAR(skip) = 1; }; @@ -894,16 +874,13 @@ class FuelExplosion: Default { }; class HelicopterExploSmall: ShellBase { - ACE_FRAG_RM_EH; GVAR(skip) = 1; }; class LightningBolt: ShellBase { - ACE_FRAG_RM_EH; GVAR(skip) = 1; }; class M_Mo_82mm_AT: MissileBase { - ACE_FRAG_RM_EH; GVAR(skip) = 1; }; diff --git a/addons/frag/CfgAmmoFragSpawner.hpp b/addons/frag/CfgAmmoFragSpawner.hpp index 6d5a4c86513..b1bd0726e1d 100644 --- a/addons/frag/CfgAmmoFragSpawner.hpp +++ b/addons/frag/CfgAmmoFragSpawner.hpp @@ -37,7 +37,7 @@ class GVAR(DOUBLES(TRIPLES(random,size,count),top)): GVAR(spawnbase) {\ } class GVAR(spawnbase): B_65x39_Caseless { - ACE_FRAG_RM_EH; + GVAR(skip) = 1; deleteParentWhenTriggered = 1; explosionEffects = ""; submunitionConeType[] = {"random", 25}; diff --git a/addons/frag/CfgAmmoSpall.hpp b/addons/frag/CfgAmmoSpall.hpp index ee9a253e0d9..60780e564ed 100644 --- a/addons/frag/CfgAmmoSpall.hpp +++ b/addons/frag/CfgAmmoSpall.hpp @@ -1,5 +1,5 @@ class GVAR(spallBase): B_65x39_Caseless { - ACE_FRAG_RM_EH; + GVAR(skip) = 1; submunitionAmmo[] = {QGVAR(small),4,QGVAR(medium),3,QGVAR(large),2,QGVAR(huge),1}; submunitionConeType[] = {"random", 20}; submunitionConeAngle = 40; From cf1860d162dadb30480ba2b6515ee13f684c3d62 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 16 Jul 2024 21:08:18 -0500 Subject: [PATCH 268/282] Changed blacklist to acting on local projectiles to match initial performance --- addons/frag/functions/fnc_addBlacklist.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_addBlacklist.sqf b/addons/frag/functions/fnc_addBlacklist.sqf index ca331a248a5..aecdbf832d2 100644 --- a/addons/frag/functions/fnc_addBlacklist.sqf +++ b/addons/frag/functions/fnc_addBlacklist.sqf @@ -18,4 +18,4 @@ params ["_projectile"]; TRACE_2("addBlackList",_projectile,typeOf projectile); -_projectile setVariable [QGVAR(blacklisted), true, 2]; +_projectile setVariable [QGVAR(blacklisted)]; From 9df2e5b1816040b1056e7c4a4f0cd2ac49c46187 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 16 Jul 2024 21:30:17 -0500 Subject: [PATCH 269/282] added fired EH and moved projectile tracking to be local to projectile --- addons/frag/XEH_postInit.sqf | 18 +++-- addons/frag/XEH_preInit.sqf | 10 ++- addons/frag/functions/fnc_dev_fired.sqf | 23 ------- .../{fnc_doSpall.sqf => fnc_doSpallLocal.sqf} | 49 +++++++------- addons/frag/functions/fnc_doSpallServer.sqf | 45 +++++++++++++ addons/frag/functions/fnc_fired.sqf | 65 +++++++++++++++++++ 6 files changed, 150 insertions(+), 60 deletions(-) delete mode 100644 addons/frag/functions/fnc_dev_fired.sqf rename addons/frag/functions/{fnc_doSpall.sqf => fnc_doSpallLocal.sqf} (68%) create mode 100644 addons/frag/functions/fnc_doSpallServer.sqf create mode 100644 addons/frag/functions/fnc_fired.sqf diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index 1da47231540..1b512b201fb 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -1,20 +1,18 @@ #include "script_component.hpp" -#ifdef DEBUG_MODE_DRAW [ "CBA_settingsInitialized", { + ["ace_firedPlayer", LINKFUNC(fired)] call CBA_fnc_addEventHandler; + ["ace_firedNonPlayer", LINKFUNC(fired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler; + ["ace_firedNonPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler; +#ifdef DEBUG_MODE_DRAW [QGVAR(dev_clearTraces), LINKFUNC(dev_clearTraces)] call CBA_fnc_addEventHandler; if (!hasInterface) exitWith {}; - if (!isServer) then { - ["ace_firedPlayer", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerNonLocal", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; - ["ace_firedNonPlayer", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerVehicle", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerVehicleNonLocal", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; - ["ace_firedNonPlayerVehicle", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; - }; + ["ace_firedPlayerVehicleNonLocal", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; + ["ace_firedNonPlayerVehicle", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; GVAR(dev_drawPFEH) = [LINKFUNC(dev_drawTrace), 0] call CBA_fnc_addPerFrameHandler; [ "ace_interact_menu_newControllableObject", @@ -39,9 +37,9 @@ ] call EFUNC(interact_menu,addActionToClass); } ] call CBA_fnc_addEventHandler; +#endif } ] call CBA_fnc_addEventHandler; -#endif #ifdef LOG_FRAG_INFO [true, true, 30] call FUNC(dev_debugAmmo); diff --git a/addons/frag/XEH_preInit.sqf b/addons/frag/XEH_preInit.sqf index 68d608c87ff..9e85fabe2a8 100644 --- a/addons/frag/XEH_preInit.sqf +++ b/addons/frag/XEH_preInit.sqf @@ -28,7 +28,15 @@ GVAR(dev_drawPFEH) = -1; #endif if (isServer) then { - [QEGVAR(common,setShotParents), {(_this#0) setVariable [QGVAR(shotParent), [_this#1, _this#2]]}] call CBA_fnc_addEventHandler; + [ + QGVAR(explosionEvent), + { + params ["_posASL", "_velocity", "_ammo", "_shotParents"]; + [_posASL, _velocity, _ammo, _shotParents] call FUNC(doFrag); + } + ] call CBA_fnc_addEventHandler; + + [QGVAR(spallEvent), LINKFUNC(doSpallServer)] call CBA_fnc_addEventHandler; }; ADDON = true; diff --git a/addons/frag/functions/fnc_dev_fired.sqf b/addons/frag/functions/fnc_dev_fired.sqf deleted file mode 100644 index 9dbd039f460..00000000000 --- a/addons/frag/functions/fnc_dev_fired.sqf +++ /dev/null @@ -1,23 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: Lambda.Tiger - * Add fired rounds to dev track. - * - * Arguments: - * Parameters inherited from EFUNC(common,firedEH) - * - * Return Value: - * Nothing Useful - * - * Example: - * [clientFiredBIS-XEH] call ace_frag_fnc_fired - * - * Public: No - */ - -//IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); - -if (GVAR(debugOptions) && {_ammo call FUNC(shouldFrag) || {_ammo call FUNC(shouldSpall)}}) then { - [_projectile, true, [side group _unit, side group ACE_player] call BIS_fnc_sideIsFriendly] call FUNC(dev_addRound); -}; diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpallLocal.sqf similarity index 68% rename from addons/frag/functions/fnc_doSpall.sqf rename to addons/frag/functions/fnc_doSpallLocal.sqf index a516648f0b1..39f85360f30 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpallLocal.sqf @@ -1,17 +1,28 @@ #include "..\script_component.hpp" /* - * Author: Jaynus, NouberNou, Lambda.Tiger, - * This function creates spalling if the hit slowed the projectile speed down enough. + * Author: Jaynus, NouberNou, Lambda.Tiger + * This function runs on every client and determines if a spall event happened. + * It is intended to be called a frame after the projectile has triggered a hit event, + * where information such as the object hit, the projectiles velocity and position on impact + * should be kept and passed to this function.If a spall event should happen, this function + * calculates the spalling parameters and then calls a server event to create the desired spall effect. * * Arguments: - * Arguments are the same as BI's "HitPart" EH: - * https://community.bistudio.com/wiki/Arma_3:_Event_Handlers#HitPart + * 0: The projectile that may be creating spall + * 1: The object the projectile hit + * 2: The 3D position (ASL) of the projectile when it hit the object + * 3: The velocity of the projectile when it hit the object + * 4: The normal of the surface of the object hit + * 5: The class name of the surface, or the bisurf path of the surface hit + * 6: The class name of the projectile that may be spalling + * 7: The spalling projectile's shot parents + * 8: The "up" vector of the projectile when it hit the object * * Return Value: * None * * Example: - * [BIS_HITPART_EH_ARGS] call ace_frag_fnc_doSpall + * [_projectile, _hitObject, _lastPosASLProjectile, _lastVelocityProjectile, _surfaceNorm, "a3\data_f\penetration\armour_plate.bisurf", "Sh_125mm_APFSDS", [0, 0, 1]] call ace_frag_fnc_doSpallLocal * * Public: No */ @@ -112,26 +123,12 @@ private _spawnSize = switch (true) do default {"_spall_huge"}; }; -private _spallSpawner = createVehicle [ - QUOTE(GLUE(ADDON,_)) + _material + _spawnSize, - ASLToATL _spallPosASL, - [], - 0, - "CAN_COLLIDE" -]; -_spallSpawner setVectorDirandUp [_lastVelocityNorm, _vectorUp]; -_spallSpawner setVelocityModelSpace [0, _speedChange * ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF, 0]; -_spallSpawner setShotParents _shotParents; - #ifdef DEBUG_MODE_FULL -systemChat ("spd: " + str speed _spallSpawner + ", spawner: " + _fragSpawnType + ", spallPow: " + str _spallPower); -#endif -#ifdef DEBUG_MODE_DRAW -_spallSpawner addEventHandler [ - "SubmunitionCreated", - { - params ["", "_submunitionProjectile"]; - _submunitionProjectile call FUNC(dev_addRound); - } -]; +systemChat ("spd: " + str (_speedChange * ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF) + ", spallPow: " + str _spallPower); #endif + +TRACE_5("Calling event:",QUOTE(GLUE(ADDON,_)) + _material + _spawnSize,_lastVelocityNorm,_vectorUp,_speedChange,_shotParents); +[ + FUNC(doSpallServer), + [QUOTE(GLUE(ADDON,_)) + _material + _spawnSize, _lastVelocityNorm, _vectorUp, _speedChange, _shotParents] +] call CBA_fnc_serverEvent; diff --git a/addons/frag/functions/fnc_doSpallServer.sqf b/addons/frag/functions/fnc_doSpallServer.sqf new file mode 100644 index 00000000000..bf4c43ce721 --- /dev/null +++ b/addons/frag/functions/fnc_doSpallServer.sqf @@ -0,0 +1,45 @@ +#include "..\script_component.hpp" +/* + * Author: Jaynus, NouberNou, Lambda.Tiger, + * This function creates the requested spalling submunition spawner at a speed and direction. + * The function is intended to create the spalling on a server via an event call by + * ace_frag_fnc_doSpallLocal. The "local" version determines whether an event has occured + * and triggers this event if it has. + * + * Arguments: + * 0: Class name of the spall spawner + * 1: Normalized 3D vector direction of the spall spawner + * 2: "Up" vector for the projectile, required for the spawner to aim out of the 2D plane + * 3: The change in velocity that spalling projectile experienced + * 4: Shot parents array for the projectile that creates spall + * + * Return Value: + * None + * + * Example: + * [QGVAR(rock_spall_tiny), [1,0,0], [0,0,1], 300, [objNull, ace_player]] call ace_frag_fnc_doSpallServer + * + * Public: No + */ +params ["_spallSpawnerName", "_lastVelocityNorm", "_vectorUp", "_speedChange", "_shotParents"]; + +private _spallSpawner = createVehicle [ + _spallSpawnerName, + ASLToATL _spallPosASL, + [], + 0, + "CAN_COLLIDE" +]; +_spallSpawner setVectorDirandUp [_lastVelocityNorm, _vectorUp]; +_spallSpawner setVelocityModelSpace [0, _speedChange * ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF, 0]; +_spallSpawner setShotParents _shotParents; + +#ifdef DEBUG_MODE_DRAW +_spallSpawner addEventHandler [ + "SubmunitionCreated", + { + params ["", "_submunitionProjectile"]; + _submunitionProjectile call FUNC(dev_addRound); + } +]; +#endif diff --git a/addons/frag/functions/fnc_fired.sqf b/addons/frag/functions/fnc_fired.sqf new file mode 100644 index 00000000000..d94ca518cc6 --- /dev/null +++ b/addons/frag/functions/fnc_fired.sqf @@ -0,0 +1,65 @@ +#include "..\script_component.hpp" +/* + * Author: Lambda.Tiger + * Add eventhandlers to rounds as needed + * + * Arguments: + * Parameters inherited from EFUNC(common,firedEH) + * + * Return Value: + * Nothing Useful + * + * Example: + * [clientFiredBIS-XEH] call ace_frag_fnc_fired + * + * Public: No + */ + +//IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); + +if (_ammo isEqualTo "" || {isNull _projectile} || + {_projectile getVariable [QGVAR(blacklisted), false]}) exitWith { + TRACE_2("bad ammo or projectile, or blackList",_ammo,_projectile); +}; + + +#ifdef DEBUG_MODE_DRAW +if (GVAR(debugOptions) && {true in (_ammo call FUNC(shouldFrag)) || {_ammo call FUNC(shouldSpall)}}) then { + [_projectile, "red", true] call FUNC(dev_trackObj); +}; +#endif + +if (GVAR(spallEnabled) && {_ammo call FUNC(shouldSpall)}) then { + _projectile addEventHandler [ + "HitPart", + { + params ["_projectile", "_hitObject", "", "_posASL", "_velocity", "_surfNorm", "", "", "_surfType"]; + + if (_projectile getVariable [QGVAR(blacklisted), false]) exitWith { + TRACE_2("projectile blackisted",typeOf _projectile,_projectile); + }; + + // starting v2.18 it may be faster to use the instigator parameter, the same as the second entry shotParents, to recreate _shotParent + // The "explode" EH does not get the same parameter + private _shotParent = getShotParents _projectile; + private _ammo = typeOf _projectile; + private _vectorUp = vectorUp _projectile; + /* + * Wait a frame to see what happens to the round, may result in + * multiple hits / slowdowns getting shunted to the first hit + */ + [ + FUNC(doSpallLocal), + [_projectile, _hitObject, _posASL, _velocity, _surfNorm, _surfType, _ammo, _shotParent, _vectorUp] + ] call CBA_fnc_execNextFrame; + } + ]; +}; +if !(GVAR(reflectionsEnabled) || GVAR(enabled)) exitWith { + TRACE_1("initExit No frag/reflections",_ammo); +}; + +[_projectile, _ammo] call FUNC(roundInitFrag); + +TRACE_1("initExit",_ammo); From f65fcbf44fd9b95665efde1d05d3c72899013a61 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 16 Jul 2024 21:45:41 -0500 Subject: [PATCH 270/282] updated initialization and should frag to check for submunitions since we no longer rely on init EH --- addons/frag/XEH_PREP.hpp | 6 +-- addons/frag/functions/fnc_roundInitFrag.sqf | 54 +++++++++++++++++++++ addons/frag/functions/fnc_shouldFrag.sqf | 32 +++++++++--- 3 files changed, 83 insertions(+), 9 deletions(-) create mode 100644 addons/frag/functions/fnc_roundInitFrag.sqf diff --git a/addons/frag/XEH_PREP.hpp b/addons/frag/XEH_PREP.hpp index 868931fa6fe..4378b6a5b00 100644 --- a/addons/frag/XEH_PREP.hpp +++ b/addons/frag/XEH_PREP.hpp @@ -3,7 +3,6 @@ PREP(dev_addRound); PREP(dev_clearTraces); PREP(dev_debugAmmo); PREP(dev_drawTrace); -PREP(dev_fired); PREP(dev_fragCalcDump); PREP(dev_trackHitBox); PREP(dev_trackObj); @@ -13,12 +12,13 @@ PREP(doFrag); PREP(doFragRandom); PREP(doFragTargeted); PREP(doReflections); -PREP(doSpall); +PREP(doSpallLocal); +PREP(doSpallServer); PREP(findReflections); +PREP(fired); PREP(getMaterialInfo); PREP(getSpallInfo); PREP(getFragInfo); PREP(initMaterialCache); -PREP(initRound); PREP(shouldFrag); PREP(shouldSpall); diff --git a/addons/frag/functions/fnc_roundInitFrag.sqf b/addons/frag/functions/fnc_roundInitFrag.sqf new file mode 100644 index 00000000000..d95c43b0b89 --- /dev/null +++ b/addons/frag/functions/fnc_roundInitFrag.sqf @@ -0,0 +1,54 @@ +#include "..\script_component.hpp" +/* + * Author: Lambda.Tiger + * Adds fragmentation event handlers to projectiles as needed. + * + * Arguments: + * 0: class name of projectile being initialized + * 1: Projectile being initialized + * + * Return Value: + * Nothing + * + * Example: + * [clientFiredBIS-XEH] call ace_frag_fnc_fired + * + * Public: No + */ +params ["_ammo", "_projectile"]; + +_ammo call FUNC(shouldFrag) params ["_shouldFrag", "_submunitionShouldFrag"]; +if (_shouldFrag) then { + _projectile addEventHandler [ + "Explode", + { + params ["_projectile", "_posASL", "_velocity"]; + + if (GVAR(reflectionsEnabled)) then { + [_posASL, _ammo] call FUNC(doReflections); + }; + + if (_projectile getVariable [QGVAR(blacklisted), false]) exitWith { + TRACE_2("projectile blackisted",typeOf _projectile,_projectile); + }; + + private _shotParents = getShotParents _projectile; + private _ammo = typeOf _projectile; + // Call server event for fragment generation + [ + QGVAR(explosionEvent), + [_posASL, _velocity, _ammo, _shotParents] + ] call CBA_fnc_serverEvent; + } + ]; +}; + +if (_submunitionShouldFrag) then { + _projectile addEventHandler [ + "SubmunitionCreated", + { + params ["", "_submunitionProjectile"]; + [typeOf _submunitionProjectile, _submunitionProjectile] call FUNC(roundInitFrag); + } + ]; +}; diff --git a/addons/frag/functions/fnc_shouldFrag.sqf b/addons/frag/functions/fnc_shouldFrag.sqf index 8edcd5e1a97..902cc4efc2e 100644 --- a/addons/frag/functions/fnc_shouldFrag.sqf +++ b/addons/frag/functions/fnc_shouldFrag.sqf @@ -7,7 +7,9 @@ * 0: Ammo classname * * Return Value: - * Should the specific round fragment + * An array containing + * 0: Should the ammo class generate fragments + * 1: Should the ammo class create submunitions that may fragment * * Example: * "B_556x45_Ball" call ace_frag_fnc_shouldFrag @@ -21,31 +23,49 @@ private _shouldFrag = GVAR(shouldFragCache) get _ammo; if (!isNil "_shouldFrag") exitWith {_shouldFrag}; -_shouldFrag = true; +_shouldFrag = [true, false]; private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; private _skip = getNumber (_ammoConfig >> QGVAR(skip)); if (_skip == 1) then { - _shouldFrag = false; + _shouldFrag set [0, false]; TRACE_1("No frag: skip",_skip); }; private _force = getNumber (_ammoConfig >> QGVAR(force)); -if (_shouldFrag && _force == 0) then { +if (_shouldFrag#0 && _force == 0) then { private _explosive = getNumber (_ammoConfig >> "explosive"); if (_explosive < 0.4) exitWith { - _shouldFrag = false; + _shouldFrag set [0, false]; TRACE_3("No frag: _explosive",_skip,_force,_explosive); }; private _indirectHit = getNumber (_ammoConfig >> "indirectHit"); private _indirectRange = getNumber (_ammoConfig >> "indirectHitRange"); if (_indirectHit < 3 || {_indirectRange < 5 && _indirectHit < _indirectRange}) then { - _shouldFrag = false; + _shouldFrag set [0, false]; TRACE_5("No frag",_ammo,_skip,_explosive,_indirectRange,_indirectHit); }; }; +private _ammoSubmunitionConfigPath = _ammoConfig >> "submunitionAmmo "; +if (isText _ammoSubmunitionConfigPath) then { + private _submunitionAmmo = getText _ammoSubmunitionConfigPath; + if (_submunitionAmmo isNotEqualTo "") then { + private _shouldSubmunitionFrag = _submunitionAmmo call FUNC(shouldFrag); + _shouldFrag set [1, _shouldSubmunitionFrag#0 || _shouldSubmunitionFrag#1]; + }; +} else { + private _submunitionArray = getArray _ammoSubmunitionConfigPath; + for "_i" from 0 to count _submunitionArray - 1 step 2 do { + private _submunitionAmmo = _submunitionArray#_i; + if (_submunitionAmmo isNotEqualTo "") then { + private _shouldSubmunitionFrag = _submunitionAmmo call FUNC(shouldFrag); + _shouldFrag set [1, _shouldSubmunitionFrag#0 || _shouldSubmunitionFrag#1]; + }; + }; +}; + GVAR(shouldFragCache) set [_ammo, _shouldFrag]; _shouldFrag From cd4d2a9cf6ce6af0da26ea8743e23fdea9b84476 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 16 Jul 2024 22:03:15 -0500 Subject: [PATCH 271/282] Fixed calls for shouldFrag and got rid of old initRound.sfq (maybe back after 2.18) --- addons/frag/functions/fnc_dev_debugAmmo.sqf | 2 +- .../frag/functions/fnc_dev_fragCalcDump.sqf | 2 +- addons/frag/functions/fnc_initRound.sqf | 84 ------------------- 3 files changed, 2 insertions(+), 86 deletions(-) delete mode 100644 addons/frag/functions/fnc_initRound.sqf diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index 7fc6b203881..fae388f1b8c 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -75,7 +75,7 @@ private _printCount = 0; _processedCfgAmmos pushBack _ammo; private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; - private _shouldFrag = _ammo call FUNC(shouldFrag); + _ammo call FUNC(shouldFrag) params ["_shouldFrag"]; if (_shouldFrag || _logAll) then { diff --git a/addons/frag/functions/fnc_dev_fragCalcDump.sqf b/addons/frag/functions/fnc_dev_fragCalcDump.sqf index c72d096f781..3812273b3cf 100644 --- a/addons/frag/functions/fnc_dev_fragCalcDump.sqf +++ b/addons/frag/functions/fnc_dev_fragCalcDump.sqf @@ -31,7 +31,7 @@ diag_log text "//****************** fragCalcDump Beg ******************//"; continue; }; - private _shouldFrag = _ammo call FUNC(shouldFrag); + _ammo call FUNC(shouldFrag) params ["_shouldFrag"]; if (_shouldFrag || _logAll) then { private _fragInfo = _ammo call FUNC(getFragInfo); _fragInfo params ["_fragRange", "_fragMaxVelocity", "", "_modifiedFragCount"]; diff --git a/addons/frag/functions/fnc_initRound.sqf b/addons/frag/functions/fnc_initRound.sqf deleted file mode 100644 index eef4488df46..00000000000 --- a/addons/frag/functions/fnc_initRound.sqf +++ /dev/null @@ -1,84 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: Lambda.Tiger - * This function adds projectile explode and hitPart event handlers and is - * intended to be called from an projectile config init event handler. - * - * Arguments: - * 0: The projectile to be initialized - * - * Return Value: - * None - * - * Example: - * _projectile call ace_frag_fnc_initRound - * - * Public: No - */ - -TRACE_1("ACE_Frag rndInit",_this); -if (!isServer) exitWith {}; -params ["_projectile"]; - -private _ammo = typeOf _projectile; -if (_ammo isEqualTo "" || {isNull _projectile} || - {_projectile getVariable [QGVAR(blacklisted), false]}) exitWith { - TRACE_2("bad ammo or projectile, or blackList",_ammo,_projectile); -}; - -if (GVAR(enabled) && {_ammo call FUNC(shouldFrag)}) then { - _projectile addEventHandler [ - "Explode", - { - params ["_projectile", "_posASL", "_velocity"]; - - if (_projectile getVariable [QGVAR(blacklisted), false]) exitWith { - TRACE_2("projectile blackisted",typeOf _projectile,_projectile); - }; - - private _shotParents = _projectile getVariable [QGVAR(shotParent), getShotParents _projectile]; - private _ammo = typeOf _projectile; - // wait for frag damage to kill units before spawning fragments - [ - FUNC(doFrag), - [_posASL, _velocity, _ammo, _shotParents] - ] call CBA_fnc_execNextFrame; - if (GVAR(reflectionsEnabled)) then { - [_posASL, _ammo] call FUNC(doReflections); - }; - } - ]; -}; - -if (GVAR(spallEnabled) && {_ammo call FUNC(shouldSpall)}) then { - _projectile addEventHandler [ - "HitPart", - { - params ["_projectile", "_hitObject", "", "_posASL", "_velocity", "_surfNorm", "", "", "_surfType"]; - - if (_projectile getVariable [QGVAR(blacklisted), false]) exitWith { - TRACE_2("projectile blackisted",typeOf _projectile,_projectile); - }; - - // starting v2.18 it may be faster to use the instigator parameter, the same as the second entry shotParents, to recreate _shotParent - // The "explode" EH does not get the same parameter - private _shotParent = getShotParents _projectile; - private _ammo = typeOf _projectile; - private _vectorUp = vectorUp _projectile; - /* - * Wait a frame to see what happens to the round, may result in - * multiple hits / slowdowns getting shunted to the first hit - */ - [ - FUNC(doSpall), - [_projectile, _hitObject, _posASL, _velocity, _surfNorm, _surfType, _ammo, _shotParent, _vectorUp] - ] call CBA_fnc_execNextFrame; - } - ]; -}; -#ifdef DEBUG_MODE_DRAW -if (GVAR(debugOptions) && {_ammo call FUNC(shouldFrag) || {_ammo call FUNC(shouldSpall)}}) then { - [_projectile, "red", true] call FUNC(dev_trackObj); -}; -#endif -TRACE_1("initExit",_ammo); From 04e844fecf017f35da737522fbf0b1287d746602 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 16 Jul 2024 22:40:13 -0500 Subject: [PATCH 272/282] fixed small mistakes in names and function calls --- addons/frag/XEH_PREP.hpp | 1 + addons/frag/XEH_postInit.sqf | 2 +- addons/frag/functions/fnc_doSpallLocal.sqf | 2 +- addons/frag/functions/fnc_fired.sqf | 6 +++--- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/addons/frag/XEH_PREP.hpp b/addons/frag/XEH_PREP.hpp index 4378b6a5b00..7af205aa8e7 100644 --- a/addons/frag/XEH_PREP.hpp +++ b/addons/frag/XEH_PREP.hpp @@ -20,5 +20,6 @@ PREP(getMaterialInfo); PREP(getSpallInfo); PREP(getFragInfo); PREP(initMaterialCache); +PREP(roundInitFrag); PREP(shouldFrag); PREP(shouldSpall); diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index 1b512b201fb..47affc99718 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -12,7 +12,7 @@ if (!hasInterface) exitWith {}; ["ace_firedPlayerVehicleNonLocal", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; - ["ace_firedNonPlayerVehicle", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerNonLocal", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; GVAR(dev_drawPFEH) = [LINKFUNC(dev_drawTrace), 0] call CBA_fnc_addPerFrameHandler; [ "ace_interact_menu_newControllableObject", diff --git a/addons/frag/functions/fnc_doSpallLocal.sqf b/addons/frag/functions/fnc_doSpallLocal.sqf index 39f85360f30..6e0fd81ca3b 100644 --- a/addons/frag/functions/fnc_doSpallLocal.sqf +++ b/addons/frag/functions/fnc_doSpallLocal.sqf @@ -129,6 +129,6 @@ systemChat ("spd: " + str (_speedChange * ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF) TRACE_5("Calling event:",QUOTE(GLUE(ADDON,_)) + _material + _spawnSize,_lastVelocityNorm,_vectorUp,_speedChange,_shotParents); [ - FUNC(doSpallServer), + QGVAR(spallEvent), [QUOTE(GLUE(ADDON,_)) + _material + _spawnSize, _lastVelocityNorm, _vectorUp, _speedChange, _shotParents] ] call CBA_fnc_serverEvent; diff --git a/addons/frag/functions/fnc_fired.sqf b/addons/frag/functions/fnc_fired.sqf index d94ca518cc6..2c5b61d349e 100644 --- a/addons/frag/functions/fnc_fired.sqf +++ b/addons/frag/functions/fnc_fired.sqf @@ -57,9 +57,9 @@ if (GVAR(spallEnabled) && {_ammo call FUNC(shouldSpall)}) then { ]; }; if !(GVAR(reflectionsEnabled) || GVAR(enabled)) exitWith { - TRACE_1("initExit No frag/reflections",_ammo); + TRACE_1("firedExit No frag/reflections",_ammo); }; -[_projectile, _ammo] call FUNC(roundInitFrag); +[_ammo, _projectile] call FUNC(roundInitFrag); -TRACE_1("initExit",_ammo); +TRACE_1("firedExit",_ammo); From 1ae4fc792d69ec3ca909d896d9712ef17dc860ac Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 16 Jul 2024 22:53:20 -0500 Subject: [PATCH 273/282] fixed frame offset to avoid hitting dead targets --- addons/frag/functions/fnc_roundInitFrag.sqf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/frag/functions/fnc_roundInitFrag.sqf b/addons/frag/functions/fnc_roundInitFrag.sqf index d95c43b0b89..15c4ac63552 100644 --- a/addons/frag/functions/fnc_roundInitFrag.sqf +++ b/addons/frag/functions/fnc_roundInitFrag.sqf @@ -34,11 +34,11 @@ if (_shouldFrag) then { private _shotParents = getShotParents _projectile; private _ammo = typeOf _projectile; - // Call server event for fragment generation + // Wait a frame to make sure it doesn't [ - QGVAR(explosionEvent), + { [QGVAR(explosionEvent), _this] call CBA_fnc_serverEvent; }, [_posASL, _velocity, _ammo, _shotParents] - ] call CBA_fnc_serverEvent; + ] call CBA_fnc_execNextFrame; } ]; }; From 32af820e77ad017ff15d0558729486adc604a496 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 16 Jul 2024 23:21:43 -0500 Subject: [PATCH 274/282] Fixed config path in shouldFrag --- addons/frag/functions/fnc_shouldFrag.sqf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/frag/functions/fnc_shouldFrag.sqf b/addons/frag/functions/fnc_shouldFrag.sqf index 902cc4efc2e..04e1d489752 100644 --- a/addons/frag/functions/fnc_shouldFrag.sqf +++ b/addons/frag/functions/fnc_shouldFrag.sqf @@ -48,15 +48,17 @@ if (_shouldFrag#0 && _force == 0) then { }; }; -private _ammoSubmunitionConfigPath = _ammoConfig >> "submunitionAmmo "; +private _ammoSubmunitionConfigPath = _ammoConfig >> "submunitionAmmo"; if (isText _ammoSubmunitionConfigPath) then { private _submunitionAmmo = getText _ammoSubmunitionConfigPath; + TRACE_1("Submunition ammo text: ",_submunitionAmmo); if (_submunitionAmmo isNotEqualTo "") then { private _shouldSubmunitionFrag = _submunitionAmmo call FUNC(shouldFrag); _shouldFrag set [1, _shouldSubmunitionFrag#0 || _shouldSubmunitionFrag#1]; }; } else { private _submunitionArray = getArray _ammoSubmunitionConfigPath; + TRACE_1("Submunition ammo array: ",_submunitionArray); for "_i" from 0 to count _submunitionArray - 1 step 2 do { private _submunitionAmmo = _submunitionArray#_i; if (_submunitionAmmo isNotEqualTo "") then { From 0269039deea2e6fcd0da10dd60f03c22db181961 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 16 Jul 2024 23:28:37 -0500 Subject: [PATCH 275/282] Didn't know that PBO project needed trailing {} on class inheritance structures --- addons/frag/CfgAmmoBaseEH.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/frag/CfgAmmoBaseEH.hpp b/addons/frag/CfgAmmoBaseEH.hpp index a2992049f0f..81a1794cbc3 100644 --- a/addons/frag/CfgAmmoBaseEH.hpp +++ b/addons/frag/CfgAmmoBaseEH.hpp @@ -1,15 +1,15 @@ // We need this since autocannons generally inherit from BulletBase class BulletCore; -class BulletBase: BulletCore; +class BulletBase: BulletCore {}; class GrenadeCore; -class GrenadeBase: GrenadeCore; +class GrenadeBase: GrenadeCore {}; class LaserBombCore; -class ammo_Bomb_LaserGuidedBase: LaserBombCore; +class ammo_Bomb_LaserGuidedBase: LaserBombCore {}; class MissileCore; -class MissileBase: MissileCore; +class MissileBase: MissileCore {}; class RocketCore; class RocketBase: RocketCore { From 15de0d9a3af170eee6d791c637c124dc97a88906 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Tue, 16 Jul 2024 23:42:44 -0500 Subject: [PATCH 276/282] fixed more useless trailing {} --- addons/frag/CfgAmmoBaseEH.hpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/addons/frag/CfgAmmoBaseEH.hpp b/addons/frag/CfgAmmoBaseEH.hpp index 81a1794cbc3..413dfe3dd93 100644 --- a/addons/frag/CfgAmmoBaseEH.hpp +++ b/addons/frag/CfgAmmoBaseEH.hpp @@ -16,10 +16,10 @@ class RocketBase: RocketCore { GVAR(skip) = 1; }; -class ArtilleryRocketCore: RocketCore; +class ArtilleryRocketCore: RocketCore {}; class ShellCore; -class ShellBase: ShellCore; +class ShellBase: ShellCore {}; class ShotDeployCore; class ShotDeployBase: ShotDeployCore { @@ -27,7 +27,7 @@ class ShotDeployBase: ShotDeployCore { }; class ShotgunCore; -class ShotgunBase: ShotgunCore; +class ShotgunBase: ShotgunCore {}; class SubmunitionCore; class SubmunitionBase: SubmunitionCore { @@ -35,13 +35,13 @@ class SubmunitionBase: SubmunitionCore { }; class BoundingMineCore; -class BoundingMineBase: BoundingMineCore; +class BoundingMineBase: BoundingMineCore {}; class PipeBombCore; -class PipeBombBase: PipeBombCore; +class PipeBombBase: PipeBombCore {}; class DirectionalBombCore; -class DirectionalBombBase: DirectionalBombCore; +class DirectionalBombBase: DirectionalBombCore {}; class MineCore; -class MineBase: MineCore; +class MineBase: MineCore {}; From 225bdd340823e9189a7fcdd8bd56fc1874f652ec Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jul 2024 00:00:48 -0500 Subject: [PATCH 277/282] Actual PBO project error fixed --- addons/frag/CfgAmmoBaseEH.hpp | 36 ++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/addons/frag/CfgAmmoBaseEH.hpp b/addons/frag/CfgAmmoBaseEH.hpp index 413dfe3dd93..2ede0bdbb06 100644 --- a/addons/frag/CfgAmmoBaseEH.hpp +++ b/addons/frag/CfgAmmoBaseEH.hpp @@ -1,22 +1,32 @@ // We need this since autocannons generally inherit from BulletBase class BulletCore; -class BulletBase: BulletCore {}; +class BulletBase: BulletCore { + class EventHandlers; +}; class GrenadeCore; -class GrenadeBase: GrenadeCore {}; +class GrenadeBase: GrenadeCore { + class EventHandlers; +}; class LaserBombCore; -class ammo_Bomb_LaserGuidedBase: LaserBombCore {}; +class ammo_Bomb_LaserGuidedBase: LaserBombCore { + class EventHandlers; +}; class MissileCore; -class MissileBase: MissileCore {}; +class MissileBase: MissileCore { + class EventHandlers; +}; class RocketCore; class RocketBase: RocketCore { GVAR(skip) = 1; }; -class ArtilleryRocketCore: RocketCore {}; +class ArtilleryRocketCore: RocketCore { + class EventHandlers; +}; class ShellCore; class ShellBase: ShellCore {}; @@ -35,13 +45,21 @@ class SubmunitionBase: SubmunitionCore { }; class BoundingMineCore; -class BoundingMineBase: BoundingMineCore {}; +class BoundingMineBase: BoundingMineCore { + class EventHandlers; +}; class PipeBombCore; -class PipeBombBase: PipeBombCore {}; +class PipeBombBase: PipeBombCore { + class EventHandlers; +}; class DirectionalBombCore; -class DirectionalBombBase: DirectionalBombCore {}; +class DirectionalBombBase: DirectionalBombCore { + class EventHandlers; +}; class MineCore; -class MineBase: MineCore {}; +class MineBase: MineCore { + class EventHandlers; +}; From f928d3755596d5d0b114c6b3b2516edcb4581293 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jul 2024 01:30:20 -0500 Subject: [PATCH 278/282] Update addons/frag/CfgAmmoFragParameters.hpp Co-authored-by: PabstMirror --- addons/frag/CfgAmmoFragParameters.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/CfgAmmoFragParameters.hpp b/addons/frag/CfgAmmoFragParameters.hpp index 28d572bf040..5ee37ba1815 100644 --- a/addons/frag/CfgAmmoFragParameters.hpp +++ b/addons/frag/CfgAmmoFragParameters.hpp @@ -372,7 +372,7 @@ class APERSMineDispenser_Mine_Ammo: APERSMine_Range_Ammo { GVAR(skip) = 1; }; -class UXO_deploy_base_f: SubmunitionBase; +class UXO_deploy_base_f: SubmunitionBase {}; class ClaymoreDirectionalMine_Remote_Ammo: DirectionalBombBase { GVAR(skip) = 1; From f69aef7cd06bcf70cd99d8c905f6ec0e19c4dfb9 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jul 2024 02:15:27 -0500 Subject: [PATCH 279/282] Maybe the last fix, let's look in the morning --- addons/frag/CfgAmmoFragParameters.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/frag/CfgAmmoFragParameters.hpp b/addons/frag/CfgAmmoFragParameters.hpp index 28d572bf040..5ee37ba1815 100644 --- a/addons/frag/CfgAmmoFragParameters.hpp +++ b/addons/frag/CfgAmmoFragParameters.hpp @@ -372,7 +372,7 @@ class APERSMineDispenser_Mine_Ammo: APERSMine_Range_Ammo { GVAR(skip) = 1; }; -class UXO_deploy_base_f: SubmunitionBase; +class UXO_deploy_base_f: SubmunitionBase {}; class ClaymoreDirectionalMine_Remote_Ammo: DirectionalBombBase { GVAR(skip) = 1; From 2dc9ab416fc9f001d100236c1b3ea44a34dfcbb0 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Wed, 17 Jul 2024 22:14:50 -0500 Subject: [PATCH 280/282] removed spare class EventHandler definitions that are now unsused and I believe everything should be fine wrt pboProject now. --- addons/frag/CfgAmmo.hpp | 4 +-- addons/frag/CfgAmmoBaseEH.hpp | 36 +++++++-------------------- addons/frag/CfgAmmoFragParameters.hpp | 19 +++----------- 3 files changed, 14 insertions(+), 45 deletions(-) diff --git a/addons/frag/CfgAmmo.hpp b/addons/frag/CfgAmmo.hpp index d10e93ba856..07bc5fc1cb0 100644 --- a/addons/frag/CfgAmmo.hpp +++ b/addons/frag/CfgAmmo.hpp @@ -6,9 +6,7 @@ class CfgAmmo { #include "CfgAmmoBaseEH.hpp" - class B_65x39_Caseless: BulletBase { - class EventHandlers: EventHandlers {}; - }; + class B_65x39_Caseless: BulletBase {}; class GVAR(base): B_65x39_Caseless { ACE_damageType = "grenade"; // compatibility with medical_damage, shrapnel should produce grenade wounds timeToLive = 4; diff --git a/addons/frag/CfgAmmoBaseEH.hpp b/addons/frag/CfgAmmoBaseEH.hpp index 2ede0bdbb06..413dfe3dd93 100644 --- a/addons/frag/CfgAmmoBaseEH.hpp +++ b/addons/frag/CfgAmmoBaseEH.hpp @@ -1,32 +1,22 @@ // We need this since autocannons generally inherit from BulletBase class BulletCore; -class BulletBase: BulletCore { - class EventHandlers; -}; +class BulletBase: BulletCore {}; class GrenadeCore; -class GrenadeBase: GrenadeCore { - class EventHandlers; -}; +class GrenadeBase: GrenadeCore {}; class LaserBombCore; -class ammo_Bomb_LaserGuidedBase: LaserBombCore { - class EventHandlers; -}; +class ammo_Bomb_LaserGuidedBase: LaserBombCore {}; class MissileCore; -class MissileBase: MissileCore { - class EventHandlers; -}; +class MissileBase: MissileCore {}; class RocketCore; class RocketBase: RocketCore { GVAR(skip) = 1; }; -class ArtilleryRocketCore: RocketCore { - class EventHandlers; -}; +class ArtilleryRocketCore: RocketCore {}; class ShellCore; class ShellBase: ShellCore {}; @@ -45,21 +35,13 @@ class SubmunitionBase: SubmunitionCore { }; class BoundingMineCore; -class BoundingMineBase: BoundingMineCore { - class EventHandlers; -}; +class BoundingMineBase: BoundingMineCore {}; class PipeBombCore; -class PipeBombBase: PipeBombCore { - class EventHandlers; -}; +class PipeBombBase: PipeBombCore {}; class DirectionalBombCore; -class DirectionalBombBase: DirectionalBombCore { - class EventHandlers; -}; +class DirectionalBombBase: DirectionalBombCore {}; class MineCore; -class MineBase: MineCore { - class EventHandlers; -}; +class MineBase: MineCore {}; diff --git a/addons/frag/CfgAmmoFragParameters.hpp b/addons/frag/CfgAmmoFragParameters.hpp index 5ee37ba1815..4638b87578a 100644 --- a/addons/frag/CfgAmmoFragParameters.hpp +++ b/addons/frag/CfgAmmoFragParameters.hpp @@ -222,7 +222,6 @@ class SmokeShell: GrenadeHand { GVAR(skip) = 1; }; class G_40mm_HE: GrenadeBase { - class EventHandlers: EventHandlers {}; // Source: http://www.inetres.com/gp/military/infantry/grenade/40mm_ammo.html#M441 GVAR(skip) = 0; GVAR(force) = 0; @@ -242,7 +241,6 @@ class G_20mm_HE: G_40mm_HE { GVAR(gurney_k) = "3/5"; // interior fragmenter/charge is a sphere }; class G_40mm_HEDP: G_40mm_HE { - class EventHandlers: EventHandlers {}; // Source: http://www.inetres.com/gp/military/infantry/grenade/40mm_ammo.html#M433 GVAR(classes)[] = {QGVAR(tiny), QGVAR(small), QGVAR(small_HD)}; GVAR(fragCount) = 270; // seems to have greater framentation ability, but lower range per source @@ -252,12 +250,8 @@ class G_40mm_HEDP: G_40mm_HE { GVAR(gurney_k) = "1/2"; }; -class ACE_G_40mm_HEDP: G_40mm_HEDP { - class EventHandlers: EventHandlers {}; -}; -class ACE_G_40mm_HE: G_40mm_HE { - class EventHandlers: EventHandlers {}; -}; +class ACE_G_40mm_HEDP: G_40mm_HEDP {}; +class ACE_G_40mm_HE: G_40mm_HE {}; class ACE_G_40mm_Practice: ACE_G_40mm_HE { GVAR(skip) = 1; GVAR(force) = 0; @@ -270,7 +264,6 @@ class ATMine_Range_Ammo: MineBase { }; class APERSMine_Range_Ammo: MineBase { // VS-50 - class EventHandlers: EventHandlers {}; GVAR(skip) = 0; GVAR(force) = 0; GVAR(classes)[] = {QGVAR(tiny), QGVAR(tiny), QGVAR(small)}; @@ -604,11 +597,8 @@ class ACE_Hellfire_AGM114K: M_Scalpel_AT { GVAR(gurney_k) = "1/2"; }; -class ammo_Missile_CruiseBase: MissileBase { - class EventHandlers: EventHandlers {}; -}; +class ammo_Missile_CruiseBase: MissileBase {}; class ammo_missile_cruise_01: ammo_Missile_CruiseBase { - class EventHandlers: EventHandlers {}; GVAR(skip) = 0; GVAR(classes)[] = {QGVAR(small), QGVAR(medium), QGVAR(large)}; GVAR(fragCount) = 20000; @@ -617,8 +607,7 @@ class ammo_missile_cruise_01: ammo_Missile_CruiseBase { GVAR(gurney_c) = 2600; GVAR(gurney_k) = "3/5"; }; -class ammo_Missile_Cruise_01_Cluster: ammo_missile_cruise_01 { -}; +class ammo_Missile_Cruise_01_Cluster: ammo_missile_cruise_01 {}; class ammo_Missile_AntiRadiationBase: MissileBase { GVAR(gurney_k) = "1/2"; From aba2a858405b9d9997569b578f0f2cefbdd99f44 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 18 Jul 2024 18:43:08 -0500 Subject: [PATCH 281/282] simplified event declarations and fixed whitespace --- addons/frag/XEH_preInit.sqf | 9 +-------- addons/frag/functions/fnc_doSpallLocal.sqf | 3 +-- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/addons/frag/XEH_preInit.sqf b/addons/frag/XEH_preInit.sqf index 9e85fabe2a8..3782ddf6e7d 100644 --- a/addons/frag/XEH_preInit.sqf +++ b/addons/frag/XEH_preInit.sqf @@ -28,14 +28,7 @@ GVAR(dev_drawPFEH) = -1; #endif if (isServer) then { - [ - QGVAR(explosionEvent), - { - params ["_posASL", "_velocity", "_ammo", "_shotParents"]; - [_posASL, _velocity, _ammo, _shotParents] call FUNC(doFrag); - } - ] call CBA_fnc_addEventHandler; - + [QGVAR(explosionEvent), LINKFUNC(doFragServer)] call CBA_fnc_addEventHandler; [QGVAR(spallEvent), LINKFUNC(doSpallServer)] call CBA_fnc_addEventHandler; }; diff --git a/addons/frag/functions/fnc_doSpallLocal.sqf b/addons/frag/functions/fnc_doSpallLocal.sqf index 6e0fd81ca3b..17224cb36f7 100644 --- a/addons/frag/functions/fnc_doSpallLocal.sqf +++ b/addons/frag/functions/fnc_doSpallLocal.sqf @@ -114,8 +114,7 @@ if GVAR(dbgSphere) then { }; #endif -private _spawnSize = switch (true) do -{ +private _spawnSize = switch (true) do { case (_spallPower < ACE_FRAG_SPALL_POWER_TINY_MAX): {"_spall_tiny"}; case (_spallPower < ACE_FRAG_SPALL_POWER_SMALL_MAX): {"_spall_small"}; case (_spallPower < ACE_FRAG_SPALL_POWER_MEDIUM_MAX): {"_spall_medium"}; From fecfe9c68e39969134ce70d4d5e28ce1c2728f88 Mon Sep 17 00:00:00 2001 From: lambdatiger Date: Thu, 15 Aug 2024 20:38:54 -0500 Subject: [PATCH 282/282] Accidentally took wrong files in merge --- addons/frag/functions/fnc_pfhRound.sqf | 60 ------------------------ addons/frag/functions/fnc_spallTrack.sqf | 40 ---------------- 2 files changed, 100 deletions(-) delete mode 100644 addons/frag/functions/fnc_pfhRound.sqf delete mode 100644 addons/frag/functions/fnc_spallTrack.sqf diff --git a/addons/frag/functions/fnc_pfhRound.sqf b/addons/frag/functions/fnc_pfhRound.sqf deleted file mode 100644 index 1486d5d585a..00000000000 --- a/addons/frag/functions/fnc_pfhRound.sqf +++ /dev/null @@ -1,60 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: ACE-Team - * - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_frag_fnc_pfhRound - * - * Public: No - */ - -params ["_round", "_lastPos", "_lastVel", "_shellType", "_firedFrame", "_firedPos", "_doSpall", "_spallTrack", "_foundObjectHPIds", "_skip", "_explosive", "_indirectRange", "_force", "_fragPower"]; - -if (_round in GVAR(blackList)) exitWith { - false -}; - -if (!alive _round) exitWith { - if ((diag_frameno - _firedFrame) > 1) then { //skip if deleted within a single frame - if (_skip == 0) then { - if ((_explosive > 0.5 && {_indirectRange >= 4.5} && {_fragPower >= 35}) || {_force == 1}) then { - // shotbullet, shotShell don't seem to explode when touching water, so don't create frags - if ((surfaceIsWater _lastPos) && {(toLowerANSI getText (configFile >> "CfgAmmo" >> _shellType >> "simulation")) in ["shotbullet", "shotshell"]}) exitWith {}; - private _fuseDist = getNumber(configFile >> "CfgAmmo" >> _shellType >> "fuseDistance"); - private _isArmed = _firedPos vectorDistance _lastPos >= _fuseDist; // rounds explode at exactly fuseDistance, so check inclusive - TRACE_2("",_fuseDist,_isArmed); - if (!_isArmed) exitWith {TRACE_1("round not armed",_this);}; - TRACE_3("Sending frag event to server",_lastPos,_lastVel,_shellType); - [QGVAR(frag_eh), [_lastPos,_lastVel,_shellType]] call CBA_fnc_serverEvent; - }; - }; - }; - if (_doSpall) then { - DEC(GVAR(spallIsTrackingCount)); - TRACE_1("doSpall",_foundObjectHPIds); - { - if (!isNil "_x") then { - _x removeEventHandler ["HitPart", _foundObjectHPIds select _forEachIndex]; - }; - } forEach _spallTrack; - }; - false -}; - -_this set [1, getPosASL _round]; -_this set [2, velocity _round]; - -if (_doSpall) then { - private _scale = ((count GVAR(objects)) / GVAR(maxTrackPerFrame)) max 0.1; - [_round, _scale, _spallTrack, _foundObjectHPIds] call FUNC(spallTrack); -}; - -true - diff --git a/addons/frag/functions/fnc_spallTrack.sqf b/addons/frag/functions/fnc_spallTrack.sqf deleted file mode 100644 index 806e2fa6ba3..00000000000 --- a/addons/frag/functions/fnc_spallTrack.sqf +++ /dev/null @@ -1,40 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: ACE-Team - * Add HitPart EventHandler to objects in the projectile's path - * - * Arguments: - * None - * - * Return Value: - * None - * - * Example: - * call ace_frag_fnc_spallTrack - * - * Public: No - */ - -params ["_round", "_multiplier", "_foundObjects", "_foundObjectHPIds"]; - -private _delta = (1 / diag_fps) * _multiplier; -private _curPos = getPosASL _round; -private _velocity = velocity _round; - -private _velocityStep = _velocity vectorMultiply _delta; -private _forwardPos = _curPos vectorAdd _velocityStep; - - -private _intersectsWith = lineIntersectsWith [_curPos, _forwardPos]; - -if (_intersectsWith isEqualTo []) exitWith {}; -{ - // diag_log text format ["Adding HP: %1", _x]; - private _index = count GVAR(spallHPData); - private _hpId = _x addEventHandler ["HitPart", compile format ["[%1, _this] call " + QFUNC(spallHP), _index]]; - _foundObjects pushBack _x; - _foundObjectHPIds pushBack _hpId; - private _data = [_hpId, _x, typeOf _round, _round, _curPos, _velocity, 0, _foundObjects, _foundObjectHPIds]; - GVAR(spallHPData) pushBack _data; -} forEach (_intersectsWith select {!(_x in _foundObjects)}); -