Merge branch 'master' into medical-treatment-work

This commit is contained in:
mharis001
2019-04-11 07:33:11 -04:00
committed by GitHub
46 changed files with 421 additions and 145 deletions

View File

@ -129,6 +129,7 @@ Raspu86
Riccardo Petricca <petriccarcc@gmail.com>
Robert Boklahánics <bokirobi@gmail.com>
ruPaladin <happyworm24@rambler.ru>
Rutger "RedBery" Meijering <c.redbery@gmail.com>
simon84 <badguy360th@gmail.com>
Skengman2
Sniperwolf572 <tenga6@gmail.com>

View File

@ -60,4 +60,13 @@ GVAR(modList) = ["","curator","kart","heli","mark","expansion","expansionpremium
call FUNC(compileStats);
// compatibility with CBA scripted 2d optics framework
[QGVAR(displayOpened), {
"cba_2doptics_arsenalOpened" call CBA_fnc_localEvent;
}] call CBA_fnc_addEventHandler;
[QGVAR(displayClosed), {
"cba_2doptics_arsenalClosed" call CBA_fnc_localEvent;
}] call CBA_fnc_addEventHandler;
ADDON = true;

View File

@ -107,14 +107,14 @@ class CfgMagazineWells {
"ACE_30Rnd_65x47_Scenar_mag",
"ACE_20Rnd_65x47_Scenar_mag"
};
};
};
class CBA_338LM_AI { //338 Lapua Magnum Accuracy International
ADDON[] = {
"ACE_10Rnd_338_300gr_HPBT_Mag",
"ACE_10Rnd_338_API526_Mag"
};
};
};
class CBA_408CT_Inter {
ADDON[] = {
@ -122,13 +122,13 @@ class CfgMagazineWells {
};
};
class CBA_50BMG_M107 {
class CBA_50BMG_M107 {
ADDON[] = {
"ACE_5Rnd_127x99_Mag",
"ACE_5Rnd_127x99_API_Mag",
"ACE_5Rnd_127x99_AMAX_Mag"
};
};
};
class CBA_9x19_P226 { // SIG P226
ADDON[] = {
@ -161,30 +161,5 @@ class CfgMagazineWells {
"ACE_10Rnd_762x54_Tracer_mag"
};
};
class CBA_762x54R_Mosin {
ADDON[] = {
"ACE_10Rnd_762x54_Tracer_mag"
};
};
class CBA_762x54R_SVT {
ADDON[] = {
"ACE_10Rnd_762x54_Tracer_mag"
};
};
class CBA_762x54R_DPM {
ADDON[] = {
"ACE_10Rnd_762x54_Tracer_mag"
};
};
class CBA_762x54R_DT {
ADDON[] = {
"ACE_10Rnd_762x54_Tracer_mag"
};
};
class CBA_762x54R_Maxim {
ADDON[] = {
"ACE_10Rnd_762x54_Tracer_mag"
};
};
};

View File

@ -1,4 +1,6 @@
class ACE_Settings {
//IGNORE_STRING_WARNING(STR_ACE_Common_SettingName);
//IGNORE_STRING_WARNING(STR_ACE_Common_SettingDescription);
/*
* class GVAR(sampleSetting) {
* value = 1; // Value

View File

@ -113,7 +113,7 @@ private _settings = configProperties [configFile >> "ACE_Settings", "(isClass _x
_output pushBack "";
_output pushBack format ["["];
_output pushBack format [" QGVAR(%1), ""%2"",", _gvarName, _cbaSettingType];
_output pushBack format [" [LSTRING(), LSTRING()], // %1, %2", _localizedName, _localizedDescription];
_output pushBack format [" [LSTRING(), LSTRING()], // %1, %2", _localizedName, _localizedDescription]; //IGNORE_STRING_WARNING(str_ace_common_);
_output pushBack format [" ""%1"", // %2", ["localize LSTRING()", _category] select _uncat, _category];
_output pushBack format [" %1, // %2", _cbaValueInfo, _cbaValueInfoHint];
_output pushBack format [" %1, // isGlobal", _cbaIsGlobal];

View File

@ -1075,7 +1075,10 @@
<Chinese></Chinese>
<Chinesesimp></Chinesesimp>
</Key>
<Key ID="STR_ACE_Common_Never">
<Key ID="STR_ACE_Common_Confirm">
<English>Confirm</English>
</Key>
<Key ID="STR_ACE_Common_Never">
<English>Never</English>
</Key>
<Key ID="STR_ACE_Common_VehiclesOnly">

View File

@ -1,40 +1,18 @@
class ACE_Settings {
class GVAR(enable) {
category = CSTRING(displayName);
displayName = CSTRING(enable_name);
description = CSTRING(enable_tooltip);
value = 0;
typeName = "BOOL";
movedToSqf = 1;
};
class GVAR(enableAmmobox) {
category = CSTRING(displayName);
displayName = CSTRING(enableBoxCookoff_name);
description = CSTRING(enableBoxCookoff_tooltip);
value = 1;
typeName = "BOOL";
movedToSQF = 1;
};
class GVAR(enableAmmoCookoff) { // For CBA Setting Switch: we can eliminate and just use (ammoCookoffDuration == 0)
category = CSTRING(displayName);
displayName = CSTRING(enableAmmoCookoff_name);
description = CSTRING(enableAmmoCookoff_tooltip);
value = 1;
typeName = "BOOL";
movedToSQF = 1;
};
class GVAR(ammoCookoffDuration) {
category = CSTRING(displayName);
displayName = CSTRING(ammoCookoffDuration_name);
description = CSTRING(ammoCookoffDuration_tooltip);
value = 1;
typeName = "SCALAR";
sliderSettings[] = {0, 5, 1, 1};
movedToSQF = 1;
};
class GVAR(probabilityCoef) {
category = CSTRING(displayName);
displayName = CSTRING(probabilityCoef_name);
description = CSTRING(probabilityCoef_tooltip);
value = 1;
typeName = "SCALAR";
sliderSettings[] = {0, 5, 1, 1};
movedToSQF = 1;
};
};

View File

@ -7,8 +7,8 @@ class Cfg3DEN {
class GVAR(enable) {
property = QGVAR(enable);
control = "Checkbox";
displayName = CSTRING(enable_name);
tooltip = CSTRING(enable_tooltip);
displayName = CSTRING(enable_hd_name);
tooltip = CSTRING(enable_hd_tooltip);
expression = QUOTE(if !(_value) then {_this setVariable [ARR_3('%s',_value,true)];};);
typeName = "BOOL";
condition = "objectVehicle";

View File

@ -6,4 +6,6 @@ PREP_RECOMPILE_START;
#include "XEH_PREP.hpp"
PREP_RECOMPILE_END;
#include "initSettings.sqf"
ADDON = true;

View File

@ -0,0 +1,51 @@
// CBA Settings [ADDON: ace_cookoff]:
[
QGVAR(enable), "CHECKBOX",
[LSTRING(enable_hd_name), LSTRING(enable_hd_tooltip)],
LSTRING(category_displayName),
false, // default value
true, // isGlobal
{[QGVAR(enable), _this] call EFUNC(common,cbaSettings_settingChanged)},
true // Needs mission restart
] call CBA_settings_fnc_init;
[
QGVAR(enableAmmobox), "CHECKBOX",
[LSTRING(enableBoxCookoff_name), LSTRING(enableBoxCookoff_tooltip)],
LSTRING(category_displayName),
true, // default value
true, // isGlobal
{[QGVAR(enableAmmobox), _this] call EFUNC(common,cbaSettings_settingChanged)},
true // Needs mission restart
] call CBA_settings_fnc_init;
[
QGVAR(enableAmmoCookoff), "CHECKBOX",
[LSTRING(enableAmmoCookoff_name), LSTRING(enableAmmoCookoff_tooltip)],
LSTRING(category_displayName),
true, // default value
true, // isGlobal
{[QGVAR(enableAmmoCookoff), _this] call EFUNC(common,cbaSettings_settingChanged)},
true // Needs mission restart
] call CBA_settings_fnc_init;
[
QGVAR(ammoCookoffDuration), "SLIDER",
[LSTRING(ammoCookoffDuration_name), LSTRING(ammoCookoffDuration_tooltip)],
LSTRING(category_displayName),
[0,5,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)]
true, // isGlobal
{[QGVAR(ammoCookoffDuration), _this] call EFUNC(common,cbaSettings_settingChanged)},
true // Needs mission restart
] call CBA_settings_fnc_init;
[
QGVAR(probabilityCoef), "SLIDER",
[LSTRING(probabilityCoef_name), LSTRING(probabilityCoef_tooltip)],
LSTRING(category_displayName),
[0,5,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)]
true, // isGlobal
{[QGVAR(probabilityCoef), _this] call EFUNC(common,cbaSettings_settingChanged)},
true // Needs mission restart
] call CBA_settings_fnc_init;

View File

@ -1,42 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<Project name="ACE">
<Package name="CookOff">
<Key ID="STR_ACE_CookOff_displayName">
<English>Cook off</English>
<Italian>Esplosione</Italian>
<Chinese>殉爆效果</Chinese>
<Chinesesimp>殉爆效果</Chinesesimp>
<Japanese>誘爆</Japanese>
<Korean>쿡오프</Korean>
<German>Durchzündung</German>
<French>Cook off</French>
<Polish>Samozapłon</Polish>
<Key ID="STR_ACE_CookOff_category_displayName">
<English>ACE Cook off</English>
<Italian>ACE Esplosione</Italian>
<Chinese>ACE 殉爆效果</Chinese>
<Chinesesimp>ACE 殉爆效果</Chinesesimp>
<Japanese>ACE 誘爆</Japanese>
<Korean>ACE 쿡오프</Korean>
<German>ACE Durchzündung</German>
<French>ACE Cook off</French>
<Polish>ACE Samozapłon</Polish>
</Key>
<Key ID="STR_ACE_CookOff_enable_name">
<English>Enable cook off</English>
<German>Durchzündung ermöglichen</German>
<Czech>Povolit explozi munice</Czech>
<Russian>Включить воспламенение</Russian>
<Japanese>誘爆を有効化</Japanese>
<Korean>쿡오프 현상 활성화</Korean>
<Polish>Aktywuj efekty samozapłonu amunicji</Polish>
<French>Activer le cook off</French>
<Italian>Abilita Esplosione</Italian>
<Chinese>開啟殉爆效果</Chinese>
<Chinesesimp>开启殉爆效果</Chinesesimp>
<Key ID="STR_ACE_CookOff_enable_hd_name">
<English>Damage handling and turret effects</English>
</Key>
<Key ID="STR_ACE_CookOff_enable_tooltip">
<English>Enables cook off and related vehicle destruction effects.</English>
<German>Ermöglicht Durchzündung und zugehörige Fahrzeug-Zerstörungseffekte.</German>
<Czech>Povolí explozi munice a její následné ničivé efekty.</Czech>
<Russian>Включает воспламенение и сопутствующие эффекты повреждения техники.</Russian>
<Japanese>誘爆を有効化し、車両が誘爆によって破壊されていきます。</Japanese>
<Korean>쿡오프 현상을 활성화 하고 관련된 차량에 폭발 이펙트를 적용합니다.</Korean>
<Polish>Aktywuje efekt samozapłonu amunicji na zniszczonych pojazdach.</Polish>
<French>Active le cook-off (autocombustion des munitions) et les effets de destruction liés.</French>
<Italian>Abilita l'esplosione e i relativi effetti di distruzione del veicolo.</Italian>
<Chinese>開啟此功能後,將使有關載具在損毀時有殉爆的效果</Chinese>
<Chinesesimp>开启此功能后,将使有关载具在损毁时有殉爆的效果。</Chinesesimp>
<Key ID="STR_ACE_CookOff_enable_hd_tooltip">
<English>Changes damage handling for cook off and turret explosion effects</English>
</Key>
<Key ID="STR_ACE_CookOff_generic_turret_wreck">
<English>Wreck (Turret)</English>

View File

@ -75,8 +75,13 @@ class CfgVehicles {
};
class ACE_cutRopes {
displayName = CSTRING(Interaction_cutRopes);
condition = [_target] call FUNC(canCutRopes);
statement = [_target] call FUNC(cutRopes);
condition = QUOTE(true);
statement = "";
class confirmCutRopes {
displayName = ECSTRING(common,confirm);
condition = QUOTE([_target] call FUNC(canCutRopes));
statement = QUOTE([_target] call FUNC(cutRopes));
};
};
class ACE_fastRope {
displayName = CSTRING(Interaction_fastRope);

View File

@ -0,0 +1,4 @@
class CfgMagazineWells {
class GVAR(K) {};
class GVAR(N) {};
};

View File

@ -6,7 +6,7 @@ class CfgWeapons {
EGVAR(laser,canSelect) = 1; // can ace_laser lock (allows switching laser code)
EGVAR(laser,showHud) = 1; // show attack profile / lock on hud
magazines[] = {"6Rnd_ACE_Hellfire_AGM114K", "PylonMissile_1Rnd_ACE_Hellfire_AGM114K", "PylonRack_1Rnd_ACE_Hellfire_AGM114K", "PylonRack_3Rnd_ACE_Hellfire_AGM114K", "PylonRack_4Rnd_ACE_Hellfire_AGM114K"};
magazineWell[] = {QGVAR(K)};
autoFire = 0;
canLock = 0;
weaponLockSystem = 0;
@ -14,7 +14,7 @@ class CfgWeapons {
lockedTargetSound[] = {"",0,1};
soundFly[] = {"A3\Sounds_F\weapons\Rockets\rocket_fly_1",1,1.1,700};
nameSound = "MissileLauncher";
sounds[] = {"StandardSound"};
sounds[] = {"StandardSound"};
class StandardSound {
begin1[] = {"A3\Sounds_F\weapons\Rockets\missile_1",1.12202,1.3,1000};
soundBegin[] = {"begin1",1};
@ -27,5 +27,6 @@ class CfgWeapons {
class GVAR(launcher_N): GVAR(launcher) {
displayName = "AGM-114N Hellfire II";
magazines[] = {"6Rnd_ACE_Hellfire_AGM114N", "PylonMissile_1Rnd_ACE_Hellfire_AGM114N", "PylonRack_1Rnd_ACE_Hellfire_AGM114N", "PylonRack_3Rnd_ACE_Hellfire_AGM114N", "PylonRack_4Rnd_ACE_Hellfire_AGM114N"};
magazineWell[] = {QGVAR(N)};
};
};

View File

@ -18,5 +18,6 @@ class CfgPatches {
#include "CfgAmmo.hpp"
#include "CfgEventHandlers.hpp"
#include "CfgMagazines.hpp"
#include "CfgMagazineWells.hpp"
#include "CfgVehicles.hpp"
#include "CfgWeapons.hpp"

View File

@ -19,11 +19,12 @@
params ["_player", "_target", "_weapon"];
if (!GVAR(enableMagazinePassing)) exitWith {false};
if (_weapon isEqualTo "") exitWith {false};
if (((vehicle _target) != _target) && {(vehicle _target) != (vehicle _player)}) exitWith {false};
private _compatibleMags = getArray (configfile >> "CfgWeapons" >> _weapon >> "magazines");
{
private _compatibleMags = [_weapon] call CBA_fnc_compatibleMagazines;
(magazinesAmmoFull _player) findIf {
_x params ["_className", "", "_loaded"];
if ((_className in _compatibleMags) && {!_loaded} && {_target canAdd _className}) exitWith {true};
false
} foreach (magazinesAmmoFull _player);
(_className in _compatibleMags) && {!_loaded} && {_target canAdd _className}
} > -1

View File

@ -12,21 +12,24 @@
* None
*
* Example:
* [_player, _target, "arifle_MX_F"] call ace_interaction_fnc_magToPassazine
* [_player, _target, "arifle_MX_F"] call ace_interaction_fnc_passMagazine
*
* Public: No
*/
params ["_player", "_target", "_weapon"];
private _compatibleMags = getArray (configfile >> "CfgWeapons" >> _weapon >> "magazines");
private _filteredMags = magazinesAmmoFull _player select {(_x select 0) in _compatibleMags && {!(_x select 2)}};
private _compatibleMags = [_weapon] call CBA_fnc_compatibleMagazines;
private _filteredMags = magazinesAmmoFull _player select {
_x params ["_className", "", "_loaded"];
(_className in _compatibleMags) && {!_loaded} && {_target canAdd _className}
};
//select magazine with most ammo
private _magToPass = _filteredMags select 0;
private _magToPassIndex = 0;
{
_x params ["_className", "_ammoCount"];
if ((_ammoCount > (_magToPass select 1)) && (_target canAdd _className)) then {
if (_ammoCount > (_magToPass select 1)) then {
_magToPass = _x;
_magToPassIndex = _forEachIndex;
};

View File

@ -14,8 +14,8 @@
* Success? <BOOLEAN>
*
* Example:
* [bob, true] call ace_medical_status__fnc_setUnconscious;
* [player, true, 5, true] call ace_medical_status_fnc_setUnconscious;
* [bob, true] call ace_medical_fnc_setUnconscious;
* [player, true, 5, true] call ace_medical_fnc_setUnconscious;
*
* Public: yes
*/

View File

@ -4,7 +4,7 @@
// #define DEBUG_MODE_FULL
// #define DISABLE_COMPILE_CACHE
//#define ENABLE_PERFORMANCE_COUNTERS
// #define ENABLE_PERFORMANCE_COUNTERS
#ifdef DEBUG_ENABLED_MEDICAL_ENGINE
#define DEBUG_MODE_FULL
@ -19,11 +19,11 @@
#include "\z\ace\addons\medical_engine\script_macros_config.hpp"
#define PRELOAD_CLASS(class) \
diag_log format["Starting preload for ""%1""",class];\
INFO_1("Starting preload for (%1)",class);\
[{\
1 preloadObject _this;\
}, {\
diag_log format ["Preload done for ""%1""",_this];\
INFO_1("Preload done for (%1)",_this);\
}, class] call CBA_fnc_waitUntilAndExecute
#define PRIORITY_HEAD 3

View File

@ -24,10 +24,13 @@ GVAR(heartBeatEffectRunning) = false;
if (_unit != ACE_player) exitWith {};
// Toggle unconscious player's ability to talk in radio addons
_unit setVariable ["tf_voiceVolume", [1, 0] select _unconscious, true];
_unit setVariable ["tf_unable_to_use_radio", _unconscious]; // Only used locally
_unit setVariable ["acre_sys_core_isDisabled", _unconscious, true];
if (["task_force_radio"] call EFUNC(common,isModLoaded)) then {
_unit setVariable ["tf_voiceVolume", [1, 0] select _unconscious, true];
_unit setVariable ["tf_unable_to_use_radio", _unconscious]; // Only used locally
};
if (["acre_main"] call EFUNC(common,isModLoaded)) then {
_unit setVariable ["acre_sys_core_isDisabled", _unconscious, true];
};
// Greatly reduce player's hearing ability while unconscious (affects radio addons)
[QUOTE(ADDON), VOL_UNCONSCIOUS, _unconscious] call EFUNC(common,setHearingCapability);
@ -40,22 +43,29 @@ GVAR(heartBeatEffectRunning) = false;
params ["_unit"];
if (_unit != ACE_player) exitWith {};
_unit setVariable ["tf_voiceVolume", 1, true];
_unit setVariable ["tf_unable_to_use_radio", false];
_unit setVariable ["acre_sys_core_isDisabled", false, true];
if (["task_force_radio"] call EFUNC(common,isModLoaded)) then {
_unit setVariable ["tf_voiceVolume", 1, true];
_unit setVariable ["tf_unable_to_use_radio", false];
};
if (["acre_main"] call EFUNC(common,isModLoaded)) then {
_unit setVariable ["acre_sys_core_isDisabled", false, true];
};
[QUOTE(ADDON), 1, false] call EFUNC(common,setHearingCapability);
}] call CBA_fnc_addEventHandler;
// Update effects to match new unit's current status (this also handles respawn)
["unit", {
params ["_new", "_old"];
params ["_new"];
private _status = _new getVariable ["ace_unconscious", false];
_new setVariable ["tf_voiceVolume", [1, 0] select _status, true];
_new setVariable ["tf_unable_to_use_radio", _status];
_new setVariable ["acre_sys_core_isDisabled", _status, true];
if (["task_force_radio"] call EFUNC(common,isModLoaded)) then {
_new setVariable ["tf_voiceVolume", [1, 0] select _status, true];
_new setVariable ["tf_unable_to_use_radio", _status];
};
if (["acre_main"] call EFUNC(common,isModLoaded)) then {
_new setVariable ["acre_sys_core_isDisabled", _status, true];
};
[QUOTE(ADDON), VOL_UNCONSCIOUS, _status] call EFUNC(common,setHearingCapability);
[_status, 0] call FUNC(effectUnconscious);
["unconscious", _status] call EFUNC(common,setDisableUserInputStatus);

View File

@ -4,18 +4,18 @@
* Handles the hear beat sound.
*
* Arguments:
* 0: Heart rate <NUMBER>
* None
*
* Return Value:
* None
*
* Example:
* [120] call ace_medical_feedback_fnc_effectHeartBeat
* [] call ace_medical_feedback_fnc_effectHeartBeat
*
* Public: No
*/
params ["_heartRate"];
private _heartRate = GET_HEART_RATE(ACE_player);
if (_heartRate == 0) exitWith {
TRACE_1("Ending heart beat effect - zero",_heartRate);

View File

@ -12,9 +12,19 @@ GVAR(pendingReopen) = false;
GVAR(menuPFH) = -1;
GVAR(selfInteractionActions) = [];
[] call FUNC(addTreatmentActions);
[] call FUNC(collectActions);
[QEGVAR(interact_menu,newControllableObject), {
params ["_type"]; // string of the object's classname
if (!(_type isKindOf "CAManBase")) exitWith {};
{
_x set [0, _type];
_x call EFUNC(interact_menu,addActionToClass);
} forEach GVAR(selfInteractionActions);
}] call CBA_fnc_addEventHandler;
["ace_treatmentSucceded", {
if (GVAR(openAfterTreatment) && {GVAR(pendingReopen)}) then {
GVAR(pendingReopen) = false;

View File

@ -10,7 +10,7 @@
* None
*
* Example:
* [] call ace_medical_gui_fnc_addInteractActions
* [] call ace_medical_gui_fnc_addTreatmentActions
*
* Public: No
*/
@ -60,6 +60,6 @@ private _fnc_condition = {
["CAManBase", 0, [_actionPath], _action, true] call EFUNC(interact_menu,addActionToClass);
["CAManBase", 0, ["ACE_MainActions", "ACE_Medical_Radial", _actionPath], _action, true] call EFUNC(interact_menu,addActionToClass);
["CAManBase", 1, ["ACE_SelfActions", "ACE_Medical", _actionPath], _action, true] call EFUNC(interact_menu,addActionToClass);
GVAR(selfInteractionActions) pushBack ["", 1, ["ACE_SelfActions", "ACE_Medical", _actionPath], _action];
} forEach _allowedBodyParts;
} forEach configProperties [_actionsConfig, "isClass _x"];

View File

@ -19,6 +19,7 @@
params ["_player", "_target"];
alive _player
&& {!IS_UNCONSCIOUS(_player)}
&& {!isNull _target}
&& {_player distance _target < GVAR(maxDistance) || {vehicle _player == vehicle _target}}
&& {GVAR(enableMedicalMenu) == 1 || {GVAR(enableMedicalMenu) == 2 && {vehicle _player != _player || {vehicle _target != _target}}}}

View File

@ -277,6 +277,7 @@ class GVAR(actions) {
allowSelfTreatment = 0;
medicRequired = QGVAR(medicSurgicalKit);
treatmentTime = QUOTE(count (_patient getVariable [ARR_2('EGVAR(medical,bandagedWounds)',[])]) * 5);
condition = QFUNC(canStitch);
callbackSuccess = "";
callbackProgress = QFUNC(surgicalKitProgress);
consumeItem = QGVAR(consumeSurgicalKit);

View File

@ -42,6 +42,7 @@ PREP(addToTriageCard);
PREP(bodyCleanupLoop);
PREP(calculateBlood);
PREP(canBandage);
PREP(canStitch);
PREP(findMostEffectiveWound);
PREP(getBandageTime);
PREP(getTriageStatus);

View File

@ -21,3 +21,7 @@ if (isServer) then {
[QGVAR(checkPulseLocal), FUNC(checkPulseLocal)] call CBA_fnc_addEventHandler;
[QGVAR(checkBloodPressureLocal), FUNC(checkBloodPressureLocal)] call CBA_fnc_addEventHandler;
[QGVAR(actionPlaceInBodyBag), FUNC(actionPlaceInBodyBag)] call CBA_fnc_addEventHandler;
// log events
[QGVAR(addToMedicalLog), FUNC(addToLog)] call CBA_fnc_addEventHandler;
[QGVAR(addToTriageCard), FUNC(addToTriageCard)] call CBA_fnc_addEventHandler;

View File

@ -13,6 +13,9 @@
* Return Value:
* Can Bandage <BOOL>
*
* Example:
* [player, cursorTarget, "Head", "FieldDressing"] call ace_medical_treatment_fnc_canBandage
*
* Public: No
*/

View File

@ -0,0 +1,21 @@
#include "script_component.hpp"
/*
* Author: Katalam
* Prevents stitch actions from showing if the body is either fully stitched or has no open wounds.
*
* Arguments:
* 0: The medic <OBJECT>
* 1: The patient <OBJECT>
*
* ReturnValue:
* Can Stitch <BOOL>
*
* Example:
* [player, cursorTarget] call ace_medical_treatment_fnc_canStitch
*
* Public: No
*/
params ["", "_patient"];
!((_patient getVariable [QEGVAR(medical,bandagedWounds), []]) isEqualTo [])

View File

@ -16,6 +16,17 @@ params ["_target"];
if (!alive _target) exitWith {};
// Treatment conditions would normally limit this to non-unconc units, but treatment event may be called externally (zeus)
if (_target getVariable [QEGVAR(medical,inCardiacArrest), false]) then {
TRACE_1("exiting cardiac arrest",_target);
[QEGVAR(medical,CPRSucceeded), _target] call CBA_fnc_localEvent;
};
if (_target getVariable ["ACE_isUnconscious",false]) then {
TRACE_1("waking up",_target); // wake up first or unconc variables will be reset
[QEGVAR(medical,WakeUp), _target] call CBA_fnc_localEvent;
};
_target setVariable [VAR_PAIN, 0, true];
_target setVariable [VAR_BLOOD_VOL, DEFAULT_BLOOD_VOLUME, true];

View File

@ -76,7 +76,9 @@ private _tourniquets = GET_TOURNIQUETS(_unit);
_tourniquetPain = _tourniquetPain max (CBA_missionTime - _x - 120) * 0.001;
};
} forEach _tourniquets;
[_unit, _tourniquetPain] call EFUNC(medical_status,adjustPainLevel);
if (_tourniquetPain > 0) then {
[_unit, _tourniquetPain] call EFUNC(medical_status,adjustPainLevel);
};
private _heartRate = [_unit, _deltaT, _syncValues] call FUNC(updateHeartRate);
[_unit, _deltaT, _syncValues] call FUNC(updatePainSuppress);

View File

@ -33,12 +33,12 @@ if (isNil "_energyIncrement") then {
// If the bullet mass is not configured, estimate it
_bulletMass = 3.4334 + 0.5171 * (getNumber (configFile >> "CfgAmmo" >> _ammo >> "hit") + getNumber (configFile >> "CfgAmmo" >> _ammo >> "caliber"));
};
// Projectile motion is roughly equal to Barrel heat
// Ref: https://en.wikipedia.org/wiki/Physics_of_firearms
// Muzzle Engergy = 1/2 * m * v^2 = (1/2 * 0.001 g/kg * bulletMass (grams) * v^2)
// Multiple by 3 becase we only calc every 3rd bullet: (3 * 1/2 * 0.001) = 0.0015
private _energyIncrement = 0.0015 * _bulletMass * (vectorMagnitudeSqr velocity _projectile);
_energyIncrement = 0.0015 * _bulletMass * (vectorMagnitudeSqr velocity _projectile);
GVAR(cacheAmmoData) setVariable [_ammo, _energyIncrement];
};

View File

@ -33,6 +33,7 @@ if (_track) then {
};
// Prepare first part of the string from stringtable
//IGNORE_STRING_WARNING(str_ace_repair_hit);
private _text = LSTRING(Hit);
// Remove "Hit" from hitpoint name if one exists

View File

@ -6,4 +6,37 @@ PREP_RECOMPILE_START;
#include "XEH_PREP.hpp"
PREP_RECOMPILE_END;
#include "initSettings.sqf"
[
"AllVehicles",
"initPost",
{
params ["_vehicle"];
_vehicle setVariable [QGVAR(engineState), isEngineOn _vehicle];
}
] call CBA_fnc_addClassEventHandler;
[
"AllVehicles",
"engine",
{
params ["_vehicle", "_state"];
_vehicle setVariable [QGVAR(engineState), _state];
}
] call CBA_fnc_addClassEventHandler;
[
"AllVehicles",
"getout",
{
params ["_vehicle", "_position", "_unit"];
if (!GVAR(keepEngineRunning)) exitWith {};
if (_unit == ACE_player && {_position == "driver" && {_vehicle getVariable [QGVAR(engineState), false]}}) then {
[{
params ["_vehicle"];
[QEGVAR(common,engineOn), _this, _vehicle] call CBA_fnc_targetEvent;
}, [_vehicle, true]] call CBA_fnc_execNextFrame;
};
}
] call CBA_fnc_addClassEventHandler;
ADDON = true;

View File

@ -0,0 +1,9 @@
[
QGVAR(keepEngineRunning),
"CHECKBOX",
[LSTRING(SettingKeepEngineRunningName), LSTRING(SettingKeepEngineRunningDesc)],
localize ELSTRING(common,ACEKeybindCategoryVehicles),
false, // default value
true // isGlobal
] call CBA_settings_fnc_init;

View File

@ -67,5 +67,13 @@
<Japanese>速度制限を減らす</Japanese>
<Polish>Zmniejsz ograniczenie prędkości</Polish>
</Key>
<Key ID="STR_ACE_Vehicles_SettingKeepEngineRunningName">
<English>Disable automatic engine shut-off</English>
<German>Motor nach Verlassen laufen lassen</German>
</Key>
<Key ID="STR_ACE_Vehicles_SettingKeepEngineRunningDesc">
<English>Prevent the automatic shut-off of the engine when exiting vehicles.</English>
<German>Verhindere das automatische Abschalten des Motors beim Verlassen des Fahrzeugs.</German>
</Key>
</Package>
</Project>

View File

@ -43,8 +43,9 @@ switch (false) do {
};
// Heal validated target
if (["ace_medical"] call EFUNC(common,isModLoaded) && {EGVAR(medical,level) > 0}) then {
[QEGVAR(medical,treatmentAdvanced_fullHealLocal), [_unit, _unit], _unit] call CBA_fnc_targetEvent;
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;
} else {
// BI's scripted revive system
if ((missionNamespace getVariable ["bis_revive_mode", 0]) != 0) then {

View File

@ -37,9 +37,9 @@ if (isNil QEFUNC(medical,setUnconscious)) then {
if !(alive _unit) then {
[LSTRING(OnlyAlive)] call FUNC(showMessage);
} else {
private _conscious = GETVAR(_unit,ACE_isUnconscious,false);
private _unconscious = GETVAR(_unit,ACE_isUnconscious,false);
// Function handles locality for me
[_unit, !_conscious, 10e10] call EFUNC(medical,setUnconscious);
[_unit, !_unconscious, 10e10] call EFUNC(medical,setUnconscious);
};
};
};

View File

@ -6,8 +6,8 @@ jobs:
steps:
- checkout
- run:
name: Validate SQF and Config style
command: python tools/sqf_validator.py && python tools/config_style_checker.py
name: Validate SQF and Config style and Stringtable entries
command: python tools/sqf_validator.py && python tools/config_style_checker.py && python tools/check_strings.py
linting:
docker:

View File

@ -0,0 +1,8 @@
class CfgMagazineWells {
class ace_hellfire_K {
ADDON[] = {QGVAR(pylon_mag_2rnd_hellfire_k)};
};
class ace_hellfire_N {
ADDON[] = {GVAR(pylon_mag_2rnd_hellfire_n)};
};
};

View File

@ -23,4 +23,17 @@ class cfgMagazines {
EGVAR(overpressure,range) = 0;
EGVAR(overpressure,damage) = 0;
};
class rhs_mag_AGM114K_2;
class GVAR(pylon_mag_2rnd_hellfire_k): rhs_mag_AGM114K_2 {
displayName = "2x AGM-114K [ACE]";
pylonWeapon = "ace_hellfire_launcher";
ammo = "ACE_Hellfire_AGM114K";
};
class GVAR(pylon_mag_2rnd_hellfire_n): rhs_mag_AGM114K_2 {
displayName = "2x AGM-114N [ACE]";
pylonWeapon = "ace_hellfire_launcher_N";
ammo = "ACE_Hellfire_AGM114N";
};
};

View File

@ -17,6 +17,7 @@ class CfgPatches {
#include "CfgAmmo.hpp"
#include "CfgEventHandlers.hpp"
#include "CfgMagazines.hpp"
#include "CfgMagazineWells.hpp"
#include "CfgWeapons.hpp"
#include "CfgVehicles.hpp"
#include "CfgGlasses.hpp"

View File

@ -1,6 +0,0 @@
class CfgInGameUI {
class Cursor {
weapon = ""; // "\A3\ui_f\data\igui\cfg\cursors\weapon_ca.paa";
};
};

View File

@ -0,0 +1,27 @@
#define EMPTY_TEXTURE(weapon) \
class weapon: default { \
texture = ""; \
}
class CfgWeaponCursors {
class default;
EMPTY_TEXTURE(arifle);
EMPTY_TEXTURE(mg);
EMPTY_TEXTURE(srifle);
EMPTY_TEXTURE(smg);
EMPTY_TEXTURE(hgun);
EMPTY_TEXTURE(sgun);
EMPTY_TEXTURE(gl);
EMPTY_TEXTURE(throw);
EMPTY_TEXTURE(put);
EMPTY_TEXTURE(missile);
EMPTY_TEXTURE(rocket);
EMPTY_TEXTURE(bomb);
EMPTY_TEXTURE(cannon);
EMPTY_TEXTURE(mortar);
EMPTY_TEXTURE(coil);
EMPTY_TEXTURE(laserdesignator);
// if these classes have empty texture the crosshair appears
// EMPTY_TEXTURE(cursorAim);
// EMPTY_TEXTURE(cursorAimOn);
};

View File

@ -15,4 +15,4 @@ class CfgPatches {
};
};
#include "CfgInGameUI.hpp"
#include "CfgWeaponCursors.hpp"

101
tools/check_strings.py Normal file
View File

@ -0,0 +1,101 @@
#!/usr/bin/env python3
# PabstMirror
# Checks all strings are defined, run with -u to return all unused strings
import fnmatch
import os
import re
import sys
def getDefinedStrings(filepath):
# print("getDefinedStrings {0}".format(filepath))
with open(filepath, 'r', encoding="latin-1") as file:
content = file.read()
srch = re.compile('Key ID\=\"(STR_ACE_[_a-zA-Z0-9]*)"', re.IGNORECASE)
modStrings = srch.findall(content)
modStrings = [s.lower() for s in modStrings]
return modStrings
def getStringUsage(filepath):
selfmodule = (re.search('addons[\W]*([_a-zA-Z0-9]*)', filepath)).group(1)
# print("Checking {0} from {1}".format(filepath,selfmodule))
fileStrings = []
with open(filepath, 'r') as file:
content = file.read()
srch = re.compile('(STR_ACE_[_a-zA-Z0-9]*)', re.IGNORECASE)
fileStrings = srch.findall(content)
srch = re.compile('[^E][CL]STRING\(([_a-zA-Z0-9]*)\)', re.IGNORECASE)
modStrings = srch.findall(content)
for localString in modStrings:
fileStrings.append("STR_ACE_{0}_{1}".format(selfmodule, localString))
srch = re.compile('E[CL]STRING\(([_a-zA-Z0-9]*),([_a-zA-Z0-9]*)\)')
exStrings = srch.findall(content)
for (exModule, exString) in exStrings:
fileStrings.append("STR_ACE_{0}_{1}".format(exModule, exString))
srch = re.compile('IGNORE_STRING_WARNING\([\'"]*([_a-zA-Z0-9]*)[\'"]*\)')
ignoreWarnings = srch.findall(content)
fileStrings = [s.lower() for s in fileStrings]
return [s for s in fileStrings if s not in (i.lower() for i in ignoreWarnings)]
def main(argv):
print("### check_strings.py {} ###".format(argv))
sqf_list = []
xml_list = []
allDefinedStrings = []
allUsedStrings = []
# Allow running from root directory as well as from inside the tools directory
rootDir = "../addons"
if (os.path.exists("addons")):
rootDir = "addons"
for root, dirnames, filenames in os.walk(rootDir):
for filename in fnmatch.filter(filenames, '*.sqf'):
sqf_list.append(os.path.join(root, filename))
for filename in fnmatch.filter(filenames, '*.cpp'):
sqf_list.append(os.path.join(root, filename))
for filename in fnmatch.filter(filenames, '*.hpp'):
sqf_list.append(os.path.join(root, filename))
for filename in fnmatch.filter(filenames, '*.h'):
sqf_list.append(os.path.join(root, filename))
for filename in fnmatch.filter(filenames, '*.xml'):
xml_list.append(os.path.join(root, filename))
for filename in xml_list:
allDefinedStrings = allDefinedStrings + getDefinedStrings(filename)
for filename in sqf_list:
allUsedStrings = allUsedStrings + getStringUsage(filename)
allDefinedStrings = list(sorted(set(allDefinedStrings)))
allUsedStrings = list(sorted(set(allUsedStrings)))
print("-----------")
countUnusedStrings = 0
countUndefinedStrings = 0
for s in allDefinedStrings:
if (not (s in allUsedStrings)):
countUnusedStrings = countUnusedStrings + 1;
if ("-u" in argv):
print("String {} defined but not used".format(s))
print("-----------")
for s in allUsedStrings:
if (not (s in allDefinedStrings)):
print("String {} not defined".format(s))
countUndefinedStrings = countUndefinedStrings + 1;
print("-----------")
print("Defined Strings:{0} Used Strings:{1}".format(len(allDefinedStrings),len(allUsedStrings)))
print("Unused Strings:{0} Undefined Strings:{1}".format(countUnusedStrings,countUndefinedStrings))
return countUndefinedStrings
if __name__ == "__main__":
main(sys.argv)