diff --git a/addons/breathing/XEH_PREP.hpp b/addons/breathing/XEH_PREP.hpp index 4046819ae..6c4614e16 100644 --- a/addons/breathing/XEH_PREP.hpp +++ b/addons/breathing/XEH_PREP.hpp @@ -12,6 +12,7 @@ PREP(gui_updateBodyImage); PREP(gui_updateInjuryListPart); PREP(gui_updateInjuryListWounds); PREP(handleBreathing); +PREP(handleBreathingConditions); PREP(handlePneumothoraxDeterioration); PREP(handlePulmoHit); PREP(handleRespawn); diff --git a/addons/breathing/XEH_postInit.sqf b/addons/breathing/XEH_postInit.sqf index 7c537488f..5c45042d4 100644 --- a/addons/breathing/XEH_postInit.sqf +++ b/addons/breathing/XEH_postInit.sqf @@ -16,6 +16,8 @@ [QEGVAR(misc,handleRespawn), LINKFUNC(handleRespawn)] call CBA_fnc_addEventHandler; +[QACEGVAR(medical_status,initialized), LINKFUNC(handleBreathingConditions)] call CBA_fnc_addEventHandler; + [QACEGVAR(medical_gui,updateInjuryListPart), LINKFUNC(gui_updateInjuryListPart)] call CBA_fnc_addEventHandler; [QACEGVAR(medical_gui,updateInjuryListWounds), LINKFUNC(gui_updateInjuryListWounds)] call CBA_fnc_addEventHandler; [QACEGVAR(medical_gui,updateBodyImage), LINKFUNC(gui_updateBodyImage)] call CBA_fnc_addEventHandler; diff --git a/addons/breathing/functions/fnc_handleBreathingConditions.sqf b/addons/breathing/functions/fnc_handleBreathingConditions.sqf new file mode 100644 index 000000000..718d554f3 --- /dev/null +++ b/addons/breathing/functions/fnc_handleBreathingConditions.sqf @@ -0,0 +1,43 @@ +#include "..\script_component.hpp" +/* + * Author: Mazinski + * Monitors breathing conditions. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [player] call kat_breathing_fnc_handleBreathingConcidtions; + * + * Public: No + */ + +params ["_unit"]; + +[{ + params ["_args", "_idPFH"]; + _args params ["_unit"]; + + private _alive = alive _unit; + + if (!_alive) exitWith { + [_idPFH] call CBA_fnc_removePerFrameHandler; + }; + + private _spo2 = GET_KAT_SPO2(_unit); + + if (GVAR(staminaLossAtLowSPO2)) then { + if (!(_unit getVariable ["ACE_isUnconscious",false]) && {_spo2 <= GVAR(lowSPO2Level)}) then { + if (ACEGVAR(advanced_fatigue,enabled)) then { + ["kat_LSDF", 1.5] call ACEFUNC(advanced_fatigue,addDutyFactor); + } else { + _unit setStamina(getStamina _unit - 3); + }; + } else { + ["kat_LSDF"] call ACEFUNC(advanced_fatigue,removeDutyFactor); + }; + }; +}, 10, [_unit]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/chemical/CfgSounds.hpp b/addons/chemical/CfgSounds.hpp index dfd199f19..00f704a4f 100644 --- a/addons/chemical/CfgSounds.hpp +++ b/addons/chemical/CfgSounds.hpp @@ -1,4 +1,15 @@ class CfgSounds { + class GVAR(cough_0) { + name = QGVAR(cough_0); + sound[] = + { + QPATHTOF(audio\cough_0.ogg), + 2, + 1, + 10 + }; + titles[] = {}; + }; class GVAR(cough_1) { name = QGVAR(cough_1); sound[] = @@ -10,6 +21,28 @@ class CfgSounds { }; titles[] = {}; }; + class GVAR(cough_2) { + name = QGVAR(cough_2); + sound[] = + { + QPATHTOF(audio\cough_2.ogg), + 2, + 1, + 10 + }; + titles[] = {}; + }; + class GVAR(cough_3) { + name = QGVAR(cough_3); + sound[] = + { + QPATHTOF(audio\cough_3.ogg), + 2, + 1, + 10 + }; + titles[] = {}; + }; class GVAR(mask_breath_1) { name = QGVAR(mask_breath_1); diff --git a/addons/chemical/audio/cough_0.ogg b/addons/chemical/audio/cough_0.ogg new file mode 100644 index 000000000..2a38c91f0 Binary files /dev/null and b/addons/chemical/audio/cough_0.ogg differ diff --git a/addons/chemical/audio/cough_1.ogg b/addons/chemical/audio/cough_1.ogg index 2a38c91f0..a061cbe78 100644 Binary files a/addons/chemical/audio/cough_1.ogg and b/addons/chemical/audio/cough_1.ogg differ diff --git a/addons/chemical/audio/cough_2.ogg b/addons/chemical/audio/cough_2.ogg new file mode 100644 index 000000000..c237c6746 Binary files /dev/null and b/addons/chemical/audio/cough_2.ogg differ diff --git a/addons/chemical/audio/cough_3.ogg b/addons/chemical/audio/cough_3.ogg new file mode 100644 index 000000000..f04a4bc7f Binary files /dev/null and b/addons/chemical/audio/cough_3.ogg differ diff --git a/addons/chemical/functions/fnc_fullHealLocal.sqf b/addons/chemical/functions/fnc_fullHealLocal.sqf index 5874a2e37..a5f155169 100644 --- a/addons/chemical/functions/fnc_fullHealLocal.sqf +++ b/addons/chemical/functions/fnc_fullHealLocal.sqf @@ -22,4 +22,5 @@ _patient setVariable [QGVAR(gasmask_durability), 10, true]; _patient setVariable [QGVAR(CSGas), 0, true]; _patient setVariable [QGVAR(airPoisoning), false, true]; _patient setVariable [QGVAR(infectionTime), missionNamespace getVariable [QGVAR(infectionTime), 60], true]; -_patient setVariable [QGVAR(infectionArray), [], true]; \ No newline at end of file +_patient setVariable [QGVAR(infectionArray), [], true]; +_patient setVariable [QGVAR(CoughCooldown), false, true]; \ No newline at end of file diff --git a/addons/chemical/functions/fnc_poison.sqf b/addons/chemical/functions/fnc_poison.sqf index 9958334f6..d483a91d5 100644 --- a/addons/chemical/functions/fnc_poison.sqf +++ b/addons/chemical/functions/fnc_poison.sqf @@ -69,5 +69,9 @@ if (_currentInfection != _newTime) then { // Exit if infection reaches 0 if (_newTime <= 0) then { + if !(_unit getVariable [QGVAR(airPoisoning), false]) then { + [QEGVAR(breathing,playCough), [_unit], _unit] call CBA_fnc_targetEvent; + }; + _unit setVariable [QGVAR(airPoisoning), true, true]; }; \ No newline at end of file diff --git a/addons/feedback/XEH_PREP.hpp b/addons/feedback/XEH_PREP.hpp index 9af508f92..82eba5926 100644 --- a/addons/feedback/XEH_PREP.hpp +++ b/addons/feedback/XEH_PREP.hpp @@ -1,3 +1,4 @@ +PREP(effectBreathingWheeze); PREP(effectCoughing); PREP(effectLowSpO2); PREP(effectOpioid); diff --git a/addons/feedback/functions/fnc_effectBreathingWheeze.sqf b/addons/feedback/functions/fnc_effectBreathingWheeze.sqf new file mode 100644 index 000000000..753f647c1 --- /dev/null +++ b/addons/feedback/functions/fnc_effectBreathingWheeze.sqf @@ -0,0 +1,37 @@ +#include "..\script_component.hpp" +/* + * Author: Mazinski + * Triggers the wheezing effect. + * + * Arguments: + * 0: Enable + * 1: Intensity + * 2: Unit + * + * Return Value: + * None + * + * Example: + * [true, 0.5, player] call kat_feedback_fnc_effectBreathingWheeze; + * + * Public: No + */ + +params ["_enable", "_effected", "_unit"]; +if (!_enable || !_effected) exitWith { false }; + +if (!(_unit getVariable [QEGVAR(breathing,PneumoBreathCooldownOn), false])) then { + _unit setVariable [QEGVAR(breathing,PneumoBreathCooldownOn), true, true]; + + private _soundTargets = allPlayers inAreaArray [ASLToAGL getPosASL _unit, 15, 15, 0, false, 15]; + + if !(_soundTargets isEqualTo []) then { + [QEGVAR(breathing,playCough), [_unit], _soundTargets] call CBA_fnc_targetEvent; + }; + + [{ + params["_unit"]; + _unit setVariable [QEGVAR(breathing,PneumoBreathCooldownOn), false, true]; + }, + [_unit], 20] call CBA_fnc_waitAndExecute; +}; \ No newline at end of file diff --git a/addons/feedback/functions/fnc_effectCoughing.sqf b/addons/feedback/functions/fnc_effectCoughing.sqf index 2a19cbf38..343e9fb71 100644 --- a/addons/feedback/functions/fnc_effectCoughing.sqf +++ b/addons/feedback/functions/fnc_effectCoughing.sqf @@ -6,30 +6,48 @@ * Arguments: * 0: Enable * 1: Intensity + * 2: Unit * * Return Value: * None * * Example: - * [true, 0.5] call kat_feedback_fnc_effectCoughing; + * [true, 0.5, player] call kat_feedback_fnc_effectCoughing; * * Public: No */ -params ["_enable", "_poisoned"]; +params ["_enable", "_poisoned", "_unit"]; if (!_enable || !_poisoned) exitWith { if (GVAR(airPoisoning) != -1) then { GVAR(airPoisoning) ppEffectEnable false; }; }; if (GVAR(airPoisoning) != -1) then { GVAR(airPoisoning) ppEffectEnable true; }; +if (!(_unit getVariable [QEGVAR(chemical,CoughCooldown), false])) then { + _unit setVariable [QEGVAR(chemical,CoughCooldown), true, true]; + + private _random = floor (random 4); + switch (_random) do { + case 0: { _unit say3D QEGVAR(chemical,cough_0); }; + case 1: { _unit say3D QEGVAR(chemical,cough_1); }; + case 2: { _unit say3D QEGVAR(chemical,cough_2); }; + case 3: { _unit say3D QEGVAR(chemical,cough_3); }; + }; + + addCamShake [3, 4, 0]; + + [{ + params["_unit"]; + _unit setVariable [QEGVAR(chemical,CoughCooldown), false, true]; + }, + [_unit], 7] call CBA_fnc_waitAndExecute; +}; + // Trigger effect every 2s private _showNextTick = missionNamespace getVariable [QGVAR(showCoughNextTick), true]; GVAR(showCoughNextTick) = !_showNextTick; if (_showNextTick) exitWith {}; -_unit say3D QEGVAR(chemical,cough_1); -addCamShake [3, 4, 0]; - private _initialAdjust = []; private _delayedAdjust = []; diff --git a/addons/feedback/functions/fnc_handleEffects.sqf b/addons/feedback/functions/fnc_handleEffects.sqf index 53feac724..119fdb3dc 100644 --- a/addons/feedback/functions/fnc_handleEffects.sqf +++ b/addons/feedback/functions/fnc_handleEffects.sqf @@ -29,6 +29,7 @@ private _spO2 = GET_KAT_SPO2(ACE_player); private _unconscious = IS_UNCONSCIOUS(ACE_player); private _poisoned = IS_AIRPOISONED(ACE_player); private _tear = IN_TEARGAS(ACE_player); +private _wheeze = ((ACE_player getVariable [QGVAR(pneumothorax), 0] > 0) || ACE_player getVariable [QGVAR(hemopneumothorax), false] || ACE_player getVariable [QGVAR(tensionpneumothorax), false] || ACE_player getVariable [QEGVAR(chemical,airPoisoning), false]); // - Visual effects ----------------------------------------------------------- @@ -39,8 +40,8 @@ private _tear = IN_TEARGAS(ACE_player); linearConversion [GVAR(effectLowSpO2), EGVAR(breathing,SpO2_dieValue), _spO2, 0, 1, true] ] call FUNC(effectLowSpO2); -[!_unconscious, _poisoned] call FUNC(effectCoughing); +[!_unconscious, _poisoned, ACE_player] call FUNC(effectCoughing); [!_unconscious, _tear] call FUNC(effectTearHaze); - +[!_unconscious, _wheeze, ACE_player] call (effectBreathingWheeze); END_COUNTER(handleEffects); diff --git a/addons/vitals/functions/fnc_handlePoisoning.sqf b/addons/vitals/functions/fnc_handlePoisoning.sqf index c150c5eae..868722913 100644 --- a/addons/vitals/functions/fnc_handlePoisoning.sqf +++ b/addons/vitals/functions/fnc_handlePoisoning.sqf @@ -24,6 +24,24 @@ private _currentCS = _unit getVariable [QEGVAR(chemical,CSGas), 0]; _unit setVariable [QEGVAR(chemical,CSGas), (_currentCS - (_poisonAdjustment * _deltaT)) max 0, _syncValue]; +private _inZone = false; +private _distance = 0; + +{ + _y params ["_gasLogic", "_radius", "_gasLevel", "_condition", "_conditionArgs", "_isSealable"]; + TRACE_2("gasVitalsPFH loop",_x,_y); + + _distance = _unit distance _gasLogic; + + if (_distance < _radius) then { + _inZone = true; + }; +} forEach GVAR(gasSources); + +if !(_inZone) then { + _unit setVariable [QGVAR(areaIntensity), 0, true]; +}; + private _infectionArray = _unit getVariable [QEGVAR(chemical,infectionArray), []]; if (count _infectionArray == 0) then { @@ -45,4 +63,4 @@ if (count _infectionArray == 0) then { } forEach _infectionArray; _unit setVariable [QEGVAR(chemical,infectionArray), _infectionArray, true]; -}; \ No newline at end of file +}; diff --git a/addons/watch/CfgSounds.hpp b/addons/watch/CfgSounds.hpp new file mode 100644 index 000000000..7c40585af --- /dev/null +++ b/addons/watch/CfgSounds.hpp @@ -0,0 +1,24 @@ +class CfgSounds { + class GVAR(watchAlarm) { + name = QGVAR(watchAlarm); + sound[] = + { + QPATHTOF(audio\watchAlarm.ogg), + 5, + 1, + 10 + }; + titles[] = {}; + }; + class GVAR(watchVibrate) { + name = QGVAR(watchVibrate); + sound[] = + { + QPATHTOF(audio\watchVibrate.ogg), + 5, + 1, + 10 + }; + titles[] = {}; + }; +}; diff --git a/addons/watch/CfgWeapons.hpp b/addons/watch/CfgWeapons.hpp index 88d16c14b..bd888acde 100644 --- a/addons/watch/CfgWeapons.hpp +++ b/addons/watch/CfgWeapons.hpp @@ -21,4 +21,11 @@ class CfgWeapons { displayName = CSTRING(STSDisplayName); picture = QPATHTOF(UI\watch_sts.paa); }; + class KAT_Ranger: ItemWatch { + ACE_hideItemType = "Watch"; + author = "Mazinski"; + descriptionShort = CSTRING(RangerDescription); + displayName = CSTRING(RangerDisplayName); + picture = QPATHTOF(UI\RangerWatchFace.paa); + }; }; diff --git a/addons/watch/RscTitles.hpp b/addons/watch/RscTitles.hpp index 45979fbf9..7a31f4fc5 100644 --- a/addons/watch/RscTitles.hpp +++ b/addons/watch/RscTitles.hpp @@ -418,4 +418,141 @@ class RscTitles }; }; }; + class KAT_Ranger + { + idd = 22935; + enableSimulation = 1; + movingEnable = 0; + fadeIn=0; + fadeOut=1; + duration = 10e10; + onLoad = "uiNamespace setVariable ['KAT_Ranger', _this select 0];"; + class controls + { + class RangerImage: RscPicture + { + idc = 22800; + text = "\x\kat\addons\watch\UI\RangerWatchFace.paa"; + x = QUOTE(SAFEZONE_X_RIGHTEDGE - FRAME_W(25) - FRAME_W(15.07)); + y = QUOTE(SAFEZONE_Y_LOWEDGE - FRAME_H(20)); + w = QUOTE(FRAME_W(28)); + h = QUOTE(FRAME_H(28)); + }; + class RangerTime: RscText + { + idc = 22806; + style = ST_RIGHT; + shadow = 0; + font = "EtelkaMonospacePro"; + text = "22:22:22"; //--- ToDo: Localize; + x = QUOTE(SAFEZONE_X_RIGHTEDGE - FRAME_W(25) - FRAME_W(4.7)); + y = QUOTE(SAFEZONE_Y_LOWEDGE - FRAME_H(5.9)); + w = QUOTE(FRAME_W(7.5)); + h = QUOTE(FRAME_H(4)); + colorBackground[] = {0,0,0,0}; + colorText[] = {0.8,0.8,0.8,0.9}; + sizeEx = QUOTE(FRAME_H(1.9)); + }; + class RangerTimer: RscText + { + idc = 22807; + style = ST_RIGHT; + valign = "middle"; + shadow = 0; + font = "EtelkaMonospacePro"; + text = ""; //--- ToDo: Localize; + x = QUOTE(SAFEZONE_X_RIGHTEDGE - FRAME_W(24.6)); + y = QUOTE(SAFEZONE_Y_LOWEDGE - FRAME_H(7.5)); + w = QUOTE(FRAME_W(3)); + h = QUOTE(FRAME_H(1.5)); + colorBackground[] = {0,0,0,0}; + colorText[] = {0.8,0.8,0.8,0.9}; + sizeEx = QUOTE(FRAME_H(1.8)); + }; + class RangerAltitude: RscText + { + idc = 22808; + style = ST_RIGHT; + valign = "middle"; + shadow = 0; + font = "EtelkaMonospacePro"; + text = "1000"; + x = QUOTE(SAFEZONE_X_RIGHTEDGE - FRAME_W(25) - FRAME_W(5.5)); + y = QUOTE(SAFEZONE_Y_LOWEDGE - FRAME_H(7.5)); + w = QUOTE(FRAME_W(4)); + h = QUOTE(FRAME_H(1.5)); + colorBackground[] = {0,0,0,0}; + colorText[] = {0.8,0.8,0.8,0.9}; + sizeEx = QUOTE(FRAME_H(1.8)); + }; + class RangerHR: RscText + { + idc = 22809; + style = ST_CENTER; + valign = "middle"; + shadow = 0; + font = "EtelkaMonospacePro"; + text = "111"; + x = QUOTE(SAFEZONE_X_RIGHTEDGE - FRAME_W(25) - FRAME_W(4.3)); + y = QUOTE(SAFEZONE_Y_LOWEDGE - FRAME_H(10.1)); + w = QUOTE(FRAME_W(4)); + h = QUOTE(FRAME_H(1.5)); + colorBackground[] = {0,0,0,0}; + colorText[] = {0.8,0.8,0.8,0.9}; + sizeEx = QUOTE(FRAME_H(1.4)); + }; + class RangerO2: RscText + { + idc = 22810; + style = ST_CENTER; + valign = "middle"; + shadow = 0; + font = "EtelkaMonospacePro"; + text = "97"; + x = QUOTE(SAFEZONE_X_RIGHTEDGE - FRAME_W(25) - FRAME_W(1.2)); + y = QUOTE(SAFEZONE_Y_LOWEDGE - FRAME_H(10.1)); + w = QUOTE(FRAME_W(3)); + h = QUOTE(FRAME_H(1.5)); + colorBackground[] = {0,0,0,0}; + colorText[] = {0.8,0.8,0.8,0.9}; + sizeEx = QUOTE(FRAME_H(1.4)); + }; + class RangerWatchMinute: RscPicture + { + idc = 22802; + text = "\x\kat\addons\watch\UI\RangerWatchMinute.paa"; + x = QUOTE(SAFEZONE_X_RIGHTEDGE - FRAME_W(25) - FRAME_W(15)); + y = QUOTE(SAFEZONE_Y_LOWEDGE - FRAME_H(20)); + w = QUOTE(FRAME_W(28)); + h = QUOTE(FRAME_H(28)); + }; + class RangerWatchHour: RangerWatchMinute + { + idc = 22803; + text = "\x\kat\addons\watch\UI\RangerWatchHour.paa"; + x = QUOTE(SAFEZONE_X_RIGHTEDGE - FRAME_W(25) - FRAME_W(15)); + y = QUOTE(SAFEZONE_Y_LOWEDGE - FRAME_H(20)); + w = QUOTE(FRAME_W(28)); + h = QUOTE(FRAME_H(28)); + }; + class RangerWatchSecond: RangerWatchMinute + { + idc = 22804; + text = "\x\kat\addons\watch\UI\RangerWatchSecond.paa"; + x = QUOTE(SAFEZONE_X_RIGHTEDGE - FRAME_W(25) - FRAME_W(15)); + y = QUOTE(SAFEZONE_Y_LOWEDGE - FRAME_H(20)); + w = QUOTE(FRAME_W(28)); + h = QUOTE(FRAME_H(28)); + }; + class RangerWatchCaps: RangerImage + { + idc = 22805; + text = "\x\kat\addons\watch\UI\RangerWatchCaps.paa"; + x = QUOTE(SAFEZONE_X_RIGHTEDGE - FRAME_W(25) - FRAME_W(15.07)); + y = QUOTE(SAFEZONE_Y_LOWEDGE - FRAME_H(20)); + w = QUOTE(FRAME_W(28)); + h = QUOTE(FRAME_H(28)); + }; + }; + }; }; \ No newline at end of file diff --git a/addons/watch/UI/RangerWatchCaps.paa b/addons/watch/UI/RangerWatchCaps.paa new file mode 100644 index 000000000..d196807f4 Binary files /dev/null and b/addons/watch/UI/RangerWatchCaps.paa differ diff --git a/addons/watch/UI/RangerWatchCompass.paa b/addons/watch/UI/RangerWatchCompass.paa new file mode 100644 index 000000000..a5a1e1107 Binary files /dev/null and b/addons/watch/UI/RangerWatchCompass.paa differ diff --git a/addons/watch/UI/RangerWatchDarkSheet.paa b/addons/watch/UI/RangerWatchDarkSheet.paa new file mode 100644 index 000000000..19cfa283a Binary files /dev/null and b/addons/watch/UI/RangerWatchDarkSheet.paa differ diff --git a/addons/watch/UI/RangerWatchFace.paa b/addons/watch/UI/RangerWatchFace.paa new file mode 100644 index 000000000..312964228 Binary files /dev/null and b/addons/watch/UI/RangerWatchFace.paa differ diff --git a/addons/watch/UI/RangerWatchHour.paa b/addons/watch/UI/RangerWatchHour.paa new file mode 100644 index 000000000..6450892e6 Binary files /dev/null and b/addons/watch/UI/RangerWatchHour.paa differ diff --git a/addons/watch/UI/RangerWatchMinute.paa b/addons/watch/UI/RangerWatchMinute.paa new file mode 100644 index 000000000..32f46f970 Binary files /dev/null and b/addons/watch/UI/RangerWatchMinute.paa differ diff --git a/addons/watch/UI/RangerWatchNVGSheet.paa b/addons/watch/UI/RangerWatchNVGSheet.paa new file mode 100644 index 000000000..e6950afd8 Binary files /dev/null and b/addons/watch/UI/RangerWatchNVGSheet.paa differ diff --git a/addons/watch/UI/RangerWatchSecond.paa b/addons/watch/UI/RangerWatchSecond.paa new file mode 100644 index 000000000..de9b08c63 Binary files /dev/null and b/addons/watch/UI/RangerWatchSecond.paa differ diff --git a/addons/watch/XEH_PREP.hpp b/addons/watch/XEH_PREP.hpp index 7335c72c5..d97090421 100644 --- a/addons/watch/XEH_PREP.hpp +++ b/addons/watch/XEH_PREP.hpp @@ -1,6 +1,11 @@ +PREP(closeWatchTimer); +PREP(handleRespawn); PREP(hideKWatch); PREP(hideCWatch); PREP(hideSWatch); +PREP(hideRWatch); +PREP(init); PREP(showKWatch); PREP(showCWatch); -PREP(showSWatch); \ No newline at end of file +PREP(showSWatch); +PREP(showRWatch); \ No newline at end of file diff --git a/addons/watch/XEH_postInit.sqf b/addons/watch/XEH_postInit.sqf index e065b019c..fc4683fb8 100644 --- a/addons/watch/XEH_postInit.sqf +++ b/addons/watch/XEH_postInit.sqf @@ -2,41 +2,107 @@ if (!hasInterface) exitWith {}; -["KAT Watch", QGVAR(showKatmin), "Show Katmin", { +[QGVAR(closeWatchTimer), LINKFUNC(closeWatchTimer)] call CBA_fnc_addEventHandler; +[QEGVAR(misc,handleRespawn), LINKFUNC(handleRespawn)] call CBA_fnc_addEventHandler; + +[QGVAR(playWatchTone), { + params ["_unit", "_tone"]; + _unit say3D [_tone, 5]; +}] call CBA_fnc_addEventHandler; + +["KAT Watch", QGVAR(showKatmin), CSTRING(ShowKATWatch_Setting), { // Conditions: canInteract - if (!([ACE_player, objNull, ["isNotEscorting", "isNotInside"]] call ACEFUNC(common,canInteractWith)) || {!('KAT_Katmin' in assignedItems ACE_player)}) exitWith { false }; + if (!([ACE_player, objNull, ["isNotEscorting", "isNotInside"]] call ACEFUNC(common,canInteractWith))) exitWith { false }; + + private _return = false; + + switch true do{ + case (('KAT_Katmin' in assignedItems ACE_player)): { + _return = true; + + if !(GETMVAR(GVAR(KatminActive),false)) then { + [ACE_player] call FUNC(showKWatch); + } else { + call FUNC(hideKWatch); + }; + }; + case (('KAT_Cavmin' in assignedItems ACE_player)): { + _return = true; + + if !(GETMVAR(GVAR(CavminActive),false)) then { + [ACE_player] call FUNC(showCWatch); + } else { + call FUNC(hideCWatch); + }; + }; + case (('KAT_STS' in assignedItems ACE_player)): { + _return = true; - if !(GETMVAR(GVAR(KatminActive),false)) then { - [ACE_player] call FUNC(showKWatch); - } else { - call FUNC(hideKWatch); + if !(GETMVAR(GVAR(STSActive),false)) then { + [ACE_player] call FUNC(showSWatch); + } else { + call FUNC(hideSWatch); + }; + }; + case (('KAT_Ranger' in assignedItems ACE_player)): { + _return = true; + + if !(GETMVAR(GVAR(RangerActive),false)) then { + [ACE_player] call FUNC(showRWatch); + } else { + call FUNC(hideRWatch); + }; + }; }; - true + _return }, { false }, [24, [false, false, false]], false] call CBA_fnc_addKeybind; -["KAT Cav Watch", QGVAR(showCavmin), "Show Cavmin", { - // Conditions: canInteract - if (!([ACE_player, objNull, ["isNotEscorting", "isNotInside"]] call ACEFUNC(common,canInteractWith)) || {!('KAT_Cavmin' in assignedItems ACE_player)}) exitWith { false }; +["KAT Watch", QGVAR(increaseTimer), CSTRING(AddTimer_Setting), { + if (!([ACE_player, objNull, ["isNotEscorting", "isNotInside"]] call ACEFUNC(common,canInteractWith)) || {!('KAT_Ranger' in assignedItems ACE_player)}) exitWith { false }; - if !(GETMVAR(GVAR(CavminActive),false)) then { - [ACE_player] call FUNC(showCWatch); - } else { - call FUNC(hideCWatch); + if !(GETMVAR(GVAR(RangerActive),false)) exitWith { false }; + + private _timerLength = ACE_player getVariable [QGVAR(rangerTimer), 0]; + + if (_timerLength < 999) then { + ACE_player setVariable [QGVAR(rangerTimer), ((_timerLength + 15) min 999), false]; }; true -}, { false }, [24, [false, false, false]], false] call CBA_fnc_addKeybind; +}, { false }, [38, [false, false, true]], false] call CBA_fnc_addKeybind; -["KAT STS Watch", QGVAR(showSTS), "Show STS", { - // Conditions: canInteract - if (!([ACE_player, objNull, ["isNotEscorting", "isNotInside"]] call ACEFUNC(common,canInteractWith)) || {!('KAT_STS' in assignedItems ACE_player)}) exitWith { false }; +["KAT Watch", QGVAR(decreaseTimer), CSTRING(SubtractTimer_Setting), { + if (!([ACE_player, objNull, ["isNotEscorting", "isNotInside"]] call ACEFUNC(common,canInteractWith)) || {!('KAT_Ranger' in assignedItems ACE_player)}) exitWith { false }; + + if !(GETMVAR(GVAR(RangerActive),false)) exitWith { false }; + + private _timerLength = ACE_player getVariable [QGVAR(rangerTimer), 0]; - if !(GETMVAR(GVAR(STSActive),false)) then { - [ACE_player] call FUNC(showSWatch); - } else { - call FUNC(hideSWatch); + if (_timerLength > 0) then { + ACE_player setVariable [QGVAR(rangerTimer), ((_timerLength - 15) max 0), false]; }; true -}, { false }, [24, [false, false, false]], false] call CBA_fnc_addKeybind; +}, { false }, [36, [false, false, true]], false] call CBA_fnc_addKeybind; + +["KAT Watch", QGVAR(startTimer), CSTRING(StartStopTimer_Setting), { + if (!([ACE_player, objNull, ["isNotEscorting", "isNotInside"]] call ACEFUNC(common,canInteractWith)) || {!('KAT_Ranger' in assignedItems ACE_player)}) exitWith { false }; + + private _timerLength = ACE_player getVariable [QGVAR(rangerTimer), 0]; + private _timerActive = ACE_player getVariable [QGVAR(rangerStart), false]; + + if (_timerLength > 0) then { + if (_timerActive) then { + ACE_player setVariable [QGVAR(rangerStart), false, false]; + } else { + if !(GETMVAR(GVAR(RangerActive),false)) then { + [QGVAR(closeWatchTimer), [ACE_player], ACE_player] call CBA_fnc_targetEvent; + }; + + ACE_player setVariable [QGVAR(rangerStart), true, false]; + }; + }; + + true +}, { false }, [37, [false, false, true]], false] call CBA_fnc_addKeybind; \ No newline at end of file diff --git a/addons/watch/audio/watchAlarm.ogg b/addons/watch/audio/watchAlarm.ogg new file mode 100644 index 000000000..84ce0fc1d Binary files /dev/null and b/addons/watch/audio/watchAlarm.ogg differ diff --git a/addons/watch/audio/watchAlarm.xmp b/addons/watch/audio/watchAlarm.xmp new file mode 100644 index 000000000..f63c73244 --- /dev/null +++ b/addons/watch/audio/watchAlarm.xmp @@ -0,0 +1,83 @@ + + + + + + + + CuePoint Markers + Cue + f44100 + + + CD Track Markers + Track + f44100 + + + Subclip Markers + InOut + f44100 + + + + 2024-12-15T22:21:16-08:00 + 2024-12-15T22:21:16-08:00 + xmp.iid:30e9deb5-bfc0-2b4d-abc4-d09b0f084d7f + xmp.did:30e9deb5-bfc0-2b4d-abc4-d09b0f084d7f + xmp.did:2c460e27-80bc-444a-9ec5-e861f49bb36a + + + + saved + xmp.iid:2c460e27-80bc-444a-9ec5-e861f49bb36a + 2024-12-15T22:21:16-08:00 + Adobe Audition 25.0 (Windows) + /metadata + + + saved + xmp.iid:30e9deb5-bfc0-2b4d-abc4-d09b0f084d7f + 2024-12-15T22:21:16-08:00 + Adobe Audition 25.0 (Windows) + / + + + + + xmp.iid:2c460e27-80bc-444a-9ec5-e861f49bb36a + xmp.did:2c460e27-80bc-444a-9ec5-e861f49bb36a + xmp.did:2c460e27-80bc-444a-9ec5-e861f49bb36a + + audio/ogg; codec="vorbis" + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/addons/watch/audio/watchVibrate.ogg b/addons/watch/audio/watchVibrate.ogg new file mode 100644 index 000000000..c85f5d063 Binary files /dev/null and b/addons/watch/audio/watchVibrate.ogg differ diff --git a/addons/watch/audio/watchVibrate.xmp b/addons/watch/audio/watchVibrate.xmp new file mode 100644 index 000000000..4d1d46b92 --- /dev/null +++ b/addons/watch/audio/watchVibrate.xmp @@ -0,0 +1,83 @@ + + + + + + + + CuePoint Markers + Cue + f44100 + + + CD Track Markers + Track + f44100 + + + Subclip Markers + InOut + f44100 + + + + 2024-12-15T22:22:22-08:00 + 2024-12-15T22:22:22-08:00 + xmp.iid:80a61fff-aa5c-fe4d-bbdc-0664eb47dd8c + xmp.did:80a61fff-aa5c-fe4d-bbdc-0664eb47dd8c + xmp.did:c29c979e-f990-0849-a1e0-1012ebd43b5d + + + + saved + xmp.iid:c29c979e-f990-0849-a1e0-1012ebd43b5d + 2024-12-15T22:22:22-08:00 + Adobe Audition 25.0 (Windows) + /metadata + + + saved + xmp.iid:80a61fff-aa5c-fe4d-bbdc-0664eb47dd8c + 2024-12-15T22:22:22-08:00 + Adobe Audition 25.0 (Windows) + / + + + + + xmp.iid:c29c979e-f990-0849-a1e0-1012ebd43b5d + xmp.did:c29c979e-f990-0849-a1e0-1012ebd43b5d + xmp.did:c29c979e-f990-0849-a1e0-1012ebd43b5d + + audio/ogg; codec="vorbis" + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/addons/watch/config.cpp b/addons/watch/config.cpp index 8d171b1e6..b8cdf2b4e 100644 --- a/addons/watch/config.cpp +++ b/addons/watch/config.cpp @@ -8,7 +8,8 @@ class CfgPatches { weapons[] = { "KAT_Katmin", "KAT_Cavmin", - "KAT_STS" + "KAT_STS", + "KAT_Ranger" }; magazines[] = { }; requiredAddons[] = { @@ -36,4 +37,5 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgWeapons.hpp" +#include "CfgSounds.hpp" #include "RscTitles.hpp" \ No newline at end of file diff --git a/addons/watch/functions/fnc_closeWatchTimer.sqf b/addons/watch/functions/fnc_closeWatchTimer.sqf new file mode 100644 index 000000000..657ec0cbb --- /dev/null +++ b/addons/watch/functions/fnc_closeWatchTimer.sqf @@ -0,0 +1,51 @@ +#include "..\script_component.hpp" +/* + * Author: Katalam + * Initializes unit variables. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [player] call kat_watch_fnc_init; + * + * Public: No + */ + +params ["_unit"]; + +[{ + _this params ["_args", "_pfhID"]; + _args params ["_unit"]; + + if (GVAR(RangerActive)) exitWith { + _pfhID call CBA_fnc_removePerFrameHandler; + }; + + if !(alive _unit) exitWith { + _pfhID call CBA_fnc_removePerFrameHandler; + }; + + if !("KAT_Ranger" in assignedItems _unit) exitWith { + _unit setVariable [QGVAR(rangerTimer), 0, false]; + _pfhID call CBA_fnc_removePerFrameHandler; + }; + + private _timeValue = _unit getVariable [QGVAR(rangerTimer), 0]; + private _active = _unit getVariable [QGVAR(rangerStart), false]; + + if (_active) then { + _timeValue = (_timeValue - 1) max 0; + _unit setVariable [QGVAR(rangerTimer), _timeValue, false]; + + if (_timeValue == 0) then { + _unit setVariable [QGVAR(rangerStart), false, false]; + [QGVAR(playWatchTone), [_unit, QGVAR(watchAlarm)], _unit] call CBA_fnc_targetEvent; + + _pfhID call CBA_fnc_removePerFrameHandler; + }; + }; +}, 1, [_unit]] call CBA_fnc_addPerFrameHandler; \ No newline at end of file diff --git a/addons/watch/functions/fnc_handleRespawn.sqf b/addons/watch/functions/fnc_handleRespawn.sqf new file mode 100644 index 000000000..ed450e087 --- /dev/null +++ b/addons/watch/functions/fnc_handleRespawn.sqf @@ -0,0 +1,24 @@ +#include "..\script_component.hpp" +/* + * Author: YetheSamartaka + * Edited: Mazinski + * Ensures proper initial values reset on respawn + * + * Arguments: + * 0: Unit + * 1: Corpse + * + * Return Value: + * None + * + * Example: + * [alive, body] call kat_watch_fnc_handleRespawn; + * + * Public: No + */ + +params ["_unit","_dead"]; +TRACE_2("handleRespawn",_unit,_dead); + +_unit setVariable [QGVAR(RangerStart), false, true]; +_unit setVariable [QGVAR(RangerTimer), 0, true]; \ No newline at end of file diff --git a/addons/watch/functions/fnc_hideRWatch.sqf b/addons/watch/functions/fnc_hideRWatch.sqf new file mode 100644 index 000000000..aedc2a813 --- /dev/null +++ b/addons/watch/functions/fnc_hideRWatch.sqf @@ -0,0 +1,19 @@ +#include "..\script_component.hpp" +/* + * Author: Garth 'L-H' de Wet + * Modified: Mazinski + * Removes the KWatch from the screen. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call kat_watch_fnc_hideKWatch + * + * Public: No + */ +GVAR(RangerActive) = false; +"KAT_Ranger" cutText ["","PLAIN",0,true]; \ No newline at end of file diff --git a/addons/watch/functions/fnc_init.sqf b/addons/watch/functions/fnc_init.sqf new file mode 100644 index 000000000..ea9a81735 --- /dev/null +++ b/addons/watch/functions/fnc_init.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: Katalam + * Initializes unit variables. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [player] call kat_watch_fnc_init; + * + * Public: No + */ + +params ["_unit", ["_isRespawn", true]]; + +if (!local _unit) exitWith {}; + +_unit setVariable [QGVAR(rangerStart), false, true]; +_unit setVariable [QGVAR(rangerTimer), 0, true]; \ No newline at end of file diff --git a/addons/watch/functions/fnc_showRWatch.sqf b/addons/watch/functions/fnc_showRWatch.sqf new file mode 100644 index 000000000..d2cb346e7 --- /dev/null +++ b/addons/watch/functions/fnc_showRWatch.sqf @@ -0,0 +1,112 @@ +#include "..\script_component.hpp" +/* + * Author: Garth 'L-H' de Wet + * Modified: Mazinski + * Displays the KWatch on screen. + * + * Arguments: + * 0: unit + * + * Return Value: + * None + * + * Example: + * [player] call kat_watch_fnc_showKWatch + * + * Public: Yes + */ + +params ["_unit"]; + +"KAT_Ranger" cutRsc ["KAT_Ranger", "PLAIN", 0, true]; + +if (isNull (uiNamespace getVariable ["KAT_Ranger", displayNull])) exitWith {}; + +GVAR(RangerActive) = true; + +private _display = uiNamespace getVariable ["KAT_Ranger", displayNull]; +private _background = _display displayCtrl 22800; +private _minute = _display displayCtrl 22802; +private _hour = _display displayCtrl 22803; +private _second = _display displayCtrl 22804; +private _time = _display displayCtrl 22806; +private _timer = _display displayCtrl 22807; +private _altitude = _display displayCtrl 22808; +private _hr = _display displayCtrl 22809; +private _o2 = _display displayCtrl 22810; + +[{ + _this params ["_args", "_pfhID"]; + _args params ["_unit", "_hour", "_minute", "_second", "_time", "_timer", "_altitude", "_hr", "_o2"]; + + if !(GVAR(RangerActive)) exitWith { + [QGVAR(closeWatchTimer), [_unit], _unit] call CBA_fnc_targetEvent; + _pfhID call CBA_fnc_removePerFrameHandler; + }; + + if !(alive _unit) exitWith { + call FUNC(hideRWatch); + _pfhID call CBA_fnc_removePerFrameHandler; + }; + + if !("KAT_Ranger" in assignedItems _unit) exitWith { + call FUNC(hideRWatch); + _pfhID call CBA_fnc_removePerFrameHandler; + }; + + private _altitudeValue = round((getPosASL _unit) select 2); + + if (GVAR(altitudeUnit) == 1) then { + _altitude ctrlSetText ([(_altitudeValue * 3.281), 1, 0] call CBA_fnc_formatNumber); + } else { + _altitude ctrlSetText ([_altitudeValue, 1, 0] call CBA_fnc_formatNumber); + }; + + _hr ctrlSetText ([GET_HEART_RATE(_unit), 1, 0] call CBA_fnc_formatNumber); + _o2 ctrlSetText ([GET_KAT_SPO2(_unit), 1, 0] call CBA_fnc_formatNumber); + + private _hours = floor dayTime; + private _minutes = floor ((dayTime - _hours) * 60); + private _seconds = floor ((((dayTime - _hours) * 60) - _minutes) * 60); + + _time ctrlSetText (format ["%1:%2:%3", [_hours, 2] call CBA_fnc_formatNumber, [_minutes, 2] call CBA_fnc_formatNumber, [_seconds, 2] call CBA_fnc_formatNumber]); + + _hours = dayTime; + + if (_hours > 12) then { + _hours = _hours - 12; + }; + + _hour ctrlSetAngle [(linearConversion [0, 12, _hours, 0, 360]), 0.5, 0.5, true]; + _minute ctrlSetAngle [(linearConversion [0, 60, _minutes, 0, 360]), 0.5, 0.5, true]; + _second ctrlSetAngle [(linearConversion [0, 60, _seconds, 0, 360]), 0.5, 0.5, true]; + + private _timeValue = _unit getVariable [QGVAR(rangerTimer), 0]; + private _active = _unit getVariable [QGVAR(rangerStart), false]; + + _timer ctrlSetText ([_timeValue, 2, 0] call CBA_fnc_formatNumber); + + if (_active) then { + _timeValue = (_timeValue - 1) max 0; + + _timer ctrlSetText ([_timeValue, 2, 0] call CBA_fnc_formatNumber); + _unit setVariable [QGVAR(rangerTimer), _timeValue, false]; + + if (_timeValue == 0) then { + _unit setVariable [QGVAR(rangerStart), false, false]; + [QGVAR(playWatchTone), [_unit, QGVAR(watchAlarm)], _unit] call CBA_fnc_targetEvent; + }; + } else { + _timer ctrlSetText ([_timeValue, 2, 0] call CBA_fnc_formatNumber); + }; +}, 1, [ + _unit, + _hour, + _minute, + _second, + _time, + _timer, + _altitude, + _hr, + _o2 +]] call CBA_fnc_addPerFrameHandler; \ No newline at end of file diff --git a/addons/watch/stringtable.xml b/addons/watch/stringtable.xml index cffe80016..523c5b983 100644 --- a/addons/watch/stringtable.xml +++ b/addons/watch/stringtable.xml @@ -137,6 +137,24 @@ Katmin Jump Standard Katmin Jump Standard + + Watch with Vital Monitoring Capabilities. Sua Sponte. + + + Katmin K12 Model R + + + Show KATMIN Watch + + + Add 15 Seconds to Watch Timer + + + Subtract 15 Seconds from Watch Timer + + + Start and Stop Watch Timer + %1ft/s %1ft/s