diff --git a/AUTHORS.txt b/AUTHORS.txt index 0b794b493c..2e8263b6f2 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -61,6 +61,7 @@ Clon1998 Codingboy Coren Crusty +C0kkie Dharma Bellamkonda Dimaslg diwako diff --git a/addons/advanced_fatigue/XEH_postInit.sqf b/addons/advanced_fatigue/XEH_postInit.sqf index 2227cd6540..78027fd3f5 100644 --- a/addons/advanced_fatigue/XEH_postInit.sqf +++ b/addons/advanced_fatigue/XEH_postInit.sqf @@ -47,8 +47,8 @@ if (!hasInterface) exitWith {}; [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); - [QEGVAR(medical,bloodVolume), { // 100->1.0, 90->1.1, 80->1.2 - linearConversion [6, 0, (_this getVariable [QEGVAR(medical,bloodVolume), 100]), 1, 2, true]; + [QEGVAR(medical,bloodVolume), { // 6->1.0, 5->1.167, 4->1.33 + linearConversion [6, 0, (_this getVariable [QEGVAR(medical,bloodVolume), 6]), 1, 2, true]; }] call FUNC(addDutyFactor); }; if (["ACE_Dragging"] call EFUNC(common,isModLoaded)) then { diff --git a/addons/advanced_fatigue/stringtable.xml b/addons/advanced_fatigue/stringtable.xml index 628801a0c0..b3a24a4396 100644 --- a/addons/advanced_fatigue/stringtable.xml +++ b/addons/advanced_fatigue/stringtable.xml @@ -123,6 +123,7 @@ Sway factor + Verwacklungsfaktor 手ぶれ因数 抖动因数 抖動因素 @@ -133,6 +134,7 @@ Influences the amount of weapon sway. Higher means more sway. + Beeinflusst den Faktor, wie ruhig man eine Waffe halten kann. Ein höherer Wert bedeutet weniger Stabilisierung 武器を持つ手のぶれ度合いを設定します。 値が高ければ高いほど、手ぶれが強くなります。 影响手持武器的晃动程度,数值越高,抖动的越厉害. 影響手持武器晃動程度,數值越高抖動越厲害 diff --git a/addons/ai/stringtable.xml b/addons/ai/stringtable.xml index 3b7fcad816..ff6f123261 100644 --- a/addons/ai/stringtable.xml +++ b/addons/ai/stringtable.xml @@ -3,6 +3,7 @@ Invalid position provided. + Ungültige Position Position invalide fourni 位置が無効です。 Posizione invalida fornita. @@ -14,6 +15,7 @@ No units provided. + Keine Einheit ausgewählt Aucune unité fourni ユニットがありません。 Nessuna unità fornita. @@ -25,6 +27,7 @@ There aren't enough positions to place all units. + Es gibt nicht genug Positionen, um alle Einheiten zu platzieren Il n'y a pas assez de positions pour placer toutes les unités 全ユニットを置くために十分な位置がありません。 Non ci sono abbastanza posizioni per piazzare tutte le unità. @@ -36,6 +39,7 @@ No building found. + Kein Gebäude gefunden Aucun bâtiment trouvé 建物がありません。 Nessun edificio trovato. diff --git a/addons/arsenal/stringtable.xml b/addons/arsenal/stringtable.xml index f89f008450..d42e27d519 100644 --- a/addons/arsenal/stringtable.xml +++ b/addons/arsenal/stringtable.xml @@ -749,6 +749,7 @@ Open the loadouts screen + Öffnet das Ausrüstungsmenü Affiche la page des équipements 開啟裝備選單 开启装备选单 @@ -759,6 +760,7 @@ Export current / default loadouts + Exportiert aktuelles / standard Loadout Exporte l'équipement actuel ou la liste d'équipements de base 匯出當前/預設的裝備 汇出当前/预设的装备 @@ -769,6 +771,7 @@ Import current / default loadouts + Importiert aktuelles / standard Loadout Importer l'équipement actuel ou la liste d'équipements de base 匯入當前/預設的裝備 汇入当前/预设的装备 @@ -845,6 +848,7 @@ Page + Seite Page ページ 页面 @@ -855,6 +859,7 @@ Enable the faces / voices / insignias tabs + Aktiviere die Gesichter-, Stimmen- und Abzeichenübersicht Activer les onglets faces / voix / insignes 顔 / 声 / 記章タブを有効化 启用脸谱/声音/徽章/选项 @@ -865,6 +870,7 @@ Empty the selected container + Aktuellen Container leeren Vider le conteneur selectionné 選択されたコンテナは空です 选择的箱子是空的 @@ -875,6 +881,7 @@ Exported class name to clipboard + Der Klassenname wurde in die Zwischenablage exportiert Nom de classe exporté dans le presse papier クリップボードへクラスネームをエクスポート 将种类复制到剪贴板 @@ -917,6 +924,7 @@ Blacklist + Blacklist 禁止リスト Lista Nera Czarna lista (lista wykluczeń) @@ -940,6 +948,7 @@ Export current items list as an array for use in scripts + Exportiert aktuelle Gegenstände als Array, um es in Scripten zu verwenden スクリプト用に現在のアイテム リストをアレイでエクスポートします Esporta l'attuale lista di elementi come un array, per essere usati negli script Eksportuj obecną listę przedmiotów jako tablicę do wykorzystania w skryptach @@ -947,24 +956,28 @@ Import items list array from clipboard (should be the same format as export) + Importiert alles aus der Zwischenablage (Sollte im gleichen Format sein, wie beim Exportieren) Zaimportuj listę przedmiotów ze schowka (lista musi być w tym samym formacie jak przy exporcie) クリップボードからアイテムリストをアレイでインポートします (エクスポートと同じフォーマットである必要があります) Импорт массива списка предметов из буфера (должен иметь тот же формат, что при экспорте) Add Compatible Items + Füge kompatible Gegenstände hinzu Dodaj kompatybilne przedmioty 対応アイテムを追加 Добавить совместимые предметы Will automatically add compatible attachments or magazines (based on selected category) for all weapons in current items list + Es werden automatisch kompatible Aufsätze oder Magazine für alle ausgewählten Waffen hinzugefügt Automatycznie doda kompatybilne dodatki oraz magazynki (odpowiednio do każdej kategorii) dla wszystkich broni na liście 現在のアイテム リスト内にある全武器に対応するアタッチメントと弾倉 (選択したカテゴリに基づき) を自動的に追加します Добавляет совместимые приспособления или магазины (в зависимости от выбранной категории) для всего оружия в текущем списке предметов Time to live + Lebenszeit Durée de vie 有効時間 Czas by żyć diff --git a/addons/ballistics/stringtable.xml b/addons/ballistics/stringtable.xml index f9f5451ff4..1c691d960a 100644 --- a/addons/ballistics/stringtable.xml +++ b/addons/ballistics/stringtable.xml @@ -2283,6 +2283,7 @@ Barrel twist + Dralllänge 銃身の転度 膛线缠距 膛線扭度 @@ -2292,6 +2293,7 @@ Barrel length + Lauflänge Longueur du canon 銃身長 身管长度 @@ -2302,6 +2304,7 @@ Ballistic coefficient + Ballistischer Koeffizient Coefficient ballistique 弾道係数 弹道系数 @@ -2312,6 +2315,7 @@ Bullet mass + Projektilgewicht Masse d'une balle 弾丸重量 弹头重量 @@ -2322,6 +2326,7 @@ Muzzle velocity + Mündungsgeschwindigkeit Vitesse à la bouche 銃口初速 枪口初速 diff --git a/addons/cargo/XEH_preInit.sqf b/addons/cargo/XEH_preInit.sqf index 3d7ac380c2..1b0894b77e 100644 --- a/addons/cargo/XEH_preInit.sqf +++ b/addons/cargo/XEH_preInit.sqf @@ -11,5 +11,6 @@ PREP_RECOMPILE_END; GVAR(initializedItemClasses) = []; GVAR(initializedVehicleClasses) = []; GVAR(cargoHolderTypes) = ["Car", "Air", "Tank", "Ship", "Cargo_base_F", "Land_PaperBox_closed_F"]; +GVAR(disableParadropEffectsClasstypes) = ["Car_F"]; ADDON = true; diff --git a/addons/cargo/functions/fnc_paradropItem.sqf b/addons/cargo/functions/fnc_paradropItem.sqf index 2f9ae06336..4c873d189e 100644 --- a/addons/cargo/functions/fnc_paradropItem.sqf +++ b/addons/cargo/functions/fnc_paradropItem.sqf @@ -69,8 +69,10 @@ _itemObject setVelocity ((velocity _vehicle) vectorAdd ((vectorNormalized (vecto _item attachTo [_parachute, [0,0,1]]; _parachute setVelocity _velocity; - private _light = "Chemlight_yellow" createVehicle [0,0,0]; - _light attachTo [_item, [0,0,0]]; + if ((GVAR(disableParadropEffectsClasstypes) findIf {_item isKindOf _x}) == -1) then { + private _light = "Chemlight_yellow" createVehicle [0,0,0]; + _light attachTo [_item, [0,0,0]]; + }; }, [_itemObject], 0.7] call CBA_fnc_waitAndExecute; @@ -83,8 +85,10 @@ _itemObject setVelocity ((velocity _vehicle) vectorAdd ((vectorNormalized (vecto }; if (getPos _item select 2 < 1) then { - private _smoke = "SmokeshellYellow" createVehicle [0,0,0]; - _smoke attachTo [_item, [0,0,0]]; + if ((GVAR(disableParadropEffectsClasstypes) findIf {_item isKindOf _x}) == -1) then { + private _smoke = "SmokeshellYellow" createVehicle [0,0,0]; + _smoke attachTo [_item, [0,0,0]]; + }; [_this select 1] call CBA_fnc_removePerFrameHandler; }; diff --git a/addons/cargo/stringtable.xml b/addons/cargo/stringtable.xml index 2ec8eae84a..ed7b135e8f 100644 --- a/addons/cargo/stringtable.xml +++ b/addons/cargo/stringtable.xml @@ -322,6 +322,7 @@ Load Time Coefficient + Ladezeitmultiplikator 積載時間の係数 Współczynnik czasu załadowania Coefficente Tempo Caricamento @@ -329,6 +330,7 @@ Modifies how long it takes to load/unload items.\nTime, in seconds, is the size of the item multiplied by this value. + Gibt an, wie lange das Laden / Entladen von Gegenständen dauern soll.\nZeit in Sekunden, die mit der Größe des Gegenstandes multipliziert wird. アイテムの積み下ろし作業にかかる時間を編集できます。\nアイテムの大きさにこの値が乗法され、時間 (秒) を変更できます。 Modyfikuje, jak długo zajmuje załadowywanie/wyładowywanie przedmiotów. \nCzasem, w sekundach, jest wielkość przedmiotu razy jego wartość. Modifica quanto tempo ci impiega a caricare o scaricare gli oggetti.\n Tempo, in secondi, è la dimensione dell'oggetto moltiplicata per questo valore diff --git a/addons/common/functions/fnc_cbaSettings.sqf b/addons/common/functions/fnc_cbaSettings.sqf index 4eb84d54da..273c72323e 100644 --- a/addons/common/functions/fnc_cbaSettings.sqf +++ b/addons/common/functions/fnc_cbaSettings.sqf @@ -21,6 +21,9 @@ LOG("Adding ACE_Settings to CBA_settings"); GVAR(cbaSettings_forcedSettings) = []; GVAR(cbaSettings_missionSettings) = []; GVAR(settings) = []; // will stay empty - for BWC? +#ifdef DEBUG_MODE_FULL +GVAR(settingsMovedToSQF) = []; +#endif // Add Event Handlers: [QGVAR(setSetting), { @@ -66,6 +69,13 @@ GVAR(settings) = []; // will stay empty - for BWC? false } count GVAR(runAtSettingsInitialized); GVAR(runAtSettingsInitialized) = nil; //cleanup + + #ifdef DEBUG_MODE_FULL + INFO_1("checking settingsMovedToSQF [%1]",count GVAR(settingsMovedToSQF)); + { + if (isNil _x) then { WARNING_1("setting [%1] NOT moved to sqf",_x); }; + } forEach GVAR(settingsMovedToSQF); + #endif }] call CBA_fnc_addEventHandler; private _start = diag_tickTime; @@ -81,6 +91,10 @@ for "_index" from 0 to (_countOptions - 1) do { } else { WARNING_1("Setting [%1] - Already defined from somewhere else??",_varName); }; + #ifdef DEBUG_MODE_FULL + } else { + GVAR(settingsMovedToSQF) pushBack configName _optionEntry; + #endif }; }; diff --git a/addons/common/functions/fnc_isEOD.sqf b/addons/common/functions/fnc_isEOD.sqf index 226d315e36..303b258cb5 100644 --- a/addons/common/functions/fnc_isEOD.sqf +++ b/addons/common/functions/fnc_isEOD.sqf @@ -13,11 +13,11 @@ * is the unit an EOD * * Example: - * isSpecialist = [player] call FUNC(isEOD); + * [player] call ace_common_fnc_isEOD * * Public: Yes */ params ["_unit"]; -_unit getVariable ["ACE_isEOD", _unit getUnitTrait "explosiveSpecialist"] // return +(_unit getVariable ["ACE_isEOD", _unit getUnitTrait "explosiveSpecialist"]) in [1, true] diff --git a/addons/common/stringtable.xml b/addons/common/stringtable.xml index 440d26e867..0bb411d168 100644 --- a/addons/common/stringtable.xml +++ b/addons/common/stringtable.xml @@ -507,6 +507,7 @@ Check PBO Action + PBO Überprüfung Controlla Azioni PBO 檢查PBO動作 检查PBO动作 @@ -517,6 +518,7 @@ Check PBO All + Alle PBOs überprüfen Controlla Tutti i PBO 檢查所有PBO 检查所有PBO @@ -527,6 +529,7 @@ Check PBO Whitelist + PBO Whitelist Controlla Whitelist PBO 檢查PBO白名單 检查PBO白名单 @@ -1004,6 +1007,7 @@ Always + Immer 常に Всегда @@ -1015,7 +1019,7 @@ Überall Kdekoliv Qualquer lugar - PArtout + Partout Akárhol Ovunque どこでも @@ -1084,11 +1088,13 @@ Confirm 確認 + Bestätigen Подтвердить Never 行わない + Nie Никогда @@ -1282,6 +1288,7 @@ Flag (ACE - Black) + Flagge (Ace - Schwarz) 旗帜(ACE-黑色): 旗幟(ACE-黑色) Bandiera (ACE - Nera) @@ -1291,6 +1298,7 @@ Flag (ACE - White) + Flagge (Ace - Weiß) 旗帜(ACE-白色): 旗幟(ACE-白色) Bandiera (ACE - Bianca) diff --git a/addons/cookoff/stringtable.xml b/addons/cookoff/stringtable.xml index 27fde6418b..452b213fe9 100644 --- a/addons/cookoff/stringtable.xml +++ b/addons/cookoff/stringtable.xml @@ -15,11 +15,13 @@ Damage handling and turret effects + Schadensberechnung und Geschützturmeffekte 損傷処理と砲塔の効果 Обработка урона и эффектов срыва башни Changes damage handling for cook off and turret explosion effects + Ändert die Schadensberechnung für die Durchzündung und die Explosionseffekte des Geschützturmes 誘爆の損傷処理と砲塔の爆発効果を変更します。 Изменяет обработку урона для возгорания и эффекта срыва башни diff --git a/addons/dogtags/stringtable.xml b/addons/dogtags/stringtable.xml index b3db573100..72793fd471 100644 --- a/addons/dogtags/stringtable.xml +++ b/addons/dogtags/stringtable.xml @@ -81,6 +81,7 @@ Onscreen display for checking dogtags + Anzeige um Hundemarke zu überprüfen 在畫面中顯示檢查兵籍牌 確認中のドッグタグを画面上で表示します Display su schermo per il controllo delle piastrine diff --git a/addons/explosives/CfgAmmo.hpp b/addons/explosives/CfgAmmo.hpp index 722fbf213c..c02885362e 100644 --- a/addons/explosives/CfgAmmo.hpp +++ b/addons/explosives/CfgAmmo.hpp @@ -164,7 +164,7 @@ class CfgAmmo { class ACE_IEDLandSmall_Command_Ammo: IEDLandSmall_Remote_Ammo { mineTrigger = "RemoteTrigger"; }; - class ACE_IEDLandSmall_Range_Ammo: IEDLandBig_Remote_Ammo { + class ACE_IEDLandSmall_Range_Ammo: IEDLandSmall_Remote_Ammo { mineTrigger = "RangeTriggerShort"; }; diff --git a/addons/explosives/stringtable.xml b/addons/explosives/stringtable.xml index 4b7628e5aa..810d74bf92 100644 --- a/addons/explosives/stringtable.xml +++ b/addons/explosives/stringtable.xml @@ -1021,6 +1021,7 @@ Explosive range + Explosionsradius Portée du détonateur 爆発範囲 爆炸范围 @@ -1031,6 +1032,7 @@ Explosive Timer + Detonationszeit Timer di detonazione 爆発タイマー Czasomierz Wybuchu diff --git a/addons/fastroping/stringtable.xml b/addons/fastroping/stringtable.xml index 6b22e639ef..5fe476a336 100644 --- a/addons/fastroping/stringtable.xml +++ b/addons/fastroping/stringtable.xml @@ -147,6 +147,7 @@ Deploy 12m ropes + 12m Seile einsetzen Déployer les cordes 12m 12m ロープを展開 Wysuń linę o długości 12 m. @@ -154,6 +155,7 @@ Deploy 15m ropes + 15m Seile einsetzen Déployer les cordes 15m 15m ロープを展開 Wysuń linę o długości 15 m. @@ -161,6 +163,7 @@ Deploy 18m ropes + 18m Seile einsetzen Déployer les cordes 18m 18m ロープを展開 Wysuń linę o długości 18 m. @@ -168,6 +171,7 @@ Deploy 27m ropes + 27m Seile einsetzen Déployer les cordes 27m 27m ロープを展開 Wysuń linę o długości 27 m. @@ -175,6 +179,7 @@ Deploy 36m ropes + 36m Seile einsetzen Déployer les cordes 36m 36m ロープを展開 Wysuń linę o długości 36 m. @@ -182,6 +187,7 @@ [ACE] Ropes Supply crate + [ACE] Seil Versorgungskiste [ACE] Caisse de Cordes [ACE] ロープ収納箱 Skrzynia z linami ACE @@ -189,6 +195,7 @@ Used to do deploy ropes from a compatibile helicopter + Wird zum Bereitstellen von Seilen aus einem kompatiblen Hubschrauber verwendet Utilisé pour déployer des cordes depuis un hélicoptère compatible 対応するヘリコプターからロープを展開する為に使用されます Używane do opuszczania lin z kompatybilnych smigłowców @@ -196,6 +203,7 @@ Rope 12.2 meters + 12.2 Meter Seil Corde 12.2 mètres ロープ (12.2 メートル) Lina, długość 12,2 m. @@ -203,6 +211,7 @@ Rope 15.2 meters + 15.2 Meter Seil Corde 15.2 mètres ロープ (15.2 メートル) Lina, długość 15,2 m. @@ -210,6 +219,7 @@ Rope 18.3 meters + 18.3 Meter Seil Corde 18.3 mètres ロープ (18.3 メートル) Lina, długość 18,3 m. @@ -217,6 +227,7 @@ Rope 27.4 meters + 27.4 Meter Seil Corde 27.4 mètres ロープ (27.4 メートル) Lina, długość 27,4 m. @@ -224,6 +235,7 @@ Rope 36.6 meters + 36.6 Meter Seil Corde 36.6 mètres ロープ (36.6 メートル) Lina, długość 36,6 m. @@ -231,6 +243,7 @@ Require rope item to deploy + Seil-Item zum aufbauen benötigt Exiger une corde pour déployer 展開にはロープ アイテムを必須に Wymaga przedmiotu typu lina diff --git a/addons/flashlights/stringtable.xml b/addons/flashlights/stringtable.xml index 9bd340c7a2..dc2c76dd4f 100644 --- a/addons/flashlights/stringtable.xml +++ b/addons/flashlights/stringtable.xml @@ -93,6 +93,7 @@ Map light color + Farbe des Kartenlichts Couleur de la lampe sur carte 光の色 地图上手电的颜色 diff --git a/addons/gforces/stringtable.xml b/addons/gforces/stringtable.xml index 0fbe8aba2a..2fb8c1b1d1 100644 --- a/addons/gforces/stringtable.xml +++ b/addons/gforces/stringtable.xml @@ -33,6 +33,7 @@ G-force reduction + G-Kräfte Reduzierung Reduction des Gs 耐 G 性 减少G力 diff --git a/addons/hearing/stringtable.xml b/addons/hearing/stringtable.xml index f1deab8373..e5cb9df251 100644 --- a/addons/hearing/stringtable.xml +++ b/addons/hearing/stringtable.xml @@ -284,6 +284,7 @@ Hearing protection + Gehörschutz Protection auditive 聴覚保護 听力保护 @@ -294,6 +295,7 @@ Volume muffling + Lautstärkedämpfung Étouffement des sons 音量低下 降低音量 @@ -304,6 +306,7 @@ Earplugs Volume + Lautstärke Ohrenstöpsel 耳栓時の音量 耳塞时音量 耳塞時音量 @@ -313,6 +316,7 @@ Volume when using earplugs. + Lautstärke wenn man Ohrenstöpsel benutzt 耳栓使用時の音量を決定します。 决定带上耳塞时的音量 使用耳塞時音量 @@ -322,6 +326,7 @@ Unconscious Volume + Lautstärke Bewusstlosigkeit 気絶時の音量 无意识时音量 昏迷時音量 @@ -331,6 +336,7 @@ Volume when unconscious. + Lautstärke während man Bewusstlos ist 気絶時の音量を決定します。 决定处于无意识时的音量 昏迷時使用耳塞的音量 diff --git a/addons/hot/stringtable.xml b/addons/hot/stringtable.xml index 84dddd874f..a6b427f408 100644 --- a/addons/hot/stringtable.xml +++ b/addons/hot/stringtable.xml @@ -27,6 +27,7 @@ HOT Missile + Lenkflugkörper Pocisk HOT Missile HOT HOT ミサイル @@ -34,6 +35,7 @@ HOT 1 + HOT 1 HOT 1 HOT 1 HOT 1 @@ -41,6 +43,7 @@ HOT 2 + HOT 2 HOT 2 HOT 2 HOT 2 @@ -48,6 +51,7 @@ HOT 2MP + HOT 2MP HOT 2MP HOT 2MP HOT 2MP @@ -55,6 +59,7 @@ HOT 3 + HOT 3 HOT 3 HOT 3 HOT 3 @@ -62,6 +67,7 @@ Wire-Guided Missile (Anti-Personnel) + Anti Personen Lenkflugkörper Pocisk kierowany przewodowo (przeciwpiechotny) Missile filoguidato antiuomo ワイヤ有線誘導ミサイル (対人) @@ -69,6 +75,7 @@ 1x HOT 1 [ACE] + 1x HOT 1 [ACE] 1x HOT 1 [ACE] 1x HOT1 [ACE] 1x HOT 1 [ACE] @@ -76,6 +83,7 @@ 3x HOT 1 [ACE] + 3x HOT 1 [ACE] 3x HOT 1 [ACE] 3x HOT 1 [ACE] 3x HOT 1 [ACE] @@ -83,6 +91,7 @@ 4x HOT 1 [ACE] + 4x HOT 1 [ACE] 4x HOT 1 [ACE] 4x HOT 1 [ACE] 4x HOT 1 [ACE] @@ -90,6 +99,7 @@ 1x HOT 2 [ACE] + 1x HOT 2 [ACE] 1x HOT 2 [ACE] 1x HOT 2 [ACE] 1x HOT 2 [ACE] @@ -97,6 +107,7 @@ 3x HOT 2 [ACE] + 3x HOT 2 [ACE] 3x HOT 2 [ACE] 3x HOT 2 [ACE] 3x HOT 2 [ACE] @@ -104,6 +115,7 @@ 4x HOT 2 [ACE] + 4x HOT 2 [ACE] 4x HOT 2 [ACE] 4x HOT 2 [ACE] 4x HOT 2 [ACE] @@ -111,6 +123,7 @@ 1x HOT 2MP [ACE] + 1x HOT 2MP [ACE] 1x HOT 2MP [ACE] 1x HOT 2MP [ACE] 1x HOT 2MP [ACE] @@ -118,6 +131,7 @@ 3x HOT 2MP [ACE] + 3x HOT 2MP [ACE] 3x HOT 2MP [ACE] 3x HOT 2MP [ACE] 3x HOT 2MP [ACE] @@ -125,6 +139,7 @@ 4x HOT 2MP [ACE] + 4x HOT 2MP [ACE] 4x HOT 2MP [ACE] 4x HOT 2MP [ACE] 4x HOT 2MP [ACE] @@ -132,6 +147,7 @@ 1x HOT 3 [ACE] + 1x HOT 3 [ACE] 1x HOT 3 [ACE] 1x HOT 3 [ACE] 1x HOT 3 [ACE] @@ -139,6 +155,7 @@ 4x HOT 3 [ACE] + 4x HOT 3 [ACE] 4x HOT 3 [ACE] 4x HOT 3 [ACE] 4x HOT 3 [ACE] @@ -146,6 +163,7 @@ 3x HOT 3 [ACE] + 3x HOT 3 [ACE] 3x HOT 3 [ACE] 3x HOT 3 [ACE] 3x HOT 3 [ACE] diff --git a/addons/interact_menu/stringtable.xml b/addons/interact_menu/stringtable.xml index 64fba31160..599855f826 100644 --- a/addons/interact_menu/stringtable.xml +++ b/addons/interact_menu/stringtable.xml @@ -448,6 +448,7 @@ Selector Color + Farbauswahl セレクターの色 选择器颜色 選單的顏色 diff --git a/addons/interaction/stringtable.xml b/addons/interaction/stringtable.xml index d8f190a560..65c1dfa00f 100644 --- a/addons/interaction/stringtable.xml +++ b/addons/interaction/stringtable.xml @@ -844,6 +844,7 @@ Flip + Umdrehen Перевернуть ひっくり返す @@ -1091,6 +1092,7 @@ Pull out body + Person herausziehen Вытащить тело 身体を引き出す Estrai il corpo diff --git a/addons/magazinerepack/stringtable.xml b/addons/magazinerepack/stringtable.xml index f7d0b45acb..6eab4dd180 100644 --- a/addons/magazinerepack/stringtable.xml +++ b/addons/magazinerepack/stringtable.xml @@ -3,6 +3,7 @@ Magazine Repack + Magazine umpacken Riempimento Caricatori 重新整理彈匣 重新整理弹匣 diff --git a/addons/main/config.cpp b/addons/main/config.cpp index 81b5e7ce3d..4852b9ff16 100644 --- a/addons/main/config.cpp +++ b/addons/main/config.cpp @@ -7,7 +7,7 @@ class CfgPatches { weapons[] = {}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = { - "A3_Data_F_Tank_Loadorder", + "A3_Data_F_Enoch_Loadorder", "A3_Data_F_Mod_Loadorder", // CBA "cba_ui", diff --git a/addons/main/script_mod.hpp b/addons/main/script_mod.hpp index 8d829092e9..a02c5c7bd9 100644 --- a/addons/main/script_mod.hpp +++ b/addons/main/script_mod.hpp @@ -9,7 +9,7 @@ #define VERSION_AR MAJOR,MINOR,PATCHLVL,BUILD // MINIMAL required version for the Mod. Components can specify others.. -#define REQUIRED_VERSION 1.88 +#define REQUIRED_VERSION 1.94 #define REQUIRED_CBA_VERSION {3,11,2} #ifdef COMPONENT_BEAUTIFIED diff --git a/addons/maptools/functions/fnc_handleMouseButton.sqf b/addons/maptools/functions/fnc_handleMouseButton.sqf index 7c2946abae..4e1c124b2a 100644 --- a/addons/maptools/functions/fnc_handleMouseButton.sqf +++ b/addons/maptools/functions/fnc_handleMouseButton.sqf @@ -24,8 +24,10 @@ TRACE_2("params",_dir,_params); if ((_button == 0) && {GVAR(freedrawing) || _ctrlKey}) exitWith { if (GVAR(freedrawing) && {_dir == 0}) then { GVAR(freedrawing) = false; - GVAR(drawPosEnd) = _control ctrlMapScreenToWorld [_screenPosX, _screenPosY]; - TRACE_2("Ending Line",GVAR(freedrawing),GVAR(drawPosEnd)); + if (_shiftKey) exitWith { + TRACE_1("using vanilla straight line",_shiftKey); + }; + TRACE_2("Ending Line",GVAR(freedrawing),GVAR(freeDrawingData)); [{ if (allMapMarkers isEqualTo []) exitWith {}; private _markerName = allMapMarkers select (count allMapMarkers - 1); diff --git a/addons/medical/CfgVehicles.hpp b/addons/medical/CfgVehicles.hpp index 424059c8e1..60bac16423 100644 --- a/addons/medical/CfgVehicles.hpp +++ b/addons/medical/CfgVehicles.hpp @@ -1,7 +1,23 @@ class CfgVehicles { + // Backwards compatibility + // Left as dumb modules so that old missions don't error about missing vehicles class Logic; - // Left as dumb logic so that old missions don't error about missing vehicle - class ACE_moduleMedicalSettings: Logic { - scope = 1; + class Module_F: Logic { + class EventHandlers; }; + class ACE_moduleMedicalSettings: Module_F { + author = ECSTRING(common,ACETeam); + scope = 1; + displayName = "[ACE] Retired Medical module (will have no effect)"; + class EventHandlers: EventHandlers { + init = "diag_log text format ['[ACE] (Medical) Warning retired module [%1] placed (will have no effect)', typeOf (_this select 0)];"; + }; + }; + class ACE_moduleBasicMedicalSettings: ACE_moduleMedicalSettings {}; + class ACE_moduleAdvancedMedicalSettings: ACE_moduleMedicalSettings {}; + class ACE_moduleReviveSettings: ACE_moduleMedicalSettings {}; + class ACE_moduleAssignMedicRoles: ACE_moduleMedicalSettings {}; + class ACE_moduleAssignMedicVehicle: ACE_moduleMedicalSettings {}; + class ACE_moduleAssignMedicalFacility: ACE_moduleMedicalSettings {}; + class ACE_moduleMedicalMenuSettings: ACE_moduleMedicalSettings {}; }; diff --git a/addons/medical/config.cpp b/addons/medical/config.cpp index e3557fab40..6c93d1e3e8 100644 --- a/addons/medical/config.cpp +++ b/addons/medical/config.cpp @@ -17,3 +17,7 @@ class CfgPatches { #include "ACE_Settings.hpp" #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" + +class ACE_Tests { + medicalHitpoints = QPATHTOF(dev\test_hitpointConfigs.sqf); +}; diff --git a/addons/medical/dev/debugDisplay.sqf b/addons/medical/dev/debugDisplay.sqf index 3d8323f46b..541aaaccba 100644 --- a/addons/medical/dev/debugDisplay.sqf +++ b/addons/medical/dev/debugDisplay.sqf @@ -23,7 +23,11 @@ if (!isNull cursorTarget && {cursorTarget isKindOf "CAManBase"}) then { private _targetState = [cursorTarget, EGVAR(medical,STATE_MACHINE)] call CBA_statemachine_fnc_getCurrentState; - drawIcon3D ["", [0.6, 0, 0, 1], cursorTarget modelToWorldVisual (cursorTarget selectionPosition "pelvis"), 0, 0, 0, format ["State: %1", _targetState], 2, 40 * pixelH, "RobotoCondensed"]; + private _targetStateAI = ""; + if (!isNil QEGVAR(medical_ai,stateMachine)) then { + _targetStateAI = [cursorTarget, EGVAR(medical_ai,stateMachine)] call CBA_statemachine_fnc_getCurrentState; + }; + drawIcon3D ["", [0.6, 0, 0, 1], cursorTarget modelToWorldVisual (cursorTarget selectionPosition "pelvis"), 0, 0, 0, format ["State: %1 / %2", _targetState,_targetStateAI], 2, 40 * pixelH, "RobotoCondensed"]; }; }, 0 ,[]] call CBA_fnc_addPerFrameHandler; }, []] call CBA_fnc_waitUntilAndExecute; diff --git a/addons/medical/dev/test_hitpointConfigs.sqf b/addons/medical/dev/test_hitpointConfigs.sqf new file mode 100644 index 0000000000..fb65b34669 --- /dev/null +++ b/addons/medical/dev/test_hitpointConfigs.sqf @@ -0,0 +1,33 @@ +// PabstMirror +// ["medicalHitpoints"] call ace_common_fnc_runTests; +// execVM "\z\ace\addons\medical\dev\test_hitpointConfigs.sqf" + +#include "\z\ace\addons\medical\script_component.hpp" + +// UAV-AI should get filtered by scope check +private _mans = configProperties [configFile >> "CfgVehicles", "(isClass _x) && {(getNumber (_x >> 'scope')) == 2} && {configName _x isKindOf 'CaManBase'}", true]; +INFO_1("Checking mans for medical hitpoints [%1 mans]",count _mans); + +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); + _testPass = false; + }; + + if (((_hitpoints findIf {_x == "HitLeftArm"}) == -1) || {(_hitpoints findIf {_x == "HitLeftArm"}) == -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; + }; +} forEach _mans; + +_testPass diff --git a/addons/medical/dev/watchVariable.sqf b/addons/medical/dev/watchVariable.sqf index 5fc0b1a065..1fa8157fd4 100644 --- a/addons/medical/dev/watchVariable.sqf +++ b/addons/medical/dev/watchVariable.sqf @@ -19,12 +19,16 @@ _return pushBack ""; // State: - private _hasStableVitals = [_unit] call EFUNC(medical_status,hasStableVitals); private _targetState = [_unit, EGVAR(medical,STATE_MACHINE)] call CBA_statemachine_fnc_getCurrentState; if (!local _unit) then {_targetState = "NotLocal";}; private _color = switch (_targetState) do {case "Default": {"33FF33"}; case "Injured": {"FF3333"}; case "Unconscious": {"FF8833"}; case "CardiacArrest": {"FF33AA"}; default {"555555"}}; - private _unconcFlag = if IS_UNCONSCIOUS(_unit) then {"[U]"} else {""}; - _return pushBack format ["State: %2 [StableVitals: %3] %4", _color, _targetState, _hasStableVitals, _unconcFlag]; + _return pushBack format ["State: %2", _color, _targetState]; + private _hasStableVitals = ["N", "Y"] select ([_unit] call EFUNC(medical_status,hasStableVitals)); + private _hasStableCondition = ["N", "Y"] select ([_unit] call EFUNC(medical_status,isInStableCondition)); + private _unconcFlag = if IS_UNCONSCIOUS(_unit) then {"[U]"} else {""}; + private _timeLeft = _unit getVariable [QEGVAR(medical_statemachine,cardiacArrestTimeLeft), -1]; + private _cardiactArrestFlag = if IN_CRDC_ARRST(_unit) then {format ["[CA %1]", _timeLeft toFixed 1]} else {""}; + _return pushBack format ["[StableVitals: %1] [StableCon: %2] %3 %4", _hasStableVitals, _hasStableCondition, _unconcFlag, _cardiactArrestFlag]; // Blood: private _bloodVolume = GET_BLOOD_VOLUME(_unit); @@ -85,7 +89,7 @@ // Wounds: _return pushBack "------- Wounds: -------"; - private _wounds = _unit getVariable [QEGVAR(medical,openWounds), []]; + private _wounds = GET_OPEN_WOUNDS(_unit); { _x params ["_xClassID", "_xBodyPartN", "_xAmountOf", "_xBleeding", "_xDamage"]; _return pushBack format ["%1: [%2] [x%3] [Bld: %4] [Dmg: %5]", ALL_SELECTIONS select _xBodyPartN, _xClassID, _xAmountOf toFixed 1, _xBleeding toFixed 4, _xDamage toFixed 2]; @@ -93,7 +97,7 @@ // Bandaged Wounds: _return pushBack "------- Bandaged Wounds: -------"; - private _wounds = _unit getVariable [QEGVAR(medical,bandagedWounds), []]; + private _wounds = GET_BANDAGED_WOUNDS(_unit); { _x params ["_xClassID", "_xBodyPartN", "_xAmountOf", "_xBleeding", "_xDamage"]; _return pushBack format ["%1: [%2] [x%3] [Bld: %4] [Dmg: %5]", ALL_SELECTIONS select _xBodyPartN, _xClassID, _xAmountOf toFixed 1, _xBleeding toFixed 4, _xDamage toFixed 2]; @@ -101,7 +105,7 @@ // Stitched Wounds: _return pushBack "------- Stitched Wounds: -------"; - private _wounds = _unit getVariable [QEGVAR(medical,stitchedWounds), []]; + private _wounds = GET_STITCHED_WOUNDS(_unit); { _x params ["_xClassID", "_xBodyPartN", "_xAmountOf", "_xBleeding", "_xDamage"]; _return pushBack format ["%1: [%2] [x%3] [Bld: %4] [Dmg: %5]", ALL_SELECTIONS select _xBodyPartN, _xClassID, _xAmountOf toFixed 1, _xBleeding toFixed 4, _xDamage toFixed 2]; diff --git a/addons/medical/initSettings.sqf b/addons/medical/initSettings.sqf index 4fc473949f..9b1aee8464 100644 --- a/addons/medical/initSettings.sqf +++ b/addons/medical/initSettings.sqf @@ -1,34 +1,30 @@ -// CBA Settings [ADDON: ace_medical]: - -private _categoryArray = [LELSTRING(medical,Category), "?"]; - -// todo: Check the description is still accurate [ - QGVAR(spontaneousWakeUpChance), "SLIDER", - [LSTRING(MedicalSettings_spontaneousWakeUpChance_DisplayName), LSTRING(MedicalSettings_spontaneousWakeUpChance_Description)], - _categoryArray, - [0,1,0.05,2], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(spontaneousWakeUpChance), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(limping), + "LIST", + [LSTRING(Limping_DisplayName), LSTRING(Limping_Description)], + LSTRING(Category), + [[0, 1, 2], [ELSTRING(common,Disabled), LSTRING(Limping_LimpOnOpenWounds), LSTRING(Limping_LimpRequiresStitching)], 1], + true, + {[QGVAR(limping), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true ] call CBA_settings_fnc_init; [ - QEGVAR(medical,limping), "LIST", - [LSTRING(setting_limping_DisplayName), LSTRING(setting_limping_Description)], - _categoryArray, - [[0,1,2],[LELSTRING(common,disabled), LLSTRING(setting_limping_limpOnOpenWounds), LLSTRING(setting_limping_limpRequiresStitching)], 1], // [values, titles, defaultIndex] - true, // isGlobal - {[QEGVAR(medical,limping), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(fractures), + "LIST", + [LSTRING(Fractures_DisplayName), LSTRING(Fractures_Description)], + LSTRING(Category), + [[0, 1, 2], [ELSTRING(common,Disabled), LSTRING(Fractures_SplintHealsFully), LSTRING(Fractures_SplintHasEffects)], 1], + true, + {[QGVAR(fractures), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true ] call CBA_settings_fnc_init; [ - QEGVAR(medical,fractures), "LIST", - [LSTRING(setting_fractures_DisplayName), LSTRING(setting_fractures_Description)], - _categoryArray, - [[0,1,2],[LELSTRING(common,disabled), LLSTRING(setting_fractures_splintHealsFully), LLSTRING(setting_fractures_splintHasEffects)], 1], // [values, titles, defaultIndex] - true, // isGlobal - {[QEGVAR(medical,fractures), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(spontaneousWakeUpChance), + "SLIDER", + [LSTRING(SpontaneousWakeUpChance_DisplayName), LSTRING(SpontaneousWakeUpChance_Description)], + LSTRING(Category), + [0, 1, 0.05, 2], + true ] call CBA_settings_fnc_init; diff --git a/addons/medical/script_component.hpp b/addons/medical/script_component.hpp index 44bdee2faa..1abe143393 100644 --- a/addons/medical/script_component.hpp +++ b/addons/medical/script_component.hpp @@ -2,7 +2,7 @@ #define COMPONENT_BEAUTIFIED Medical Core #include "\z\ace\addons\main\script_mod.hpp" -#define DEBUG_MODE_FULL +// #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS diff --git a/addons/medical/stringtable.xml b/addons/medical/stringtable.xml index 17b60f1703..af61c91714 100644 --- a/addons/medical/stringtable.xml +++ b/addons/medical/stringtable.xml @@ -17,117 +17,57 @@ ACE 医疗系统 ACE 醫療系統 - - Medical Level - Сложность медицины - Poziom medyczny - Nivel médico - Stufe des Sanitätssystem - Úroveň medického - Nível médico - Niveau de simulation médicale - Orvosi szint - Livello Medico - 医療レベル - 의료 수준 - 医疗等级 - 醫療等級 + + Unconscious Wake Up Chance + Wahrscheinlichkeit aufzuwachen + 気絶から覚醒する可能性 + Шанс очнуться при потере сознания - - What is the medical simulation level? - Каков уровень сложности медицинской системы? - Jaki jest poziom symulacji medycznej? - ¿Cuál es el nivel de simulación médica? - Wie hoch soll das medizinische Simulationslevel sein? - Jaká je úroveň lékařské simulace? - Qual o nível de simulação médica? - Quel niveau de simulation médicale choisissez-vous? - Milyen komplex legyen az orvosi szimuláció? - Qual'è il livello di simulazione medica? - 治療の再現度は? - 의료 시뮬레이션의 수준 - 选择需要的医疗模拟等级 - 選擇需要的醫療模擬等級 + + The probablity that a unit with stable vitals will wake up from unconsciousness (checked every 15 seconds). + Wahrscheinlichkeit, dass eine bewusstlose Person mit stabilen Vitalwerten wieder aufwacht ()Überprüfung alle 15 Sekunden) + 安定状態にある人が覚醒する確率です。(15 秒毎に確認) + Вероятность, что стабилизированный юнит очнется от потери сознания (Проверяется каждые 15 сек) - - Disable medics - Отключить медиков - Wyłącz medyków - Desactivar médicos - Sanitäter deaktivieren - Zakázat zdravotníky - Desativar médicos - Désactiver les infirmiers - Orvosok letiltása - Disabilita medici - 衛生兵を無効化 - 의무병 비활성화 - 关闭医护兵 - 關閉醫護兵 + + Limping + Хромота + 跛行 - - Enable Litter - Включить мусор - Aktywuj odpadki - Activar restos médicos - Abfälle aktivieren - Povolit odpadky - Ativar lixo médico - Activer les détritus - Szemét engedélyezése - Abilita Barella - 医療廃棄物の表示を有効化 - 의료폐기물 활성화 - 启用医疗废弃物 - 啟用醫療廢棄物 + + Limp when unit has leg wounds...(todo) + Хромота, когда юнит имеет ранения ног... + 足を負傷時に引きずって歩くようにします・・・(TODO) - - Enable litter being created upon treatment - Включить появление мусора после лечения - Twórz odpadki medyczne podczas leczenia - Activar los restos médicos que se crean en el tratamiento - Aktiviere Abfälle, wenn eine Behandlung durchgeführt wurde - Vytváří odpad zdravotnického materiálu pří léčení - Ativar lixo ser criado após tratamento - Activer la création de détrimus au début des traitements - Engedélyezi a szemét keletkezését ellátáskor - Abilita la creazione della barella dopo trattamento - 治療を始めると、医療廃棄物の作成を有効化する - 의료폐기물이 치료중 주변에 생성되는것을 활성화 합니다 - 本功能启用后,当每次医疗动作结束时,地上会产生相应的医疗废弃物 - 本功能啟用後,當每次醫療動作結束時,地上會產生相應的醫療廢棄物 + + Limp on open wounds + Хромота при открытых ранах + 創傷開放時に跛行 - - Life time of litter objects - Время удаления мусора - Długość życia odpadków - Tiempo de vida de los restos médicos - Dauer des angezeigten Abfalls - Životnost pro odpadky - Tempo de vida dos objetos do lixo - Durée d'affichage des détritus - Szemétobjektumok élettartama - Tempo di vita delle barelle - 医療廃棄物の作成限界数を設定 - 의료폐기물 시간제한 - 医疗废弃物存在时间 - 醫療廢棄物存在時間 + + Limp on open or bandaged wounds + Хромота при открытых или забинтованых ранах + 負傷時は引きずって歩くようにします - - How long should litter objects stay? In seconds. -1 is forever. - Как долго мусор будет оставаться на земле? В секундах. -1 означает бесконечное время. - Ile czasu musi upłynąć, aby odpadki zaczęły znikać? W sekundach. -1 dla nieskończoności. - ¿Por cuánto tiempo deben permanecer los restos médicos? En segundos. -1 es para siempre. - Wie lange sollen Abfälle am Boden liegen (in Sekunden)? -1 ist für immer. - Za jak dlouho začnou odpadky mizet? V sekundách. -1 navždy. - Quanto tempo os objetos do lixo devem ficar? Em segundos. -1 é para sempre. - Combien de temps doivent rester affiché les détritus? En secondes. -1 pour tout le temps - Milyen sokáig legyenek jelen a szemétobjektumok (másodpercben)? A -1 végtelen időt jelent. - Per quanto devono restare le barelle? In secondi. -1 è permanente - 医療廃棄物オブジェクトが表示されつづける時間を設定しますか? -1 は永遠です。 - 얼마동안 폐기물이 존재합니까? 초 단위. -1 은 영구적. - 定义医疗废弃物存在时间,以秒为单位,-1为永远存在。 - 定義醫療廢棄物存在時間,以秒為單位,-1為永遠存在。 + + Fractures + Переломы + 骨折 + + + Limp fractures... (todo) + Хромота при переломах... + 骨折時は引きずって歩くようにします・・・ (TODO) + + + Splints fully heal fractures + Шины полностью лечат перелом + 添え木で骨折完治 + + + Splints heal (but cannot sprint) + Шины вылечивают, но не дают бегать + 添え木で治療しますが、走れません Remote Controlled AI @@ -209,21 +149,6 @@ 医疗系统将同时对玩家与AI发生作用 醫療系統將同時對玩家與AI發生作用 - - Basic Medical Settings [ACE] - Standard Sanitätseinstellungen [ACE] - Podstawowe ustawienia medyczne - Ajustes médicos básicos [ACE] - Paramètres des soins basiques [ACE] - Impostazioni Mediche Di Base [ACE] - Základní zdravotnické nastavení [ACE] - Ajustes médicos básicos [ACE] - Настройки базовой медицины [ACE] - ベーシック医療設定 [ACE] - 기본 의료 설정 [ACE] - 基本医疗设定 [ACE] - 基本醫療設定 [ACE] - Enabled for Включено для @@ -320,21 +245,6 @@ 设定人员是否会因为载具冲撞别的物件而产生伤害? 設定人員是否會因為載具衝撞別的物件而產生傷害? - - Where can the Epinephrine be used? (Basic Medical) - Wo kann Epiniphrin verwendet werden? (Standard Sanitätseinstellungen) - Configura donde puede usarse Epinefrina (Solo sistema médico básico) - Gdzie można korzystać z adrenaliny? (Podstawowy system medyczny) - Où peut être utilisé l'épinéphrine ? (Médical basique) - Dove si può usare l'epinefrina? (Sistema medico di base) - Kde může být použit adrenalin? (Pouze základní zdravotní systém) - Onde pode-se usar a Epinefrina? (Somente sistema médico básico) - Где может использоваться адреналин? (Базовая медицина) - どこでもアドレナリンを使えるようにしますか? (ベーシック医療のみ) - 어디에서 에피네프린을 사용할 수 있습니까? (기본 의료) - 在哪里可以使用肾上腺素? (基本医疗) - 在哪裡可以使用腎上腺素? (基本醫療) - Heal hitpoints Heile Trefferpunkte @@ -440,20 +350,10 @@ 设定当距离超过%1将不能使用治疗动作 設定當距離超過%1將不能使用治療動作 - - Unconscious Wake Up Chance - 気絶から覚醒する可能性 - Шанс очнуться при потере сознания - - - Probablity that a unit with stable vitals will wake up from unconscious [Checked every 15 sec] - 安定状態にある人が覚醒する確率です。(15 秒毎に確認) - Вероятность, что стабилизированный юнит очнется от потери сознания [Проверяется каждые 15 сек] - Open lid Deckel aufklappen - フタをあける + フタを開ける Apri lid 打開蓋子 打开盖子 @@ -464,7 +364,7 @@ Close lid Deckel zuklappen - フタをしめる + フタを閉める Chiudi lid 關閉蓋子 关闭盖子 @@ -472,37 +372,5 @@ Zamknij pokrywę Закрыть крышку - - Limping - Хромота - - - Limp when unit has leg wounds...(todo) - Хромота, когда юнит имеет ранения ног... - - - Limp on open wounds - Хромота при открытых ранах - - - Limp on open or bandaged wounds - Хромота при открытых или забинтованых ранах - - - Fractures - Переломы - - - Limp fractures... (todo) - Хромота при переломах... - - - Splints fully heal fractures - Шины полностью лечат перелом - - - Splints heal (but cannot sprint) - Шины вылечивают, но не дают бегать - diff --git a/addons/medical_ai/StateMachine.hpp b/addons/medical_ai/StateMachine.hpp deleted file mode 100644 index 0c428e4c65..0000000000 --- a/addons/medical_ai/StateMachine.hpp +++ /dev/null @@ -1,86 +0,0 @@ -class GVAR(stateMachine) { - list = QUOTE(call EFUNC(common,getLocalUnits)); - skipNull = 1; - - class Initial { - class Injured { - targetState = "Injured"; - condition = QFUNC(isInjured); - }; - class HealUnit { - targetState = "HealUnit"; - condition = QUOTE((call FUNC(isSafe)) && {call FUNC(wasRequested)}); - }; - }; - - class Injured { - #ifdef DEBUG_MODE_FULL - onState = "systemChat format [""%1 is injured"", _this]"; - #endif - - class InSafety { - targetState = "Safe"; - condition = QFUNC(isSafe); - }; - }; - - class Safe { - #ifdef DEBUG_MODE_FULL - onState = "systemChat format [""%1 is injured, but safe"", _this]"; - #endif - - class RequestMedic { - targetState = "HealSelf"; - condition = QFUNC(canRequestMedic); - onTransition = QFUNC(requestMedic); - }; - class HealSelf { - targetState = "HealSelf"; - condition = "true"; - }; - }; - - class HealSelf { - onState = QFUNC(healSelf); - onStateLeaving = QUOTE(_this setVariable [ARR_2(QUOTE(QGVAR(treatmentOverAt)),nil)]); - - class Initial { - // Go back to initial state when done healing - targetState = "Initial"; - condition = QUOTE( \ - !(call FUNC(isInjured)) \ - && {_this getVariable [ARR_2(QUOTE(QGVAR(treatmentOverAt)),CBA_missionTime)] <= CBA_missionTime} \ - ); - }; - class Injured { - // Stop treating when it's no more safe - targetState = "Injured"; - condition = QUOTE( \ - !(call FUNC(isSafe)) \ - && {_this getVariable [ARR_2(QUOTE(QGVAR(treatmentOverAt)),CBA_missionTime)] <= CBA_missionTime} \ - ); - }; - }; - - class HealUnit { - onState = QFUNC(healUnit); - onStateLeaving = QUOTE(_this setVariable [ARR_2(QUOTE(QGVAR(treatmentOverAt)),nil)]); - - class Initial { - // Go back to initial state when done healing or it's no more safe to treat - targetState = "Initial"; - condition = QUOTE( \ - !((call FUNC(wasRequested)) && {call FUNC(isSafe)}) \ - && {_this getVariable [ARR_2(QUOTE(QGVAR(treatmentOverAt)),CBA_missionTime)] <= CBA_missionTime} \ - ); - }; - class Injured { - // Treating yourself has priority - targetState = "Injured"; - condition = QUOTE( \ - (call FUNC(isInjured)) \ - && {_this getVariable [ARR_2(QUOTE(QGVAR(treatmentOverAt)),CBA_missionTime)] <= CBA_missionTime} \ - ); - }; - }; -}; diff --git a/addons/medical_ai/XEH_PREP.hpp b/addons/medical_ai/XEH_PREP.hpp index f55636612a..9300f0cbb3 100644 --- a/addons/medical_ai/XEH_PREP.hpp +++ b/addons/medical_ai/XEH_PREP.hpp @@ -1,4 +1,5 @@ PREP(canRequestMedic); +PREP(healingLogic); PREP(healSelf); PREP(healUnit); PREP(isInjured); diff --git a/addons/medical_ai/XEH_postInit.sqf b/addons/medical_ai/XEH_postInit.sqf index e3a902d27a..d8676e9695 100644 --- a/addons/medical_ai/XEH_postInit.sqf +++ b/addons/medical_ai/XEH_postInit.sqf @@ -1,35 +1,14 @@ #include "script_component.hpp" -/*["ace_settingsInitialized", { +["ace_settingsInitialized", { TRACE_1("settingsInitialized", GVAR(enabledFor)); if (GVAR(enabledFor) == 0) exitWith {}; // 0: disabled if ((GVAR(enabledFor) == 1) && {!isServer} && {hasInterface}) exitWith {}; // 1: Don't Run on non-hc Clients - // Only run for AI that does not have to deal with advanced medical - if (EGVAR(medical,enableFor) == 1 || {hasInterface}) exitWith {}; - ["ace_firedNonPlayer", { _unit setVariable [QGVAR(lastFired), CBA_missionTime]; }] call CBA_fnc_addEventHandler; - if (hasInterface) then { - ["ace_unconscious", { - params ["_unit", "_unconscious"]; - if (!_unconscious || {_unit != ACE_player}) exitWith {}; + #include "stateMachine.sqf" +}] call CBA_fnc_addEventHandler; - private _medic = objNull; - { - if ((!isPlayer _x) && {[_x] call EFUNC(medical_treatment,isMedic)}) exitWith { - _medic = _x; - }; - } forEach (units _unit); - if (isNull _medic) exitWith {}; - - private _healQueue = _medic getVariable [QGVAR(healQueue), []]; - _healQueue pushBack _unit; - _medic setVariable [QGVAR(healQueue), _healQueue]; - }] call CBA_fnc_addEventHandler; - }; - - GVAR(statemachine) = [configFile >> "ACE_Medical_AI_StateMachine"] call CBA_statemachine_fnc_createFromConfig; -}] call CBA_fnc_addEventHandler;*/ diff --git a/addons/medical_ai/config.cpp b/addons/medical_ai/config.cpp index e9df7730c4..c42fc98f95 100644 --- a/addons/medical_ai/config.cpp +++ b/addons/medical_ai/config.cpp @@ -16,4 +16,3 @@ class CfgPatches { #include "ACE_Settings.hpp" #include "CfgEventHandlers.hpp" -#include "StateMachine.hpp" diff --git a/addons/medical_ai/functions/fnc_canRequestMedic.sqf b/addons/medical_ai/functions/fnc_canRequestMedic.sqf index 8865819d6a..c2a29c1c9f 100644 --- a/addons/medical_ai/functions/fnc_canRequestMedic.sqf +++ b/addons/medical_ai/functions/fnc_canRequestMedic.sqf @@ -10,7 +10,7 @@ * Can request medic * * Example: - * call ACE_medical_ai_fnc_canRequestMedic + * player call ACE_medical_ai_fnc_canRequestMedic * * Public: No */ @@ -21,10 +21,14 @@ if ([_this] call EFUNC(medical_treatment,isMedic) || {vehicle _this != _this}) exitWith {false}; +// Search for a medic, prioritize unitReady +private _medic = objNull; { - if ([_x] call EFUNC(medical_treatment,isMedic) && {!([_x] call EFUNC(common,isPlayer))}) exitWith { - _this setVariable [QGVAR(assignedMedic), _x]; - true - }; - false + if ([_x] call EFUNC(medical_treatment,isMedic) && {!([_x] call EFUNC(common,isPlayer))} && { + _medic = _x; + (unitReady _medic) + }) exitWith {}; } forEach (units _this); + +_this setVariable [QGVAR(assignedMedic), _medic]; +!isNull _medic diff --git a/addons/medical_ai/functions/fnc_healSelf.sqf b/addons/medical_ai/functions/fnc_healSelf.sqf index c03dccdad8..524625f3c3 100644 --- a/addons/medical_ai/functions/fnc_healSelf.sqf +++ b/addons/medical_ai/functions/fnc_healSelf.sqf @@ -18,41 +18,8 @@ // Player will have to do this manually of course if ([_this] call EFUNC(common,isPlayer)) exitWith {}; // Can't heal self when unconscious -if IS_UNCONSCIOUS(_this) exitWith {}; -// Check if we're still treating -if ((_this getVariable [QGVAR(treatmentOverAt), CBA_missionTime]) > CBA_missionTime) exitWith {}; - -private _needsBandaging = GET_BLOOD_LOSS(_this) > 0; -private _needsMorphine = GET_PAIN(_this) > 0.2; - -switch (true) do { - case _needsBandaging: { - // Select first wound and bandage it - private _openWounds = _this getVariable [QEGVAR(medical,openWounds), []]; - private _partIndex = { - _x params ["", "", "_index", "_amount", "_percentage"]; - if (_amount * _percentage > 0) exitWith { - _index - }; - } forEach _openWounds; - private _selection = ALL_BODY_PARTS select _partIndex; - [_this, "BasicBandage", _selection] call EFUNC(medical_treatment,treatmentBandageLocal); - - #ifdef DEBUG_MODE_FULL - systemChat format ["%1 is bandaging selection %2", _this, _selection]; - #endif - - // Play animation - [_this, true, true] call FUNC(playTreatmentAnim); - _this setVariable [QGVAR(treatmentOverAt), CBA_missionTime + 5]; - }; - case _needsMorphine: { - [_this, "Morphine", 2] call EFUNC(medical_treatment,treatmentMedicationLocal); - [_this, false, true] call FUNC(playTreatmentAnim); - _this setVariable [QGVAR(treatmentOverAt), CBA_missionTime + 2]; - - #ifdef DEBUG_MODE_FULL - systemChat format ["%1 is giving himself morphine", _this]; - #endif - }; +if IS_UNCONSCIOUS(_this) exitWith { + _this setVariable [QGVAR(currentTreatment), nil]; }; + +[_this, _this] call FUNC(healingLogic); diff --git a/addons/medical_ai/functions/fnc_healUnit.sqf b/addons/medical_ai/functions/fnc_healUnit.sqf index 003c85a4b5..158de90f36 100644 --- a/addons/medical_ai/functions/fnc_healUnit.sqf +++ b/addons/medical_ai/functions/fnc_healUnit.sqf @@ -14,11 +14,12 @@ * * Public: No */ - +// Player will have to do this manually of course +if ([_this] call EFUNC(common,isPlayer)) exitWith {}; // Can't heal other units when unconscious -if IS_UNCONSCIOUS(_this) exitWith {}; -// Check if we're still treating -if ((_this getVariable [QGVAR(treatmentOverAt), CBA_missionTime]) > CBA_missionTime) exitWith {}; +if IS_UNCONSCIOUS(_this) exitWith { + _this setVariable [QGVAR(currentTreatment), nil]; +}; // Find next unit to treat private _healQueue = _this getVariable [QGVAR(healQueue), []]; @@ -26,74 +27,34 @@ private _target = _healQueue select 0; // If unit died or was healed, be lazy and wait for the next tick if (isNull _target || {!alive _target} || {!(_target call FUNC(isInjured))}) exitWith { + _this forceSpeed -1; _target forceSpeed -1; _healQueue deleteAt 0; - _this getVariable [QGVAR(healQueue), _healQueue]; - _this forceSpeed -1; + _this setVariable [QGVAR(healQueue), _healQueue]; // return to formation instead of going where the injured unit was if it healed itself in the mean time _this doFollow leader _this; - _this setVariable [QGVAR(movingToInjured), false]; + _this setVariable [QGVAR(nextMoveOrder), nil]; + _this setVariable [QGVAR(currentTreatment), nil]; #ifdef DEBUG_MODE_FULL - systemChat format ["%1 finished healing %2", _this, _target]; + systemChat format ["%1 finished healing %2", _this, _target]; #endif }; // Move to target... -if (_this distance _target > 2) exitWith { - if !(_this getVariable [QGVAR(movingToInjured), false]) then { - _this setVariable [QGVAR(movingToInjured), true]; +if (_this distance _target > 2.5) exitWith { + _this setVariable [QGVAR(currentTreatment), nil]; + if (CBA_missionTime >= (_this getVariable [QGVAR(nextMoveOrder), CBA_missionTime])) then { + _this setVariable [QGVAR(nextMoveOrder), CBA_missionTime + 10]; _this doMove getPosATL _target; + #ifdef DEBUG_MODE_FULL + systemChat format ["%1 moving to %2", _this, _target]; + #endif }; }; -_this setVariable [QGVAR(movingToInjured), false]; // ...and make sure medic and target don't move _this forceSpeed 0; _target forceSpeed 0; -private _needsBandaging = GET_BLOOD_LOSS(_target) > 0; -private _needsMorphine = GET_PAIN(_target) > 0.2; -private _needsEpinephrine = IS_UNCONSCIOUS(_target); - -switch (true) do { - case _needsBandaging: { - // Select first wound and bandage it - private _openWounds = _target getVariable [QEGVAR(medical,openWounds), []]; - private _partIndex = { - _x params ["", "", "_index", "_amount", "_percentage"]; - if (_amount * _percentage > 0) exitWith { - _index - }; - } forEach _openWounds; - private _selection = ALL_BODY_PARTS select _partIndex; - [_target, "BasicBandage", _selection] call EFUNC(medical_treatment,treatmentBandageLocal); - - #ifdef DEBUG_MODE_FULL - systemChat format ["%1 is bandaging selection %2 on %3", _this, _selection, _target]; - #endif - - // Play animation - [_this, true, false] call FUNC(playTreatmentAnim); - _this setVariable [QGVAR(treatmentOverAt), CBA_missionTime + 5]; - }; - case _needsMorphine: { - [_this, "Morphine", 2] call EFUNC(medical_treatment,treatmentMedicationLocal); - [_this, false, false] call FUNC(playTreatmentAnim); - _this setVariable [QGVAR(treatmentOverAt), CBA_missionTime + 2]; - - #ifdef DEBUG_MODE_FULL - systemChat format ["%1 is giving %2 morphine", _this, _target]; - #endif - }; -//ToDo - Figure out how to connect to new medical - // case _needsEpinephrine: { - // [_this, _target] call EFUNC(medical,treatmentBasic_epipen); - // [_this, false, false] call FUNC(playTreatmentAnim); - // _this setVariable [QGVAR(treatmentOverAt), CBA_missionTime + 2]; - - // #ifdef DEBUG_MODE_FULL - // systemChat format ["%1 is using an epipen on %2", _this, _target]; - // #endif - // }; -}; +[_this, _target] call FUNC(healingLogic); diff --git a/addons/medical_ai/functions/fnc_healingLogic.sqf b/addons/medical_ai/functions/fnc_healingLogic.sqf new file mode 100644 index 0000000000..d2beec1a2d --- /dev/null +++ b/addons/medical_ai/functions/fnc_healingLogic.sqf @@ -0,0 +1,117 @@ +#include "script_component.hpp" +/* + * Author: BaerMitUmlaut, PabstMirror + * Applies healing to target + * + * Arguments: + * 0: Healer + * 1: Target + * + * Return Value: + * Nothing + * + * Example: + * [a, b] call ACE_medical_ai_fnc_healingLogic + * + * Public: No + */ + +params ["_healer", "_target"]; +(_healer getVariable [QGVAR(currentTreatment), [-1]]) params ["_finishTime", "_treatmentTarget", "_treatmentEvent", "_treatmentArgs"]; + +// Treatment in progress, check if finished and apply +if (_finishTime > 0) exitWith { + if (CBA_missionTime >= _finishTime) then { + TRACE_4("treatment finished",_finishTime,_treatmentTarget,_treatmentEvent,_treatmentArgs); + _healer setVariable [QGVAR(currentTreatment), nil]; + if ((_treatmentTarget == _target) && {(_treatmentEvent select [0, 1]) != "#"}) then { + [_treatmentEvent, _treatmentArgs, _target] call CBA_fnc_targetEvent; + #ifdef DEBUG_MODE_FULL + INFO_4("%1->%2: %3 - %4",_healer,_target,_treatmentEvent,_treatmentArgs); + systemChat format ["Applying [%1->%2]: %3", _healer, _treatmentTarget, _treatmentEvent]; + #endif + }; + }; +}; + +private _isMedic = [_healer] call EFUNC(medical_treatment,isMedic); +private _heartRate = GET_HEART_RATE(_target); +private _fractures = GET_FRACTURES(_target); + +private _treatmentEvent = "#none"; +private _treatmentArgs = []; +private _treatmentTime = 6; +switch (true) do { + case (GET_WOUND_BLEEDING(_target) > 0): { + // Select first bleeding wound and bandage it + private _openWounds = GET_OPEN_WOUNDS(_target); + private _selection = "?"; + { + _x params ["", "_index", "_amount", "_percentage"]; + if ((_amount * _percentage) > 0) exitWith { _selection = ALL_BODY_PARTS select _index; }; + } forEach _openWounds; + _treatmentEvent = QEGVAR(medical_treatment,bandageLocal); + _treatmentTime = 5; + _treatmentArgs = [_target, _selection, "FieldDressing"]; + }; + case (_isMedic && {GET_BLOOD_VOLUME(_target) < BLOOD_VOLUME_CLASS_2_HEMORRHAGE}): { + private _bloodBags = _target getVariable [QEGVAR(medical,ivBags), []]; + if ((count _bloodBags) >= 2) exitWith { + _treatmentEvent = "#waitForBlood"; + }; + _treatmentEvent = QEGVAR(medical_treatment,ivBagLocal); + _treatmentTime = 5; + _treatmentArgs = [_target, selectRandom ["leftarm", "rightarm", "leftleg", "rightleg"], "SalineIV"]; + }; + case ((count (_target getVariable [VAR_MEDICATIONS, []])) >= 6): { + _treatmentEvent = "#tooManyMeds"; + }; + case ((_fractures select 4) == 1): { + _treatmentEvent = QEGVAR(medical_treatment,splintLocal); + _treatmentTime = 6; + _treatmentArgs = [_healer, _target, "leftleg"]; + }; + case ((_fractures select 5) == 1): { + _treatmentEvent = QEGVAR(medical_treatment,splintLocal); + _treatmentTime = 6; + _treatmentArgs = [_healer, _target, "rightleg"]; + }; + case (IS_UNCONSCIOUS(_target) || {_heartRate <= 50}): { + if (CBA_missionTime < (_target getVariable [QGVAR(nextEpinephrine), -1])) exitWith { + _treatmentEvent = "#waitForEpinephrineToTakeEffect"; + }; + if (_heartRate > 180) exitWith { + _treatmentEvent = "#waitForSlowerHeart"; + }; + _target setVariable [QGVAR(nextEpinephrine), CBA_missionTime + 10]; + _treatmentEvent = QEGVAR(medical_treatment,medicationLocal); + _treatmentTime = 2.5; + _treatmentArgs = [_target, selectRandom ["leftarm", "rightarm", "leftleg", "rightleg"], "Epinephrine"]; + }; + case ((GET_PAIN_PERCEIVED(_target) > 0.25) || {_heartRate >= 180}): { + if (CBA_missionTime < (_target getVariable [QGVAR(nextMorphine), -1])) exitWith { + _treatmentEvent = "#waitForMorphineToTakeEffect"; + }; + if (_heartRate < 60) exitWith { + _treatmentEvent = "#waitForFasterHeart"; + }; + _target setVariable [QGVAR(nextMorphine), CBA_missionTime + 30]; + _treatmentEvent = QEGVAR(medical_treatment,medicationLocal); + _treatmentTime = 2.5; + _treatmentArgs = [_target, selectRandom ["leftarm", "rightarm", "leftleg", "rightleg"], "Morphine"]; + }; +}; + +_healer setVariable [QGVAR(currentTreatment), [CBA_missionTime + _treatmentTime, _target, _treatmentEvent, _treatmentArgs]]; + +// Play animation +if ((_treatmentEvent select [0,1]) != "#") then { + private _treatmentClassname = _treatmentArgs select 2; + if (_treatmentEvent == QEGVAR(medical_treatment,splintLocal)) then { _treatmentClassname = "Splint" }; + [_healer, _treatmentClassname, (_healer == _target)] call FUNC(playTreatmentAnim); +}; + +#ifdef DEBUG_MODE_FULL +TRACE_4("treatment started",_treatmentTime,_target,_treatmentEvent,_treatmentArgs); +systemChat format ["Treatment [%1->%2]: %3", _healer, _target, _treatmentEvent]; +#endif diff --git a/addons/medical_ai/functions/fnc_isInjured.sqf b/addons/medical_ai/functions/fnc_isInjured.sqf index 3fa5370641..d022770f6d 100644 --- a/addons/medical_ai/functions/fnc_isInjured.sqf +++ b/addons/medical_ai/functions/fnc_isInjured.sqf @@ -17,8 +17,10 @@ if !(alive _this) exitWith {false}; -private _bloodLoss = GET_BLOOD_LOSS(_this); -private _pain = GET_PAIN_PERCEIVED(_this); -private _unconscious = IS_UNCONSCIOUS(_this); - -(_bloodLoss > 0) || {_pain > 0.2} || _unconscious +(GET_WOUND_BLEEDING(_this) > 0) +|| {GET_PAIN_PERCEIVED(_this) > 0.25} +|| {IS_UNCONSCIOUS(_this)} +|| { + private _fractures = GET_FRACTURES(_this); + ((_fractures select 4) == 1) || {(_fractures select 5) == 1} +} diff --git a/addons/medical_ai/functions/fnc_playTreatmentAnim.sqf b/addons/medical_ai/functions/fnc_playTreatmentAnim.sqf index 0a2587cd00..5b594edae2 100644 --- a/addons/medical_ai/functions/fnc_playTreatmentAnim.sqf +++ b/addons/medical_ai/functions/fnc_playTreatmentAnim.sqf @@ -5,7 +5,7 @@ * * Arguments: * 0: Unit - * 1: Is bandage + * 1: Treatment name * 2: Is self treatment * * Return Value: @@ -16,16 +16,11 @@ * * Public: No */ -params ["_unit", "_isBandage", "_isSelfTreatment"]; +params ["_unit", "_actionName", "_isSelfTreatment"]; +TRACE_3("playTreatmentAnim",_unit,_actionName,_isSelfTreatment); if (vehicle _unit != _unit) exitWith {}; -private _animConfig = if (_isBandage) then { - configFile >> "ACE_Medical_Actions" >> "Basic" >> "BasicBandage"; -} else { - configFile >> "ACE_Medical_Actions" >> "Basic" >> "Morphine"; -}; - private _configProperty = "animationMedic"; if (_isSelfTreatment) then { _configProperty = _configProperty + "Self"; @@ -34,7 +29,9 @@ if (stance _unit == "PRONE") then { _configProperty = _configProperty + "Prone"; }; -private _anim = getText (_animConfig >> _configProperty); +private _anim = getText (configFile >> QEGVAR(medical_treatment,Actions) >> _actionName >> _configProperty); +if (_anim == "") exitWith { WARNING_2("no anim [%1, %2]",_actionName,_configProperty); }; + private _wpn = switch (true) do { case ((currentWeapon _unit) == ""): {"non"}; case ((currentWeapon _unit) == (primaryWeapon _unit)): {"rfl"}; diff --git a/addons/medical_ai/initSettings.sqf b/addons/medical_ai/initSettings.sqf index 297961872c..6fada00db5 100644 --- a/addons/medical_ai/initSettings.sqf +++ b/addons/medical_ai/initSettings.sqf @@ -1,12 +1,17 @@ +// CBA Settings [ADDON: ace_medical_ai]: + +private _categoryArray = [ELSTRING(medical,Category), "STR_TEAM_SWITCH_AI"]; + [ - QGVAR(enabledFor), - "LIST", + QGVAR(enabledFor), "LIST", [LLSTRING(enableFor_title), LLSTRING(enableFor_desc)], - LLSTRING(settingCategory), + _categoryArray, [ [0, 1, 2], [LELSTRING(Common,Disabled), LLSTRING(enabledFor_OnlyServerAndHC), LELSTRING(Common,Enabled)], 2 ], - true + true, // isGlobal + {[QGVAR(enabledFor), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_settings_fnc_init; diff --git a/addons/medical_ai/stateMachine.sqf b/addons/medical_ai/stateMachine.sqf new file mode 100644 index 0000000000..48d5a6ef8e --- /dev/null +++ b/addons/medical_ai/stateMachine.sqf @@ -0,0 +1,67 @@ +GVAR(stateMachine) = [{call EFUNC(common,getLocalUnits)}, true] call CBA_statemachine_fnc_create; + +// Add states [statemachine, onState, onStateEntered, onStateLeaving, name] +[GVAR(stateMachine), {}, {}, {}, "Initial"] call CBA_statemachine_fnc_addState; + +[GVAR(stateMachine), { + #ifdef DEBUG_MODE_FULL + systemChat format ["%1 is injured", _this]; + #endif +}, {}, {}, "Injured"] call CBA_statemachine_fnc_addState; + +[GVAR(stateMachine), { + #ifdef DEBUG_MODE_FULL + systemChat format ["%1 is injured and safe", _this]; + #endif +}, {}, {}, "Safe"] call CBA_statemachine_fnc_addState; + +[GVAR(stateMachine), LINKFUNC(healSelf), {}, { + _this setVariable [QGVAR(treatmentOverAt), nil]; +}, "HealSelf"] call CBA_statemachine_fnc_addState; + +[GVAR(stateMachine), LINKFUNC(healUnit), {}, { + _this setVariable [QGVAR(treatmentOverAt), nil]; +}, "HealUnit"] call CBA_statemachine_fnc_addState; + +// Add Transistions [statemachine, originalState, targetState, condition, onTransition, name] +[GVAR(stateMachine), "Initial", "Injured", LINKFUNC(isInjured), {}, "Injured"] call CBA_statemachine_fnc_addTransition; +[GVAR(stateMachine), "Initial", "HealUnit", {(call FUNC(isSafe)) && FUNC(wasRequested)}, {}, "HealUnit"] call CBA_statemachine_fnc_addTransition; + +[GVAR(stateMachine), "Injured", "Safe", LINKFUNC(isSafe), {}, "InSafety"] call CBA_statemachine_fnc_addTransition; + +[GVAR(stateMachine), "Safe", "HealSelf", LINKFUNC(canRequestMedic), LINKFUNC(requestMedic), "RequestMedic"] call CBA_statemachine_fnc_addTransition; +[GVAR(stateMachine), "Safe", "HealSelf", {true}, {}, "HealSelf"] call CBA_statemachine_fnc_addTransition; + + +[GVAR(stateMachine), "HealSelf", "Initial", { // Go back to initial state when done healing + !(call FUNC(isInjured)) && {isNil {_this getVariable QGVAR(currentTreatment)}} +}, { + #ifdef DEBUG_MODE_FULL + systemChat format ["%1 finished healing themself", _this]; + #endif +}, "Initial"] call CBA_statemachine_fnc_addTransition; + +[GVAR(stateMachine), "HealSelf", "Injured", { // Stop treating when it's no more safe + !(call FUNC(isSafe)) && {isNil {_this getVariable QGVAR(currentTreatment)}} +}, { + #ifdef DEBUG_MODE_FULL + systemChat format ["%1 is no longer safe", _this]; + #endif +}, "Injured"] call CBA_statemachine_fnc_addTransition; + + +[GVAR(stateMachine), "HealUnit", "Initial", { // Go back to initial state when done healing or it's no more safe to treat + !((call FUNC(wasRequested)) && FUNC(isSafe)) && {isNil {_this getVariable QGVAR(currentTreatment)}} +}, { + #ifdef DEBUG_MODE_FULL + systemChat format ["%1 finished healing someone", _this]; + #endif +}, "Initial"] call CBA_statemachine_fnc_addTransition; + +[GVAR(stateMachine), "HealUnit", "Injured", { // Treating yourself has priority + (call FUNC(isInjured)) && {isNil {_this getVariable QGVAR(currentTreatment)}} +}, { + #ifdef DEBUG_MODE_FULL + systemChat format ["%1 was injured while healing someone", _this]; + #endif +}, "Injured"] call CBA_statemachine_fnc_addTransition; diff --git a/addons/medical_ai/stringtable.xml b/addons/medical_ai/stringtable.xml index 6315086323..13a57f26f3 100644 --- a/addons/medical_ai/stringtable.xml +++ b/addons/medical_ai/stringtable.xml @@ -1,18 +1,15 @@ - - ACE Medical - AI - ACE 医療 - AI - ACE Медицина - ИИ - Medic AI + Sanitäts KI AI 衛生兵 ИИ Медик AI will respond to injury and unconsciousness + KI reagiert auf Verletzungen und Bewusstlosigkeit AI が負傷者と気絶している人に対して行動するようになります。 ИИ будет реагировать на травмы и потерю сознания diff --git a/addons/medical_blood/CfgEventHandlers.hpp b/addons/medical_blood/CfgEventHandlers.hpp index becf395052..0d3301d6e0 100644 --- a/addons/medical_blood/CfgEventHandlers.hpp +++ b/addons/medical_blood/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_FILE(XEH_preStart)); diff --git a/addons/medical_blood/README.md b/addons/medical_blood/README.md index 29632ffd29..848f8f0308 100644 --- a/addons/medical_blood/README.md +++ b/addons/medical_blood/README.md @@ -1,7 +1,7 @@ ace_medical_blood -=============== +================= -Adds blood visual effect on the ground near a bleeding player. +Creates blood drops on the ground near bleeding units. ## Maintainers diff --git a/addons/medical_blood/XEH_PREP.hpp b/addons/medical_blood/XEH_PREP.hpp index aa7d358388..ebed657cc5 100644 --- a/addons/medical_blood/XEH_PREP.hpp +++ b/addons/medical_blood/XEH_PREP.hpp @@ -1,7 +1,7 @@ - +PREP(cleanupLoop); +PREP(createBlood); PREP(handleWoundReceived); +PREP(init); PREP(isBleeding); PREP(onBleeding); -PREP(createBlood); -PREP(serverCleanupBlood); PREP(spurt); diff --git a/addons/medical_blood/XEH_postInit.sqf b/addons/medical_blood/XEH_postInit.sqf index 11f86fdaca..02201f5506 100644 --- a/addons/medical_blood/XEH_postInit.sqf +++ b/addons/medical_blood/XEH_postInit.sqf @@ -10,33 +10,18 @@ if (isServer) then { [QGVAR(bloodDropCreated), { params ["_bloodDrop"]; - // Add to created queue with format [expireTime, object] - private _index = GVAR(bloodDrops) pushBack [(CBA_missionTime + BLOOD_OBJECT_LIFETIME), _bloodDrop]; - if (count GVAR(bloodDrops) >= MAX_BLOOD_OBJECTS) then { + // Add to created queue with format: [expire time, blood object] + private _index = GVAR(bloodDrops) pushBack [CBA_missionTime + GVAR(bloodLifetime), _bloodDrop]; + + if (count GVAR(bloodDrops) >= GVAR(maxBloodObjects)) then { (GVAR(bloodDrops) deleteAt 0) params ["", "_deletedBloodDrop"]; deleteVehicle _deletedBloodDrop; }; - if (_index == 1) then { // Start the waitAndExecute loop - [FUNC(serverCleanupBlood), [], BLOOD_OBJECT_LIFETIME] call CBA_fnc_waitAndExecute; + // Start the cleanup loop + if (_index == 0) then { + [FUNC(cleanupLoop), [], GVAR(bloodLifetime)] call CBA_fnc_waitAndExecute; }; }] call CBA_fnc_addEventHandler; }; - -["ace_settingsInitialized", { - TRACE_1("settingsInitialized", GVAR(enabledFor)); - if (GVAR(enabledFor) == 0) exitWith {}; // 0: disabled - if ((GVAR(enabledFor) == 1) && {!hasInterface}) exitWith {}; // 1: enabledFor_OnlyPlayers - - private _listcode = if (GVAR(enabledFor) == 1) then { - {if (alive ACE_player) then {[ACE_player]} else {[]}} // ace_player is only possible local player - } else { - EFUNC(common,getLocalUnits) // filter all local units - }; - - private _stateMachine = [_listcode, true] call CBA_statemachine_fnc_create; - [_stateMachine, LINKFUNC(onBleeding), {}, {}, "Bleeding"] call CBA_statemachine_fnc_addState; - - [QEGVAR(medical,woundReceived), FUNC(handleWoundReceived)] call CBA_fnc_addEventHandler; -}] call CBA_fnc_addEventHandler; diff --git a/addons/medical_blood/config.cpp b/addons/medical_blood/config.cpp index 5c133b9456..3e5d5227da 100644 --- a/addons/medical_blood/config.cpp +++ b/addons/medical_blood/config.cpp @@ -14,5 +14,5 @@ class CfgPatches { }; }; -#include "ACE_Settings.hpp" #include "CfgEventHandlers.hpp" +#include "ACE_Settings.hpp" diff --git a/addons/medical_blood/functions/fnc_serverCleanupBlood.sqf b/addons/medical_blood/functions/fnc_cleanupLoop.sqf similarity index 55% rename from addons/medical_blood/functions/fnc_serverCleanupBlood.sqf rename to addons/medical_blood/functions/fnc_cleanupLoop.sqf index 5a1762a7a8..e8461b2e31 100644 --- a/addons/medical_blood/functions/fnc_serverCleanupBlood.sqf +++ b/addons/medical_blood/functions/fnc_cleanupLoop.sqf @@ -1,23 +1,26 @@ #include "script_component.hpp" /* * Author: PabstMirror - * Loop that cleans up blood + * Handles cleaning up blood objects that have reached the end of their lifetime. * * Arguments: * None * - * ReturnValue: + * Return Value: * None * + * Example: + * [] call ace_medical_blood_fnc_cleanupLoop + * * Public: No */ - + (GVAR(bloodDrops) deleteAt 0) params ["", "_deletedBloodDrop"]; deleteVehicle _deletedBloodDrop; -// If we cleaned out the array, exit loop +// Exit the loop if we have cleaned out the array if (GVAR(bloodDrops) isEqualTo []) exitWith {}; // Wait until the next blood drop in the queue will expire (GVAR(bloodDrops) select 0) params ["_expireTime"]; -[FUNC(serverCleanupBlood), [], (_expireTime - CBA_missionTime)] call CBA_fnc_waitAndExecute; +[FUNC(cleanupLoop), [], _expireTime - CBA_missionTime] call CBA_fnc_waitAndExecute; diff --git a/addons/medical_blood/functions/fnc_createBlood.sqf b/addons/medical_blood/functions/fnc_createBlood.sqf index 8d3fbc8776..e54247d02e 100644 --- a/addons/medical_blood/functions/fnc_createBlood.sqf +++ b/addons/medical_blood/functions/fnc_createBlood.sqf @@ -1,15 +1,15 @@ #include "script_component.hpp" /* * Author: Glowbal - * Spawn a blood drop. + * Creates a blood object and handles its cleanup. * Available blood drop classes are blooddrop_1 through blooddrop_4. * * Arguments: - * 0: classname of blood drop + * 0: Blood Drop Type * 1: Position * * Return Value: - * Created blood drop + * Blood Drop * * Example: * ["blooddrop_2", getPos player] call ace_medical_blood_fnc_createBlood @@ -17,15 +17,15 @@ * Public: No */ -params ["_type", "_pos"]; -TRACE_2("creating blood",_type,_pos); +params ["_type", "_position"]; +TRACE_2("Creating blood",_type,_position); private _model = GVAR(models) getVariable _type; -private _object = createSimpleObject [_model, [0,0,0]]; -_object setDir random 360; -_object setPos _pos; +private _bloodDrop = createSimpleObject [_model, [0, 0, 0]]; +_bloodDrop setDir random 360; +_bloodDrop setPos _position; -[QGVAR(bloodDropCreated), [_object]] call CBA_fnc_serverEvent; +[QGVAR(bloodDropCreated), _bloodDrop] call CBA_fnc_serverEvent; -_object +_bloodDrop diff --git a/addons/medical_blood/functions/fnc_handleWoundReceived.sqf b/addons/medical_blood/functions/fnc_handleWoundReceived.sqf index 20abbd4621..7447cac52f 100644 --- a/addons/medical_blood/functions/fnc_handleWoundReceived.sqf +++ b/addons/medical_blood/functions/fnc_handleWoundReceived.sqf @@ -1,13 +1,13 @@ #include "script_component.hpp" /* * Author: Glowbal, commy2 - * Handle wounds received event. + * Handles the wounds received event by triggering any needed blood creation. * * Arguments: - * 0: unit - * 1: bodyPart - * 2: damage - * 3: shooter + * 0: Unit + * 1: Body Part (not used) + * 2: Damage + * 3: Shooter * * Return Value: * None @@ -20,16 +20,16 @@ params ["_unit", "", "_damage", "_shooter"]; -if (GVAR(enabledFor) == 1 && {!isPlayer _unit && {_unit != ACE_player}}) exitWith {}; -if (vehicle _unit != _unit && {!((vehicle _unit) isKindOf "StaticWeapon")}) exitWith {}; // Don't bleed on ground if mounted +// 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 {}; -_damage = _damage min 1; +// Don't bleed on the ground if in a vehicle +if (vehicle _unit != _unit && {!(vehicle _unit isKindOf "StaticWeapon")}) exitWith {}; -if (isNull _shooter) exitWith { // won't be able to calculate the direction properly, so instead we pick something at random - [QGVAR(spurt), [_unit, random 360, _damage]] call CBA_fnc_serverEvent; +private _bulletDir = if (isNull _shooter) then { + random 360 // Cannot calculate the direction properly, pick a random direction +} else { + _shooter getDir _unit // Calculate the bullet direction }; -// Calculate bulletDirection -private _bulletDir = _shooter getDir _unit; - -[QGVAR(spurt), [_unit, _bulletDir, _damage]] call CBA_fnc_serverEvent; +[QGVAR(spurt), [_unit, _bulletDir, _damage min 1]] call CBA_fnc_serverEvent; diff --git a/addons/medical_blood/functions/fnc_init.sqf b/addons/medical_blood/functions/fnc_init.sqf new file mode 100644 index 0000000000..336d964de7 --- /dev/null +++ b/addons/medical_blood/functions/fnc_init.sqf @@ -0,0 +1,65 @@ +#include "script_component.hpp" +/* + * Author: mharis001 + * Initializes the medical blood system based on the given mode. + * Should only be called from the CBA setting changed script. + * + * Arguments: + * 0: Mode + * + * Return Value: + * None + * + * Example: + * [2] call ace_medical_blood_fnc_init + * + * Public: No + */ + +params ["_mode"]; + +// Exit if setting is refreshed to the same value +if (!isNil QGVAR(currentSetup) && {_mode == GVAR(currentSetup)}) exitWith { + TRACE_2("Setting refreshed to current setup",GVAR(currentSetup),_mode); +}; + +// Track this new configuration that will be set up +GVAR(currentSetup) = _mode; + +// Delete current state machine if it exists +if (!isNil QGVAR(stateMachine)) then { + GVAR(stateMachine) call CBA_statemachine_fnc_delete; + GVAR(stateMachine) = nil; +}; + +// Remove wound received if it was previously added +if (!isNil QGVAR(woundReceivedEH)) then { + [QEGVAR(medical,woundReceived), GVAR(woundReceivedEH)] call CBA_fnc_removeEventHandler; + GVAR(woundReceivedEH) = nil; +}; + +// Don't need to set up anything if blood is disabled or players only on a non-player machine +if (_mode == BLOOD_DISABLED || {_mode == BLOOD_ONLY_PLAYERS && {!hasInterface}}) exitWith { + TRACE_1("Mode does not require any setup",_mode); +}; + +private _listCode = if (_mode == BLOOD_ONLY_PLAYERS) then { + // ACE_player is the only possible local player + { + if (alive ACE_player) then { + [ACE_player] + } else { + [] + }; + } +} else { + // Filter all local units + EFUNC(common,getLocalUnits) +}; + +GVAR(stateMachine) = [_listCode, true] call CBA_statemachine_fnc_create; +[GVAR(stateMachine), LINKFUNC(onBleeding), {}, {}, "Bleeding"] call CBA_statemachine_fnc_addState; + +GVAR(woundReceivedEH) = [QEGVAR(medical,woundReceived), FUNC(handleWoundReceived)] call CBA_fnc_addEventHandler; + +TRACE_3("Set up state machine and wounds event",_mode,GVAR(stateMachine),GVAR(woundReceivedEH)); diff --git a/addons/medical_blood/functions/fnc_isBleeding.sqf b/addons/medical_blood/functions/fnc_isBleeding.sqf index b063c52ab0..14aecbb55b 100644 --- a/addons/medical_blood/functions/fnc_isBleeding.sqf +++ b/addons/medical_blood/functions/fnc_isBleeding.sqf @@ -1,13 +1,13 @@ #include "script_component.hpp" /* * Author: Glowbal - * Check if is bleeding + * Checks if the given unit is bleeding. Handles both ACE Medical and Vanilla. * * Arguments: - * 0: unit + * 0: Unit * * Return Value: - * is Bleeding + * Is Bleeding * * Example: * [player] call ace_medical_blood_fnc_isBleeding diff --git a/addons/medical_blood/functions/fnc_onBleeding.sqf b/addons/medical_blood/functions/fnc_onBleeding.sqf index 2fe7b34043..8b6bcbb8f6 100644 --- a/addons/medical_blood/functions/fnc_onBleeding.sqf +++ b/addons/medical_blood/functions/fnc_onBleeding.sqf @@ -1,13 +1,14 @@ #include "script_component.hpp" /* * Author: Glowbal - * handle bleeding state (state machine) + * Handles periodically creating blood for a bleeding unit. + * Called from the medical_blood state machine. * * Arguments: - * 0: unit + * 0: Unit * * Return Value: - * is Bleeding + * None * * Example: * [player] call ace_medical_blood_fnc_onBleeding @@ -17,20 +18,20 @@ params ["_unit"]; -if (!([_unit] call FUNC(isBleeding))) exitWith {}; -if (((vehicle _unit) != _unit) && {!((vehicle _unit) isKindOf "StaticWeapon")}) exitWith {}; // Don't bleed on ground if mounted +// Nothing to do if unit is not bleeding +if !(_unit call FUNC(isBleeding)) exitWith {}; + +// Don't bleed on the ground if in a vehicle +if (vehicle _unit != _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; - TRACE_2("",_unit,_bloodLoss); _unit setVariable [QGVAR(nextTime), CBA_missionTime + 8 + random 2 - _bloodLoss]; + TRACE_2("Creating blood drop for bleeding unit",_unit,_bloodLoss); + private _position = getPosASL _unit; - _position = _position vectorAdd [ - random 0.4 - 0.2, - random 0.4 - 0.2, - 0 - ]; + _position = _position vectorAdd [random 0.4 - 0.2, random 0.4 - 0.2, 0]; _position set [2, 0]; private _bloodDrop = ["blooddrop_1", "blooddrop_2", "blooddrop_3", "blooddrop_4"] select floor (_bloodLoss min 3); diff --git a/addons/medical_blood/functions/fnc_spurt.sqf b/addons/medical_blood/functions/fnc_spurt.sqf index 9e3a1bf5e2..fd5c7a9fc0 100644 --- a/addons/medical_blood/functions/fnc_spurt.sqf +++ b/addons/medical_blood/functions/fnc_spurt.sqf @@ -1,18 +1,18 @@ #include "script_component.hpp" /* * Author: Sickboy - * Spurt blood on the ground + * Spurts blood on the ground based on the direction and damage. * * Arguments: - * 0: unit - * 1: direction - * 2: damage + * 0: Unit + * 1: Direction + * 2: Damage * * Return Value: * None * * Example: - * [UNIT, random 360, 1] call ace_medical_blood_fnc_spurt + * [player, random 360, 1] call ace_medical_blood_fnc_spurt * * Public: No */ @@ -21,20 +21,20 @@ #define DISTANCE_BETWEEN_DROPS 0.20 #define OFFSET 0.25 -params ["_unit", "_dir", "_damage"]; +params ["_unit", "_direction", "_damage"]; private _distanceBetweenDrops = DISTANCE_BETWEEN_DROPS * _damage; private _offset = OFFSET + _distanceBetweenDrops; -private _pos = _unit getPos [_offset, _dir]; +private _position = _unit getPos [_offset, _direction]; -["blooddrop_2", _pos, _dir] call FUNC(createBlood); +["blooddrop_2", _position, _direction] call FUNC(createBlood); private _dropAmount = ceil (MAXIMUM_DROPS * _damage); -TRACE_2("spurt blood",_dropAmount,_damage); +TRACE_2("Spurting blood",_dropAmount,_damage); if (_dropAmount > 1) then { for "_i" from 2 to _dropAmount do { - _pos = _pos getPos [_distanceBetweenDrops, _dir]; - ["blooddrop_1", _pos, _dir] call FUNC(createBlood); + _position = _position getPos [_distanceBetweenDrops, _direction]; + ["blooddrop_1", _position, _direction] call FUNC(createBlood); }; }; diff --git a/addons/medical_blood/initSettings.sqf b/addons/medical_blood/initSettings.sqf index 2ba5edccbf..c2c52f93b8 100644 --- a/addons/medical_blood/initSettings.sqf +++ b/addons/medical_blood/initSettings.sqf @@ -1,13 +1,27 @@ -// CBA Settings [ADDON: ace_medical_blood]: - -private _categoryArray = [LELSTRING(medical,Category), LLSTRING(subCategory)]; +[ + QGVAR(enabledFor), + "LIST", + [LSTRING(EnabledFor_DisplayName), LSTRING(EnabledFor_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + [[BLOOD_DISABLED, BLOOD_ONLY_PLAYERS, BLOOD_ENABLED], [ELSTRING(Common,Disabled), LSTRING(OnlyPlayers), ELSTRING(Common,Enabled)], 2], + true, + LINKFUNC(init) +] call CBA_settings_fnc_init; [ - QGVAR(enabledFor), "LIST", - [LSTRING(MedicalBloodSettings_enabledFor_DisplayName), LSTRING(MedicalBloodSettings_enabledFor_Description)], - _categoryArray, - [[0,1,2],[LELSTRING(Common,Disabled),LLSTRING(enabledFor_OnlyPlayers),LELSTRING(Common,Enabled)],2], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(enabledFor), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(maxBloodObjects), + "LIST", + [LSTRING(MaxBloodObjects_DisplayName), LSTRING(MaxBloodObjects_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + [[50, 100, 200, 300, 400, 500, 1000, 2000, 3000, 4000, 5000], [/* settings function will auto create names */], 5], + true +] call CBA_settings_fnc_init; + +[ + QGVAR(bloodLifetime), + "TIME", + [LSTRING(BloodLifetime_DisplayName), LSTRING(BloodLifetime_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + [1, 3600, 900], + true ] call CBA_settings_fnc_init; diff --git a/addons/medical_blood/script_component.hpp b/addons/medical_blood/script_component.hpp index ef72e2fdd5..d2bcbf9599 100644 --- a/addons/medical_blood/script_component.hpp +++ b/addons/medical_blood/script_component.hpp @@ -2,7 +2,7 @@ #define COMPONENT_BEAUTIFIED Medical Blood #include "\z\ace\addons\main\script_mod.hpp" -// #define DEBUG_ENABLED_MEDICAL_BLOOD +// #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS @@ -17,5 +17,6 @@ #include "\z\ace\addons\medical_engine\script_macros_medical.hpp" #include "\z\ace\addons\main\script_macros.hpp" -#define MAX_BLOOD_OBJECTS 500 -#define BLOOD_OBJECT_LIFETIME 900 +#define BLOOD_DISABLED 0 +#define BLOOD_ONLY_PLAYERS 1 +#define BLOOD_ENABLED 2 diff --git a/addons/medical_blood/stringtable.xml b/addons/medical_blood/stringtable.xml index 7e776f90f0..1186a01ee6 100644 --- a/addons/medical_blood/stringtable.xml +++ b/addons/medical_blood/stringtable.xml @@ -1,24 +1,20 @@ - - - Bleeding Effect - 出血中の効果 - Эффекты кровотечения + + + Blood + Sang + Sangre + Sangue + Krew + Кровь + Blut + Krev + Sangue + 혈흔 + 血痕 - - Only Players - プレイヤーのみ - Nur Spieler - 오직 플레이어만 - Tylko gracze - Joueurs seulement - Solo Giocatori - 只有玩家 - 只有玩家 - Только игроки - - + Enable Blood Drops 血痕を有効化 Aktiviere Blutspritzer @@ -30,17 +26,37 @@ 開啟血液滴落效果 Разрешить капли крови - - Enable or disable Blood Drops created on bleeding and taking damage - ダメージを受けたり、出血していると出る血痕の有効か無効化 - Aktiviere oder deaktiviere Blutspritzer, die durch Blutungen oder bei Schadensnahme entstehen. - Włącz lub wyłącz pozostawianie śladów krwi na ziemi kiedy postać odnosi obrażenia bądź krwawi - (Dés)active les gouttes de sang lors d'un saignement ou de blessure - Abilita o disabilita la Perdite di Sangue create sanguinando e prendendo danno - 开启后, 会让受伤时伤口有血液滴落的效果 - 開啟後, 會讓受傷時傷口有血液滴落的效果 - 출혈이나 부상을 입었을 때, 떨어지는 혈액을 활성화 하거나 비활성화 합니다. - Включает или отключает капли крови при кровотечении и получении урона + + Enables the creation of blood drops when units are bleeding or take damage. + ユニットが出血かダメージを受けた時に、血痕を残すようにします。 + + + Max Blood Objects + 最大血痕数 + + + Sets the maximum number of blood drop objects which can be spawned, excessive amounts can cause FPS lag. + 生成される血痕オブジェクト数を設定できます。極端に増やすと FPS ラグを引き起こします。 + + + Blood Lifetime + 血痕の寿命 + + + Controls the lifetime of blood drop objects. + 血痕オブジェクトの寿命を決定します。 + + + Only Players + プレイヤーのみ + Nur Spieler + 오직 플레이어만 + Tylko gracze + Joueurs seulement + Solo Giocatori + 只有玩家 + 只有玩家 + Только игроки diff --git a/addons/medical_damage/ACE_Medical_Injuries.hpp b/addons/medical_damage/ACE_Medical_Injuries.hpp index 9cdeb6d6a7..4dfc066993 100644 --- a/addons/medical_damage/ACE_Medical_Injuries.hpp +++ b/addons/medical_damage/ACE_Medical_Injuries.hpp @@ -1,4 +1,4 @@ -// bleeding - maximum possible bleeding rate for a given wound type (0 .. 1) +// bleeding - maximum possible percentage of cardiac output bled for a given wound type (0 .. 1) // pain - maximum possible pain level for a given wound type (0 .. 1) class ACE_Medical_Injuries { @@ -16,7 +16,7 @@ class ACE_Medical_Injuries { // Occur when an entire structure or part of it is forcibly pulled away, such as the loss of a permanent tooth or an ear lobe. Explosions, gunshots, and animal bites may cause avulsions. class Avulsion { causes[] = {"explosive", "vehiclecrash", "collision", "grenade", "shell", "bullet", "backblast", "bite"}; - bleeding = 0.25; + bleeding = 0.1; pain = 1.0; minDamage = 0.01; causeLimping = 1; @@ -24,7 +24,7 @@ class ACE_Medical_Injuries { // Also called bruises, these are the result of a forceful trauma that injures an internal structure without breaking the skin. Blows to the chest, abdomen, or head with a blunt instrument (e.g. a football or a fist) can cause contusions. class Contusion { causes[] = {"bullet", "backblast", "punch", "vehiclecrash", "collision", "falling"}; - bleeding = 0.0; + bleeding = 0; pain = 0.3; minDamage = 0.02; maxDamage = 0.35; @@ -41,7 +41,7 @@ class ACE_Medical_Injuries { // Slicing wounds made with a sharp instrument, leaving even edges. They may be as minimal as a paper cut or as significant as a surgical incision. class Cut { causes[] = {"vehiclecrash", "collision", "grenade", "explosive", "shell", "backblast", "stab", "unknown"}; - bleeding = 0.04; + bleeding = 0.01; pain = 0.1; minDamage = 0.1; }; @@ -56,7 +56,7 @@ class ACE_Medical_Injuries { // Also called velocity wounds, they are caused by an object entering the body at a high speed, typically a bullet or small peices of shrapnel. class VelocityWound { causes[] = {"bullet", "grenade","explosive", "shell", "unknown"}; - bleeding = 0.5; + bleeding = 0.2; pain = 0.9; minDamage = 0.35; causeLimping = 1; diff --git a/addons/medical_damage/functions/fnc_handleIncapacitation.sqf b/addons/medical_damage/functions/fnc_handleIncapacitation.sqf index 1adaf997b8..1a5b2a313b 100644 --- a/addons/medical_damage/functions/fnc_handleIncapacitation.sqf +++ b/addons/medical_damage/functions/fnc_handleIncapacitation.sqf @@ -28,7 +28,7 @@ _bodyPartDamage params ["_headDamage", "_bodyDamage", "_leftArmDamage", "_rightA if (_bodyPartN == 1 && {_damage < PENETRATION_THRESHOLD}) then { _bodyDamage = _bodyDamage - (_amountOf * _damage); }; -} forEach (_unit getVariable [QEGVAR(medical,openWounds), []]); +} forEach GET_OPEN_WOUNDS(_unit); private _damageThreshold = [ EGVAR(medical,AIDamageThreshold), diff --git a/addons/medical_damage/functions/fnc_woundsHandler.sqf b/addons/medical_damage/functions/fnc_woundsHandler.sqf index 41bc97e609..630f387fa5 100644 --- a/addons/medical_damage/functions/fnc_woundsHandler.sqf +++ b/addons/medical_damage/functions/fnc_woundsHandler.sqf @@ -32,7 +32,7 @@ if (isNil {GVAR(allDamageTypesData) getVariable _typeOfDamage} ) then { }; // Administration for open wounds and ids -private _openWounds = _unit getVariable [QEGVAR(medical,openWounds), []]; +private _openWounds = GET_OPEN_WOUNDS(_unit); private _woundID = _unit getVariable [QEGVAR(medical,lastUniqueWoundID), 1]; // Unique wound ids are not used anywhere: ToDo Remove from openWounds array TRACE_4("extension call",_bodyPart,_damage,_typeOfDamage,_woundID); @@ -128,7 +128,7 @@ private _bodyPartVisParams = [_unit, false, false, false, false]; // params arra }; } forEach _woundsCreated; -_unit setVariable [QEGVAR(medical,openWounds), _openWounds, true]; +_unit setVariable [VAR_OPEN_WOUNDS, _openWounds, true]; _unit setVariable [QEGVAR(medical,bodyPartDamage), _bodyPartDamage, true]; [_unit] call EFUNC(medical_status,updateWoundBloodLoss); @@ -141,4 +141,4 @@ if (_critialDamage || {_painLevel > PAIN_UNCONSCIOUS}) then { [_unit] call FUNC(handleIncapacitation); }; -TRACE_5("exit",_unit,_painLevel,GET_PAIN(_unit),_unit getVariable QEGVAR(medical,openWounds),_woundsCreated); +TRACE_5("exit",_unit,_painLevel,GET_PAIN(_unit),GET_OPEN_WOUNDS(_unit),_woundsCreated); diff --git a/addons/medical_damage/functions/fnc_woundsHandlerSQF.sqf b/addons/medical_damage/functions/fnc_woundsHandlerSQF.sqf index 4a05b75e2c..f7ec2dd540 100644 --- a/addons/medical_damage/functions/fnc_woundsHandlerSQF.sqf +++ b/addons/medical_damage/functions/fnc_woundsHandlerSQF.sqf @@ -65,7 +65,7 @@ private _allPossibleInjuries = []; if (_highestPossibleSpot < 0) exitWith { TRACE_2("no wounds possible",_damage,_highestPossibleSpot); }; // Administration for open wounds and ids -private _openWounds = _unit getVariable [QEGVAR(medical,openWounds), []]; +private _openWounds = GET_OPEN_WOUNDS(_unit); private _updateDamageEffects = false; private _painLevel = 0; @@ -75,11 +75,11 @@ private _bodyPartVisParams = [_unit, false, false, false, false]; // params arra { _x params ["_thresholdMinDam", "_thresholdWoundCount"]; - if (_thresholdMinDam <= _damage) exitWith { + if (_damage > _thresholdMinDam) exitWith { private _woundDamage = _damage / (_thresholdWoundCount max 1); // If the damage creates multiple wounds for "_i" from 1 to _thresholdWoundCount do { - // Find the injury we are going to add. Format [ classID, allowdSelections, bleedingRate, injuryPain] - private _oldInjury = if (random 1 >= 0.85) then { + // Find the injury we are going to add. Format [ classID, allowedSelections, bleedingRate, injuryPain] + private _oldInjury = if (random 1 < 0.15) then { _woundTypes select _highestPossibleSpot } else { selectRandom _allPossibleInjuries @@ -93,17 +93,24 @@ private _bodyPartVisParams = [_unit, false, false, false, false]; // params arra _bodyPartVisParams set [[1,2,3,3,4,4] select _bodyPartNToAdd, true]; // Mark the body part index needs updating - // The higher the nastiness likelihood the higher the change to get a painful and bloody wound - private _nastinessLikelihood = linearConversion [0, 20, (_woundDamage / _thresholdWoundCount), 0.5, 30, true]; - private _bleedingModifier = 0.25 + 8 * exp ((random [-4.5, -5, -6]) / _nastinessLikelihood); - private _painModifier = 0.05 + 2 * exp (-2 / _nastinessLikelihood); + // Damage to limbs/head is scaled higher than torso by engine + // Anything above this value is guaranteed worst wound possible + private _worstDamage = [2, 1, 4, 4, 4, 4] select _bodyPartNToAdd; - private _bleeding = _injuryBleedingRate * _bleedingModifier; + // More wounds means more likely to get nasty wound + private _countModifier = 1 + random(_i - 1); + + // Config specifies bleeding and pain for worst possible wound + // Worse wound correlates to higher damage, damage is not capped at 1 + private _bleedModifier = linearConversion [0.1, _worstDamage, _woundDamage * _countModifier, 0.25, 1, true]; + private _painModifier = (_bleedModifier * random [0.7, 1, 1.3]) min 1; // Pain isn't directly scaled to bleeding + + private _bleeding = _injuryBleedingRate * _bleedModifier; private _pain = _injuryPain * _painModifier; _painLevel = _painLevel + _pain; - // wound category (minor [0..0.5], medium[0.5..1.0], large[1.0+]) - private _category = floor linearConversion [0, 1, _bleedingModifier, 0, 2, true]; + // wound category (minor [0.25-0.5], medium [0.5-0.75], large [0.75+]) + private _category = floor linearConversion [0.25, 0.75, _bleedModifier, 0, 2, true]; private _classComplex = 10 * _woundClassIDToAdd + _category; @@ -135,7 +142,6 @@ private _bodyPartVisParams = [_unit, false, false, false, false]; // params arra }; case (_causeFracture && {EGVAR(medical,fractures) > 0} && {_bodyPartNToAdd > 1} && {_woundDamage > FRACTURE_DAMAGE_THRESHOLD}): { TRACE_1("limb fracture",_bodyPartNToAdd); - // todo: play sound? private _fractures = GET_FRACTURES(_unit); _fractures set [_bodyPartNToAdd, 1]; _unit setVariable [VAR_FRACTURES, _fractures, true]; @@ -180,7 +186,7 @@ if (_updateDamageEffects) then { [_unit] call EFUNC(medical_engine,updateDamageEffects); }; -_unit setVariable [QEGVAR(medical,openWounds), _openWounds, true]; +_unit setVariable [VAR_OPEN_WOUNDS, _openWounds, true]; _unit setVariable [QEGVAR(medical,bodyPartDamage), _bodyPartDamage, true]; [_unit] call EFUNC(medical_status,updateWoundBloodLoss); @@ -193,4 +199,4 @@ if (_critialDamage || {_painLevel > PAIN_UNCONSCIOUS}) then { [_unit] call FUNC(handleIncapacitation); }; -TRACE_4("exit",_unit,_painLevel,GET_PAIN(_unit),_unit getVariable QEGVAR(medical,openWounds)); +TRACE_4("exit",_unit,_painLevel,GET_PAIN(_unit),GET_OPEN_WOUNDS(_unit)); diff --git a/addons/medical_damage/initSettings.sqf b/addons/medical_damage/initSettings.sqf index 0982be17d2..25a153739c 100644 --- a/addons/medical_damage/initSettings.sqf +++ b/addons/medical_damage/initSettings.sqf @@ -1,23 +1,17 @@ -// CBA Settings [ADDON: ace_medical_damage]: - -private _categoryArray = [LELSTRING(medical,Category), LLSTRING(subCategory)]; - [ - QEGVAR(medical,playerDamageThreshold), "SLIDER", - [LSTRING(playerDamageThreshold_DisplayName), LSTRING(playerDamageThreshold_Description)], - _categoryArray, - [0,25,1,2], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QEGVAR(medical,playerDamageThreshold), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QEGVAR(medical,playerDamageThreshold), + "SLIDER", + [LSTRING(PlayerDamageThreshold_DisplayName), LSTRING(PlayerDamageThreshold_Description)], + ELSTRING(medical,Category), + [0, 25, 1, 2], + true ] call CBA_settings_fnc_init; [ - QEGVAR(medical,AIDamageThreshold), "SLIDER", + QEGVAR(medical,AIDamageThreshold), + "SLIDER", [LSTRING(AIDamageThreshold_DisplayName), LSTRING(AIDamageThreshold_Description)], - _categoryArray, - [0,25,1,2], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QEGVAR(medical,AIDamageThreshold), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + ELSTRING(medical,Category), + [0, 25, 1, 2], + true ] call CBA_settings_fnc_init; diff --git a/addons/medical_damage/stringtable.xml b/addons/medical_damage/stringtable.xml index a5a4bf1457..dbe8205775 100644 --- a/addons/medical_damage/stringtable.xml +++ b/addons/medical_damage/stringtable.xml @@ -1,77 +1,22 @@ - - - Damage Threshold - 損傷のしきい値 - Порог повреждения - - - Player Damage - Урон игроку - Próg obrażeń graczy - Daño de jugador - Spielerschaden - Poškození hráče - Dano do jogador - Dégats du joueur - Játékos sérülés - Danno Giocatore - プレイヤーへの損傷 - 플레이어 부상 - 玩家伤害 - 玩家傷害 - - - What is the damage a player can take before being killed? - Какой уровень урона необходим, чтобы убить игрока? - Jaki jest próg obrażeń, jakie gracz może otrzymać zanim zostanie zabity? - ¿Cuál es el daño que un jugador puede sufrir antes de morir? - Wie viel Schaden kann ein Spieler erleiden, bevor er getötet wird? - Jaké poškození může hráč dostat než bude zabit? - Qal é o dano que um jogador pode sofrer antes de morrer? - Quels dégâts peut subir un joueur avant d'être tué - Mennyi sérülést szenvedhet el egy játékos, mielőtt meghal? - Quanto è il danno che un giocatore può sostenere prima di essere ucciso? - プレイヤーが死に始める前に損傷を受けるようにしますか? - 얼마정도의 부상을 플레이어가 죽기 전까지 버틸 수 있습니까? - 玩家死亡前所能承受的伤害程度 - 玩家死亡前所能承受的傷害程度 - - - AI Damage - Урон ботам - Próg obrażeń AI - Daño IA - KI-Schaden - Poškození AI - Dano da IA - Dégâts des IA - AI sérülés - Danno AI - AI への損傷 - 인공지능 부상 - AI伤害 - AI傷害 - - - What is the damage an AI can take before being killed? - Какой уровень урона необходим, чтобы убить бота? - Jaki jest próg obrażeń, jakie AI może otrzymać zanim zostanie zabite? - ¿Cuál es el daño que la IA puede sufrir antes de morir? - Wie viel Schaden kann eine KI erleiden, bis sie getötet wird? - Jaké poškození může AI dostat než bude zabito? - Qual é o dano que uma IA pode sofrer antes de morrer? - Quels dégâts peut subir une IA avant d'être tuée - Mennyi sérülést szenvedhet el egy AI, mielőtt meghal? - Quanto è il danno che un'IA può sostenere prima di essere uccisa? - AI が死に始める前に損傷を受けるようにしますか? - 얼마정도의 부상을 인공지능이 죽기 전까지 버틸 수 있습니까? - AI 死亡前所能承受的伤害程度 - AI 死亡前所能承受的傷害程度 - - + + Player Critical Damage Threshold + プレイヤーのクリティカル ダメージしきい値 + + + Sets the amount of damage a player can receive before going unconscious. + プレイヤーが気絶になる前に受けられるダメージ量を決定できます。 + + + AI Critical Damage Threshold + AI のクリティカル ダメージしきい値 + + + Sets the amount of damage an AI unit can receive before going unconscious. + AI が気絶になる前に受けられるダメージ量を決定できます。 + Scrape Kratzer diff --git a/addons/medical_engine/CfgVehicles.hpp b/addons/medical_engine/CfgVehicles.hpp index 3cccea2c3f..58a4b47114 100644 --- a/addons/medical_engine/CfgVehicles.hpp +++ b/addons/medical_engine/CfgVehicles.hpp @@ -63,6 +63,11 @@ class CfgVehicles { ADD_ACE_HITPOINTS(1,1); }; }; + class B_Protagonist_VR_F: B_Soldier_base_F { + class HitPoints { + ADD_ACE_HITPOINTS(1,1); + }; + }; class O_Soldier_VR_F: O_Soldier_base_F { class HitPoints { ADD_ACE_HITPOINTS(1,1); @@ -73,10 +78,7 @@ class CfgVehicles { ADD_ACE_HITPOINTS(1,1); }; }; - - // Civilians - class C_man_1; - class C_Soldier_VR_F: C_man_1 { + class I_Protagonist_VR_F: I_Soldier_base_F { class HitPoints { ADD_ACE_HITPOINTS(1,1); }; @@ -86,6 +88,19 @@ class CfgVehicles { ADD_ACE_HITPOINTS(1,1); }; }; + class C_man_1; + class C_Protagonist_VR_F: C_man_1 { + class HitPoints { + ADD_ACE_HITPOINTS(1,1); + }; + }; + + // Civilians + class C_Soldier_VR_F: C_man_1 { + class HitPoints { + ADD_ACE_HITPOINTS(1,1); + }; + }; // APEX class O_V_Soldier_Viper_F: O_Soldier_base_F { diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index 3ff3065471..d810960f4d 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -82,6 +82,11 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { _allDamages sort false; (_allDamages select 0) params ["_receivedDamage", "", "_woundedHitPoint"]; + if (_damageHead >= HEAD_DAMAGE_THRESHOLD) then { + TRACE_3("reporting fatal head damage instead of max",_damageHead,_receivedDamage,_woundedHitPoint); + _receivedDamage = _damageHead; + _woundedHitPoint = "Head"; + }; // We know it's structural when no specific hitpoint is damaged if (_receivedDamage == 0) then { diff --git a/addons/medical_engine/functions/fnc_updateDamageEffects.sqf b/addons/medical_engine/functions/fnc_updateDamageEffects.sqf index 6fa09effcc..9adfc2e855 100644 --- a/addons/medical_engine/functions/fnc_updateDamageEffects.sqf +++ b/addons/medical_engine/functions/fnc_updateDamageEffects.sqf @@ -46,9 +46,9 @@ if (EGVAR(medical,fractures) > 0) then { }; if (!_isLimping && {EGVAR(medical,limping) > 0}) then { - private _woundsToCheck = _unit getVariable [QEGVAR(medical,openWounds), []]; + private _woundsToCheck = GET_OPEN_WOUNDS(_unit); if (EGVAR(medical,limping) == 2) then { - _woundsToCheck = _woundsToCheck + (_unit getVariable [QEGVAR(medical,bandagedWounds), []]); // do not append + _woundsToCheck = _woundsToCheck + GET_BANDAGED_WOUNDS(_unit); // do not append }; { _x params ["_xClassID", "_xBodyPartN", "_xAmountOf", "", "_xDamage"]; diff --git a/addons/medical_engine/script_component.hpp b/addons/medical_engine/script_component.hpp index dbe6e2a2cb..5166324b1e 100644 --- a/addons/medical_engine/script_component.hpp +++ b/addons/medical_engine/script_component.hpp @@ -1,5 +1,5 @@ #define COMPONENT medical_engine -#define COMPONENT_BEAUTIFIED Medical (Engine) +#define COMPONENT_BEAUTIFIED Medical Engine #include "\z\ace\addons\main\script_mod.hpp" // #define DEBUG_MODE_FULL diff --git a/addons/medical_engine/script_macros_medical.hpp b/addons/medical_engine/script_macros_medical.hpp index a56e357fe1..cffa87d5cf 100644 --- a/addons/medical_engine/script_macros_medical.hpp +++ b/addons/medical_engine/script_macros_medical.hpp @@ -118,38 +118,44 @@ // - Unit Variables ---------------------------------------------------- // These variables get stored in object space and used across components // Defined here for easy consistency with GETVAR/SETVAR (also a list for reference) -#define VAR_BLOOD_PRESS QEGVAR(medical,bloodPressure) -#define VAR_BLOOD_VOL QEGVAR(medical,bloodVolume) -#define VAR_WOUND_BLEEDING QEGVAR(medical,woundBleeding) -#define VAR_CRDC_ARRST QEGVAR(medical,inCardiacArrest) -#define VAR_HEART_RATE QEGVAR(medical,heartRate) -#define VAR_PAIN QEGVAR(medical,pain) -#define VAR_PAIN_SUPP QEGVAR(medical,painSuppress) -#define VAR_PERIPH_RES QEGVAR(medical,peripheralResistance) -#define VAR_UNCON "ACE_isUnconscious" +#define VAR_BLOOD_PRESS QEGVAR(medical,bloodPressure) +#define VAR_BLOOD_VOL QEGVAR(medical,bloodVolume) +#define VAR_WOUND_BLEEDING QEGVAR(medical,woundBleeding) +#define VAR_CRDC_ARRST QEGVAR(medical,inCardiacArrest) +#define VAR_HEART_RATE QEGVAR(medical,heartRate) +#define VAR_PAIN QEGVAR(medical,pain) +#define VAR_PAIN_SUPP QEGVAR(medical,painSuppress) +#define VAR_PERIPH_RES QEGVAR(medical,peripheralResistance) +#define VAR_UNCON "ACE_isUnconscious" +#define VAR_OPEN_WOUNDS QEGVAR(medical,openWounds) +#define VAR_BANDAGED_WOUNDS QEGVAR(medical,bandagedWounds) +#define VAR_STITCHED_WOUNDS QEGVAR(medical,stitchedWounds) // These variables track gradual adjustments (from medication, etc.) -#define VAR_MEDICATIONS QEGVAR(medical,medications) +#define VAR_MEDICATIONS QEGVAR(medical,medications) // These variables track the current state of status values above -#define VAR_HEMORRHAGE QEGVAR(medical,hemorrhage) -#define VAR_IN_PAIN QEGVAR(medical,inPain) -#define VAR_TOURNIQUET QEGVAR(medical,tourniquets) -#define VAR_FRACTURES QEGVAR(medical,fractures) +#define VAR_HEMORRHAGE QEGVAR(medical,hemorrhage) +#define VAR_IN_PAIN QEGVAR(medical,inPain) +#define VAR_TOURNIQUET QEGVAR(medical,tourniquets) +#define VAR_FRACTURES QEGVAR(medical,fractures) // - Unit Functions --------------------------------------------------- // Retrieval macros for common unit values // Defined for easy consistency and speed -#define GET_BLOOD_VOLUME(unit) (unit getVariable [VAR_BLOOD_VOL,DEFAULT_BLOOD_VOLUME]) -#define GET_WOUND_BLEEDING(unit) (unit getVariable [VAR_WOUND_BLEEDING,0]) -#define GET_HEART_RATE(unit) (unit getVariable [VAR_HEART_RATE,DEFAULT_HEART_RATE]) -#define GET_HEMORRHAGE(unit) (unit getVariable [VAR_HEMORRHAGE,0]) -#define GET_PAIN(unit) (unit getVariable [VAR_PAIN,0]) -#define GET_PAIN_SUPPRESS(unit) (unit getVariable [VAR_PAIN_SUPP,0]) +#define GET_BLOOD_VOLUME(unit) (unit getVariable [VAR_BLOOD_VOL, DEFAULT_BLOOD_VOLUME]) +#define GET_WOUND_BLEEDING(unit) (unit getVariable [VAR_WOUND_BLEEDING, 0]) +#define GET_HEART_RATE(unit) (unit getVariable [VAR_HEART_RATE, DEFAULT_HEART_RATE]) +#define GET_HEMORRHAGE(unit) (unit getVariable [VAR_HEMORRHAGE, 0]) +#define GET_PAIN(unit) (unit getVariable [VAR_PAIN, 0]) +#define GET_PAIN_SUPPRESS(unit) (unit getVariable [VAR_PAIN_SUPP, 0]) #define GET_TOURNIQUETS(unit) (unit getVariable [VAR_TOURNIQUET, DEFAULT_TOURNIQUET_VALUES]) #define GET_FRACTURES(unit) (unit getVariable [VAR_FRACTURES, DEFAULT_FRACTURE_VALUES]) -#define IN_CRDC_ARRST(unit) (unit getVariable [VAR_CRDC_ARRST,false]) +#define IN_CRDC_ARRST(unit) (unit getVariable [VAR_CRDC_ARRST, false]) #define IS_BLEEDING(unit) (GET_WOUND_BLEEDING(unit) > 0) -#define IS_IN_PAIN(unit) (unit getVariable [VAR_IN_PAIN,false]) -#define IS_UNCONSCIOUS(unit) (unit getVariable [VAR_UNCON,false]) +#define IS_IN_PAIN(unit) (unit getVariable [VAR_IN_PAIN, false]) +#define IS_UNCONSCIOUS(unit) (unit getVariable [VAR_UNCON, false]) +#define GET_OPEN_WOUNDS(unit) (unit getVariable [VAR_OPEN_WOUNDS, []]) +#define GET_BANDAGED_WOUNDS(unit) (unit getVariable [VAR_BANDAGED_WOUNDS, []]) +#define GET_STITCHED_WOUNDS(unit) (unit getVariable [VAR_STITCHED_WOUNDS, []]) // The following function calls are defined here just for consistency #define GET_BLOOD_LOSS(unit) ([unit] call EFUNC(medical_status,getBloodLoss)) diff --git a/addons/medical_feedback/ACE_Settings.hpp b/addons/medical_feedback/ACE_Settings.hpp index 63266003e2..a42a2d0e59 100644 --- a/addons/medical_feedback/ACE_Settings.hpp +++ b/addons/medical_feedback/ACE_Settings.hpp @@ -1,4 +1,5 @@ class ACE_Settings { + /* // Not currently used anywhere class GVAR(enableScreams) { category = ECSTRING(medical,Category_Medical); @@ -7,4 +8,5 @@ class ACE_Settings { typeName = "BOOL"; value = 1; }; + */ }; diff --git a/addons/medical_feedback/CfgSounds.hpp b/addons/medical_feedback/CfgSounds.hpp index 077c32ba5e..be641ef27f 100644 --- a/addons/medical_feedback/CfgSounds.hpp +++ b/addons/medical_feedback/CfgSounds.hpp @@ -34,4 +34,24 @@ class CfgSounds { sound[] = {QPATHTOF(sounds\slow_2.wav), "db+1", 1}; titles[] = {}; }; + class ACE_fracture_1 { + name = "ACE_fracture_1"; + sound[] = {QPATHTOF(sounds\fracture_1.wav), "db+1", 1}; + titles[] = {}; + }; + class ACE_fracture_2 { + name = "ACE_fracture_2"; + sound[] = {QPATHTOF(sounds\fracture_2.wav), "db+1", 1}; + titles[] = {}; + }; + class ACE_fracture_3 { + name = "ACE_fracture_3"; + sound[] = {QPATHTOF(sounds\fracture_3.wav), "db+1", 1}; + titles[] = {}; + }; + class ACE_fracture_4 { + name = "ACE_fracture_4"; + sound[] = {QPATHTOF(sounds\fracture_4.wav), "db+1", 1}; + titles[] = {}; + }; }; diff --git a/addons/medical_feedback/XEH_postInit.sqf b/addons/medical_feedback/XEH_postInit.sqf index ece7297f4d..45054daccc 100644 --- a/addons/medical_feedback/XEH_postInit.sqf +++ b/addons/medical_feedback/XEH_postInit.sqf @@ -10,6 +10,14 @@ [_unit, "moan", PAIN_TO_MOAN(_painLevel)] call FUNC(playInjuredSound); }] call CBA_fnc_addEventHandler; +[QEGVAR(medical,fracture), { + params ["_unit"]; + + if (_unit == ACE_player) then { + playSound SND_FRACTURE; + }; +}] call CBA_fnc_addEventHandler; + if (!hasInterface) exitWith {}; GVAR(nextFadeIn) = 0; diff --git a/addons/medical_feedback/functions/fnc_initEffects.sqf b/addons/medical_feedback/functions/fnc_initEffects.sqf index 66099d5806..504b77f2fc 100644 --- a/addons/medical_feedback/functions/fnc_initEffects.sqf +++ b/addons/medical_feedback/functions/fnc_initEffects.sqf @@ -39,7 +39,7 @@ if (GVAR(painEffectType) == 0) then { GVAR(ppPain) = [ "ColorCorrections", 13502, - [1, 1, 0, [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] + [1, 1, 0, [1, 1, 1, 0], [1, 1, 1, 1], [0.33, 0.33, 0.33, 0], [0.59, 0.64, 0, 0, 0, 0, 4]] ] call _fnc_createEffect; } else { GVAR(ppPain) = [ diff --git a/addons/medical_feedback/initSettings.sqf b/addons/medical_feedback/initSettings.sqf index e22a953f76..36c7dafc0c 100644 --- a/addons/medical_feedback/initSettings.sqf +++ b/addons/medical_feedback/initSettings.sqf @@ -1,21 +1,16 @@ -// CBA Settings [ADDON: ace_medical_feedback]: - -private _categoryArray = [LELSTRING(medical,Category), LLSTRING(subCategory)]; - [ QGVAR(painEffectType), "LIST", - [localize LSTRING(painEffectType), "Selects the used pain effect type"], //@todo - _categoryArray, - [ - [0, 1], - [LLSTRING(painEffectType_whiteFlashing), LLSTRING(painEffectType_pulsingBlur)], - 0 - ], + [LSTRING(PainEffectType_DisplayName), LSTRING(PainEffectType_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + [[0, 1], [LSTRING(PainEffectType_WhiteFlashing), LSTRING(PainEffectType_PulsingBlur)], 0], false, { - if (isNil QGVAR(ppPain)) exitWith {TRACE_1("Before Post-Init",_this)}; - TRACE_1("reseting ppEffect type",_this); + if (isNil QGVAR(ppPain)) exitWith { + TRACE_1("painEffectType setting - before postInit",_this); + }; + + TRACE_1("painEffectType setting - resetting effect",_this); [true] call FUNC(initEffects); } ] call CBA_Settings_fnc_init; diff --git a/addons/medical_feedback/script_component.hpp b/addons/medical_feedback/script_component.hpp index e39fa42c8b..dc2c3baf9c 100644 --- a/addons/medical_feedback/script_component.hpp +++ b/addons/medical_feedback/script_component.hpp @@ -34,5 +34,6 @@ #define SND_HEARBEAT_FAST (selectRandom ["ACE_heartbeat_fast_1", "ACE_heartbeat_fast_2", "ACE_heartbeat_fast_3"]) #define SND_HEARBEAT_NORMAL (selectRandom ["ACE_heartbeat_norm_1", "ACE_heartbeat_norm_2"]) #define SND_HEARBEAT_SLOW (selectRandom ["ACE_heartbeat_slow_1", "ACE_heartbeat_slow_2"]) +#define SND_FRACTURE (selectRandom ["ACE_fracture_1", "ACE_fracture_2", "ACE_fracture_3", "ACE_fracture_4"]) #define VOL_UNCONSCIOUS 0.25 diff --git a/addons/medical_feedback/sounds/fracture_1.wav b/addons/medical_feedback/sounds/fracture_1.wav new file mode 100644 index 0000000000..b68a71da55 Binary files /dev/null and b/addons/medical_feedback/sounds/fracture_1.wav differ diff --git a/addons/medical_feedback/sounds/fracture_2.wav b/addons/medical_feedback/sounds/fracture_2.wav new file mode 100644 index 0000000000..2725a8769e Binary files /dev/null and b/addons/medical_feedback/sounds/fracture_2.wav differ diff --git a/addons/medical_feedback/sounds/fracture_3.wav b/addons/medical_feedback/sounds/fracture_3.wav new file mode 100644 index 0000000000..c96126b15c Binary files /dev/null and b/addons/medical_feedback/sounds/fracture_3.wav differ diff --git a/addons/medical_feedback/sounds/fracture_4.wav b/addons/medical_feedback/sounds/fracture_4.wav new file mode 100644 index 0000000000..0ff6a9e008 Binary files /dev/null and b/addons/medical_feedback/sounds/fracture_4.wav differ diff --git a/addons/medical_feedback/stringtable.xml b/addons/medical_feedback/stringtable.xml index c35d3da4db..2774ad6a38 100644 --- a/addons/medical_feedback/stringtable.xml +++ b/addons/medical_feedback/stringtable.xml @@ -1,12 +1,43 @@ + + Feedback + Feedback + フィードバック + Реакция на ранения + + + Pain Effect Type + Schmerzeffekt-Typ + Rodzaj efektu bólu + Визуальный эффект боли + Pain Effect Type + Tipo de efecto de dolor + Type d'effet de douleur + Fájdalom-effekt típusa + Tipo do efeito de dor + Typ bolesti - efekt + 痛み効果の種類 + 고통 효과 종류 + + + Selects the used pain effect type. + 痛みの効果の種類を選択できます。 + + + White Flashing + Weißes blinken + 白く点滅 + Белые вспышки + + + Pulsing Blur + Wiederkehrende Unschärfe + ボケの強弱 + Пульсирующее размытие + - - Feedback - フィードバック - Реакция на ранения - Enable Screams Включить крики @@ -34,35 +65,11 @@ Active les hurlements d'unités blessées Engedélyezi a sérült egységek kiáltásait Abilita Grida da parte delle unità ferite - 負傷したユニットが叫びだします。 + 負傷したユニットを叫ぶようにします。 부상당한 인원이 소리지르는것을 활성화합니다 启用伤者的尖叫声 啟用傷者的尖叫聲 - - Pain Effect Type - Schmerzeffekt-Typ - Rodzaj efektu bólu - Визуальный эффект боли - Pain Effect Type - Tipo de efecto de dolor - Type d'effet de douleur - Fájdalom-effekt típusa - Tipo do efeito de dor - Typ bolesti - efekt - 痛み効果の種類 - 고통 효과 종류 - - - White flashing - 白く点滅 - Белые вспышки - - - Pulsing blur - ボケの強弱 - Пульсирующее размытие - diff --git a/addons/medical_gui/functions/fnc_menuPFH.sqf b/addons/medical_gui/functions/fnc_menuPFH.sqf index 2a12ede13c..c2dc7a277f 100644 --- a/addons/medical_gui/functions/fnc_menuPFH.sqf +++ b/addons/medical_gui/functions/fnc_menuPFH.sqf @@ -19,7 +19,7 @@ if !([ACE_player, GVAR(target), ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith) && {[ACE_player, GVAR(target)] call FUNC(canOpenMenu)}) then { closeDialog 0; // Show hint if distance condition failed - if (ACE_player distance GVAR(target) > GVAR(maxDistance)) then { + if ((ACE_player distance GVAR(target) > GVAR(maxDistance)) && {vehicle ACE_player != vehicle GVAR(target)}) then { [[ELSTRING(medical,DistanceToFar), GVAR(target) call EFUNC(common,getName)], 2] call EFUNC(common,displayTextStructured); }; }; diff --git a/addons/medical_gui/functions/fnc_modifyAction.sqf b/addons/medical_gui/functions/fnc_modifyAction.sqf index 7c197cc102..422c73a475 100644 --- a/addons/medical_gui/functions/fnc_modifyAction.sqf +++ b/addons/medical_gui/functions/fnc_modifyAction.sqf @@ -30,7 +30,7 @@ private _bloodLossOnBodyPart = 0; if (_bodyPartN == _partIndex) then { _bloodLossOnBodyPart = _bloodLossOnBodyPart + (_amountOf * _bleeding); }; -} forEach (_target getvariable [QEGVAR(medical,openWounds), []]); +} forEach GET_OPEN_WOUNDS(_target); private _frBL = 0 max (_bloodLossOnBodyPart / BLOOD_LOSS_RED_THRESHOLD) min 1; private _colorInt = ceil (_frBL * (BLOOD_LOSS_TOTAL_COLORS - 1)); // ceil because any bleeding more than zero shouldn't be white diff --git a/addons/medical_gui/functions/fnc_onMenuClose.sqf b/addons/medical_gui/functions/fnc_onMenuClose.sqf index bc65e975fd..a531eca4e8 100644 --- a/addons/medical_gui/functions/fnc_onMenuClose.sqf +++ b/addons/medical_gui/functions/fnc_onMenuClose.sqf @@ -18,5 +18,6 @@ if (EGVAR(interact_menu,menuBackground) == 1) then {[QGVAR(id), false] call EFUNC(common,blurScreen)}; if (EGVAR(interact_menu,menuBackground) == 2) then {(uiNamespace getVariable [QEGVAR(interact_menu,menuBackground), displayNull]) closeDisplay 0}; +GVAR(pendingReopen) = false; GVAR(menuPFH) call CBA_fnc_removePerFrameHandler; GVAR(menuPFH) = -1; diff --git a/addons/medical_gui/functions/fnc_onMenuOpen.sqf b/addons/medical_gui/functions/fnc_onMenuOpen.sqf index be4707918f..b6c326f590 100644 --- a/addons/medical_gui/functions/fnc_onMenuOpen.sqf +++ b/addons/medical_gui/functions/fnc_onMenuOpen.sqf @@ -42,3 +42,32 @@ if (GVAR(menuPFH) != -1) exitWith { }; GVAR(menuPFH) = [FUNC(menuPFH), 0, []] call CBA_fnc_addPerFrameHandler; + +// Hide categories if they don't have any actions (airway) +private _list = [ + [IDC_TRIAGE, true], + [IDC_EXAMINE, true], + [IDC_BANDAGE, "bandage"], + [IDC_MEDICATION, "medication"], + [IDC_AIRWAY, "airway"], + [IDC_ADVANCED, "advanced"], + [IDC_DRAG, "drag"], + [IDC_TOGGLE, true] +]; +private _countEnabled = { + _x params ["", "_category"]; + if (_category isEqualType "") then { _x set [1, (GVAR(actions) findIf {_category == _x select 1}) > -1]; }; + _x select 1 +} count _list; +private _offsetX = POS_X(1.5) + 0.5 * (POS_X(12) - POS_X(_countEnabled * 1.5)); +{ + _x params ["_idc", "_enabled"]; + private _ctrl = _display displayCtrl _idc; + if (_enabled) then { + _ctrl ctrlSetPositionX _offsetX; + _ctrl ctrlCommit 0; + _offsetX = _offsetX + POS_W(1.5); + } else { + _ctrl ctrlShow false; + }; +} forEach _list; diff --git a/addons/medical_gui/functions/fnc_updateBodyImage.sqf b/addons/medical_gui/functions/fnc_updateBodyImage.sqf index 7f08e9bddf..3841f58d2e 100644 --- a/addons/medical_gui/functions/fnc_updateBodyImage.sqf +++ b/addons/medical_gui/functions/fnc_updateBodyImage.sqf @@ -27,7 +27,7 @@ private _bodyPartBloodLoss = [0, 0, 0, 0, 0, 0]; { _x params ["", "_bodyPartN", "_amountOf", "_bleeding"]; _bodyPartBloodLoss set [_bodyPartN, (_bodyPartBloodLoss select _bodyPartN) + (_bleeding * _amountOf)]; -} forEach (_target getVariable [QEGVAR(medical,openWounds), []]); +} forEach GET_OPEN_WOUNDS(_target); { _x params ["_bodyPartIDC", ["_tourniquetIDC", -1], ["_fractureIDC", -1]]; diff --git a/addons/medical_gui/functions/fnc_updateInjuryList.sqf b/addons/medical_gui/functions/fnc_updateInjuryList.sqf index 736be6eba1..2770dc04ea 100644 --- a/addons/medical_gui/functions/fnc_updateInjuryList.sqf +++ b/addons/medical_gui/functions/fnc_updateInjuryList.sqf @@ -128,21 +128,21 @@ private _fnc_getWoundDescription = { }; }; }; -} forEach (_target getVariable [QEGVAR(medical,openWounds), []]); +} forEach GET_OPEN_WOUNDS(_target); { _x params ["_woundClassID", "_bodyPartN", "_amountOf"]; if (_selectionN == _bodyPartN && {_amountOf > 0}) then { _woundEntries pushBack [format ["[B] %1", call _fnc_getWoundDescription], [0.88, 0.7, 0.65, 1]]; }; -} forEach (_target getVariable [QEGVAR(medical,bandagedWounds), []]); +} forEach GET_BANDAGED_WOUNDS(_target); { _x params ["_woundClassID", "_bodyPartN", "_amountOf"]; if (_selectionN == _bodyPartN && {_amountOf > 0}) then { _woundEntries pushBack [format ["[S] %1", call _fnc_getWoundDescription], [0.7, 0.7, 0.7, 1]]; }; -} forEach (_target getVariable [QEGVAR(medical,stitchedWounds), []]); +} forEach GET_STITCHED_WOUNDS(_target); // Handle no wound entries if (_woundEntries isEqualTo []) then { diff --git a/addons/medical_gui/initSettings.sqf b/addons/medical_gui/initSettings.sqf index 245b3fd5ca..be7dc60fa6 100644 --- a/addons/medical_gui/initSettings.sqf +++ b/addons/medical_gui/initSettings.sqf @@ -40,5 +40,5 @@ [LSTRING(MaxDistance_DisplayName), LSTRING(MaxDistance_Description)], [ELSTRING(medical,Category), LSTRING(SubCategory)], [0, 10, 3, 1], - false + true ] call CBA_settings_fnc_init; diff --git a/addons/medical_gui/stringtable.xml b/addons/medical_gui/stringtable.xml index 41d59dc54b..a6116ecb0e 100644 --- a/addons/medical_gui/stringtable.xml +++ b/addons/medical_gui/stringtable.xml @@ -1,18 +1,19 @@ - - ACE Medical GUI - ACE 医療 GUI - ACE Медицина - Интерфейс + + GUI + GUI Enable Medical Actions + Aktiviere Sanitätsaktionen 医療行為を有効化 Разрешить Медицинские действия Enables medical actions for the Interaction Menu and selects their style. + Aktiviert die Sanitätsaktionen für das Interaktionsmenü und legt das Aussehen fest インタラクション メニューから選択した表示方式で医療行為をできるようになります。 Включает медицинские действия для меню взаимодействия и выбирает их стиль. @@ -50,41 +51,49 @@ Enable Medical Self Actions + Medizinische Selbst-Interaktionen anzeigen 自分への医療行為を有効化 Разрешить Медицинские действия на себе Enables medical actions for the Self Interaction Menu. + Medizinische Interaktionen bei Selbst-Interaktionen anzeigen セルフ インタラクション メニューで医療行為をできるようになります。 Включает медицинские действия для меню взаимодействия с собой. Enable Medical Menu + Aktiviere das Sanitätsmenü 医療メニューを有効化 Разрешить Медицинское меню Enables the use of the Medical Menu through the keybind or interaction menu. + Aktiviere die Nutzung des Sanitätsmenüs durch eine Tastenkombination oder durch das Interaktionsmenü 割り当てられたキーかインタラクション メニューから医療メニューを使えるようになります。 Позволяет использовать Медицинское меню через связку клавиш или меню взаимодействия. Reopen Medical Menu + Sanitätsmenü wieder öffnen 医療メニューの再使用 Открывать меню после лечения Reopen the Medical Menu after successful treatment. + Öffne das Sanitätsmenü nach einer Behandlung 治療が成功した後に、再度医療メニューを開きます。 Открывает Медицинское меню после успешного лечения Maximum Distance + Maximale Entfernung 最大距離 Макс. дистанция Maximum distance from which the Medical Menu can be opened. + Maximale Entfernung, um das Sanitätsmenü zu öffnen. 治療メニューを開いたままにできる最大距離を決定します。 Максимальное расстояние, с которого можно открыть Медицинское меню. @@ -129,7 +138,7 @@ Otevřít zdravotnickou nabídku Apri Menù Medico Ouvir le menu médical - 治療メニューをひらく + 治療メニューを開く 의료 메뉴 열기 开起医疗选单 開起醫療選單 @@ -357,7 +366,7 @@ Arrastar / Carregar Táhnout / Nést Trascina / Trasporta - 引きずる/運ぶ + 引きずる / 担ぐ 끌기 / 들기 拖 / 背 拖 / 背 @@ -800,16 +809,19 @@ Fractured Перелом + 骨折している Splint Applied Наложена шина + 添え木が当てている Lost some blood + Hat etwas Blut verloren いくらか失血している Небольшая кровопотеря @@ -831,11 +843,13 @@ Lost a large amount of blood + Hat eine sehr große Menge Blut verloren かなり酷く大量失血している Огромная кровопотеря Lost a fatal amount of blood + Hat eine kritische Menge an Blut verloren 致命的な程失血している Фатальная кровопотеря diff --git a/addons/medical_gui/ui/splint.paa b/addons/medical_gui/ui/splint.paa index 521809124a..8cd9866d5e 100644 Binary files a/addons/medical_gui/ui/splint.paa and b/addons/medical_gui/ui/splint.paa differ diff --git a/addons/medical_statemachine/ACE_Settings.hpp b/addons/medical_statemachine/ACE_Settings.hpp deleted file mode 100644 index 8b47bd106d..0000000000 --- a/addons/medical_statemachine/ACE_Settings.hpp +++ /dev/null @@ -1,14 +0,0 @@ -class ACE_Settings { - class GVAR(fatalInjuryCondition) { - movedToSQF = 1; - }; - class GVAR(fatalInjuryConditionAI) { - movedToSQF = 1; - }; - class GVAR(unconsciousConditionAI) { - movedToSQF = 1; - }; - class GVAR(cardiacArrestTime) { - movedToSQF = 1; - }; -}; diff --git a/addons/medical_statemachine/Statemachine.hpp b/addons/medical_statemachine/Statemachine.hpp index 12a5a01779..1516c680e2 100644 --- a/addons/medical_statemachine/Statemachine.hpp +++ b/addons/medical_statemachine/Statemachine.hpp @@ -47,7 +47,7 @@ class ACE_Medical_StateMachine { onStateEntered = QUOTE([ARR_2(_this,(true))] call EFUNC(medical_status,setUnconscious)); class DeathAI { targetState = "Dead"; - condition = QUOTE(!isPlayer _this && {GVAR(unconsciousConditionAI)}); + condition = QUOTE(!GVAR(AIUnconsciousness) && {!isPlayer _this}); }; class WakeUp { targetState = "Injured"; @@ -86,6 +86,7 @@ class ACE_Medical_StateMachine { }; }; class CardiacArrest { + onState = QFUNC(handleStateCardiacArrest); onStateEntered = QFUNC(enteredStateCardiacArrest); onStateLeaving = QFUNC(leftStateCardiacArrest); class DeathAI { diff --git a/addons/medical_statemachine/XEH_PREP.hpp b/addons/medical_statemachine/XEH_PREP.hpp index 26595cfb62..8e2725d3da 100644 --- a/addons/medical_statemachine/XEH_PREP.hpp +++ b/addons/medical_statemachine/XEH_PREP.hpp @@ -3,6 +3,7 @@ PREP(conditionExecutionDeath); PREP(enteredStateCardiacArrest); PREP(enteredStateDeath); PREP(enteredStateFatalInjury); +PREP(handleStateCardiacArrest); PREP(handleStateDefault); PREP(handleStateInjured); PREP(handleStateUnconscious); diff --git a/addons/medical_statemachine/XEH_preInit.sqf b/addons/medical_statemachine/XEH_preInit.sqf index 2d8754ad32..d77d8067a8 100644 --- a/addons/medical_statemachine/XEH_preInit.sqf +++ b/addons/medical_statemachine/XEH_preInit.sqf @@ -2,7 +2,9 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; #include "initSettings.sqf" diff --git a/addons/medical_statemachine/config.cpp b/addons/medical_statemachine/config.cpp index a87d797163..23a55f5258 100644 --- a/addons/medical_statemachine/config.cpp +++ b/addons/medical_statemachine/config.cpp @@ -14,6 +14,5 @@ class CfgPatches { }; }; -#include "ACE_Settings.hpp" #include "Statemachine.hpp" #include "CfgEventHandlers.hpp" diff --git a/addons/medical_statemachine/functions/fnc_conditionCardiacArrestTimer.sqf b/addons/medical_statemachine/functions/fnc_conditionCardiacArrestTimer.sqf index df29c592a1..b28459db53 100644 --- a/addons/medical_statemachine/functions/fnc_conditionCardiacArrestTimer.sqf +++ b/addons/medical_statemachine/functions/fnc_conditionCardiacArrestTimer.sqf @@ -17,7 +17,4 @@ params ["_unit"]; -private _startTime = _unit getVariable [QGVAR(cardiacArrestStart), CBA_missionTime]; -private _lifeTime = _unit getVariable [QGVAR(cardiacArrestTime), GVAR(cardiacArrestTime)]; - -(CBA_missionTime - _startTime) > _lifeTime +(_unit getVariable [QGVAR(cardiacArrestTimeLeft), -1]) <= 0 diff --git a/addons/medical_statemachine/functions/fnc_enteredStateCardiacArrest.sqf b/addons/medical_statemachine/functions/fnc_enteredStateCardiacArrest.sqf index f418e38b84..0c5e184029 100644 --- a/addons/medical_statemachine/functions/fnc_enteredStateCardiacArrest.sqf +++ b/addons/medical_statemachine/functions/fnc_enteredStateCardiacArrest.sqf @@ -20,10 +20,12 @@ params ["_unit"]; // 10% possible variance in cardiac arrest time private _time = GVAR(cardiacArrestTime); -_time = _time + random [_time*-0.1, 0, _time*0.1]; +_time = _time + _time * random [-0.1, 0, 0.1]; -_unit setVariable [QGVAR(cardiacArrestTime), _time]; -_unit setVariable [QGVAR(cardiacArrestStart), CBA_missionTime]; +_unit setVariable [QGVAR(cardiacArrestTimeLeft), _time]; +_unit setVariable [QGVAR(cardiacArrestTimeLastUpdate), CBA_missionTime]; + +TRACE_3("enteredStateCardiacArrest",_unit,_time,CBA_missionTime); // Update the unit status to reflect cardiac arrest [_unit, true] call EFUNC(medical_status,setCardiacArrest); diff --git a/addons/medical_statemachine/functions/fnc_handleStateCardiacArrest.sqf b/addons/medical_statemachine/functions/fnc_handleStateCardiacArrest.sqf new file mode 100644 index 0000000000..b9e49adfe3 --- /dev/null +++ b/addons/medical_statemachine/functions/fnc_handleStateCardiacArrest.sqf @@ -0,0 +1,37 @@ +#include "script_component.hpp" +/* + * Author: BaerMitUmlaut + * Handles the unconscious state + * + * Arguments: + * 0: The Unit + * + * Return Value: + * None + * + * Example: + * [player] call ace_medical_statemachine_fnc_handleStateCardiacArrest + * + * Public: No + */ + +params ["_unit"]; + +// If the unit died the loop is finished +if (!alive _unit) exitWith {}; +if (!local _unit) exitWith {}; + +[_unit] call EFUNC(medical_vitals,handleUnitVitals); + +private _timeDiff = CBA_missionTime - (_unit getVariable [QGVAR(cardiacArrestTimeLastUpdate), 0]); +if (_timeDiff >= 1) then { + _timeDiff = _timeDiff min 10; + _unit setVariable [QGVAR(cardiacArrestTimeLastUpdate), CBA_missionTime]; + private _recieveingCPR = alive (_unit getVariable [QEGVAR(medical,CPR_provider), objNull]); + private _timeLeft = _unit getVariable [QGVAR(cardiacArrestTimeLeft), -1]; + TRACE_3("cardiac arrest life tick",_unit,_recieveingCPR,_timeDiff); + if (_recieveingCPR) then { _timeDiff = _timeDiff * 0.5; }; // if being cpr'ed, then time decrease is reduced + _timeLeft = _timeLeft - _timeDiff; // negative values are fine + _unit setVariable [QGVAR(cardiacArrestTimeLeft), _timeLeft]; +}; + diff --git a/addons/medical_statemachine/functions/fnc_handleStateUnconscious.sqf b/addons/medical_statemachine/functions/fnc_handleStateUnconscious.sqf index 7bc147e1be..bd79e2b51b 100644 --- a/addons/medical_statemachine/functions/fnc_handleStateUnconscious.sqf +++ b/addons/medical_statemachine/functions/fnc_handleStateUnconscious.sqf @@ -18,8 +18,7 @@ params ["_unit"]; // If the unit died the loop is finished -if (!alive _unit) exitWith {}; -if (!local _unit) exitWith {}; +if (!alive _unit || {!local _unit}) exitWith {}; [_unit] call EFUNC(medical_vitals,handleUnitVitals); @@ -28,20 +27,29 @@ if (_painLevel > 0) then { [QEGVAR(medical,moan), [_unit, _painLevel]] call CBA_fnc_localEvent; }; -// Handle spontaneous wakeup from unconsciousness +// Handle spontaneous wake up from unconsciousness if (EGVAR(medical,spontaneousWakeUpChance) > 0) then { if (_unit call EFUNC(medical_status,hasStableVitals)) then { - private _lastWakeUpCheck = _unit getVariable [QEGVAR(medical,lastWakeUpCheck), CBA_missionTime]; + private _lastWakeUpCheck = _unit getVariable QEGVAR(medical,lastWakeUpCheck); + + // Handle setting being changed mid-mission and still properly check + // already unconscious units, should handle locality changes as well + if (isNil "_lastWakeUpCheck") exitWith { + _unit setVariable [QEGVAR(medical,lastWakeUpCheck), CBA_missionTime]; + }; + if (CBA_missionTime - _lastWakeUpCheck > SPONTANEOUS_WAKE_UP_INTERVAL) then { TRACE_2("Checking for wake up",_unit,EGVAR(medical,spontaneousWakeUpChance)); _unit setVariable [QEGVAR(medical,lastWakeUpCheck), CBA_missionTime]; - if ((random 1) < EGVAR(medical,spontaneousWakeUpChance)) then { + + if (random 1 <= EGVAR(medical,spontaneousWakeUpChance)) then { TRACE_1("Spontaneous wake up!",_unit); [QEGVAR(medical,WakeUp), _unit] call CBA_fnc_localEvent; }; }; } else { // Unstable vitals, procrastinate the next wakeup check - _unit setVariable [QEGVAR(medical,lastWakeUpCheck), CBA_missionTime]; + private _lastWakeUpCheck = _unit getVariable [QEGVAR(medical,lastWakeUpCheck), 0]; + _unit setVariable [QEGVAR(medical,lastWakeUpCheck), _lastWakeUpCheck max CBA_missionTime]; }; }; diff --git a/addons/medical_statemachine/functions/fnc_leftStateCardiacArrest.sqf b/addons/medical_statemachine/functions/fnc_leftStateCardiacArrest.sqf index 85c469c4a5..5b077be771 100644 --- a/addons/medical_statemachine/functions/fnc_leftStateCardiacArrest.sqf +++ b/addons/medical_statemachine/functions/fnc_leftStateCardiacArrest.sqf @@ -17,11 +17,9 @@ */ params ["_unit"]; +TRACE_1("leftStateCardiacArrest",_unit); -_unit setVariable [QGVAR(cardiacArrestTime), nil]; -_unit setVariable [QEGVAR(medical,cardiacArrestStart), nil]; - -// Temporary fix for vitals loop on cardiac arrest exit -_unit setVariable [QGVAR(lastTimeUpdated), CBA_missionTime]; +_unit setVariable [QGVAR(cardiacArrestTimeLeft), nil]; +_unit setVariable [QGVAR(cardiacArrestTimeLastUpdate), nil]; [_unit, false] call EFUNC(medical_status,setCardiacArrest); diff --git a/addons/medical_statemachine/initSettings.sqf b/addons/medical_statemachine/initSettings.sqf index 34f5b487bb..2dfe27463e 100644 --- a/addons/medical_statemachine/initSettings.sqf +++ b/addons/medical_statemachine/initSettings.sqf @@ -1,43 +1,35 @@ -// CBA Settings [ADDON: ace_medical_statemachine]: - -private _categoryArray = [LELSTRING(medical,Category), LLSTRING(subCategory)]; - [ - QGVAR(fatalInjuryCondition), "LIST", - [LSTRING(fatalInjuryCondition_DisplayName), LSTRING(fatalInjuryCondition_Description)], - _categoryArray, - [[0,1,2],["Always","In Cardiac Arrest","Never"],0], // [values, titles, defaultIndex] //ToDo: Localize - true, // isGlobal - {[QGVAR(fatalInjuryCondition), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(fatalInjuryCondition), + "LIST", + [LSTRING(FatalInjuryCondition_DisplayName), LSTRING(FatalInjuryCondition_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + [[0, 1, 2], [ELSTRING(common,Always), LSTRING(InCardiacArrest), ELSTRING(common,Never)], 0], + true ] call CBA_settings_fnc_init; [ - QGVAR(fatalInjuryConditionAI), "CHECKBOX", - [LSTRING(fatalInjuryConditionAI_DisplayName), LSTRING(fatalInjuryConditionAI_Description)], - _categoryArray, - true, // default value - true, // isGlobal - {[QGVAR(fatalInjuryConditionAI), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(fatalInjuryConditionAI), + "CHECKBOX", + [LSTRING(FatalInjuryConditionAI_DisplayName), LSTRING(FatalInjuryConditionAI_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + true, + true ] call CBA_settings_fnc_init; [ - QGVAR(unconsciousConditionAI), "CHECKBOX", - [LSTRING(unconsciousConditionAI_DisplayName), LSTRING(unconsciousConditionAI_Description)], - _categoryArray, - true, // default value - true, // isGlobal - {[QGVAR(unconsciousConditionAI), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(AIUnconsciousness), + "CHECKBOX", + [LSTRING(AIUnconsciousness_DisplayName), LSTRING(AIUnconsciousness_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + true, + true ] call CBA_settings_fnc_init; [ - QGVAR(cardiacArrestTime), "SLIDER", - [LSTRING(cardiacArrestTime_DisplayName), LSTRING(cardiacArrestTime_Description)], - _categoryArray, - [1,3600,30,0], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(cardiacArrestTime), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QGVAR(cardiacArrestTime), + "TIME", + [LSTRING(CardiacArrestTime_DisplayName), LSTRING(CardiacArrestTime_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + [1, 3600, 30], + true ] call CBA_settings_fnc_init; diff --git a/addons/medical_statemachine/stringtable.xml b/addons/medical_statemachine/stringtable.xml index aec253b0ff..8652e02e77 100644 --- a/addons/medical_statemachine/stringtable.xml +++ b/addons/medical_statemachine/stringtable.xml @@ -1,89 +1,71 @@ - - - States - 状態 - Состояния - - - Fatal Injury Player - 致命傷プレイヤー - Смертельные ранения игрока - - - Defines when Player can receive a fatal injury - プレイヤーが致命傷から蘇生できるかどうか決定します - Определяет, когда игрок может получить смертельное ранение - - - Instant death AI - AI の即死 - Мгновенная смерть ИИ - - - Defines if AI will be able to die instantly - AI が即死できるかどうか決定します - Определяет, сможет ли ИИ мгновенно умереть - - - Forbid unconscious AI - AI の気絶を禁止 - Запретить потерю сознания ИИ - - - Defines if AI will be denied to go unconscious and will die instead - AI が気絶すると、即時に死亡するかどうか決定します - Определяет, потеряет ли ИИ сознание или вместо этого умрет - - - In Cardiac Arrest - 心停止中 - При остановке сердца - - - Cardiac Arrest time (seconds) - 心停止時間 (秒) - Длительность остановки сердца (сек) - - - Defines how long it takes to die from cardiac arrest? - 心停止がどのくらい続けば死亡するようにしますか? - Определяет, сколько времени требуется, чтобы умереть от остановки сердца - - - AI Unconsciousness - Потеря сознания ботами - Nieprzytomność AI - Inconsciencia IA - KI-Bewusstlosigkeit - Bezvědomí AI - Inconsciência da IA - Inconscience des IA - AI eszméletlenség - Incoscienza IA - AI の気絶 - 인공지능 기절 - AI无意识 - AI無意識 - - - Allow AI to go unconscious - Позволить ботам терять сознание - Czy AI może być nieprzytomne od odniesionych obrażeń? - Permita a la IA caer inconsciente - KI kann bewusstlos werden - Umožňuje AI upadnout do bezvědomí - Permite IA ficar inconsciente - Autoriser les IA à tomber inconscients - Engedélyezi az AI eszméletének elvesztését - Permetti alle IA di diventare incoscienti - AI が気絶をするようになります - 인공지능도 기절에 빠지게 합니다 - 允许AI进入无意识状态 - 允許AI進入無意識狀態 - - + + States + Zustände + 状態 + Состояния + + + Fatal Injury Player + Tödliche Spielerverletzungen + 致命傷プレイヤー + Смертельные ранения игрока + + + Controls when a player can receive a fatal injury. + Definiert wann ein Spieler tödliche Verletzungen bekommen kann + プレイヤーが致命傷から蘇生できるかどうか決定します + Определяет, когда игрок может получить смертельное ранение + + + AI Instant Death + Direkter Tod KI + AI の即死 + Мгновенная смерть ИИ + + + Controls if AI units are able to die instantly. + Legt fest, ob eine KI direkt sterben kann + AI が即死できるかどうか決定します + Определяет, сможет ли ИИ мгновенно умереть + + + AI Unconsciousness + Потеря сознания ботами + Nieprzytomność AI + Inconsciencia IA + KI-Bewusstlosigkeit + Bezvědomí AI + Inconsciência da IA + Inconscience des IA + AI eszméletlenség + Incoscienza IA + AI の気絶 + 인공지능 기절 + AI无意识 + AI無意識 + + + Allows AI to go unconscious instead of dying. + AI が即死ではなく気絶へ移行できるかどうか決定します。 + + + Cardiac Arrest Time + Zeit bis zum Herzstillstand + 心停止時間 + Длительность остановки сердца + + + Controls how long it takes to die from cardiac arrest. + どのくらいの時間、心停止すると死亡するかを決定します。 + + + In Cardiac Arrest + Herzstillstand + 心停止中 + При остановке сердца + diff --git a/addons/medical_status/ACE_settings.hpp b/addons/medical_status/ACE_settings.hpp index 11783ac42f..8613092861 100644 --- a/addons/medical_status/ACE_settings.hpp +++ b/addons/medical_status/ACE_settings.hpp @@ -5,7 +5,7 @@ class ACE_Settings { class EGVAR(medical,painCoefficient) { movedToSQF = 1; }; - class GVAR(ivFlowRate) { + class EGVAR(medical,ivFlowRate) { movedToSQF = 1; }; }; diff --git a/addons/medical_status/functions/fnc_getBloodLoss.sqf b/addons/medical_status/functions/fnc_getBloodLoss.sqf index 199b92356e..ca3cba77cd 100644 --- a/addons/medical_status/functions/fnc_getBloodLoss.sqf +++ b/addons/medical_status/functions/fnc_getBloodLoss.sqf @@ -7,7 +7,7 @@ * 0: The Unit * * Return Value: - * Total blood loss of unit + * Total blood loss of unit (litres/second) * * Example: * [player] call ace_medical_status_fnc_getBloodLoss @@ -22,4 +22,5 @@ if (_woundBleeding == 0) exitWith {0}; private _cardiacOutput = [_unit] call FUNC(getCardiacOutput); -(_woundBleeding * _cardiacOutput * EGVAR(medical,bleedingCoefficient)) +// even if heart stops blood will still flow slowly (gravity) +(_woundBleeding * (_cardiacOutput max 0.05) * EGVAR(medical,bleedingCoefficient)) diff --git a/addons/medical_status/functions/fnc_getBloodPressure.sqf b/addons/medical_status/functions/fnc_getBloodPressure.sqf index 244a421201..bbb0e5b65e 100644 --- a/addons/medical_status/functions/fnc_getBloodPressure.sqf +++ b/addons/medical_status/functions/fnc_getBloodPressure.sqf @@ -17,10 +17,10 @@ */ // Value is taken because with cardic output and resistance at default values, it will put blood pressure High at 120. -#define MODIFIER_BP_HIGH 13.7142792 +#define MODIFIER_BP_HIGH 9.4736842 // Value is taken because with cardic output and resistance at default values, it will put blood pressure Low at 80. -#define MODIFIER_BP_LOW 9.1428528 +#define MODIFIER_BP_LOW 6.3157894 params ["_unit"]; diff --git a/addons/medical_status/functions/fnc_getBloodVolumeChange.sqf b/addons/medical_status/functions/fnc_getBloodVolumeChange.sqf index 904d33c79f..c46338a475 100644 --- a/addons/medical_status/functions/fnc_getBloodVolumeChange.sqf +++ b/addons/medical_status/functions/fnc_getBloodVolumeChange.sqf @@ -29,7 +29,7 @@ if (!isNil {_unit getVariable QEGVAR(medical,ivBags)}) then { _x params ["_bagVolumeRemaining", "_type", "_bodyPart"]; if (_tourniquets select _bodyPart == 0) then { - private _bagChange = (_deltaT * GVAR(ivFlowRate) * IV_CHANGE_PER_SECOND) min _bagVolumeRemaining; // absolute value of the change in miliLiters + private _bagChange = (_deltaT * EGVAR(medical,ivFlowRate) * IV_CHANGE_PER_SECOND) min _bagVolumeRemaining; // absolute value of the change in miliLiters _bagVolumeRemaining = _bagVolumeRemaining - _bagChange; _bloodVolumeChange = _bloodVolumeChange + (_bagChange / 1000); }; diff --git a/addons/medical_status/functions/fnc_getCardiacOutput.sqf b/addons/medical_status/functions/fnc_getCardiacOutput.sqf index 649fade76f..cf405b52bc 100644 --- a/addons/medical_status/functions/fnc_getCardiacOutput.sqf +++ b/addons/medical_status/functions/fnc_getCardiacOutput.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" /* - * Author: Glowbal + * Author: Glowbal, SilentSpike * Get the cardiac output from the Heart, based on current Heart Rate and Blood Volume. * * Arguments: @@ -16,17 +16,22 @@ */ /* - Cardiac output (Q or or CO ) is the volume of blood being pumped by the heart, in particular by a left or right ventricle in the CBA_missionTime interval of one second. CO may be measured in many ways, for example dm3/min (1 dm3 equals 1 litre). + Cardiac output (Q or or CO ) is the volume of blood being pumped by the heart, in particular by a left or right ventricle in the CBA_missionTime interval of one second. CO may be measured in many ways, for example dm3/min (1 dm3 equals 1 liter). Source: http://en.wikipedia.org/wiki/Cardiac_output */ -// to limit the amount of complex calculations necessary, we take a set modifier to calculate Stroke Volume. -#define MODIFIER_CARDIAC_OUTPUT 0.1904761 +// Value taken from https://doi.org/10.1093%2Feurheartj%2Fehl336 +// as 94/95 ml ± 15 ml +#define VENTRICLE_STROKE_VOL 95e-3 params ["_unit"]; -private _bloodVolumeRatio = (GET_BLOOD_VOLUME(_unit) / DEFAULT_BLOOD_VOLUME); +private _bloodVolumeRatio = GET_BLOOD_VOLUME(_unit) / DEFAULT_BLOOD_VOLUME; private _heartRate = GET_HEART_RATE(_unit); -private _cardiacOutput = ((_bloodVolumeRatio / MODIFIER_CARDIAC_OUTPUT) + ((_heartRate / DEFAULT_HEART_RATE) - 1)) / 60; -(0 max _cardiacOutput) +// Blood volume ratio dictates how much is entering the ventricle (this is an approximation) +private _entering = linearConversion [0.5, 1, _bloodVolumeRatio, 0, 1, true]; + +private _cardiacOutput = (_entering * VENTRICLE_STROKE_VOL) * _heartRate / 60; + +0 max _cardiacOutput diff --git a/addons/medical_status/functions/fnc_initUnit.sqf b/addons/medical_status/functions/fnc_initUnit.sqf index 859ea83e80..4700d78393 100644 --- a/addons/medical_status/functions/fnc_initUnit.sqf +++ b/addons/medical_status/functions/fnc_initUnit.sqf @@ -46,9 +46,9 @@ if (_isRespawn) then { _unit setVariable [VAR_PAIN_SUPP, 0, true]; // - Wounds ------------------------------------------------------------------- - _unit setVariable [QEGVAR(medical,openWounds), [], true]; - _unit setVariable [QEGVAR(medical,bandagedWounds), [], true]; - _unit setVariable [QEGVAR(medical,stitchedWounds), [], true]; + _unit setVariable [VAR_OPEN_WOUNDS, [], true]; + _unit setVariable [VAR_BANDAGED_WOUNDS, [], true]; + _unit setVariable [VAR_STITCHED_WOUNDS, [], true]; _unit setVariable [QEGVAR(medical,isLimping), false, true]; _unit setVariable [VAR_FRACTURES, DEFAULT_FRACTURE_VALUES, true]; @@ -57,21 +57,24 @@ if (_isRespawn) then { // - Treatments --------------------------------------------------------------- _unit setVariable [VAR_TOURNIQUET, DEFAULT_TOURNIQUET_VALUES, true]; - _unit setVariable [QEGVAR(medical,occludedMedications), nil, true]; //Delayed Medications (from tourniquets) + _unit setVariable [QEGVAR(medical,occludedMedications), nil, true]; // Delayed Medications (from tourniquets) _unit setVariable [QEGVAR(medical,ivBags), nil, true]; - // - Update wound bleeding + // Update wound bleeding [_unit] call EFUNC(medical_status,updateWoundBloodLoss); - // triage card and logs + // Triage card and logs _unit setVariable [QEGVAR(medical,triageLevel), 0, true]; _unit setVariable [QEGVAR(medical,triageCard), [], true]; - // damage storage + // Damage storage _unit setVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0], true]; - // medication + // Medication _unit setVariable [VAR_MEDICATIONS, [], true]; + + // Unconscious spontanious wake up chance + _unit setVariable [QEGVAR(medical,lastWakeUpCheck), nil]; }; [{ diff --git a/addons/medical_status/functions/fnc_setCardiacArrest.sqf b/addons/medical_status/functions/fnc_setCardiacArrest.sqf index 32c858b36d..5ce67938e9 100644 --- a/addons/medical_status/functions/fnc_setCardiacArrest.sqf +++ b/addons/medical_status/functions/fnc_setCardiacArrest.sqf @@ -14,6 +14,7 @@ */ params ["_unit", "_active"]; +TRACE_2("setCardiacArrest",_unit,_active); // No change to make if (_active isEqualTo IN_CRDC_ARRST(_unit)) exitWith {}; diff --git a/addons/medical_status/functions/fnc_setUnconscious.sqf b/addons/medical_status/functions/fnc_setUnconscious.sqf index 5c3a24d759..cfc20e6a6f 100644 --- a/addons/medical_status/functions/fnc_setUnconscious.sqf +++ b/addons/medical_status/functions/fnc_setUnconscious.sqf @@ -24,10 +24,14 @@ _unit setVariable [VAR_UNCON, _active, true]; // Toggle unit ragdoll state [_unit, _active] call EFUNC(medical_engine,setUnconsciousAnim); +// Stop AI firing at unconscious units in most situations (global effect) +[_unit, "setHidden", "ace_unconscious", _active] call EFUNC(common,statusEffect_set); + if (_active) then { // Don't bother setting this if not used if (EGVAR(medical,spontaneousWakeUpChance) > 0) then { - _unit setVariable [QEGVAR(medical,lastWakeUpCheck), CBA_missionTime]; + private _lastWakeUpCheck = _unit getVariable [QEGVAR(medical,lastWakeUpCheck), 0]; // could be set higher from ace_medical_fnc_setUnconscious + _unit setVariable [QEGVAR(medical,lastWakeUpCheck), _lastWakeUpCheck max CBA_missionTime]; }; if (_unit == ACE_player) then { diff --git a/addons/medical_status/functions/fnc_updateWoundBloodLoss.sqf b/addons/medical_status/functions/fnc_updateWoundBloodLoss.sqf index 037a098c9d..fe38aabadc 100644 --- a/addons/medical_status/functions/fnc_updateWoundBloodLoss.sqf +++ b/addons/medical_status/functions/fnc_updateWoundBloodLoss.sqf @@ -2,6 +2,7 @@ /* * Author: Glowbal * Update total wound bleeding based on open wounds and tourniquets + * Wound bleeding = percentage of cardiac output lost * * Arguments: * 0: The Unit @@ -24,7 +25,7 @@ private _bodyPartBleeding = [0,0,0,0,0,0]; if (_tourniquets select _bodyPart == 0) then { _bodyPartBleeding set [_bodyPart, (_bodyPartBleeding select _bodyPart) + (_amountOf * _bleeeding)]; }; -} forEach (_unit getVariable [QEGVAR(medical,openWounds), []]); +} forEach GET_OPEN_WOUNDS(_unit); if (_bodyPartBleeding isEqualTo [0,0,0,0,0,0]) then { TRACE_1("updateWoundBloodLoss-none",_unit); diff --git a/addons/medical_status/initSettings.sqf b/addons/medical_status/initSettings.sqf index 32d6193a7d..95231b0acc 100644 --- a/addons/medical_status/initSettings.sqf +++ b/addons/medical_status/initSettings.sqf @@ -1,33 +1,26 @@ -// CBA Settings [ADDON: ace_medical_status]: - -private _categoryArray = [LELSTRING(medical,Category), LLSTRING(subCategory)]; - [ - QEGVAR(medical,bleedingCoefficient), "SLIDER", - [LSTRING(bleedingCoefficient_DisplayName), LSTRING(bleedingCoefficient_Description)], - _categoryArray, - [0,25,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QEGVAR(medical,bleedingCoefficient), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QEGVAR(medical,bleedingCoefficient), + "SLIDER", + [LSTRING(BleedingCoefficient_DisplayName), LSTRING(BleedingCoefficient_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + [0, 25, 1, 1], + true ] call CBA_settings_fnc_init; [ - QEGVAR(medical,painCoefficient), "SLIDER", - [LSTRING(painCoefficient_DisplayName), LSTRING(painCoefficient_Description)], - _categoryArray, - [0,25,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QEGVAR(medical,painCoefficient), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QEGVAR(medical,painCoefficient), + "SLIDER", + [LSTRING(PainCoefficient_DisplayName), LSTRING(PainCoefficient_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + [0, 25, 1, 1], + true ] call CBA_settings_fnc_init; [ - QGVAR(ivFlowRate), "SLIDER", - [LSTRING(ivFlowRate_DisplayName), LSTRING(ivFlowRate_Description)], - _categoryArray, - [0,25,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(ivFlowRate), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + QEGVAR(medical,ivFlowRate), + "SLIDER", + [LSTRING(IvFlowRate_DisplayName), LSTRING(IvFlowRate_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + [0, 25, 1, 1], + true ] call CBA_settings_fnc_init; diff --git a/addons/medical_status/stringtable.xml b/addons/medical_status/stringtable.xml index a7f4798df7..1bbea55902 100644 --- a/addons/medical_status/stringtable.xml +++ b/addons/medical_status/stringtable.xml @@ -1,86 +1,87 @@ - - - Status - 状態 - Статус - - - Bleeding coefficient - Коэффициент кровопотери - Mnożnik krwawienia - Coeficiente de sangrado - Verblutungsmultiplikator - Koeficient krvácení - Coeficiente de sangramento - Coéfficient de saignement - Vérzési koefficiens - Coefficiente sanguinamento - 出血の係数 - 출혈 계수 - 流血系数 - 流血係數 - - - Coefficient to modify the bleeding speed - Коэффициент, изменяющий скорость потери крови - Mnożnik modyfikujący prędkość wykrwawiania się - Coeficiente para modificar la velocidad de sangrado - Multiplikator um die Verblutungsgeschwindigkeit zu verändern - Koeficient rychlosti krvácení - Coeficiente para modificar a velocidade do sangramento - Modifie le débit des saignements - Egy szorzó a vérzés sebességének szabályozására - Coefficiente che modifica la velocità di sanguinamento - この係数では出血速度を変更できます - 출혈의 속도를 계수만큼 변경합니다 - 修改流血速度 - 修改流血速度 - - - Pain coefficient - Коэффициент боли - Mnożnik bólu - Coeficiente de dolor - Schmerzmultiplikator - Koeficient bolesti - Coeficiente de dor - Coéfficient de douleur - Fájdalmi koefficiens - Coefficiente dolore - 痛みの係数 - 고통 계수 - 疼痛系数 - 疼痛係數 - - - Coefficient to modify the pain intensity - Коэффициент, изменяющий уровень боли - Mnożnik modyfikujący intensywność bólu - Coeficiente para modificar la intensidad del dolor - Multiplikator um die Schmerzintensität zu verändern - Koeficient intenzity bolesti - Coeficiente para modificar a instensidade de dor - Modifie l'intensité de la douleur - Egy szorzó a fájdalom erősségének szabályozására - Coefficiente che modifica l'intensità del dolore - この係数では痛みの強さを変更できます - 고통의 정도를 계수만큼 변경합니다 - 修改疼痛强度的系数 - 修改疼痛強度的係數 - - - IV Transfusion Flow Rate - IV 輸血の流量 - Скорость внутривенного переливания - - - Effects how quickly IV Bags will have effect - IV による輸血速度を変更できます - Определяет, насколько быстро подействуют эффекты внутривенного переливания - - + + Status + Zustand + 状態 + Статус + + + Bleeding Coefficient + Коэффициент кровопотери + Mnożnik krwawienia + Coeficiente de sangrado + Verblutungsmultiplikator + Koeficient krvácení + Coeficiente de sangramento + Coéfficient de saignement + Vérzési koefficiens + Coefficiente sanguinamento + 出血の係数 + 출혈 계수 + 流血系数 + 流血係數 + + + Coefficient for controlling the bleeding speed. + Коэффициент, изменяющий скорость потери крови + Mnożnik modyfikujący prędkość wykrwawiania się + Coeficiente para modificar la velocidad de sangrado + Multiplikator um die Verblutungsgeschwindigkeit zu verändern + Koeficient rychlosti krvácení + Coeficiente para modificar a velocidade do sangramento + Modifie le débit des saignements + Egy szorzó a vérzés sebességének szabályozására + Coefficiente che modifica la velocità di sanguinamento + この係数では出血速度を変更できます + 출혈의 속도를 계수만큼 변경합니다 + 修改流血速度 + 修改流血速度 + + + Pain Coefficient + Коэффициент боли + Mnożnik bólu + Coeficiente de dolor + Schmerzmultiplikator + Koeficient bolesti + Coeficiente de dor + Coéfficient de douleur + Fájdalmi koefficiens + Coefficiente dolore + 痛みの係数 + 고통 계수 + 疼痛系数 + 疼痛係數 + + + Coefficient for controlling the intensity of pain adjustments. + Коэффициент, изменяющий уровень боли + Mnożnik modyfikujący intensywność bólu + Coeficiente para modificar la intensidad del dolor + Multiplikator um die Schmerzintensität zu verändern + Koeficient intenzity bolesti + Coeficiente para modificar a instensidade de dor + Modifie l'intensité de la douleur + Egy szorzó a fájdalom erősségének szabályozására + Coefficiente che modifica l'intensità del dolore + この係数では痛みの強さを変更できます + 고통의 정도를 계수만큼 변경합니다 + 修改疼痛强度的系数 + 修改疼痛強度的係數 + + + IV Transfusion Flow Rate + Transfusions Fließrate + IV 輸血の流量 + Скорость внутривенного переливания + + + Controls how quickly fluid flows out of IV Bags. The IV Bag volume change is calculated as:\ntime interval (s) * iv change per second (4.1667 mL/s) * flow rate (this coefficient). + Wie schnell der Effekt der Transfusion eintritt + IV による輸血速度を変更できます + Определяет, насколько быстро подействуют эффекты внутривенного переливания + diff --git a/addons/medical_treatment/ACE_Medical_Facilities.hpp b/addons/medical_treatment/ACE_Medical_Facilities.hpp new file mode 100644 index 0000000000..32ab19d233 --- /dev/null +++ b/addons/medical_treatment/ACE_Medical_Facilities.hpp @@ -0,0 +1,26 @@ +class EGVAR(medical,facilities) { + BI[] = { + "Land_Medevac_house_V1_F", + "Land_Medevac_HQ_V1_F", + "Land_MedicalTent_01_white_IDAP_med_closed_F", + "Land_MedicalTent_01_MTP_closed_F", + "Land_MedicalTent_01_brownhex_closed_F", + "Land_MedicalTent_01_digital_closed_F" + }; + CUP[] = { + "TK_GUE_WarfareBFieldhHospital_Base_EP1", + "TK_GUE_WarfareBFieldhHospital_EP1", + "TK_WarfareBFieldhHospital_Base_EP1", + "TK_WarfareBFieldhHospital_EP1", + "US_WarfareBFieldhHospital_Base_EP1", + "US_WarfareBFieldhHospital_EP1", + "MASH_EP1", + "MASH", + "Land_A_Hospital", + "CDF_WarfareBFieldhHospital", + "GUE_WarfareBFieldhHospital", + "INS_WarfareBFieldhHospital", + "RU_WarfareBFieldhHospital", + "USMC_WarfareBFieldhHospital" + }; +}; diff --git a/addons/medical_treatment/ACE_Medical_Treatment_Actions.hpp b/addons/medical_treatment/ACE_Medical_Treatment_Actions.hpp index 2ba1ceaaa5..1791568b34 100644 --- a/addons/medical_treatment/ACE_Medical_Treatment_Actions.hpp +++ b/addons/medical_treatment/ACE_Medical_Treatment_Actions.hpp @@ -103,7 +103,9 @@ class GVAR(actions) { treatmentTime = 7; callbackSuccess = QFUNC(splint); condition = QFUNC(canSplint); - litter[] = {}; + litter[] = { + {"ACE_MedicalLitter_splint"}, {}, {} + }; }; // - Syringes ------------------------------------------------------------- @@ -267,12 +269,12 @@ class GVAR(actions) { treatmentTime = 15; items[] = {}; condition = QFUNC(canCPR); - callbackSuccess = QFUNC(cpr); + callbackSuccess = QFUNC(cprSuccess); callbackFailure = QFUNC(cprFailure); callbackProgress = QFUNC(cprProgress); callbackStart = QFUNC(cprStart); - animationMedic = "AinvPknlMstpSlayW[wpn]Dnon_medic"; - animationMedicProne = "AinvPpneMstpSlayW[wpn]Dnon_medic"; + animationMedic = "AinvPknlMstpSnonWnonDr_medic0"; + animationMedicProne = "AinvPknlMstpSnonWnonDr_medic0"; animationMedicSelf = ""; animationMedicSelfProne = ""; consumeItem = 0; diff --git a/addons/medical_treatment/ACE_Settings.hpp b/addons/medical_treatment/ACE_Settings.hpp deleted file mode 100644 index 309c923299..0000000000 --- a/addons/medical_treatment/ACE_Settings.hpp +++ /dev/null @@ -1,48 +0,0 @@ -class ACE_Settings { - class EGVAR(medical,allowLitterCreation) { - movedToSqf = 1; - }; - class EGVAR(medical,CPRcreatesPulse) { - movedToSqf = 1; - }; - class EGVAR(medical,litterCleanUpDelay) { - movedToSqf = 1; - }; - class EGVAR(medical,litterSimulationDetail) { - movedToSqf = 1; - _values[] = { 0, 50, 100, 1000, 5000 }; - }; - class EGVAR(medical,increaseTrainingInLocations) { - movedToSqf = 1; - }; - class EGVAR(medical,PAKTime) { - movedToSqf = 1; - }; - class EGVAR(medical,medicSetting_Epi) { - movedToSqf = 1; - }; - class EGVAR(medical,medicSetting_PAK) { - movedToSqf = 1; - }; - class EGVAR(medical,medicSetting_SurgicalKit) { - movedToSqf = 1; - }; - class EGVAR(medical,consumeItem_PAK) { - movedToSqf = 1; - }; - class EGVAR(medical,consumeItem_SurgicalKit) { - movedToSqf = 1; - }; - class EGVAR(medical,useLocation_Epi) { - movedToSqf = 1; - }; - class EGVAR(medical,useLocation_PAK) { - movedToSqf = 1; - }; - class EGVAR(medical,useLocation_SurgicalKit) { - movedToSqf = 1; - }; - class EGVAR(medical,convertItems) { - movedToSqf = 1; - }; -}; diff --git a/addons/medical_treatment/Cfg3DEN.hpp b/addons/medical_treatment/Cfg3DEN.hpp index 74e2730c3e..04c3fc3efd 100644 --- a/addons/medical_treatment/Cfg3DEN.hpp +++ b/addons/medical_treatment/Cfg3DEN.hpp @@ -2,8 +2,9 @@ #define GRID_3DEN_W (pixelW * pixelGrid * 0.5) #define GRID_3DEN_H (pixelH * pixelGrid * 0.5) -#define DEFAULT_IS_MEDIC (parseNumber (_this getUnitTrait 'medic')) +#define DEFAULT_IS_MEDIC (parseNumber (_this getUnitTrait 'medic')) #define DEFAULT_IS_MEDICAL_VEHICLE (getNumber (configFile >> 'CfgVehicles' >> typeOf _this >> 'attendant') > 0) +#define DEFAULT_IS_MEDICAL_FACILITY (typeOf _this in GVAR(facilityClasses)) class ctrlToolbox; @@ -67,7 +68,7 @@ class Cfg3DEN { property = QUOTE(ace_isMedicalFacility); control = "Checkbox"; expression = QUOTE(_this setVariable [ARR_3(QQEGVAR(medical,isMedicalFacility),_value,true)];); - defaultValue = "false"; + defaultValue = QUOTE(DEFAULT_IS_MEDICAL_FACILITY); condition = "(1 - objectBrain) * (1 - objectVehicle)"; typeName = "BOOL"; }; diff --git a/addons/medical_treatment/CfgReplacementItems.hpp b/addons/medical_treatment/CfgReplacementItems.hpp index 4c5c4f126d..295935e055 100644 --- a/addons/medical_treatment/CfgReplacementItems.hpp +++ b/addons/medical_treatment/CfgReplacementItems.hpp @@ -11,7 +11,8 @@ class EGVAR(medical,replacementItems) { {"ACE_epinephrine", 1}, {"ACE_morphine", 1}, {"ACE_salineIV_250", 1}, - {"ACE_tourniquet", 1} + {"ACE_tourniquet", 1}, + {"ACE_splint", 2} }; // todo: add GM medical items }; diff --git a/addons/medical_treatment/CfgVehicles.hpp b/addons/medical_treatment/CfgVehicles.hpp index 39940da4fc..d7e0ed50d3 100644 --- a/addons/medical_treatment/CfgVehicles.hpp +++ b/addons/medical_treatment/CfgVehicles.hpp @@ -74,6 +74,9 @@ class CfgVehicles { class ACE_MedicalLitter_QuickClot: ACE_MedicalLitterBase { model = QPATHTOF(data\littergeneric_Quikclot.p3d); }; + class ACE_MedicalLitter_splint: ACE_MedicalLitterBase { + model = QPATHTOF(data\littergeneric_splint.p3d); + }; // Treatment items class Item_Base_F; @@ -117,6 +120,16 @@ class CfgVehicles { MACRO_ADDITEM(ACE_tourniquet,1); }; }; + class ACE_splintItem: Item_Base_F { + scope = 2; + scopeCurator = 2; + displayName = CSTRING(splint_Display); + author = ECSTRING(common,ACETeam); + vehicleClass = "Items"; + class TransportItems { + MACRO_ADDITEM(ACE_splint,1); + }; + }; class ACE_morphineItem: Item_Base_F { scope = 2; scopeCurator = 2; @@ -292,6 +305,7 @@ class CfgVehicles { MACRO_ADDITEM(ACE_packingBandage,25); MACRO_ADDITEM(ACE_elasticBandage,25); MACRO_ADDITEM(ACE_tourniquet,15); + MACRO_ADDITEM(ACE_splint,15); MACRO_ADDITEM(ACE_morphine,15); MACRO_ADDITEM(ACE_adenosine,15); MACRO_ADDITEM(ACE_atropine,15); diff --git a/addons/medical_treatment/CfgWeapons.hpp b/addons/medical_treatment/CfgWeapons.hpp index ecb4572858..afbf3faa4a 100644 --- a/addons/medical_treatment/CfgWeapons.hpp +++ b/addons/medical_treatment/CfgWeapons.hpp @@ -8,14 +8,12 @@ class CfgWeapons { class FirstAidKit: ItemCore { type = 0; - EGVAR(arsenal,hide) = 1; class ItemInfo: InventoryFirstAidKitItem_Base_F { mass = 4; }; }; class Medikit: ItemCore { type = 0; - EGVAR(arsenal,hide) = 1; class ItemInfo: MedikitItem { mass = 60; }; @@ -73,8 +71,8 @@ class CfgWeapons { scope = 2; author = ECSTRING(common,ACETeam); displayName = CSTRING(splint_Display); - picture = QPATHTOF(ui\tourniquet_ca.paa); - model = QPATHTOF(data\tourniquet.p3d); + picture = QPATHTOF(ui\splint_ca.paa); + model = QPATHTOF(data\splint.p3d); descriptionShort = CSTRING(splint_Desc_Short); class ItemInfo: CBA_MiscItem_ItemInfo { mass = 2; diff --git a/addons/medical_treatment/XEH_PREP.hpp b/addons/medical_treatment/XEH_PREP.hpp index 628003ff62..5b18bba14e 100644 --- a/addons/medical_treatment/XEH_PREP.hpp +++ b/addons/medical_treatment/XEH_PREP.hpp @@ -4,7 +4,6 @@ PREP(addToTriageCard); PREP(bandage); PREP(bandageLocal); PREP(bodyCleanupLoop); -PREP(calculateBlood); PREP(canBandage); PREP(canCPR); PREP(canSplint); @@ -17,7 +16,7 @@ PREP(checkItems); PREP(checkPulse); PREP(checkPulseLocal); PREP(checkResponse); -PREP(cpr); +PREP(cprSuccess); PREP(cprFailure); PREP(cprLocal); PREP(cprProgress); diff --git a/addons/medical_treatment/XEH_postInit.sqf b/addons/medical_treatment/XEH_postInit.sqf index 76222dca57..1896d8d9f1 100644 --- a/addons/medical_treatment/XEH_postInit.sqf +++ b/addons/medical_treatment/XEH_postInit.sqf @@ -13,26 +13,26 @@ [_unit] call FUNC(checkItems); }] call CBA_fnc_addEventHandler; -["loadout", FUNC(checkItems)] call CBA_fnc_addPlayerEventHandler; +["loadout", LINKFUNC(checkItems)] call CBA_fnc_addPlayerEventHandler; // Handle body removal and litter on server if (isServer) then { - [QGVAR(createLitterServer), FUNC(createLitterServer)] call CBA_fnc_addEventHandler; - ["ace_placedInBodyBag", FUNC(removeBody)] call CBA_fnc_addEventHandler; + [QGVAR(createLitterServer), LINKFUNC(createLitterServer)] call CBA_fnc_addEventHandler; + ["ace_placedInBodyBag", LINKFUNC(removeBody)] call CBA_fnc_addEventHandler; }; // Treatment events -[QGVAR(bandageLocal), FUNC(bandageLocal)] call CBA_fnc_addEventHandler; -[QGVAR(checkBloodPressureLocal), FUNC(checkBloodPressureLocal)] call CBA_fnc_addEventHandler; -[QGVAR(checkPulseLocal), FUNC(checkPulseLocal)] call CBA_fnc_addEventHandler; -[QGVAR(cprLocal), FUNC(cprLocal)] call CBA_fnc_addEventHandler; -[QGVAR(fullHealLocal), FUNC(fullHealLocal)] call CBA_fnc_addEventHandler; -[QGVAR(ivBagLocal), FUNC(ivBagLocal)] call CBA_fnc_addEventHandler; -[QGVAR(medicationLocal), FUNC(medicationLocal)] call CBA_fnc_addEventHandler; -[QGVAR(placeInBodyBag), FUNC(placeInBodyBag)] call CBA_fnc_addEventHandler; -[QGVAR(splintLocal), FUNC(splintLocal)] call CBA_fnc_addEventHandler; -[QGVAR(tourniquetLocal), FUNC(tourniquetLocal)] call CBA_fnc_addEventHandler; +[QGVAR(bandageLocal), LINKFUNC(bandageLocal)] call CBA_fnc_addEventHandler; +[QGVAR(checkBloodPressureLocal), LINKFUNC(checkBloodPressureLocal)] call CBA_fnc_addEventHandler; +[QGVAR(checkPulseLocal), LINKFUNC(checkPulseLocal)] call CBA_fnc_addEventHandler; +[QGVAR(cprLocal), LINKFUNC(cprLocal)] call CBA_fnc_addEventHandler; +[QGVAR(fullHealLocal), LINKFUNC(fullHealLocal)] call CBA_fnc_addEventHandler; +[QGVAR(ivBagLocal), LINKFUNC(ivBagLocal)] call CBA_fnc_addEventHandler; +[QGVAR(medicationLocal), LINKFUNC(medicationLocal)] call CBA_fnc_addEventHandler; +[QGVAR(placeInBodyBag), LINKFUNC(placeInBodyBag)] call CBA_fnc_addEventHandler; +[QGVAR(splintLocal), LINKFUNC(splintLocal)] call CBA_fnc_addEventHandler; +[QGVAR(tourniquetLocal), LINKFUNC(tourniquetLocal)] call CBA_fnc_addEventHandler; // Logging events -[QGVAR(addToLog), FUNC(addToLog)] call CBA_fnc_addEventHandler; -[QGVAR(addToTriageCard), FUNC(addToTriageCard)] call CBA_fnc_addEventHandler; +[QGVAR(addToLog), LINKFUNC(addToLog)] call CBA_fnc_addEventHandler; +[QGVAR(addToTriageCard), LINKFUNC(addToTriageCard)] call CBA_fnc_addEventHandler; diff --git a/addons/medical_treatment/XEH_preInit.sqf b/addons/medical_treatment/XEH_preInit.sqf index 19c28ab4ab..dc65ebc308 100644 --- a/addons/medical_treatment/XEH_preInit.sqf +++ b/addons/medical_treatment/XEH_preInit.sqf @@ -34,24 +34,14 @@ GVAR(animDurations) = [] call CBA_fnc_createNamespace; ["AinvPknlMstpSnonWnonDnon_medic1", 10] ]; -// class names of medical facilities -// global variable so it can be accessed by mission makers -GVAR(facilityClasses) = [ - "TK_GUE_WarfareBFieldhHospital_Base_EP1", - "TK_GUE_WarfareBFieldhHospital_EP1", - "TK_WarfareBFieldhHospital_Base_EP1", - "TK_WarfareBFieldhHospital_EP1", - "US_WarfareBFieldhHospital_Base_EP1", - "US_WarfareBFieldhHospital_EP1", - "MASH_EP1", - "MASH", - "Land_A_Hospital", - "CDF_WarfareBFieldhHospital", - "GUE_WarfareBFieldhHospital", - "INS_WarfareBFieldhHospital", - "RU_WarfareBFieldhHospital", - "USMC_WarfareBFieldhHospital" -]; +// class names of medical facilities (config case) +GVAR(facilityClasses) = []; +{ + { + private _name = configName (configFile >> "CfgVehicles" >> _x); + if (_name != "") then { GVAR(facilityClasses) pushBackUnique _name; }; + } forEach getArray _x; +} forEach configProperties [configFile >> QEGVAR(medical,facilities), "isArray _x"]; // array of medical items to replace and their ACE equivalents GVAR(replacementItems) = configProperties [configFile >> QEGVAR(medical,replacementItems), "isArray _x"] apply { diff --git a/addons/medical_treatment/config.cpp b/addons/medical_treatment/config.cpp index 2dfe99d04a..29c11c18ad 100644 --- a/addons/medical_treatment/config.cpp +++ b/addons/medical_treatment/config.cpp @@ -16,7 +16,7 @@ class CfgPatches { #include "ACE_Medical_Treatment.hpp" #include "ACE_Medical_Treatment_Actions.hpp" -#include "ACE_Settings.hpp" +#include "ACE_Medical_Facilities.hpp" #include "CfgEventHandlers.hpp" #include "CfgReplacementItems.hpp" #include "CfgVehicles.hpp" diff --git a/addons/medical_treatment/data/littergeneric_splint.p3d b/addons/medical_treatment/data/littergeneric_splint.p3d new file mode 100644 index 0000000000..4918cacaf4 Binary files /dev/null and b/addons/medical_treatment/data/littergeneric_splint.p3d differ diff --git a/addons/medical_treatment/data/model.cfg b/addons/medical_treatment/data/model.cfg index 58f288c3b9..344141e28e 100644 --- a/addons/medical_treatment/data/model.cfg +++ b/addons/medical_treatment/data/model.cfg @@ -47,6 +47,7 @@ class CfgModels { class bandage: Default {}; class bodybagItem: Default {}; class epinephrine: Default {}; + class splint: Default {}; class IVBagBase: Default { sectionsInherit = ""; @@ -69,6 +70,7 @@ class CfgModels { class littergeneric_morphine: Default {}; class littergeneric_packingbandage: Default {}; class littergeneric_Quikclot: Default {}; + class littergeneric_splint: Default {}; class morphine: Default {}; class packingbandage: Default {}; class QuikClot: Default {}; diff --git a/addons/medical_treatment/data/splint.p3d b/addons/medical_treatment/data/splint.p3d new file mode 100644 index 0000000000..20cbe0a5d0 Binary files /dev/null and b/addons/medical_treatment/data/splint.p3d differ diff --git a/addons/medical_treatment/data/splint.rvmat b/addons/medical_treatment/data/splint.rvmat new file mode 100644 index 0000000000..69af44f738 --- /dev/null +++ b/addons/medical_treatment/data/splint.rvmat @@ -0,0 +1,92 @@ +ambient[]={1,1,1,1}; +diffuse[]={1,1,1,1}; +forcedDiffuse[]={0,0,0,0}; +emmisive[]={0,0,0,1}; +specular[]={1,1,1,0}; +specularPower=50; +PixelShaderID="Super"; +VertexShaderID="Super"; +class Stage1 +{ + texture="z\ace\addons\medical_treatment\data\splint_nohq.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage2 +{ + texture="#(argb,8,8,3)color(0.5,0.5,0.5,1,DT)"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage3 +{ + texture="#(argb,8,8,3)color(0,0,0,0,MC)"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage4 +{ + texture="z\ace\addons\medical_treatment\data\splint_as.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage5 +{ + texture="z\ace\addons\medical_treatment\data\splint_smdi.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage6 +{ + texture="#(ai,64,64,1)fresnel(2,0.1)"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage7 +{ + texture="a3\data_f\env_land_co.paa"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; diff --git a/addons/medical_treatment/data/splint_as.paa b/addons/medical_treatment/data/splint_as.paa new file mode 100644 index 0000000000..810525bdab Binary files /dev/null and b/addons/medical_treatment/data/splint_as.paa differ diff --git a/addons/medical_treatment/data/splint_ca.paa b/addons/medical_treatment/data/splint_ca.paa new file mode 100644 index 0000000000..cff2ab6ff8 Binary files /dev/null and b/addons/medical_treatment/data/splint_ca.paa differ diff --git a/addons/medical_treatment/data/splint_nohq.paa b/addons/medical_treatment/data/splint_nohq.paa new file mode 100644 index 0000000000..2ed96ef112 Binary files /dev/null and b/addons/medical_treatment/data/splint_nohq.paa differ diff --git a/addons/medical_treatment/data/splint_smdi.paa b/addons/medical_treatment/data/splint_smdi.paa new file mode 100644 index 0000000000..e9c4efb07b Binary files /dev/null and b/addons/medical_treatment/data/splint_smdi.paa differ diff --git a/addons/medical_treatment/functions/fnc_bandageLocal.sqf b/addons/medical_treatment/functions/fnc_bandageLocal.sqf index a27eaa511c..f001d2f0c1 100644 --- a/addons/medical_treatment/functions/fnc_bandageLocal.sqf +++ b/addons/medical_treatment/functions/fnc_bandageLocal.sqf @@ -22,7 +22,7 @@ params ["_patient", "_bodyPart", "_bandage"]; private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; if (_partIndex < 0) exitWith {false}; -private _openWounds = _patient getVariable [QEGVAR(medical,openWounds), []]; +private _openWounds = GET_OPEN_WOUNDS(_patient); if (_openWounds isEqualTo []) exitWith {false}; // Figure out which injury for this bodypart is the best choice to bandage @@ -40,7 +40,7 @@ _amountOf = _amountOf - _impact; _wound set [2, _amountOf]; _openWounds set [_woundIndex, _wound]; -_patient setVariable [QEGVAR(medical,openWounds), _openWounds, true]; +_patient setVariable [VAR_OPEN_WOUNDS, _openWounds, true]; [_patient] call EFUNC(medical_status,updateWoundBloodLoss); diff --git a/addons/medical_treatment/functions/fnc_calculateBlood.sqf b/addons/medical_treatment/functions/fnc_calculateBlood.sqf deleted file mode 100644 index 074022ed29..0000000000 --- a/addons/medical_treatment/functions/fnc_calculateBlood.sqf +++ /dev/null @@ -1,29 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Zakant - * Calculate the blood lost and blood volume for a unit. Used from CPR to simulate a heart rate while in cardiac arrest. - * - * Arguments: - * 0: Unit - * - * Return Value: - * None - * - * Public: No - */ - -params["_unit"]; - -// We will just simulate blood flow for now! -private _lastTimeUpdated = _unit getVariable [QEGVAR(medical,lastTimeUpdated), CBA_missionTime]; -private _deltaT = CBA_missionTime - _lastTimeUpdated; - -private _lastTimeValuesSynced = _unit getVariable [QEGVAR(medical,lastMomentValuesSynced), 0]; -private _syncValues = (CBA_missionTime - _lastTimeValuesSynced) >= (10 + floor(random(10))); - -_unit setVariable [QEGVAR(medical,lastTimeUpdated), CBA_missionTime]; -if (_deltaT != 0) then { - private _change = ([_unit, _deltaT, _syncValues] call EFUNC(medical_status,getBloodVolumeChange)); - private _bloodVolume = 0 max (GET_BLOOD_VOLUME(_unit) + _change) min DEFAULT_BLOOD_VOLUME; - _unit setVariable [VAR_BLOOD_VOL, _bloodVolume, _syncValues]; -}; diff --git a/addons/medical_treatment/functions/fnc_canBandage.sqf b/addons/medical_treatment/functions/fnc_canBandage.sqf index a67dbb7873..f60836f38c 100644 --- a/addons/medical_treatment/functions/fnc_canBandage.sqf +++ b/addons/medical_treatment/functions/fnc_canBandage.sqf @@ -34,6 +34,6 @@ private _canBandage = false; if (_bodyPartN == _index && {_amountOf * _bleeding > 0}) exitWith { _canBandage = true; }; -} forEach (_patient getVariable [QEGVAR(medical,openWounds), []]); +} forEach GET_OPEN_WOUNDS(_patient); _canBandage diff --git a/addons/medical_treatment/functions/fnc_canCPR.sqf b/addons/medical_treatment/functions/fnc_canCPR.sqf index 9da6ec6891..172cbe5aa9 100644 --- a/addons/medical_treatment/functions/fnc_canCPR.sqf +++ b/addons/medical_treatment/functions/fnc_canCPR.sqf @@ -18,4 +18,6 @@ params ["", "_patient"]; -!(_patient call EFUNC(common,isAwake)) && {!(_patient getVariable [QGVAR(isReceivingCPR), false])} +!(_patient call EFUNC(common,isAwake)) +&& {(GVAR(advancedDiagnose)) || {IN_CRDC_ARRST(_patient)}} // if basic diagnose, then only show action if appropriate (they can't tell difference between uncon/ca) +&& {isNull (_patient getVariable [QEGVAR(medical,CPR_provider), objNull])} diff --git a/addons/medical_treatment/functions/fnc_canStitch.sqf b/addons/medical_treatment/functions/fnc_canStitch.sqf index 738823114f..6d1ab36465 100644 --- a/addons/medical_treatment/functions/fnc_canStitch.sqf +++ b/addons/medical_treatment/functions/fnc_canStitch.sqf @@ -18,4 +18,4 @@ params ["", "_patient"]; -!((_patient getVariable [QEGVAR(medical,bandagedWounds), []]) isEqualTo []) +!(GET_BANDAGED_WOUNDS(_patient) isEqualTo []) diff --git a/addons/medical_treatment/functions/fnc_canTreat.sqf b/addons/medical_treatment/functions/fnc_canTreat.sqf index efb7778f09..d8905626c9 100644 --- a/addons/medical_treatment/functions/fnc_canTreat.sqf +++ b/addons/medical_treatment/functions/fnc_canTreat.sqf @@ -36,6 +36,10 @@ isClass _config GET_FUNCTION(_condition,_config >> "condition"); if (_condition isEqualType {}) then { + if (_condition isEqualTo {}) exitWith { + _condition = true; + }; + _condition = call _condition; }; diff --git a/addons/medical_treatment/functions/fnc_cprFailure.sqf b/addons/medical_treatment/functions/fnc_cprFailure.sqf index a19179c5f8..513c2e43ee 100644 --- a/addons/medical_treatment/functions/fnc_cprFailure.sqf +++ b/addons/medical_treatment/functions/fnc_cprFailure.sqf @@ -16,13 +16,7 @@ * Public: No */ -params ["", "_patient"]; +params ["_medic", "_patient"]; +TRACE_2("cprFailure",_medic,_patient); -if (!(_patient call EFUNC(common,isAwake)) || {IN_CRDC_ARRST(_patient)}) then { - _patient setVariable [VAR_HEART_RATE, 0, true]; -}; - -// Patient is no longer receiving CPR -_patient setVariable [QGVAR(isReceivingCPR), false, true]; - -_patient call FUNC(calculateBlood); +_patient setVariable [QEGVAR(medical,CPR_provider), objNull, true]; diff --git a/addons/medical_treatment/functions/fnc_cprLocal.sqf b/addons/medical_treatment/functions/fnc_cprLocal.sqf index da72faba45..3d9dfd1e32 100644 --- a/addons/medical_treatment/functions/fnc_cprLocal.sqf +++ b/addons/medical_treatment/functions/fnc_cprLocal.sqf @@ -17,9 +17,14 @@ */ params ["_medic", "_patient"]; +TRACE_2("cprLocal",_medic,_patient); [_patient, "activity", LSTRING(Activity_CPR), [[_medic, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); -if (random 1 >= 0.6) then { +if ((random 1) < GVAR(cprSuccessChance)) then { + TRACE_1("CPR random success",GVAR(cprSuccessChance)); [QEGVAR(medical,CPRSucceeded), _patient] call CBA_fnc_localEvent; +} else { + TRACE_1("CPR random fail",GVAR(cprSuccessChance)); }; + diff --git a/addons/medical_treatment/functions/fnc_cprProgress.sqf b/addons/medical_treatment/functions/fnc_cprProgress.sqf index e595b7ffdd..f41fefe5bf 100644 --- a/addons/medical_treatment/functions/fnc_cprProgress.sqf +++ b/addons/medical_treatment/functions/fnc_cprProgress.sqf @@ -5,7 +5,7 @@ * * Arguments: * 0: Arguments - * 0: Medic (not used) + * 0: Medic * 1: Patient * * Return Value: @@ -18,12 +18,10 @@ */ params ["_args"]; -_args params ["", "_patient"]; +_args params ["_medic", "_patient"]; -// Cancel CPR is patient wakes up -if (_patient getVariable EFUNC(common,isAwake) || {!IN_CRDC_ARRST(_patient)}) exitWith {false}; +// Cancel CPR if patient wakes up -// Calculate blood volume, if there is no pulse nothing happens -_patient call FUNC(calculateBlood); - -true +!(_patient call EFUNC(common,isAwake)) +&& {(GVAR(advancedDiagnose)) || {IN_CRDC_ARRST(_patient)}} // if basic diagnose, then only show action if appropriate (they can't tell difference between uncon/ca) +&& {_medic == (_patient getVariable [QEGVAR(medical,CPR_provider), objNull])} diff --git a/addons/medical_treatment/functions/fnc_cprStart.sqf b/addons/medical_treatment/functions/fnc_cprStart.sqf index 677e8a516a..f49ccbb4a3 100644 --- a/addons/medical_treatment/functions/fnc_cprStart.sqf +++ b/addons/medical_treatment/functions/fnc_cprStart.sqf @@ -4,7 +4,7 @@ * Handles starting the CPR treatment. * * Arguments: - * 0: Medic (not used) + * 0: Medic * 1: Patient * * Return Value: @@ -16,14 +16,7 @@ * Public: No */ -params ["", "_patient"]; +params ["_medic", "_patient"]; +TRACE_2("cprStart",_medic,_patient); -// Prevent others from performing CPR -_patient setVariable [QGVAR(isReceivingCPR), true, true]; - -// Create a random pulse based on setting -if (GVAR(cprCreatesPulse) && {GET_HEART_RATE(_patient) == 0}) then { - _patient setVariable [VAR_HEART_RATE, round random [25, 30, 35], true]; -}; - -_patient setVariable [QEGVAR(medical,lastTimeUpdated), CBA_missionTime, true]; +_patient setVariable [QEGVAR(medical,CPR_provider), _medic, true]; diff --git a/addons/medical_treatment/functions/fnc_cpr.sqf b/addons/medical_treatment/functions/fnc_cprSuccess.sqf similarity index 58% rename from addons/medical_treatment/functions/fnc_cpr.sqf rename to addons/medical_treatment/functions/fnc_cprSuccess.sqf index a0732bcbf8..bd9d0c3e2b 100644 --- a/addons/medical_treatment/functions/fnc_cpr.sqf +++ b/addons/medical_treatment/functions/fnc_cprSuccess.sqf @@ -11,17 +11,19 @@ * None * * Example: - * [player, cursorObject] call ace_medical_treatment_fnc_cpr + * [player, cursorObject] call ace_medical_treatment_fnc_cprSuccess * * Public: No */ params ["_medic", "_patient"]; +TRACE_2("cprSuccess",_medic,_patient); -_patient setVariable [QGVAR(isReceivingCPR), false, true]; -_patient setVariable [VAR_HEART_RATE, 0, true]; -_patient call FUNC(calculateBlood); +_patient setVariable [QEGVAR(medical,CPR_provider), objNull, true]; if (alive _patient && {IN_CRDC_ARRST(_patient)}) then { + TRACE_1("sending cprLocal event",_patient); [QGVAR(cprLocal), [_medic, _patient], _patient] call CBA_fnc_targetEvent; +} else { + TRACE_1("not alive or in cardiac arrest",_patient); }; diff --git a/addons/medical_treatment/functions/fnc_createLitter.sqf b/addons/medical_treatment/functions/fnc_createLitter.sqf index 587648de49..5aa2a5bed1 100644 --- a/addons/medical_treatment/functions/fnc_createLitter.sqf +++ b/addons/medical_treatment/functions/fnc_createLitter.sqf @@ -28,7 +28,7 @@ if (vehicle _medic != _medic || {vehicle _patient != _patient}) exitWith {}; // Determine if treated body part is bleeding private _index = ALL_BODY_PARTS find toLower _bodyPart; -private _isBleeding = (_patient getVariable [QEGVAR(medical,openWounds), []]) findIf { +private _isBleeding = GET_OPEN_WOUNDS(_patient) findIf { _x params ["", "_bodyPartN", "_amountOf", "_bleeding"]; _bodyPartN == _index && {_amountOf * _bleeding > 0} diff --git a/addons/medical_treatment/functions/fnc_findMostEffectiveWound.sqf b/addons/medical_treatment/functions/fnc_findMostEffectiveWound.sqf index d1a451e3af..7bdff17b4f 100644 --- a/addons/medical_treatment/functions/fnc_findMostEffectiveWound.sqf +++ b/addons/medical_treatment/functions/fnc_findMostEffectiveWound.sqf @@ -29,7 +29,7 @@ if (isClass (_config >> _bandage)) then { }; // Iterate over open wounds to find the most effective target -private _openWounds = _patient getVariable [QEGVAR(medical,openWounds), []]; +private _openWounds = GET_OPEN_WOUNDS(_patient); if (_openWounds isEqualTo []) exitWith { [EMPTY_WOUND, -1, -1] }; private _wound = EMPTY_WOUND; diff --git a/addons/medical_treatment/functions/fnc_fullHealLocal.sqf b/addons/medical_treatment/functions/fnc_fullHealLocal.sqf index 75ccb26674..e1ccc6fddd 100644 --- a/addons/medical_treatment/functions/fnc_fullHealLocal.sqf +++ b/addons/medical_treatment/functions/fnc_fullHealLocal.sqf @@ -16,6 +16,7 @@ */ params ["_patient"]; +TRACE_1("fullHealLocal",_patient); if (!alive _patient) exitWith {}; @@ -26,12 +27,6 @@ if IN_CRDC_ARRST(_patient) then { [QEGVAR(medical,CPRSucceeded), _patient] call CBA_fnc_localEvent; }; -if IS_UNCONSCIOUS(_patient) then { - TRACE_1("Waking up",_patient); - // Wake patient up first or unconscious variables will be reset - [QEGVAR(medical,WakeUp), _patient] call CBA_fnc_localEvent; -}; - _patient setVariable [VAR_PAIN, 0, true]; _patient setVariable [VAR_BLOOD_VOL, DEFAULT_BLOOD_VOLUME, true]; @@ -40,9 +35,9 @@ _patient setVariable [VAR_TOURNIQUET, DEFAULT_TOURNIQUET_VALUES, true]; _patient setVariable [QGVAR(occludedMedications), nil, true]; // Wounds and Injuries -_patient setVariable [QEGVAR(medical,openWounds), [], true]; -_patient setVariable [QEGVAR(medical,bandagedWounds), [], true]; -_patient setVariable [QEGVAR(medical,stitchedWounds), [], true]; +_patient setVariable [VAR_OPEN_WOUNDS, [], true]; +_patient setVariable [VAR_BANDAGED_WOUNDS, [], true]; +_patient setVariable [VAR_STITCHED_WOUNDS, [], true]; _patient setVariable [QEGVAR(medical,isLimping), false, true]; _patient setVariable [VAR_FRACTURES, DEFAULT_FRACTURE_VALUES, true]; @@ -59,9 +54,13 @@ _patient setVariable [QEGVAR(medical,ivBags), nil, true]; // Damage storage _patient setVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0], true]; -#ifdef DEBUG_TESTRESULTS -_patient setVariable [QEGVAR(medical,bodyPartStatus), [0,0,0,0,0,0], true]; -#endif + +// 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 { WARNING_1("fullheal [%1] did not restore stable vitals",_patient); }; + TRACE_1("Waking up",_patient); + [QEGVAR(medical,WakeUp), _patient] call CBA_fnc_localEvent; +}; // Generic medical admin _patient setVariable [VAR_CRDC_ARRST, false, true]; diff --git a/addons/medical_treatment/functions/fnc_getBandageTime.sqf b/addons/medical_treatment/functions/fnc_getBandageTime.sqf index e56727cfc7..d66a8515ae 100644 --- a/addons/medical_treatment/functions/fnc_getBandageTime.sqf +++ b/addons/medical_treatment/functions/fnc_getBandageTime.sqf @@ -21,7 +21,7 @@ params ["_medic", "_patient", "_bodypart", "_bandage"]; private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; -if (_partIndex < 0) exitWith { 0 }; +if (_partIndex < 0) exitWith { ERROR_1("invalid partIndex - %1",_this); 0 }; private _targetWound = [_patient, _bandage, _partIndex] call FUNC(findMostEffectiveWound); _targetWound params ["_wound", "_woundIndex", "_effectiveness"]; @@ -34,11 +34,12 @@ _wound params ["_classID", "", "_amountOf", "_bloodloss", "_damage"]; private _category = (_classID % 10); // Base bandage time is based on wound size and remaining percentage -private _bandageTime = ([ - BANDAGE_TIME_S, - BANDAGE_TIME_M, - BANDAGE_TIME_L -] select _category) * _amountOf; +private _bandageTime = [BANDAGE_TIME_S, BANDAGE_TIME_M, BANDAGE_TIME_L] select _category; + +// Scale bandage time based on amount left and effectiveness (less time if only a little wound left) +if (GVAR(advancedBandages)) then { // basicBandage will have a very high effectiveness and can be ignored + _bandageTime = _bandageTime * (linearConversion [0, _effectiveness, _amountOf, 0.666, 1, true]); +}; // Medics are more practised at applying bandages if ([_medic] call FUNC(isMedic)) then { @@ -50,5 +51,6 @@ if (_medic == _patient) then { _bandageTime = _bandageTime + BANDAGE_TIME_MOD_SELF; }; +TRACE_1("",_bandageTime); // Nobody can bandage instantly -_bandageTime max 2 +_bandageTime max 2.25 diff --git a/addons/medical_treatment/functions/fnc_getStitchTime.sqf b/addons/medical_treatment/functions/fnc_getStitchTime.sqf index 63e970301b..81bf948ab2 100644 --- a/addons/medical_treatment/functions/fnc_getStitchTime.sqf +++ b/addons/medical_treatment/functions/fnc_getStitchTime.sqf @@ -20,4 +20,4 @@ params ["", "_patient"]; -count (_patient getVariable [QEGVAR(medical,bandagedWounds), []]) * TIME_PER_WOUND +count GET_BANDAGED_WOUNDS(_patient) * TIME_PER_WOUND diff --git a/addons/medical_treatment/functions/fnc_handleBandageOpening.sqf b/addons/medical_treatment/functions/fnc_handleBandageOpening.sqf index 2c8b46b76e..f2966d5f9c 100644 --- a/addons/medical_treatment/functions/fnc_handleBandageOpening.sqf +++ b/addons/medical_treatment/functions/fnc_handleBandageOpening.sqf @@ -58,7 +58,7 @@ if (isClass (_config >> _className)) then { }; TRACE_5("configs",_bandage,_className,_reopeningChance,_reopeningMinDelay,_reopeningMaxDelay); -private _bandagedWounds = _target getVariable [QEGVAR(medical,bandagedWounds), []]; +private _bandagedWounds = GET_BANDAGED_WOUNDS(_target); private _exist = false; { _x params ["_id", "_partN", "_amountOf"]; @@ -76,7 +76,7 @@ if (!_exist) then { _bandagedWounds pushBack _bandagedInjury; }; -_target setVariable [QEGVAR(medical,bandagedWounds), _bandagedWounds, true]; +_target setVariable [VAR_BANDAGED_WOUNDS, _bandagedWounds, true]; // _reopeningChance = 1; // _reopeningMinDelay = 5; @@ -91,7 +91,7 @@ if (random 1 <= _reopeningChance) then { params ["_target", "_impact", "_part", "_injuryIndex", "_injury"]; TRACE_5("reopen delay finished",_target,_impact,_part,_injuryIndex,_injury); - private _openWounds = _target getVariable [QEGVAR(medical,openWounds), []]; + private _openWounds = GET_OPEN_WOUNDS(_target); if (count _openWounds - 1 < _injuryIndex) exitWith { TRACE_2("index bounds",_injuryIndex,count _openWounds); }; _injury params ["_classID", "_bodyPartN"]; @@ -99,7 +99,7 @@ if (random 1 <= _reopeningChance) then { private _selectedInjury = _openWounds select _injuryIndex; _selectedInjury params ["_selClassID", "_selBodyPart", "_selAmmount"]; if ((_selClassID == _classID) && {_selBodyPart == _bodyPartN}) then { // matching the IDs - private _bandagedWounds = _target getVariable [QEGVAR(medical,bandagedWounds), []]; + private _bandagedWounds = GET_BANDAGED_WOUNDS(_target); private _exist = false; { _x params ["_id", "_partN", "_amountOf"]; @@ -113,8 +113,8 @@ if (random 1 <= _reopeningChance) then { if (_exist) then { TRACE_2("Reopening Wound",_bandagedWounds,_openWounds); _selectedInjury set [2, _selAmmount + _impact]; - _target setVariable [QEGVAR(medical,bandagedWounds), _bandagedWounds, true]; - _target setVariable [QEGVAR(medical,openWounds), _openWounds, true]; + _target setVariable [VAR_BANDAGED_WOUNDS, _bandagedWounds, true]; + _target setVariable [VAR_OPEN_WOUNDS, _openWounds, true]; [_target] call EFUNC(medical_status,updateWoundBloodLoss); diff --git a/addons/medical_treatment/functions/fnc_ivBagLocal.sqf b/addons/medical_treatment/functions/fnc_ivBagLocal.sqf index 5017e74aae..f2640fb0bf 100644 --- a/addons/medical_treatment/functions/fnc_ivBagLocal.sqf +++ b/addons/medical_treatment/functions/fnc_ivBagLocal.sqf @@ -35,4 +35,4 @@ private _type = GET_STRING(_ivConfig >> "type",getText (_defaultConfig >> "typ // Add IV bag to patient's ivBags array private _ivBags = _patient getVariable [QEGVAR(medical,ivBags), []]; _ivBags pushBack [_volume, _type, _partIndex]; -_ivBags setVariable [QEGVAR(medical,ivBags), _ivBags, true]; +_patient setVariable [QEGVAR(medical,ivBags), _ivBags, true]; diff --git a/addons/medical_treatment/functions/fnc_medication.sqf b/addons/medical_treatment/functions/fnc_medication.sqf index 32124c23a4..6def70b212 100644 --- a/addons/medical_treatment/functions/fnc_medication.sqf +++ b/addons/medical_treatment/functions/fnc_medication.sqf @@ -25,4 +25,4 @@ params ["_medic", "_patient", "_bodyPart", "_classname", "", "_usedItem"]; [_patient, _usedItem] call FUNC(addToTriageCard); [_patient, "activity", LSTRING(Activity_usedItem), [[_medic, false, true] call EFUNC(common,getName), getText (configFile >> "CfgWeapons" >> _usedItem >> "displayName")]] call FUNC(addToLog); -[QGVAR(medicationLocal), [_patient, _bodyPart, _classname]] call CBA_fnc_targetEvent; +[QGVAR(medicationLocal), [_patient, _bodyPart, _classname], _patient] call CBA_fnc_targetEvent; diff --git a/addons/medical_treatment/functions/fnc_surgicalKitProgress.sqf b/addons/medical_treatment/functions/fnc_surgicalKitProgress.sqf index 565df32e54..e41cdf16b7 100644 --- a/addons/medical_treatment/functions/fnc_surgicalKitProgress.sqf +++ b/addons/medical_treatment/functions/fnc_surgicalKitProgress.sqf @@ -22,8 +22,8 @@ params ["_args", "_elapsedTime", "_totalTime"]; _args params ["", "_patient"]; -private _bandagedWounds = _patient getVariable [QEGVAR(medical,bandagedWounds), []]; -private _stitchedWounds = _patient getVariable [QEGVAR(medical,stitchedWounds), []]; +private _bandagedWounds = GET_BANDAGED_WOUNDS(_patient); +private _stitchedWounds = GET_STITCHED_WOUNDS(_patient); // Stop treatment if there are no wounds that can be stitched remaining if (_bandagedWounds isEqualTo []) exitWith { false }; @@ -32,8 +32,8 @@ if (_bandagedWounds isEqualTo []) exitWith { false }; if (_totalTime - _elapsedTime <= (count _bandagedWounds - 1) * 5) then { private _treatedWound = _bandagedWounds deleteAt 0; _stitchedWounds pushBack _treatedWound; - _patient setVariable [QEGVAR(medical,bandagedWounds), _bandagedWounds, true]; - _patient setVariable [QEGVAR(medical,stitchedWounds), _stitchedWounds, true]; + _patient setVariable [VAR_BANDAGED_WOUNDS, _bandagedWounds, true]; + _patient setVariable [VAR_STITCHED_WOUNDS, _stitchedWounds, true]; TRACE_3("stitched",_treatedWound,count _bandagedWounds,count _stitchedWounds); // Check if we fixed limping from this treatment diff --git a/addons/medical_treatment/functions/fnc_tourniquet.sqf b/addons/medical_treatment/functions/fnc_tourniquet.sqf index cd1a4c8267..155a2c502b 100644 --- a/addons/medical_treatment/functions/fnc_tourniquet.sqf +++ b/addons/medical_treatment/functions/fnc_tourniquet.sqf @@ -27,7 +27,7 @@ if ([_patient, _bodyPart] call FUNC(hasTourniquetAppliedTo)) exitWith { ["There is already a tourniquet on this body part!", 1.5] call EFUNC(common,displayTextStructured); // todo: localize }; -[_patient, _usedItem] call FUNC(addToTraigeCard); +[_patient, _usedItem] call FUNC(addToTriageCard); [_patient, "activity", LSTRING(Activity_appliedTourniquet), [[_medic, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); [QGVAR(tourniquetLocal), [_patient, _bodyPart], _patient] call CBA_fnc_targetEvent; diff --git a/addons/medical_treatment/initSettings.sqf b/addons/medical_treatment/initSettings.sqf index 0717c8e88f..f42e4d4009 100644 --- a/addons/medical_treatment/initSettings.sqf +++ b/addons/medical_treatment/initSettings.sqf @@ -38,15 +38,6 @@ true ] call CBA_settings_fnc_init; -[ - QGVAR(cprCreatesPulse), - "CHECKBOX", - [LSTRING(CPRCreatesPulse_DisplayName), LSTRING(CPRCreatesPulse_Description)], - [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], - true, - true -] call CBA_settings_fnc_init; - // todo: should this setting differentiate between medical vehicles and facilities? [ QGVAR(locationsBoostTraining), @@ -62,7 +53,7 @@ "LIST", [LSTRING(AllowSelfIV_DisplayName), LSTRING(AllowSelfIV_Description)], [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], - [[0, 1], [ELSTRING(common,No), ELSTRING(common,Yes)], 0], + [[0, 1], [ELSTRING(common,No), ELSTRING(common,Yes)], 1], true ] call CBA_settings_fnc_init; @@ -165,6 +156,15 @@ true ] call CBA_settings_fnc_init; +[ + QGVAR(cprSuccessChance), + "SLIDER", + [LSTRING(cprSuccessChance_DisplayName), LSTRING(cprSuccessChance_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [0, 1, 0.4, 2], + true +] call CBA_settings_fnc_init; + [ QGVAR(allowLitterCreation), "CHECKBOX", diff --git a/addons/medical_treatment/script_component.hpp b/addons/medical_treatment/script_component.hpp index db40133248..bed5241f85 100644 --- a/addons/medical_treatment/script_component.hpp +++ b/addons/medical_treatment/script_component.hpp @@ -2,9 +2,9 @@ #define COMPONENT_BEAUTIFIED Medical Treatment #include "\z\ace\addons\main\script_mod.hpp" -#define DEBUG_MODE_FULL -#define DISABLE_COMPILE_CACHE -#define ENABLE_PERFORMANCE_COUNTERS +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_MEDICAL_TREATMENT #define DEBUG_MODE_FULL diff --git a/addons/medical_treatment/stringtable.xml b/addons/medical_treatment/stringtable.xml index cee2599676..efe108805f 100644 --- a/addons/medical_treatment/stringtable.xml +++ b/addons/medical_treatment/stringtable.xml @@ -3,51 +3,52 @@ Treatment + Behandlung 治療 Лечение Litter + 廃棄物 Advanced Diagnose + Erweiterte Diagnose アドバンスド診断 Расширенная Диагностика Enables the Check Pulse, Check Blood Pressure, and Check Response treatment actions instead of the generic Diagnose action. + 有効化すると通常の診断動作に代わり、心拍や血圧測定、反応を確認できます。 Advanced Bandages + Erweiterte Bandagen アドバンスド包帯 Расширенная Перевязка Enables treatment actions for different bandage types instead of the generic Bandage action. + 有効化すると通常の包帯動作に代わり、様々な種類がある包帯で治療ができます。 Wound Reopening + 創傷再開放 Enables the reopening of bandaged wounds. Requires Advanced Bandages to be enabled. + 有効化すると治療をした創傷を再開放します。アドバンスド包帯を有効化している必要があります。 Advanced Medication + Erweiterte Medikamente アドバンスド医薬品 Расширенные Лекарства Enables extended, more in-depth medication handling. Also, enables the use of Adenosine and Atropine. Устанавливает расширенное использование лекарств - - - CPR Creates Pulse - HLW erzeugt einen Puls - 心肺蘇生による脈 - СЛР создаст пульс - - - Controls whether performing CPR creates a pulse for the patient. + 有効化するともっと多くの多様な機能を持つ医薬品を使えます。また、アデノシンとアトロピンが利用可能になります。 Locations Boost Training @@ -59,33 +60,42 @@ Localização melhora treinamento Le lieu améliore l'efficacité Места ускоренного обучения - 衛生兵としての能力を与える場所 + 衛生能力の上昇位置 교육 증가 지역 受所在位置影响提升医疗能力 受所在位置影響提升醫療能力 Boost medical training when in medical vehicles or facilities. Untrained becomes medic, medic becomes doctor. + 衛生車両か施設では衛生能力を上昇します。未訓練では衛生兵に、衛生兵では医師になります。 Self IV Transfusion + Eigennutzung von Bluttransfusionen Внутривенное переливание на себе + 自己 IV 輸血 Enables the use of IV Transfusions on oneself. + Erlaube Bluttransfusionen an sich selbst zu benutzen Позволяет использовать внутривенные переливания на себе + 自らに対して IV 輸血を可能にします。 Allow Shared Equipment + 装備共有を許可 Controls whether medical equipment can be shared between the patient and the medic. + 患者と衛生兵との間で医療品の共有をするかどうかを決定します。 Patient's Equipment First + 患者の装備を先に使用 Medic's Equipment First + 衛生兵の装備を先に使用 Allow Epinephrine @@ -104,6 +114,7 @@ Training level required to use Epinephrine. + アドレナリンの使用に訓練レベルを必要とさせます。 Locations Epinephrine @@ -115,13 +126,14 @@ Oblast k použití adrenalinu Localizações de Epinefrina Место использования адреналина - アドレナリンをつかう場所 + アドレナリンの使用可能場所 에피네프린 사용 장소 肾上腺素使用地点 腎上腺素使用地點 Controls where Epinephrine can be used. + アドレナリンが使える場所を決定します。 Allow PAK @@ -141,6 +153,7 @@ Training level required to use a PAK. + 応急処置キットの使用に訓練レベルを必要とさせます。 Locations PAK @@ -153,53 +166,69 @@ Lieu d'utilisation da trousse sanitaire Elsősegélycsomag helyek Locazioni Kit Pronto Soccorso - 応急処置キットを使う場所 + 応急処置キットの使用可能場所 개인응급키트 사용 장소 个人急救包使用地点 個人急救包使用地點 Controls where a PAK can be used. + 応急処置キットが使える場所を決定します。 Consume PAK + 応急処置キットの消費 Controls whether a PAK should be consumed after use. + 応急処置キットの使用後に消費するかどうかを決定します。 Time Coefficient PAK + 応急処置キットの時間係数 Modifies how long a PAK takes to apply.\nThe treatment time is based on the total body part damage multiplied by this coefficient, with a minimum of 10 seconds. + 応急処置キットの使用にかかる時間を変更できます。\n総治療時間は最低でも 10 秒間で、この係数と体全体に負ったダメージによって決まります。 Allow Surgical Kit + 縫合キットを許可 Training level required to use a Surgical Kit. + 縫合キットの使用に訓練レベルを必要とさせます。 Locations Surgical Kit + 縫合キットの使用可能場所 Controls where a Surgical Kit can be used. + 縫合キットが使える場所を決定します。 Consume Surgical Kit + 縫合キットの消費 Controls whether a Surgical Kit should be consumed after use. + 縫合キットの使用後に消費するかどうかを決定します。 Convert Vanilla Items + Standard Arma-Equipment in ACE-Items umwandeln Конвертировать ванильные медикаменты + 標準アイテムの変換 Controls whether vanilla medical items are converted to ACE Medical items, removed only, or ignored. + Legt fest, ob Standard Medic-Equipment in ACE-Equipment umgewandelt oder entfernt wird + ゲーム標準の医療アイテムを ACE 医療アイテムへ変換、削除、そのままにするかを決定します。 Remove Only + 削除 Enable Litter @@ -212,24 +241,28 @@ Activer les détritus Szemét engedélyezése Abilita Barella - 医療廃棄物の表示を有効化 + 廃棄物の有効化 Enables the creation of litter upon treatment. + 治療後に廃棄物の生成を有効化します。 Max Litter Objects + 最大廃棄物数 Sets the maximum number of litter objects which can be spawned, excessive amounts can cause FPS lag. + 生成される最大廃棄物数を設定できます。極端に増やすと FPS ラグを引き起こします。 Litter Lifetime + 廃棄物寿命 Controls the lifetime of litter objects, in seconds. -1 is forever. + 廃棄物の寿命を秒で決定できます。-1 で永遠です。 - Anyone Кем угодно @@ -248,17 +281,20 @@ Medics + 衛生兵 Doctors + 医師 Medical Facilities + 医療施設 Vehicles & Facilities + 車両 & 施設 - [ACE] Medical Supply Crate (Basic) [ACE] Ящик с медикаментами (базовая медицина) @@ -315,7 +351,7 @@ Lékařský výcvik Treino médico Медицинская подготовка - 治療の訓練 + 衛生訓練 의료 훈련 医疗训练 醫療訓練 @@ -331,7 +367,7 @@ Est infirmier Orvos-e E' Medico - 衛生兵として + 衛生兵に 의무병 是医疗兵 是醫療兵 @@ -395,7 +431,7 @@ Véhicule médical Orvosi jármű-e E' Veicolo Medico - 医療車両として + 医療車両に 의료 차량 是医疗载具 是醫療載具 @@ -411,7 +447,7 @@ Est une installation médical Orvosi létesítmény-e E' Struttura Medica - 医療施設として + 医療施設に 의료시설 是医疗设施 是醫療設施 @@ -491,7 +527,7 @@ Usato per coprire una ferita Usado para cobrir um ferimento Slouží k překrytí poranění - 傷口をおおう + 傷口を覆います 상처를 덮을때 씁니다 用于覆盖伤口 用於覆蓋傷口 @@ -659,10 +695,12 @@ Splint Шина + 添え木 Stabilizes a fractured limb Стабилизирует перелом конечности + 骨折部位を安定させます。 Morphine autoinjector @@ -1862,10 +1900,12 @@ Apply Splint Наложить Шину + 添え木を当てる Applying Splint... Накладывается Шина... + 添え木を当てています・・・ Diagnose @@ -1931,6 +1971,14 @@ 进行心肺复苏术中... 進行心肺復甦術中... + + CPR Success Chance + 心肺蘇生の成功率 + + + Probability that cpr will be successful in restoring heart rhythm. + 心肺蘇生によって心拍を戻せる確率を決定できます。 + Give Blood IV (1000ml) Bluttransfusion IV (1000ml) @@ -2077,6 +2125,7 @@ Minimal + Minimal 軽処置群 Минимально @@ -3063,7 +3112,7 @@ Cipelés Carregar Trasporta - 運ぶ + 担ぐ 업다 背起 背起 diff --git a/addons/medical_treatment/ui/splint_ca.paa b/addons/medical_treatment/ui/splint_ca.paa new file mode 100644 index 0000000000..ea09181ef0 Binary files /dev/null and b/addons/medical_treatment/ui/splint_ca.paa differ diff --git a/addons/medical_vitals/XEH_preInit.sqf b/addons/medical_vitals/XEH_preInit.sqf index a7feade1c3..b47cf6628d 100644 --- a/addons/medical_vitals/XEH_preInit.sqf +++ b/addons/medical_vitals/XEH_preInit.sqf @@ -2,6 +2,8 @@ ADDON = false; +PREP_RECOMPILE_START; #include "XEH_PREP.hpp" +PREP_RECOMPILE_END; ADDON = true; diff --git a/addons/medical_vitals/functions/fnc_handleUnitVitals.sqf b/addons/medical_vitals/functions/fnc_handleUnitVitals.sqf index 64c8b0cd4c..5fe474ad38 100644 --- a/addons/medical_vitals/functions/fnc_handleUnitVitals.sqf +++ b/addons/medical_vitals/functions/fnc_handleUnitVitals.sqf @@ -113,6 +113,7 @@ switch (true) do { TRACE_3("BloodVolume Fatal",_unit,BLOOD_VOLUME_FATAL,_bloodVolume); [QEGVAR(medical,Bleedout), _unit] call CBA_fnc_localEvent; }; + case (IN_CRDC_ARRST(_unit)): {}; // if in cardiac arrest just break now to avoid throwing unneeded events case (_hemorrhage == 4): { TRACE_3("Class IV Hemorrhage",_unit,_hemorrhage,_bloodVolume); [QEGVAR(medical,FatalVitals), _unit] call CBA_fnc_localEvent; diff --git a/addons/medical_vitals/functions/fnc_updateHeartRate.sqf b/addons/medical_vitals/functions/fnc_updateHeartRate.sqf index b7abb89a24..4da8519077 100644 --- a/addons/medical_vitals/functions/fnc_updateHeartRate.sqf +++ b/addons/medical_vitals/functions/fnc_updateHeartRate.sqf @@ -22,7 +22,15 @@ params ["_unit", "_hrTargetAdjustment", "_deltaT", "_syncValue"]; private _heartRate = GET_HEART_RATE(_unit); -if !IN_CRDC_ARRST(_unit) then { +if IN_CRDC_ARRST(_unit) then { + if (alive (_unit getVariable [QEGVAR(medical,CPR_provider), objNull])) then { + if (_heartRate == 0) then { _syncValue = true }; // always sync on large change + _heartRate = random [25, 30, 35]; + } else { + if (_heartRate != 0) then { _syncValue = true }; // always sync on large change + _heartRate = 0 + }; +} else { private _hrChange = 0; private _targetHR = 0; private _bloodVolume = GET_BLOOD_VOLUME(_unit); @@ -32,12 +40,12 @@ if !IN_CRDC_ARRST(_unit) then { private _painLevel = GET_PAIN_PERCEIVED(_unit); private _targetBP = 107; - if (_bloodVolume < BLOOD_VOLUME_CLASS_3_HEMORRHAGE) then { + if (_bloodVolume < BLOOD_VOLUME_CLASS_2_HEMORRHAGE) then { _targetBP = _targetBP * (_bloodVolume / DEFAULT_BLOOD_VOLUME); }; _targetHR = DEFAULT_HEART_RATE; - if (_bloodVolume < BLOOD_VOLUME_CLASS_2_HEMORRHAGE) then { + if (_bloodVolume < BLOOD_VOLUME_CLASS_3_HEMORRHAGE) then { _targetHR = _heartRate * (_targetBP / (45 max _meanBP)); }; if (_painLevel > 0.2) then { diff --git a/addons/movement/CfgMoves.hpp b/addons/movement/CfgMoves.hpp index c8273fcdb2..edf6bac4a3 100644 --- a/addons/movement/CfgMoves.hpp +++ b/addons/movement/CfgMoves.hpp @@ -57,13 +57,24 @@ class CfgMovesBasic { // jump animation - WEAPON LOWERED - RUNNING class RifleLowStandActionsNoAdjust; class RifleLowStandActionsRunF: RifleLowStandActionsNoAdjust { - getOver = "AovrPercMrunSrasWrflDf"; + getOver = "ACE_AovrPercMrunSlowWrflDf"; }; class RifleLowStandActionsRunFL: RifleLowStandActionsNoAdjust { - getOver = "AovrPercMrunSrasWrflDf"; + getOver = "ACE_AovrPercMrunSlowWrflDf"; }; class RifleLowStandActionsRunFR: RifleLowStandActionsNoAdjust { - getOver = "AovrPercMrunSrasWrflDf"; + getOver = "ACE_AovrPercMrunSlowWrflDf"; + }; + + // jump animation - WEAPON LOWERED - SPRINTING + class RifleStandLowEvasiveActionsF: RifleLowStandActionsNoAdjust { + getOver = "ACE_AovrPercMrunSlowWrflDf"; + }; + class RifleStandLowEvasiveActionsFR: RifleLowStandActionsNoAdjust { + getOver = "ACE_AovrPercMrunSlowWrflDf"; + }; + class RifleStandLowEvasiveActionsFL: RifleLowStandActionsNoAdjust { + getOver = "ACE_AovrPercMrunSlowWrflDf"; }; }; }; @@ -76,11 +87,178 @@ class CfgMovesMaleSdr: CfgMovesBasic { class AovrPercMrunSrasWrflDf: AovrPercMstpSrasWrflDf { forceAim = 0; }; + class ACE_AovrPercMrunSlowWrflDf: AovrPercMrunSrasWrflDf { // custom + actions = "RifleLowStandActionsRunF"; - // replace link of vault with jump animation + ConnectTo[] = { + "AidlPercMstpSlowWrflDnon_G0S",0.02, + "AmovPercMstpSlowWrflDnon",0.03, + "WeaponMagazineReloadStand",0.1, + //"AmovPercMstpSrasWrflDnon_AmovPercMstpSrasWlnrDnon",0.01, + "AmovPercMstpSlowWrflDnon_AmovPercMstpSrasWrflDnon",0.01, + //"AmovPercMstpSrasWrflDnon_AmovPercMstpSrasWpstDnon",0.02, + //"AmovPercMstpSrasWrflDnon_AwopPercMstpSoptWbinDnon",0.02, + //"AmovPercMstpSrasWrflDnon_AmovPercMstpSnonWnonDnon",0.02, + "AwopPercMstpSgthWrflDnon_Start2",0.1, + "AmovPercMstpSrasWrflDnon_AinvPknlMstpSlayWrflDnon",0.02, + //"AmovPercMstpSrasWrflDnon_AadjPercMstpSrasWrflDup",0.02, + //"AmovPercMstpSrasWrflDnon_AadjPercMstpSrasWrflDdown",0.02, + //"AmovPercMstpSrasWrflDnon_AadjPercMstpSrasWrflDleft",0.02, + //"AmovPercMstpSrasWrflDnon_AadjPercMstpSrasWrflDright",0.02, + "AmovPercMstpSrasWrflDnon_AmovPercMstpSrasWrflDnon_gear",0.02 + }; + InterpolateTo[] = { + "AmovPercMstpSlowWrflDnon_turnL",0.02, + "AmovPercMstpSlowWrflDnon_turnR",0.02, + "AmovPercMstpSlowWrflDnon_AmovPknlMstpSlowWrflDnon",0.01, + "AmovPercMstpSlowWrflDnon_AmovPpneMstpSrasWrflDnon",0.01, + "AmovPercMstpSlowWrflDnon_AcinPknlMwlkSlowWrflDb_1",0.01, + "Helper_SwitchToCarryRfl",0.2, + "AmovPercMstpSrasWrflDnon_AinvPercMstpSrasWrflDnon",0.02, + "AmovPercMstpSrasWrflDnon_AinvPercMstpSrasWrflDnon_Putdown",0.02, + "AmovPercMwlkSlowWrflDf",0.02, + "AmovPercMwlkSlowWrflDfl",0.02, + "AmovPercMwlkSlowWrflDl",0.02, + "AmovPercMwlkSlowWrflDbl",0.02, + "AmovPercMwlkSlowWrflDb",0.02, + "AmovPercMwlkSlowWrflDbr",0.02, + "AmovPercMwlkSlowWrflDr",0.02, + "AmovPercMwlkSlowWrflDfr",0.02, + "AmovPercMrunSlowWrflDf",0.02, + "AmovPercMrunSlowWrflDfl",0.02, + "AmovPercMrunSlowWrflDl",0.02, + "AmovPercMrunSlowWrflDbl",0.02, + "AmovPercMrunSlowWrflDb",0.02, + "AmovPercMrunSlowWrflDbr",0.02, + "AmovPercMrunSlowWrflDr",0.02, + "AmovPercMrunSlowWrflDfr",0.02, + //"AmovPercMrunSrasWrflDf_ldst",0.02, + //"AmovPercMrunSrasWrflDfl_ldst",0.02, + //"AmovPercMrunSrasWrflDl_ldst",0.02, + //"AmovPercMrunSrasWrflDbl_ldst",0.02, + //"AmovPercMrunSrasWrflDb_ldst",0.02, + //"AmovPercMrunSrasWrflDbr_ldst",0.02, + //"AmovPercMrunSrasWrflDr_ldst",0.02, + //"AmovPercMrunSrasWrflDfr_ldst",0.02, + "AmovPercMstpSlowWrflDnon_AmovPknlMstpSlowWrflDnon",0.02, + "AmovPercMevaSlowWrflDf",0.02, + "AmovPercMevaSlowWrflDfl",0.02, + "AmovPercMevaSlowWrflDfr",0.02, + "AmovPercMstpSlowWrflDnon_SaluteIn",0.03, + "Unconscious",0.02, + "AidlPercMstpSlowWrflDnon_AI",0.02, + "AidlPercMstpSlowWrflDnon_AI",0.02, + "AovrPercMstpSlowWrflDf",1.01, + "AmovPercMtacSlowWrflDfl",0.2, + "AmovPercMtacSlowWrflDl",0.2, + "AmovPercMtacSlowWrflDbl",0.2, + "AmovPercMtacSlowWrflDb",0.2, + "AmovPercMtacSlowWrflDbr",0.2, + "AmovPercMtacSlowWrflDr",0.2, + "AmovPercMtacSlowWrflDfr",0.22, + "AmovPercMtacSlowWrflDf",0.02, + "HaloFreeFall_non",10.2, + "AmovPercMrunSlowWrflDf",0.02, + "AmovPercMrunSlowWrflDfl",0.02, + "AmovPercMrunSlowWrflDl",0.02, + "AmovPercMrunSlowWrflDb",0.02, + "AmovPercMrunSlowWrflDbr",0.02, + "AmovPercMrunSlowWrflDr",0.02, + "AmovPercMrunSlowWrflDbl",0.02, + "AmovPercMrunSlowWrflDfr",0.02, + "AmovPercMstpSrasWrflDnon_falling",0.02, + "AsdvPercMstpSnonWrflDnon",2.02, + "AdvePercMstpSnonWrflDnon",2.02, + "AbdvPercMstpSnonWrflDnon",2.02, + "AinvPercMstpSrasWrflDnon",0.05, + "AmovPknlMstpSlowWrflDnon_AmovPercMstpSlowWrflDnon",0.02, + //"AmovPpneMstpSrasWrflDnon_AmovPercMstpSrasWrflDnon",0.02, + //"AmovPercMstpSlowWrflDnon_AmovPercMstpSrasWrflDnon",0.02, + "AmovPercMstpSlowWrflDnon_AmovPsitMstpSlowWrflDnon",0.02, + "AfalPercMstpSrasWrflDnon",0.025, + //"AmovPercMevaSrasWrflDl",0.025, + //"AmovPercMevaSrasWrflDr",0.025, + "Acts_PercMstpSlowWrflDnon_handup2",1, + "Acts_WalkingChecking",1, + "Acts_PercMstpSlowWrflDnon_handup1",1, + "Acts_PercMstpSlowWrflDnon_handup2b",1, + "Acts_PercMstpSlowWrflDnon_handup2c",1, + "Acts_PercMstpSlowWrflDnon_handup1b",1, + "Acts_PercMstpSlowWrflDnon_handup1c",1, + "HubSpectator_stand",1, + "HubSpectator_walk",1, + "HubStanding_idle1",1, + "HubStanding_idle2",1, + "HubStanding_idle3",1, + "Campaign_Base",0.5, + "CutSceneAnimationBase",0.5, + "AmovPercMlmpSlowWrflDf",0.05, + "AmovPercMlmpSlowWrflDfl",0.05, + "AmovPercMlmpSlowWrflDl",0.05, + "AmovPercMlmpSlowWrflDbl",0.05, + "AmovPercMlmpSlowWrflDb",0.05, + "AmovPercMlmpSlowWrflDbr",0.05, + "AmovPercMlmpSlowWrflDr",0.05, + "AmovPercMlmpSlowWrflDfr",0.05, + "acts_millerDisarming_runToDesk",0.05, + "CutSceneAnimationSmk",0.1, + "UnconsciousFaceDown",0.25, + "UnconsciousMedicFromRifle",0.2 + }; + }; + + // rifle raised, replace link of vault with jump animation class AmovPercMstpSrasWrflDnon; class AmovPercMrunSrasWrflDf: AmovPercMstpSrasWrflDnon { - InterpolateTo[] = {"AovrPercMrunSrasWrflDf",0.22,"AmovPercMrunSlowWrflDf",0.025,"AmovPercMwlkSrasWrflDf",0.025,"AmovPknlMrunSrasWrflDf",0.03,"AmovPercMrunSlowWrflDf_AmovPpneMstpSrasWrflDnon",0.02,"AmovPercMevaSrasWrflDf",0.025,"Unconscious",0.01,"AmovPercMtacSrasWrflDf",0.02,"AmovPercMrunSrasWrflDfl",0.02,"AmovPercMrunSrasWrflDfl_ldst",0.02,"AmovPercMrunSrasWrflDfr",0.02,"AmovPercMrunSrasWrflDfr_ldst",0.02,"AmovPercMstpSrasWrflDnon",0.02,"AmovPercMrunSrasWrflDl",0.02,"AmovPercMrunSrasWrflDbl",0.02,"AmovPercMrunSrasWrflDb",0.02,"AmovPercMrunSrasWrflDbr",0.02,"AmovPercMrunSrasWrflDr",0.02,"AmovPknlMstpSlowWrflDnon_relax",0.1,"AmovPercMrunSrasWrflDf_ldst",0.02,"AmovPercMrunSrasWrflDf",0.02}; + InterpolateTo[] = { + "AovrPercMrunSrasWrflDf",0.22, + "AmovPercMrunSlowWrflDf",0.025, + "AmovPercMwlkSrasWrflDf",0.025, + "AmovPknlMrunSrasWrflDf",0.03, + "AmovPercMrunSlowWrflDf_AmovPpneMstpSrasWrflDnon",0.02, + "AmovPercMevaSrasWrflDf",0.025, + "Unconscious",0.01, + "AmovPercMtacSrasWrflDf",0.02, + "AmovPercMrunSrasWrflDfl",0.02, + "AmovPercMrunSrasWrflDfl_ldst",0.02, + "AmovPercMrunSrasWrflDfr",0.02, + "AmovPercMrunSrasWrflDfr_ldst",0.02, + "AmovPercMstpSrasWrflDnon",0.02, + "AmovPercMrunSrasWrflDl",0.02, + "AmovPercMrunSrasWrflDbl",0.02, + "AmovPercMrunSrasWrflDb",0.02, + "AmovPercMrunSrasWrflDbr",0.02, + "AmovPercMrunSrasWrflDr",0.02, + "AmovPknlMstpSlowWrflDnon_relax",0.1, + "AmovPercMrunSrasWrflDf_ldst",0.02, + "AmovPercMrunSrasWrflDf",0.02 + }; + }; + + // rifle lowered, add link to jump animation + class AmovPercMstpSlowWrflDnon; + class AmovPercMrunSlowWrflDf: AmovPercMstpSlowWrflDnon { + InterpolateTo[] = { + "ACE_AovrPercMrunSlowWrflDf",0.22, + "AmovPercMstpSlowWrflDnon",0.02, + "AmovPercMwlkSlowWrflDf_ver2",0.025, + "AmovPercMwlkSlowWrflDf",0.5, + "AidlPercMrunSrasWrflDf",0.01, + "AmovPercMrunSlowWrflDfl",0.025, + "AmovPercMrunSlowWrflDfr",0.025, + "AmovPercMrunSrasWrflDf",0.025, + "AmovPknlMrunSlowWrflDf",0.03, + "AmovPercMrunSlowWrflDf_AmovPpneMstpSrasWrflDnon",0.02, + "AmovPercMevaSrasWrflDf",0.025, + "AmovPercMevaSlowWrflDf",0.025, + "Unconscious",0.02, + "AmovPercMrunSlowWrflDf_AmovPercMstpSrasWrflDnon_gthStart",0.1, + "AmovPknlMstpSlowWrflDnon_relax",0.1, + "AmovPercMtacSlowWrflDf_ver2",0.2, + "AmovPercMtacSlowWrflDf",0.5, + "AmovPercMwlkSrasWrflDf",0.02, + "AmovPercMtacSrasWrflDf",0.02 + }; }; // enable optics in prone down stance diff --git a/addons/nametags/stringtable.xml b/addons/nametags/stringtable.xml index 2bc6da0ab7..02993e83e9 100644 --- a/addons/nametags/stringtable.xml +++ b/addons/nametags/stringtable.xml @@ -542,6 +542,7 @@ Player tags transparency + Spielernamen Transparenz プレイヤー名札の透明度 玩家名字标签透明度 玩家名稱透明度 diff --git a/addons/nightvision/stringtable.xml b/addons/nightvision/stringtable.xml index 024d3c63c7..827f318e20 100644 --- a/addons/nightvision/stringtable.xml +++ b/addons/nightvision/stringtable.xml @@ -327,6 +327,7 @@ Shutter Effects + Rolling-Shutter-Effekt シャッター効果 快门效果 快門效果 @@ -337,6 +338,7 @@ Rolling shutter effect from muzzle flashes + Rolling-Shutter-Effekt bei Müdungsfeuer 発射炎が作るローリング シャッター効果です 枪械开火时产生瞬间快门效果 槍開火時瞬間產生快門效果 diff --git a/addons/overpressure/stringtable.xml b/addons/overpressure/stringtable.xml index 14455f9ccc..e66a31f608 100644 --- a/addons/overpressure/stringtable.xml +++ b/addons/overpressure/stringtable.xml @@ -27,6 +27,7 @@ Backblast range + Rückstoßbereich 後方噴射の範囲 向后喷射的范围 後方尾焰的範圍 @@ -36,6 +37,7 @@ Backblast angle + Rückstoßwinkel 後方噴射の角度 向后喷射的角度 後方尾焰的角度 diff --git a/addons/pylons/stringtable.xml b/addons/pylons/stringtable.xml index b107e85aa5..a24650d543 100644 --- a/addons/pylons/stringtable.xml +++ b/addons/pylons/stringtable.xml @@ -127,6 +127,7 @@ 啟用派龍架選單給宙斯 Abilita Menù Piloni da Zeus Zeus でパイロン メニューを有効化 + Aktiviert Außenlaststationsmenü im Zeus Activer le menu des pylônes (Zeus) Aktywuj Menu Pylonów dla Zeus'a Активировать Меню пилонов для Зевса @@ -137,6 +138,7 @@ 允啟使用宙斯模塊 Abilita l'uso dal modulo di Zeus Zeus モジュールでパイロン メニューを利用できます。 + Aktiviert die Nutzung im Zeus Autorise l'utilisation des modules Zeus Aktywuj wykorzystanie modułu zeus'a. Позволяет использовать модуль Зевса @@ -147,6 +149,7 @@ 啟用從彈藥卡車使用派龍架選單 Abilita Menù Piloni da mezzi rifornimento munizioni 弾薬トラックからパイロン メニューを有効化 + Aktiviert Außenlaststationsmenü von Munitionstransportern Activer le menu des pylônes (camion de munitions) Aktywuj Menu Pylonów dla Ciężarówek z amunicją Меню пилонов из грузовика боеприпасов @@ -157,6 +160,7 @@ 允許從彈藥卡車使用派龍架選單 Abilita l'uso del Menù Piloni da mezzi rifornimento munizioni 弾薬給弾トラックからパイロン メニューを利用できます。 + Aktiviert die Nutzung von Außenlaststationsmenü von Munitionstransportern. Autorise l'utilisation du menu des pylônes depuis les camions de munitions. Aktywuj wykorzystanie menu pylonów z ciężarówek z amunicją. Позволяет использовать меню пилонов из грузовика с боеприпасами @@ -167,6 +171,7 @@ 這架飛機沒有派龍架 Questo aereo non ha piloni 航空機にパイロンがありません + Dieses Flugzeug hat keine Außenlaststationen Cet aéronef n'a pas de pylônes Ten pojazd nie posiada pylonów Эта авиатехника не имеет пилонов @@ -177,6 +182,7 @@ 宙斯模塊的派龍架設定已被禁用 Il modulo per configurare i piloni da Zeus è disabilitato Zeus のパイロン モジュールを無効化 + Die Konfiguration für das Außenlaststationen ist im Zeus deaktiviert La configuration de pylônes est désactivé pour Zeus Konfiguracja modułu pylonów jest wyłączona dla zeus'a Модуль Настройка пилонов отключен для Zeus diff --git a/addons/quickmount/XEH_postInitClient.sqf b/addons/quickmount/XEH_postInitClient.sqf index 718c08b843..23c225f583 100644 --- a/addons/quickmount/XEH_postInitClient.sqf +++ b/addons/quickmount/XEH_postInitClient.sqf @@ -4,7 +4,7 @@ if (!hasInterface) exitWith {}; ["ACE3 Movement", QGVAR(mount), [localize LSTRING(KeybindName), localize LSTRING(KeybindDescription)], "", { if (!dialog) then { - call FUNC(getInNearest); + [] call FUNC(getInNearest); }; false }] call CBA_fnc_addKeybind; diff --git a/addons/quickmount/functions/fnc_getInNearest.sqf b/addons/quickmount/functions/fnc_getInNearest.sqf index 8e8d77fe8d..b94ba8f0d9 100644 --- a/addons/quickmount/functions/fnc_getInNearest.sqf +++ b/addons/quickmount/functions/fnc_getInNearest.sqf @@ -4,7 +4,7 @@ * Mount the player in the vehicle they are directly looking at based on their distance. * * Arguments: - * None + * 0: Target (Optional) * * Return Value: * None @@ -22,17 +22,27 @@ if (!GVAR(enabled) || {ACE_player getVariable ["ace_unconscious", false]} ) exitWith {}; +params [["_interactionTarget", objNull, [objNull]]]; +TRACE_1("getInNearest",_interactionTarget); + private _start = AGLtoASL (ACE_player modelToWorldVisual (ACE_player selectionPosition "pilot")); private _end = (_start vectorAdd (getCameraViewDirection ACE_player vectorMultiply GVAR(distance))); private _objects = lineIntersectsSurfaces [_start, _end, ACE_player]; private _target = (_objects param [0, []]) param [2, objNull]; +if ((isNull _target) && {alive _interactionTarget}) then { + _end = _start vectorAdd ((_start vectorFromTo (aimPos _interactionTarget)) vectorMultiply GVAR(distance)); + _objects = lineIntersectsSurfaces [_start, _end, ACE_player]; + TRACE_1("2nd ray attempt at interaction target aim pos",_objects); + _target = (_objects param [0, []]) param [2, objNull]; +}; + if (locked _target in [2,3]) exitWith { [localize LSTRING(VehicleLocked)] call EFUNC(common,displayTextStructured); true }; -TRACE_1("",_target); +TRACE_2("",_target,typeOf _target); if (!isNull _target && {alive _target} && diff --git a/addons/quickmount/stringtable.xml b/addons/quickmount/stringtable.xml index c55fa32970..e6496fd86a 100644 --- a/addons/quickmount/stringtable.xml +++ b/addons/quickmount/stringtable.xml @@ -124,6 +124,7 @@ Change seat + Sitz wechseln Пересесть 席の変更 Zmień zajmowaną pozycję diff --git a/addons/repair/stringtable.xml b/addons/repair/stringtable.xml index 49b869c1f1..c1ac98892f 100644 --- a/addons/repair/stringtable.xml +++ b/addons/repair/stringtable.xml @@ -1868,6 +1868,7 @@ Auto shut off engine on repair + Motor automatisch ausschalten 修理時にエンジン自動停止 维修时自动关闭发动机。 維修時自動關閉引擎 @@ -1877,6 +1878,7 @@ Automatically shut off the engine when doing repairs. + Schaltet den Motor automatisch aus, sobald das Fahrzeug repariert wird. 修理時にエンジンを自動で停止します。 修理时自动关闭发动机。 維修時自動關閉引擎 diff --git a/addons/respawn/stringtable.xml b/addons/respawn/stringtable.xml index beddc62c35..210ccf520d 100644 --- a/addons/respawn/stringtable.xml +++ b/addons/respawn/stringtable.xml @@ -3,6 +3,7 @@ Respawn + Wiedereinstieg Riapparizione 重生 重生 @@ -284,6 +285,7 @@ Body remove timer + Zeit bis Körper entfernt werden Timer rimozione corpo 屍體移除計時器 尸体移除计时器 diff --git a/addons/scopes/stringtable.xml b/addons/scopes/stringtable.xml index b97392f561..b437f82d99 100644 --- a/addons/scopes/stringtable.xml +++ b/addons/scopes/stringtable.xml @@ -478,6 +478,7 @@ Horizontal limits + Horizontale Grenzen 水平限制 水平制限 Limite orrizontale @@ -486,6 +487,7 @@ Vertical limits + Vertikale Grenzen 垂直限制 垂直制限 Limite verticale diff --git a/addons/spectator/stringtable.xml b/addons/spectator/stringtable.xml index 8ca9afd2e3..9bce522433 100644 --- a/addons/spectator/stringtable.xml +++ b/addons/spectator/stringtable.xml @@ -187,10 +187,12 @@ Max Follow Distance Макс. дистанция следования + 最大追随距離 Maximum distance the follow camera can be from the target Максимальная дистанция от камеры слежения до цели + カメラが目標へ追随できる最大距離を決定できます。 diff --git a/addons/vehicles/stringtable.xml b/addons/vehicles/stringtable.xml index f4d1904072..ffca34b7ec 100644 --- a/addons/vehicles/stringtable.xml +++ b/addons/vehicles/stringtable.xml @@ -35,6 +35,7 @@ Speed Limit + Geschwindigkeitsbegrenzung Limite di velocità 速度制限 Ograniczenie prędkości @@ -58,6 +59,7 @@ Increase Speed Limit + Maximale Geschwindigkeit erhöhen Aumenta limite di velocità 速度制限を増やす Zwiększ ograniczenie prędkości @@ -65,6 +67,7 @@ Decrease Speed Limit + Maximale Geschwindigkeit verringern Diminuisce limite di velocità 速度制限を減らす Zmniejsz ograniczenie prędkości @@ -87,12 +90,14 @@ Abspringen-Aktion verstecken Ukryj akcję Wyskocz Убрать действие 'Выпрыгнуть' + 脱出アクションを非表示 Hides the Eject entry from the action menu. Requires a game restart. Versteckt den Abspringen-Eintrag aus dem Aktionsmenü. Benötigt Neustart des Spiels. Usuwa akcję Wyskocz z menu akcji. Wymaga restartu gry. Убирает действие 'Выпрыгнуть' из меню. (Требует перезагрузки) + アクション メニューから脱出アクションを消します。ゲームの再起動が必要です。 diff --git a/addons/weaponselect/stringtable.xml b/addons/weaponselect/stringtable.xml index 36815cebb4..d1f3ce670f 100644 --- a/addons/weaponselect/stringtable.xml +++ b/addons/weaponselect/stringtable.xml @@ -371,6 +371,7 @@ Toggle Collision Lights + Kollisionslichter an/ausschalten Attiva Luci di Collisione 충돌 표시등 토글 切換碰撞燈 diff --git a/addons/zeus/functions/fnc_moduleHeal.sqf b/addons/zeus/functions/fnc_moduleHeal.sqf index 287a84ac79..627c48ef36 100644 --- a/addons/zeus/functions/fnc_moduleHeal.sqf +++ b/addons/zeus/functions/fnc_moduleHeal.sqf @@ -45,7 +45,7 @@ switch (false) do { // Heal validated target if (["ace_medical"] call EFUNC(common,isModLoaded)) then { TRACE_1("healing with ace_medical",_unit); - [QEGVAR(medical_treatment,treatmentFullHealLocal), [_unit], _unit] call CBA_fnc_targetEvent; + [QEGVAR(medical_treatment,fullHealLocal), [_unit], _unit] call CBA_fnc_targetEvent; } else { // BI's scripted revive system if ((missionNamespace getVariable ["bis_revive_mode", 0]) != 0) then { diff --git a/addons/zeus/stringtable.xml b/addons/zeus/stringtable.xml index 66174a31e1..9ec53fe265 100644 --- a/addons/zeus/stringtable.xml +++ b/addons/zeus/stringtable.xml @@ -6,6 +6,7 @@ Zeus 宙斯 宙斯 + Zeus Zeus 제우스 Zeus @@ -280,6 +281,7 @@ Editing Mode 編輯模式 Modalità per editare + Bearbeitungsmodus 編集モード Tryb Edytowania Режим редактирования @@ -287,6 +289,7 @@ Add or remove editable objects from Zeus 新增或移除可編輯物件給宙斯 + Aktiviere oder deaktiviere zu bearbeitende Objekte von Zeus Agguingi o rimuovi oggetti che Zeus può modificare Zeus から編集可能オブジェクトの追加と削除をする Dodaj lub usuń edytowalne obiekty z Zeus'a @@ -338,6 +341,7 @@ Additional Objects + Zusätzliche Objekte Oggetti aggiuntivi オブジェクト増加 Dodatkowe obiekty @@ -345,6 +349,7 @@ Additional objects to include in the action regardless of Task Radius + Zusätzliche Objekte unabhängig vom Aufgabenradius einbeziehen Oggetti aggiuntivi da includere nell'azione indipendentemente dal Raggio di Attività タスク範囲に関係無くオブジェクトを更に増加させます Dodatkowe obiekty do uwzględnienia w akcji niezależnie od zasięgu zadania @@ -959,6 +964,7 @@ None + Keiner Niente Żadne なし @@ -966,6 +972,7 @@ Players + Spieler Giocatori Gracze プレイヤー @@ -973,6 +980,7 @@ Players and AI + Spieler und KI's Giocati e AI Gracze i SI プレイヤーと AI @@ -1023,6 +1031,7 @@ Select cargo to unload + Ladung zum ausladen auswählen 選擇要卸載的貨物 Scegli il carico da scaricare 選択したカーゴを降ろす @@ -1151,6 +1160,7 @@ Toggle Target + Ziel umschalten 目標を切り替え 切换目标 切換目標 @@ -1160,6 +1170,7 @@ Units affected by the toggle + Betroffene Spieler beim umschalten ユニットは切り替えに影響を受けます 被选单位受切换影响 受切換所影響的單位 @@ -1217,6 +1228,7 @@ Garrison Group + Gebäude besetzen Garnir zone 歩哨グループ Proteggi gruppo @@ -1228,6 +1240,7 @@ Fill from top to bottom + Von oben nach unten befüllen Remplir de haut en bas 上から下まで占拠 Riempi dall'alto al basso @@ -1239,6 +1252,7 @@ Fill buildings from the highest position first + Gebäude von der höchsten Position zuerst befüllen Remplir les bâtiments par la position la plus haute d'abord 建物を最も高い位置から占拠していきます Riempi gli edifici dalla posizione più alta prima @@ -1250,6 +1264,7 @@ Building filling mode + Gebäude befüllen Mode de remplissage de bâtiment 建物占拠モード Modalità riempimento edifici @@ -1261,6 +1276,7 @@ Even filling + Gleichmäßig befüllen Remplissage égal 均一に占拠 Riempimento uguale @@ -1272,6 +1288,7 @@ Building by building + Gebäude nach Gebäude Bâtiment par bâtiment 建物から建物へ Edificio per edificio @@ -1283,6 +1300,7 @@ Random filling + Zufällig füllen Remplir au hasard ランダムに占拠 Riempimento casuale @@ -1294,6 +1312,7 @@ Teleport + Teleportieren Téléporter テレポート Teletrasporto @@ -1305,6 +1324,7 @@ Un-garrison Group + Garnisionsgruppe auflösen Dégarnir zone 非歩哨グループ Non proteggere gruppo @@ -1524,6 +1544,7 @@ Add full ACE Arsenal + Vollständiges ACE Arsenal hinzufügen ACE 武器庫を追加 添加ACE模式军火库 增加完整的ACE軍火庫 @@ -1533,6 +1554,7 @@ Remove ACE Arsenal + ACE Arsenal entfernen ACE 武器庫を削除 删除ACE模式军火库 移除ACE軍火庫 @@ -1542,6 +1564,7 @@ Create Zeus + Zeus erstellen Создать Зевса Zeus を作る Stwórz Zeus'a @@ -1549,6 +1572,7 @@ Delete Zeus + Zeus löschen Удалить Зевса Zeus を消す Usuń Zeus'a @@ -1556,6 +1580,7 @@ "%1" menu + "%1" Menü Меню "%1" "%1" メニュー "%1" menu @@ -1563,12 +1588,14 @@ Paradrop Cargo + Paradrop Ladung カーゴを空中投下 Zrzut ładunku (cargo) Десантировать груз No cargo loaded + Keine Ladung geladen カーゴは未積載 Niczego nie załadowano do cargo Грузовой отсек пуст diff --git a/docs/_includes/dependencies_list.md b/docs/_includes/dependencies_list.md index c3ce51ec82..ae724aaeb6 100644 --- a/docs/_includes/dependencies_list.md +++ b/docs/_includes/dependencies_list.md @@ -507,7 +507,7 @@ {% endif %} {% if include.component == "compat_rhs_usf3" %} -`ace_javelin`, `ace_rearm`, `ace_refuel`, `ace_repair`, `rhsusf_c_weapons`, `rhsusf_c_troops`, `rhsusf_c_m1a1`, `rhsusf_c_m1a2`, `RHS_US_A2_AirImport`, `rhsusf_c_m109`, `rhsusf_c_HEMTT_A4`, `rhsusf_c_hmmwv`, `rhsusf_c_rg33`, `rhsusf_c_fmtv`, `rhsusf_c_m113`, `RHS_US_A2Port_Armor`, `rhsusf_c_melb` +`ace_explosives`, `ace_javelin`, `ace_rearm`, `ace_refuel`, `ace_repair`, `rhsusf_c_weapons`, `rhsusf_c_troops`, `rhsusf_c_m1a1`, `rhsusf_c_m1a2`, `RHS_US_A2_AirImport`, `rhsusf_c_m109`, `rhsusf_c_HEMTT_A4`, `rhsusf_c_hmmwv`, `rhsusf_c_rg33`, `rhsusf_c_fmtv`, `rhsusf_c_m113`, `RHS_US_A2Port_Armor`, `rhsusf_c_melb` {% endif %} {% if include.component == "compat_rksl_pm_ii" %} diff --git a/docs/src/package-lock.json b/docs/src/package-lock.json index dd0491e67c..3cf214ead7 100644 --- a/docs/src/package-lock.json +++ b/docs/src/package-lock.json @@ -425,7 +425,7 @@ }, "p-cancelable": { "version": "0.4.1", - "resolved": "http://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==", "dev": true, "optional": true @@ -496,7 +496,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "optional": true, @@ -512,7 +512,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "optional": true, @@ -1135,14 +1135,14 @@ "dependencies": { "file-type": { "version": "3.9.0", - "resolved": "http://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", "dev": true, "optional": true }, "get-stream": { "version": "2.3.1", - "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", "dev": true, "optional": true, @@ -1251,7 +1251,7 @@ "dependencies": { "domelementtype": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", "dev": true, "optional": true @@ -1872,7 +1872,7 @@ }, "get-stream": { "version": "3.0.0", - "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", "dev": true, "optional": true @@ -2617,7 +2617,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { @@ -2654,7 +2654,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { @@ -2933,9 +2933,9 @@ } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.13.tgz", + "integrity": "sha512-vm3/XWXfWtRua0FkUyEHBZy8kCPjErNBT9fJx8Zvs+U6zjqPbTUOpkaoum3O5uiA8sm+yNMHXfYkTUHFoMxFNA==" }, "logalot": { "version": "2.1.0", @@ -3679,7 +3679,7 @@ "dependencies": { "string_decoder": { "version": "0.10.31", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } diff --git a/docs/src/package.json b/docs/src/package.json index cd6f1d4d0b..5a7586ac7e 100644 --- a/docs/src/package.json +++ b/docs/src/package.json @@ -2,7 +2,7 @@ "name": "ACE3", "version": "0.1.0", "dependencies": { - "lodash": "^4.17.11" + "lodash": "^4.17.13" }, "devDependencies": { "grunt": "^1.0.4", diff --git a/docs/wiki/development/coding-guidelines.md b/docs/wiki/development/coding-guidelines.md index 23ad2317f9..370a10275c 100644 --- a/docs/wiki/development/coding-guidelines.md +++ b/docs/wiki/development/coding-guidelines.md @@ -126,7 +126,8 @@ These macros are allowed but are not enforced. |`GETVAR(player,MyVarName,false)` | `player getVariable ["MyVarName", false]` | |`GETMVAR(MyVarName,objNull)` | `missionNamespace getVariable ["MyVarName", objNull]` | |`GETUVAR(MyVarName,displayNull)` | `uiNamespace getVariable ["MyVarName", displayNull]` | -|`SETVAR(player,MyVarName,127)` | `player setVariable ["MyVarName", 127] SETPVAR(player,MyVarName,127) player setVariable ["MyVarName", 127, true]` | +|`SETVAR(player,MyVarName,127)` | `player setVariable ["MyVarName", 127]` | +|`SETPVAR(player,MyVarName,127)` | `player setVariable ["MyVarName", 127, true]` | |`SETMVAR(MyVarName,player)` | `missionNamespace setVariable ["MyVarName", player]` | |`SETUVAR(MyVarName,_control)` | `uiNamespace setVariable ["MyVarName", _control]` | diff --git a/optionals/compat_rhs_usf3/CfgAmmo.hpp b/optionals/compat_rhs_usf3/CfgAmmo.hpp index d72f5b0a39..471c5d4dd3 100644 --- a/optionals/compat_rhs_usf3/CfgAmmo.hpp +++ b/optionals/compat_rhs_usf3/CfgAmmo.hpp @@ -297,4 +297,23 @@ class CfgAmmo { class rhs_ammo_smaw_SR: RocketBase { ACE_caliber = 9; }; + + class PipeBombBase; + class rhsusf_m112_ammo: PipeBombBase { + ace_explosives_magazine = "rhsusf_m112_mag"; + ace_explosives_Explosive = "rhsusf_m112_ammo_scripted"; + ace_explosives_size = 0; + ace_explosives_defuseObjectPosition[] = {-0.155,0,0.01}; + soundActivation[] = {"", 0, 0, 0}; + soundDeactivation[] = {"", 0, 0, 0}; + }; + + class rhsusf_m112x4_ammo: PipeBombBase { + ace_explosives_magazine = "rhsusf_m112x4_mag"; + ace_explosives_Explosive = "rhsusf_m112x4_ammo_scripted"; + ace_explosives_size = 0; + ace_explosives_defuseObjectPosition[] = {-0.155,0.025,0.01}; + soundActivation[] = {"", 0, 0, 0}; + soundDeactivation[] = {"", 0, 0, 0}; + }; }; diff --git a/optionals/compat_rhs_usf3/CfgMagazines.hpp b/optionals/compat_rhs_usf3/CfgMagazines.hpp index f4cbaaf759..a6a2db402b 100644 --- a/optionals/compat_rhs_usf3/CfgMagazines.hpp +++ b/optionals/compat_rhs_usf3/CfgMagazines.hpp @@ -51,7 +51,64 @@ class cfgMagazines { ammo = "ACE_Hellfire_AGM114N"; }; - // RHS magazines for crew handled ammo + class rhsusf_m112_mag: CA_Magazine { + ace_explosives_DelayTime = 1; + ace_explosives_Placeable = 1; + ace_explosives_SetupObject = "ACE_Explosives_Place_rhsusf_m112_DemoCharge"; + useAction = 0; + class ACE_Triggers { + SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "DeadmanSwitch"}; + class Timer { + FuseTime = 0.5; + }; + class Command { + FuseTime = 0.5; + }; + class MK16_Transmitter: Command {}; + class DeadmanSwitch: Command {}; + }; + }; + + class rhsusf_m112x4_mag: CA_Magazine { + ace_explosives_DelayTime = 1; + ace_explosives_Placeable = 1; + ace_explosives_SetupObject = "ACE_Explosives_Place_rhsusf_m112x4_DemoCharge"; + useAction = 0; + class ACE_Triggers { + SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "DeadmanSwitch"}; + class Timer { + FuseTime = 0.5; + }; + class Command { + FuseTime = 0.5; + }; + class MK16_Transmitter: Command {}; + class DeadmanSwitch: Command {}; + }; + }; + + class ATMine_Range_Mag; + class rhs_mine_M19_mag: ATMine_Range_Mag { + ace_explosives_SetupObject = "ACE_Explosives_Place_rhs_mine_M19_Mine"; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.075; + }; + }; + }; + + class rhsusf_mine_m14_mag: ATMine_Range_Mag { + ace_explosives_SetupObject = "ACE_Explosives_Place_rhsusf_mine_m14_mag_Mine"; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.03; + }; + }; + }; + + // RHS magazines for crew handled ammo class rhs_mag_TOW; class GVAR(mag_TOW): rhs_mag_TOW { scope = 2; @@ -151,5 +208,4 @@ class cfgMagazines { model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; // ammo can instead of any special model so no one gets especially confused over what it is picture = QPATHTOEF(csw,UI\ammoBox_50bmg_ca.paa); }; - }; diff --git a/optionals/compat_rhs_usf3/CfgVehicles.hpp b/optionals/compat_rhs_usf3/CfgVehicles.hpp index 503dc9c79b..5c68bb13c1 100644 --- a/optionals/compat_rhs_usf3/CfgVehicles.hpp +++ b/optionals/compat_rhs_usf3/CfgVehicles.hpp @@ -380,4 +380,51 @@ class CfgVehicles { class rhsusf_airforce_jetpilot: rhsusf_usmc_marpat_wd_rifleman_m4 { ace_gforcecoef = 0.55; }; + + class Items_base_F; + class ACE_Explosives_Place: Items_base_F { + class ACE_Actions { + class ACE_MainActions; + }; + }; + + class ACE_Explosives_Place_rhsusf_m112_DemoCharge: ACE_Explosives_Place { + displayName = "$STR_RHSUSF_M112_EXPLOSIVE_DISPLAY_NAME"; + model = "\rhsusf\addons\rhsusf_weapons\explosives\rhsusf_m112x1_e"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.155,0,0.01]"; + }; + }; + }; + + class ACE_Explosives_Place_rhsusf_m112x4_DemoCharge: ACE_Explosives_Place { + displayName = "$STR_RHSUSF_M112X4_EXPLOSIVE_DISPLAY_NAME"; + model = "\rhsusf\addons\rhsusf_weapons\explosives\rhsusf_m112x4_e"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[-0.155,0.025,0.01]"; + }; + }; + }; + + class ACE_Explosives_Place_rhs_mine_M19_Mine: ACE_Explosives_Place { + displayName = "$STR_RHSUSF_M19_ATMINE_DISPLAY_NAME"; + model = "\rhsusf\addons\rhsusf_weapons\mines\rhsusf_m19_e"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0.011,0.011,0.045]"; + }; + }; + }; + + class ACE_Explosives_Place_rhsusf_mine_m14_mag_Mine: ACE_Explosives_Place { + displayName = "$STR_RHSUSF_M14_APMINE_DISPLAY_NAME"; + model = "\rhsusf\addons\rhsusf_weapons\mines\rhsusf_m14_e"; + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = "[0.02,0.015,0.02]"; + }; + }; + }; }; diff --git a/optionals/compat_rhs_usf3/config.cpp b/optionals/compat_rhs_usf3/config.cpp index 26441eff35..246d63f5a0 100644 --- a/optionals/compat_rhs_usf3/config.cpp +++ b/optionals/compat_rhs_usf3/config.cpp @@ -7,7 +7,7 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ace_javelin", "ace_rearm", "ace_refuel", "ace_repair", "ace_csw", "rhsusf_c_weapons", "rhsusf_c_troops", "rhsusf_c_m1a1", "rhsusf_c_m1a2", "RHS_US_A2_AirImport", "rhsusf_c_m109", "rhsusf_c_HEMTT_A4", "rhsusf_c_hmmwv", "rhsusf_c_rg33", "rhsusf_c_fmtv", "rhsusf_c_m113", "RHS_US_A2Port_Armor", "rhsusf_c_melb"}; + requiredAddons[] = {"ace_explosives", "ace_javelin", "ace_rearm", "ace_refuel", "ace_repair", "ace_csw", "rhsusf_c_weapons", "rhsusf_c_troops", "rhsusf_c_m1a1", "rhsusf_c_m1a2", "RHS_US_A2_AirImport", "rhsusf_c_m109", "rhsusf_c_HEMTT_A4", "rhsusf_c_hmmwv", "rhsusf_c_rg33", "rhsusf_c_fmtv", "rhsusf_c_m113", "RHS_US_A2Port_Armor", "rhsusf_c_melb"}; author = ECSTRING(common,ACETeam); authors[] = {"Ruthberg", "GitHawk", "BaerMitUmlaut"}; url = ECSTRING(main,URL);