Merge remote-tracking branch 'origin/medicalFixes' into simpleDiagnosis

Conflicts:
	addons/medical/ACE_Medical_Actions.hpp
	addons/medical/ACE_Medical_SelfActions.hpp
This commit is contained in:
esteldunedain 2015-04-17 20:02:51 -03:00
commit c423e9d743
74 changed files with 528 additions and 1111 deletions

View File

@ -2,7 +2,7 @@
class CfgAmmo {
class BulletBase;
class B_20mm : BulletBase {
hit = 80;
hit = 80;
indirectHit = 12;
indirectHitRange = 2; //2;
caliber = 1.4;
@ -13,7 +13,7 @@ class CfgAmmo {
tracerEndTime = 3.5;
CraterEffects = "ExploAmmoCrater";
explosionEffects = "ExploAmmoExplosion";
explosionEffects = "ExploAmmoExplosion";
model = "\A3\Weapons_f\Data\bullettracer\tracer_red";
};
class ACE_20mm_HE : B_20mm {};
@ -23,7 +23,7 @@ class CfgAmmo {
indirectHitRange = 0.3; //2;
explosive = 0;
CraterEffects = "";
explosionEffects = "";
explosionEffects = "";
};
// adjust minigun caliber and deflection to other ammo

View File

@ -907,7 +907,7 @@ class Heli_Attack_01_base_F: Helicopter_Base_F {
thermalMode[] = {0,1};
gunnerOpticsColor[] = {0,0,0,1};
directionStabilized = 1;
horizontallyStabilized = 1;
horizontallyStabilized = 1;
gunnerOpticsModel = "\A3\Weapons_F_Beta\Reticle\Heli_Attack_01_Optics_Gunner_wide_F";
};
class Medium: Wide
@ -918,7 +918,7 @@ class Heli_Attack_01_base_F: Helicopter_Base_F {
maxFov = 0.093;
gunnerOpticsColor[] = {0,0,0,1};
directionStabilized = 1;
horizontallyStabilized = 1;
horizontallyStabilized = 1;
gunnerOpticsModel = "\A3\Weapons_F_Beta\Reticle\Heli_Attack_01_Optics_Gunner_medium_F";
};
class Narrow: Wide
@ -929,7 +929,7 @@ class Heli_Attack_01_base_F: Helicopter_Base_F {
maxFov = 0.029;
gunnerOpticsColor[] = {0,0,0,1};
directionStabilized = 1;
horizontallyStabilized = 1;
horizontallyStabilized = 1;
gunnerOpticsModel = "\A3\Weapons_F_Beta\Reticle\Heli_Attack_01_Optics_Gunner_narrow_F";
};
@ -941,7 +941,7 @@ class Heli_Attack_01_base_F: Helicopter_Base_F {
maxFov = 0.01;
gunnerOpticsColor[] = {0,0,0,1};
directionStabilized = 1;
horizontallyStabilized = 1;
horizontallyStabilized = 1;
gunnerOpticsModel = "\A3\Weapons_F_Beta\Reticle\Heli_Attack_01_Optics_Gunner_narrow_F";
};

View File

@ -95,7 +95,7 @@
<Portuguese>Algema Plástica</Portuguese>
<Italian>Fascietta</Italian>
<Hungarian>Gyorskötöző</Hungarian>
<Russian>Пластиковые наручники</Russian>
<Russian>Кабельная стяжка</Russian>
</Key>
<Key ID="STR_ACE_Captives_CableTieDescription">
<English>Cable ties that allow you to restrain prisoners.</English>
@ -107,7 +107,7 @@
<Portuguese>A algema plástica permite que você contenha prisioneiros.</Portuguese>
<Italian>Fascietta che ti consente di arrestare i prigionieri.</Italian>
<Hungarian>Gyorskötöző, emberek foglyulejtéséhez használható.</Hungarian>
<Russian>Пластиковые наручники позволяют связывать пленников.</Russian>
<Russian>Кабельные стяжки позволяют связывать пленников.</Russian>
</Key>
<Key ID="STR_ACE_Captives_FriskMenuHeader">
<English>Inventory of frisked person</English>

View File

@ -1,7 +1,7 @@
class GVAR(ProgressBar_Dialog) {
idd = -1;
movingEnable = false;
onLoad = QUOTE(uiNamespace setVariable [ARR_2(QUOTE(QGVAR(ctrlProgressBar)),(_this select 0) displayCtrl 1)]; uiNamespace setVariable [ARR_2(QUOTE(QGVAR(ctrlProgressBarTitle)),(_this select 0) displayCtrl 2)];);
onLoad = QUOTE(uiNamespace setVariable [ARR_2(QUOTE(QGVAR(ctrlProgressBG)),(_this select 0) displayCtrl 1)]; uiNamespace setVariable [ARR_2(QUOTE(QGVAR(ctrlProgressBar)),(_this select 0) displayCtrl 2)]; uiNamespace setVariable [ARR_2(QUOTE(QGVAR(ctrlProgressBarTitle)),(_this select 0) displayCtrl 3)];);
objects[] = {};
class controlsBackground {
@ -23,26 +23,31 @@ class GVAR(ProgressBar_Dialog) {
w = "safezoneW";
h = "safezoneH";
};
class Progress: ACE_gui_RscProgress {
class TitleBackground: ACE_gui_staticBase {
idc = 1;
x = "1.2 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)";
y = "0.1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)";
w = "37.8 * (((safezoneW / safezoneH) min 1.2) / 40)";
h = ".8 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
colorFrame[] = {0,0,0,0.0};
colorBar[] = {0.27,0.5,0.31,0.8};
texture = "#(argb,8,8,3)color(1,1,1,0.7)";
};
class Title_Bar : ACE_gui_staticBase {
idc = 2;
style = 0x22;
colorBackground[] = {0, 0, 0, 0};
style = ST_CENTER;
sizeEx = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
colorBackground[] = {0, 0, 0, 0.5};
colorText[] = {1, 1, 1, 1};
x = "1 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)";
y = "0 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)";
w = "38 * (((safezoneW / safezoneH) min 1.2) / 40)";
h = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
};
class Progress: ACE_gui_RscProgress {
idc = 2;
x = "1.2 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)";
y = "0.1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)";
w = "38 * (((safezoneW / safezoneH) min 1.2) / 40)";
h = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
colorFrame[] = {1,1,1,0.5};
colorBar[] = {"(profilenamespace getvariable ['GUI_BCG_RGB_R',0.77])","(profilenamespace getvariable ['GUI_BCG_RGB_G',0.51])","(profilenamespace getvariable ['GUI_BCG_RGB_B',0.08])","(profilenamespace getvariable ['GUI_BCG_RGB_A',0.8])"};
texture = "#(argb,8,8,3)color(1,1,1,0.7)";
};
class TitleText: TitleBackground {
idc = 3;
colorBackground[] = {0, 0, 0, 0};
};
};
};

View File

@ -27,7 +27,7 @@ if ((local _unit) && {!([_unit] call EFUNC(common,isPlayer))}) then {
_unit disableConversation true;
} else {
//Sanity check to make sure we don't enable unconsious AI
if (_unit getVariable ["ace_isunconscious", false]) exitWith {ERROR("Enabling AI for unconsious unit");};
if (_unit getVariable ["ace_isunconscious", false] && alive _unit) exitWith {ERROR("Enabling AI for unconsious unit");};
_unit enableAI "MOVE";
_unit enableAI "TARGET";
_unit enableAI "AUTOTARGET";

View File

@ -38,12 +38,14 @@ createDialog QGVAR(ProgressBar_Dialog);
//Adjust position based on user setting:
_ctrlPos = ctrlPosition (uiNamespace getVariable QGVAR(ctrlProgressBarTitle));
_ctrlPos set [1, ((0 + 29 * GVAR(SettingProgressBarLocation)) * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2))];
(uiNamespace getVariable QGVAR(ctrlProgressBarTitle)) ctrlSetPosition _ctrlPos;
(uiNamespace getVariable QGVAR(ctrlProgressBarTitle)) ctrlCommit 0;
_ctrlPos = ctrlPosition (uiNamespace getVariable QGVAR(ctrlProgressBar));
_ctrlPos set [1, ((0.1 + 29 * GVAR(SettingProgressBarLocation)) * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2))];
(uiNamespace getVariable QGVAR(ctrlProgressBG)) ctrlSetPosition _ctrlPos;
(uiNamespace getVariable QGVAR(ctrlProgressBG)) ctrlCommit 0;
(uiNamespace getVariable QGVAR(ctrlProgressBar)) ctrlSetPosition _ctrlPos;
(uiNamespace getVariable QGVAR(ctrlProgressBar)) ctrlCommit 0;
(uiNamespace getVariable QGVAR(ctrlProgressBarTitle)) ctrlSetPosition _ctrlPos;
(uiNamespace getVariable QGVAR(ctrlProgressBarTitle)) ctrlCommit 0;
_perFrameFunction = {

View File

@ -1,44 +1,28 @@
class Extended_PreInit_EventHandlers {
class ADDON {
init = QUOTE( call COMPILE_FILE(XEH_preInit) );
init = QUOTE(call COMPILE_FILE(XEH_preInit));
};
};
class Extended_PostInit_EventHandlers {
class ADDON {
clientInit = QUOTE( call COMPILE_FILE(XEH_postInitClient) );
init = QUOTE(call COMPILE_FILE(XEH_postInit));
};
};
class Extended_FiredBIS_EventHandlers {
class CAManBase {
class ADDON {
firedBIS = QUOTE( _this call FUNC(replaceATWeapon) );
firedBIS = QUOTE(_this call FUNC(replaceATWeapon));
};
};
};
// handle preloaded missile
class Extended_Init_EventHandlers {
class Extended_InitPost_EventHandlers {
class CAManBase {
class ADDON {
init = QUOTE( _this call FUNC(takeLoadedATWeapon) );
};
};
};
class Extended_Take_EventHandlers {
class CAManBase {
class ADDON {
take = QUOTE( _this call FUNC(takeLoadedATWeapon); [_this select 0] call FUNC(updateInventoryDisplay); );
};
};
};
class Extended_Put_EventHandlers {
class CAManBase {
class ADDON {
put = QUOTE( [_this select 0] call FUNC(updateInventoryDisplay); );
init = QUOTE([ARR_2(_this select 0, secondaryWeapon (_this select 0))] call FUNC(takeLoadedATWeapon); systemChat str [ARR_2(_this select 0, secondaryWeapon (_this select 0))]);
};
};
};

View File

@ -3,6 +3,7 @@ class CfgMagazines {
class ACE_PreloadedMissileDummy: NLAW_F { // The dummy magazine
author = "$STR_ACE_Common_ACETeam";
scope = 1;
scopeArsenal = 1;
displayName = "$STR_ACE_Disposable_PreloadedMissileDummy";
picture = PATHTOEF(common,UI\blank_CO.paa);
weaponPoolAvailable = 0;

View File

@ -0,0 +1,10 @@
// by commy2
#include "script_component.hpp"
if (!hasInterface) exitWith {};
["inventoryDisplayLoaded", {[ACE_player, _this select 0] call FUNC(updateInventoryDisplay)}] call EFUNC(common,addEventHandler);
["playerInventoryChanged", {
[_this select 0, _this select 1 select 11] call FUNC(takeLoadedATWeapon);
[_this select 0] call FUNC(updateInventoryDisplay);
}] call EFUNC(common,addEventHandler);

View File

@ -1,10 +0,0 @@
// by commy2
// The Arma InventoryOpened EH fires actually before the inventory dialog is opened (findDisplay 602 => displayNull).
#include "script_component.hpp"
["inventoryDisplayLoaded",{
[ACE_player] call FUNC(takeLoadedATWeapon);
[ACE_player, (_this select 0)] call FUNC(updateInventoryDisplay);
}] call EFUNC(common,addEventHandler);

View File

@ -9,8 +9,6 @@ _isUnconscious = _this select 1;
private "_player";
_player = ACE_player;
if ((_unit getHitPointDamage "HitLeftLeg") + (_unit getHitPointDamage "HitRightLeg") > 0.4) exitwith {};
if (_player getVariable [QGVAR(isDragging), false]) then {
private "_draggedObject";
@ -22,9 +20,9 @@ if (_player getVariable [QGVAR(isDragging), false]) then {
};
// handle waking up dragged unit
if (_unit == _draggedObject) then {
[_player, _draggedObject] call FUNC(dropObject);
};
//if (_unit == _draggedObject) then {
// [_player, _draggedObject] call FUNC(dropObject);
//};
};
@ -39,8 +37,8 @@ if (_player getVariable [QGVAR(isCarrying), false]) then {
};
// handle waking up dragged unit
if (_unit == _carriedObject) then {
[_player, _carriedObject] call FUNC(dropObject_carry);
};
//if (_unit == _carriedObject) then {
// [_player, _carriedObject] call FUNC(dropObject_carry);
//};
};

View File

@ -1,4 +1,3 @@
class Extended_PreInit_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_FILE(XEH_preInit));

View File

@ -1,12 +0,0 @@
class CfgSounds {
class ACE_Wirecutter_sound {
name = "ACE_wirecutter_sound";
sound[] = {QUOTE(PATHTOF(sound\wire_cut.ogg)), "db-0", 1};
titles[] = {};
};
class ACE_Wirecutter_sound_long {
name = "ACE_wirecutter_sound_long";
sound[] = {QUOTE(PATHTOF(sound\wire_cut_long.ogg)), "db-0", 1};
titles[] = {};
};
};

View File

@ -0,0 +1,8 @@
class CfgVehicles {
class Box_NATO_Support_F;
class ACE_Box_Misc: Box_NATO_Support_F {
class TransportItems {
MACRO_ADDITEM(ACE_wirecutter,4);
};
};
};

View File

@ -1,16 +1,16 @@
class CfgWeapons {
class InventoryItem_Base_F;
class ACE_ItemCore;
class InventoryItem_Base_F;
class ACE_ItemCore;
class ACE_wirecutter: ACE_ItemCore {
author = "$STR_ACE_Common_ACETeam";
displayName = "$STR_ACE_logistics_wirecutter_wirecutterName";
descriptionShort = "$STR_ACE_logistics_wirecutter_wirecutterDescription";
model = "\A3\weapons_F\ammo\mag_univ.p3d";
picture = QUOTE(PATHTOF(ui\item_wirecutter_ca.paa));
scope = 2;
class ItemInfo: InventoryItem_Base_F {
mass = 100;
class ACE_wirecutter: ACE_ItemCore {
author = "$STR_ACE_Common_ACETeam";
displayName = "$STR_ACE_logistics_wirecutter_wirecutterName";
descriptionShort = "$STR_ACE_logistics_wirecutter_wirecutterDescription";
model = "\A3\weapons_F\ammo\mag_univ.p3d";
picture = QUOTE(PATHTOF(ui\item_wirecutter_ca.paa));
scope = 2;
class ItemInfo: InventoryItem_Base_F {
mass = 100;
};
};
};
};

View File

@ -3,7 +3,7 @@
class CfgPatches {
class ADDON {
units[] = {};
weapons[] = {};
weapons[] = {"ACE_wirecutter"};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"ace_interaction"};
author[] = {"gpgpgpgp", "PabstMirror"};
@ -13,5 +13,5 @@ class CfgPatches {
};
#include "CfgEventHandlers.hpp"
#include "CfgSounds.hpp"
#include "CfgWeapons.hpp"
#include "CfgVehicles.hpp"

View File

@ -16,19 +16,26 @@
*/
#include "script_component.hpp"
#define SOUND_CLIP_TIME_SPACEING 1.5
private ["_timeToCut"];
PARAMS_2(_unit,_fenceObject);
if (_unit != ACE_player) exitWith {};
_timeToCut = if ([ACE_player] call EFUNC(common,isEngineer)) then {5} else {10};
_timeToCut = if ([ACE_player] call EFUNC(common,isEngineer)) then {7.5} else {11};
[ACE_player, "AinvPknlMstpSnonWnonDr_medic5", 0] call EFUNC(common,doAnimation);
if (_timeToCut > 5) then {
playSound "ACE_wirecutter_sound_long";
} else {
playSound "ACE_wirecutter_sound";
_progressCheck = {
PARAMS_2(_args,_passedTime);
EXPLODE_2_PVT(_args,_fenceObject,_lastSoundEffectTime);
if (_passedTime > (_lastSoundEffectTime + SOUND_CLIP_TIME_SPACEING)) then {
// playSound "ACE_wirecutter_sound";
playSound3D [QUOTE(PATHTO_R(sound\wirecut.ogg)), objNull, false, (getPosASL ACE_player), 3, 1, 10];
_args set [1, _passedTime];
};
((!isNull _fenceObject) && {(damage _fenceObject) < 1} && {("ACE_wirecutter" in (items ACE_player))})
};
[_timeToCut, [_fenceObject], {(_this select 0) call FUNC(cutDownFenceCallback)}, {(_this select 0) call FUNC(cutDownFenceAbort)}, localize "STR_ACE_logistics_wirecutter_CuttingFence"] call EFUNC(common,progressBar);
[_timeToCut, [_fenceObject,0], {(_this select 0) call FUNC(cutDownFenceCallback)}, {(_this select 0) call FUNC(cutDownFenceAbort)}, localize "STR_ACE_logistics_wirecutter_CuttingFence", _progressCheck] call EFUNC(common,progressBar);

View File

@ -20,9 +20,9 @@ PARAMS_1(_unit);
_nearestFence = objNull;
{
if ((isNull _nearestFence) && {[_x] call FUNC(isFence)}) then {
_nearestFence = _x;
};
if ((isNull _nearestFence) && {[_x] call FUNC(isFence)}) then {
_nearestFence = _x;
};
} forEach nearestObjects [_unit, [], 15];
_nearestFence

View File

@ -35,7 +35,7 @@ if (!("ACE_wirecutter" in (items ace_player))) exitWith {};
} else {
// Prevent Rare Error when ending mission with interact key down:
if (isNull ace_player) exitWith {};
//If player moved >5 meters from last pos, then rescan
if (((getPosASL ace_player) distance _setPosition) > 5) then {

View File

@ -17,11 +17,9 @@
#include "script_component.hpp"
//find is case sensitive, so keep everything lowercase
#define FENCE_A3_TYPENAMES ["land_net_fence_4m_f", "land_net_fence_8m_f", "land_net_fenced_8m_f", "land_new_wiredfence_5m_f", "land_new_wiredfence_10m_dam_f", "land_new_wiredfence_10m_f", "land_pipe_fence_4m_f", "land_pipe_fence_4mnolc_f", "land_sportground_fence_f", "land_wired_fence_4m_f", "land_wired_fence_4md_f", "land_wired_fence_8m_f", "land_wired_fence_8md_f", "land_razorwire_f"]
#define FENCE_A3_P3DS ["mil_wiredfence_f.p3d"]
#define FENCE_TYPENAMES ["land_net_fence_4m_f", "land_net_fence_8m_f", "land_net_fenced_8m_f", "land_new_wiredfence_5m_f", "land_new_wiredfence_10m_dam_f", "land_new_wiredfence_10m_f", "land_pipe_fence_4m_f", "land_pipe_fence_4mnolc_f", "land_sportground_fence_f", "land_wired_fence_4m_f", "land_wired_fence_4md_f", "land_wired_fence_8m_f", "land_wired_fence_8md_f", "land_razorwire_f"]
#define FENCE_AIA_TYPENAMES []
#define FENCE_AIA_P3DS ["wall_indfnc_3.p3d", "wall_indfnc_9.p3d", "wall_indfnc_corner.p3d", "pletivo_wired.p3d", "wall_fen1_5.p3d"]
#define FENCE_P3DS ["mil_wiredfence_f.p3d","wall_indfnc_3.p3d", "wall_indfnc_9.p3d", "wall_indfnc_corner.p3d", "pletivo_wired.p3d", "wall_fen1_5.p3d"]
private ["_typeOf", "_returnValue"];
PARAMS_1(_object);
@ -30,14 +28,15 @@ _typeOf = toLower (typeOf _object);
_returnValue = false;
if (_typeOf != "") then {
_returnValue = _typeOf in (FENCE_A3_TYPENAMES + FENCE_AIA_TYPENAMES);
//If the fence has configEntry we can check it directly
_returnValue = _typeOf in FENCE_TYPENAMES;
} else {
_typeOf = toLower (str _object); //something like "123201: wall_indfnc_9.p3d"
{
if ((_typeOf find _x) != -1) then {
if ((_typeOf find _x) != -1) exitWith {
_returnValue = true;
};
} forEach (FENCE_A3_P3DS + FENCE_AIA_P3DS);
} forEach FENCE_P3DS;
};
_returnValue

View File

@ -4,6 +4,7 @@ class ACE_Head {
runOnHover = 1;
statement = QUOTE([ARR_3(_target, true, 0)] call DFUNC(displayPatientInformation));
modifierFunction = QUOTE([ARR_4(_target,_player,0,_this select 3)] call FUNC(modifyMedicalAction));
condition = "true";
EXCEPTIONS
icon = PATHTOF(UI\icons\medical_cross.paa);
distance = MEDICAL_ACTION_DISTANCE;
@ -82,6 +83,7 @@ class ACE_Torso {
runOnHover = 1;
statement = QUOTE([ARR_3(_target, true, 1)] call DFUNC(displayPatientInformation));
modifierFunction = QUOTE([ARR_4(_target,_player,1,_this select 3)] call FUNC(modifyMedicalAction));
condition = "true";
EXCEPTIONS
icon = PATHTOF(UI\icons\medical_cross.paa);
distance = MEDICAL_ACTION_DISTANCE;
@ -182,6 +184,7 @@ class ACE_ArmLeft {
runOnHover = 1;
statement = QUOTE([ARR_3(_target, true, 2)] call DFUNC(displayPatientInformation));
modifierFunction = QUOTE([ARR_4(_target,_player,2,_this select 3)] call FUNC(modifyMedicalAction));
condition = "true";
EXCEPTIONS
icon = PATHTOF(UI\icons\medical_cross.paa);
distance = MEDICAL_ACTION_DISTANCE;
@ -339,6 +342,7 @@ class ACE_ArmRight {
runOnHover = 1;
statement = QUOTE([ARR_3(_target, true, 3)] call DFUNC(displayPatientInformation));
modifierFunction = QUOTE([ARR_4(_target,_player,3,_this select 3)] call FUNC(modifyMedicalAction));
condition = "true";
EXCEPTIONS
icon = PATHTOF(UI\icons\medical_cross.paa);
distance = MEDICAL_ACTION_DISTANCE;
@ -433,8 +437,8 @@ class ACE_ArmRight {
};
class PlasmaIV: BloodIV {
displayName = "$STR_ACE_MEDICAL_ACTIONS_Plasma4_1000";
condition = QUOTE([ARR_4(_player, _target, 'hand_r', 'BloodIV')] call DFUNC(canTreatCached));
statement = QUOTE([ARR_4(_player, _target, 'hand_r', 'BloodIV')] call DFUNC(treatment));
condition = QUOTE([ARR_4(_player, _target, 'hand_r', 'PlasmaIV')] call DFUNC(canTreatCached));
statement = QUOTE([ARR_4(_player, _target, 'hand_r', 'PlasmaIV')] call DFUNC(treatment));
EXCEPTIONS
};
class PlasmaIV_500: PlasmaIV {
@ -493,6 +497,7 @@ class ACE_LegLeft {
runOnHover = 1;
statement = QUOTE([ARR_3(_target, true, 4)] call DFUNC(displayPatientInformation));
modifierFunction = QUOTE([ARR_4(_target,_player,4,_this select 3)] call FUNC(modifyMedicalAction));
condition = "true";
EXCEPTIONS
icon = PATHTOF(UI\icons\medical_cross.paa);
distance = MEDICAL_ACTION_DISTANCE;
@ -589,8 +594,8 @@ class ACE_LegLeft {
};
class PlasmaIV: BloodIV {
displayName = "$STR_ACE_MEDICAL_ACTIONS_Plasma4_1000";
condition = QUOTE([ARR_4(_player, _target, 'leg_l', 'BloodIV')] call DFUNC(canTreatCached));
statement = QUOTE([ARR_4(_player, _target, 'leg_l', 'BloodIV')] call DFUNC(treatment));
condition = QUOTE([ARR_4(_player, _target, 'leg_l', 'PlasmaIV')] call DFUNC(canTreatCached));
statement = QUOTE([ARR_4(_player, _target, 'leg_l', 'PlasmaIV')] call DFUNC(treatment));
EXCEPTIONS
};
class PlasmaIV_500: PlasmaIV {
@ -635,6 +640,7 @@ class ACE_LegRight {
runOnHover = 1;
statement = QUOTE([ARR_3(_target, true, 5)] call DFUNC(displayPatientInformation));
modifierFunction = QUOTE([ARR_4(_target,_player,5,_this select 3)] call FUNC(modifyMedicalAction));
condition = "true";
EXCEPTIONS
icon = PATHTOF(UI\icons\medical_cross.paa);
distance = MEDICAL_ACTION_DISTANCE;
@ -730,8 +736,8 @@ class ACE_LegRight {
};
class PlasmaIV: BloodIV {
displayName = "$STR_ACE_MEDICAL_ACTIONS_Plasma4_1000";
condition = QUOTE([ARR_4(_player, _target, 'leg_r', 'BloodIV')] call DFUNC(canTreatCached));
statement = QUOTE([ARR_4(_player, _target, 'leg_r', 'BloodIV')] call DFUNC(treatment));
condition = QUOTE([ARR_4(_player, _target, 'leg_r', 'PlasmaIV')] call DFUNC(canTreatCached));
statement = QUOTE([ARR_4(_player, _target, 'leg_r', 'PlasmaIV')] call DFUNC(treatment));
EXCEPTIONS
};
class PlasmaIV_500: PlasmaIV {

View File

@ -4,6 +4,7 @@ class Medical {
hotkey = "M";
exceptions[] = {"isNotInside"};
statement = QUOTE([ARR_3(_target, true, 0)] call DFUNC(displayPatientInformation));
condition = "true";
icon = PATHTOF(UI\icons\medical_cross.paa);
class ACE_Head {
@ -12,6 +13,7 @@ class Medical {
exceptions[] = {"isNotInside"};
statement = QUOTE([ARR_3(_target, true, 0)] call DFUNC(displayPatientInformation));
modifierFunction = QUOTE([ARR_4(_target,_player,0,_this select 3)] call FUNC(modifyMedicalAction));
condition = "true";
runOnHover = 1;
class Bandage {
@ -149,6 +151,7 @@ class Medical {
exceptions[] = {"isNotInside"};
statement = QUOTE([ARR_3(_target, true, 2)] call DFUNC(displayPatientInformation));
modifierFunction = QUOTE([ARR_4(_target,_player,2,_this select 3)] call FUNC(modifyMedicalAction));
condition = "true";
icon = PATHTOF(UI\icons\medical_cross.paa);
class Bandage {
@ -250,6 +253,7 @@ class Medical {
exceptions[] = {"isNotInside"};
statement = QUOTE([ARR_3(_target, true, 3)] call DFUNC(displayPatientInformation));
modifierFunction = QUOTE([ARR_4(_target,_player,3,_this select 3)] call FUNC(modifyMedicalAction));
condition = "true";
icon = PATHTOF(UI\icons\medical_cross.paa);
class Bandage {
@ -347,6 +351,7 @@ class Medical {
exceptions[] = {"isNotInside"};
statement = QUOTE([ARR_3(_target, true, 4)] call DFUNC(displayPatientInformation));
modifierFunction = QUOTE([ARR_4(_target,_player,4,_this select 3)] call FUNC(modifyMedicalAction));
condition = "true";
icon = PATHTOF(UI\icons\medical_cross.paa);
class Bandage {
@ -433,6 +438,7 @@ class Medical {
exceptions[] = {"isNotInside"};
statement = QUOTE([ARR_3(_target, true, 5)] call DFUNC(displayPatientInformation));
modifierFunction = QUOTE([ARR_4(_target,_player,5,_this select 3)] call FUNC(modifyMedicalAction));
condition = "true";
icon = PATHTOF(UI\icons\medical_cross.paa);
class Bandage {

View File

@ -124,4 +124,8 @@ class ACE_Settings {
values[] = {"$STR_ACE_Medical_painEffect_Flash", "$STR_ACE_Medical_painEffect_Chroma"};
isClientSettable = 1;
};
class GVAR(allowUnconsciousAnimationOnTreatment) {
typeName = "BOOL";
value = 0;
};
};

View File

@ -4,7 +4,4 @@ private ["_unit"];
_unit = _this select 0;
_unit addEventHandler ["HandleDamage", {_this call FUNC(handleDamage)}];
if (local _unit) then {
[_unit] call FUNC(init);
};
[_unit] call FUNC(init);

View File

@ -241,14 +241,14 @@ if (USE_WOUND_EVENT_SYNC) then {
// We are only pulling the wounds for the units in the player group. Anything else will come when the unit interacts with them.
{
[_x, _newPlayer] call FUNC(requestWoundSync);
}foreach units group player;
}foreach units group _newPlayer;
};
}] call EFUNC(common,addEventhandler);
};
};
[
{(((_this select 0) getvariable [QGVAR(bloodVolume), 0]) < 65)},
{(((_this select 0) getvariable [QGVAR(bloodVolume), 100]) < 65)},
{(((_this select 0) getvariable [QGVAR(pain), 0]) > 0.9)},
{(((_this select 0) call FUNC(getBloodLoss)) > 0.25)},
{((_this select 0) getvariable [QGVAR(inReviveState), false])},

View File

@ -100,6 +100,7 @@ PREP(moduleAssignMedicalFacility);
PREP(moduleTreatmentConfiguration);
PREP(copyDeadBody);
PREP(requestWoundSync);
PREP(unconsciousPFH);
GVAR(injuredUnitCollection) = [];
GVAR(IVBags) = [];

View File

@ -6,8 +6,7 @@ _unit = _this select 0;
if !(local _unit) exitWith {};
diag_log "running respawn";
[_unit] call FUNC(init);
[_unit, true] call FUNC(init);
//Reset captive status for respawning unit
if (!(_unit getVariable ["ACE_isUnconscious", false])) then {

View File

@ -33,10 +33,10 @@ if ([_unit] call FUNC(hasMedicalEnabled) || _force) then {
[_this select 1] call CBA_fnc_removePerFrameHandler;
if (!local _unit) then {
if (GVAR(level) >= 2) then {
_unit setvariable [QGVAR(heartRate), _unit getvariable [QGVAR(heartRate), 0], true];
_unit setvariable [QGVAR(bloodPressure), _unit getvariable [QGVAR(bloodPressure), [0, 0]], true];
_unit setvariable [QGVAR(heartRate), _unit getvariable [QGVAR(heartRate), 80], true];
_unit setvariable [QGVAR(bloodPressure), _unit getvariable [QGVAR(bloodPressure), [80, 120]], true];
};
_unit setvariable [QGVAR(bloodVolume), _unit getvariable [QGVAR(bloodVolume), 0], true];
_unit setvariable [QGVAR(bloodVolume), _unit getvariable [QGVAR(bloodVolume), 100], true];
};
} else {
[_unit] call FUNC(handleUnitVitals);

View File

@ -19,4 +19,4 @@
#define MAX_DURATION_CACHE 2
// parameters, function, namespace, uid
[_this, DFUNC(canTreat), _this select 0, format[QGVAR(canTreat_%1_%2), _this select 2, _this select 3], MAX_DURATION_CACHE, "clearConditionCaches"] call EFUNC(common,cachedCall);
[_this, DFUNC(canTreat), _this select 1, format[QGVAR(canTreat_%1_%2), _this select 2, _this select 3], MAX_DURATION_CACHE, "clearConditionCaches"] call EFUNC(common,cachedCall);

View File

@ -21,10 +21,10 @@ if ((vehicle _unit != _unit) && {!alive (vehicle _unit)}) exitwith { true };
// Find the correct Damage threshold for unit.
_damageThreshold = [1,1,1];
if (isPlayer _unit) then {
//_damageThreshold =_unit getvariable[QGVAR(unitDamageThreshold), [GVAR(damageThreshold_Players), GVAR(damageThreshold_Players), GVAR(damageThreshold_Players) * 1.7]];
if ([_unit] call EFUNC(common,IsPlayer)) then {
_damageThreshold =_unit getvariable[QGVAR(unitDamageThreshold), [GVAR(playerDamageThreshold), GVAR(playerDamageThreshold), GVAR(playerDamageThreshold) * 1.7]];
} else {
//_damageThreshold =_unit getvariable[QGVAR(unitDamageThreshold), [GVAR(damageThreshold_AI), GVAR(damageThreshold_AI), GVAR(damageThreshold_AI) * 1.7]];
_damageThreshold =_unit getvariable[QGVAR(unitDamageThreshold), [GVAR(AIDamageThreshold), GVAR(AIDamageThreshold), GVAR(AIDamageThreshold) * 1.7]];
};
_damageBodyPart = ((_unit getvariable [QGVAR(bodyPartStatus),[0, 0, 0, 0, 0, 0]]) select _part) + _withDamage;

View File

@ -59,20 +59,30 @@ if (isClass (_config >> _className)) then {
_bandagedWounds = _target getvariable [QGVAR(bandagedWounds), []];
_exist = false;
_injuryId = _injury select 0;
_bandagedInjury = [];
{
if ((_x select 0) == _injuryId) exitwith {
_exist = true;
_existingInjury = _x;
_existingInjury set [3, (_existingInjury select 3) + _impact];
_bandagedWounds set [_foreachIndex, _existingInjury];
_bandagedInjury = _existingInjury;
};
}foreach _bandagedWounds;
if !(_exist) then {
// [ID, classID, bodypart, percentage treated, bloodloss rate]
_bandagedWounds pushback [_injuryId, _injury select 1, _injury select 2, _impact, _injury select 4];
_bandagedInjury = [_injuryId, _injury select 1, _injury select 2, _impact, _injury select 4];
_bandagedWounds pushback _bandagedInjury;
};
_target setvariable [QGVAR(bandagedWounds), _bandagedWounds, !USE_WOUND_EVENT_SYNC];
if (USE_WOUND_EVENT_SYNC) then {
// sync _bandagedInjury
};
_target setvariable [QGVAR(bandagedWounds), _bandagedWounds, true];
// Check if we are ever going to reopen this
if (random(1) <= _reopeningChance) then {
@ -109,7 +119,7 @@ if (random(1) <= _reopeningChance) then {
}foreach _bandagedWounds;
if (_exist) then {
_target setvariable [QGVAR(bandagedWounds), _bandagedWounds, true];
_target setvariable [QGVAR(bandagedWounds), _bandagedWounds, !USE_WOUND_EVENT_SYNC];
};
};
// Otherwise something went wrong, we we don't reopen them..

View File

@ -57,6 +57,12 @@ if (GVAR(level) >= 2) then {
_minLethalDamage = GVAR(minLethalDamages) select _typeIndex;
};
if (vehicle _unit != _unit && {!(vehicle _unit isKindOf "StaticWeapon")} && {isNull _source} && {_projectile == ""} && {_selection == ""}) then {
if (GVAR(enableVehicleCrashes)) then {
_selection = GVAR(SELECTIONS) select (floor(random(count GVAR(SELECTIONS))));
};
};
if ((_minLethalDamage <= _newDamage) && {[_unit, [_selection] call FUNC(selectionNameToNumber), _newDamage] call FUNC(determineIfFatal)} && {_selection in ["", "head", "body"]}) then {
if ([_unit] call FUNC(setDead)) then {
_damageReturn = 1;

View File

@ -33,10 +33,12 @@ if (isNull _sourceOfDamage && {_typeOfProjectile == ""} && {vehicle _unit == _un
};
_typeOfDamage = [_typeOfProjectile] call FUNC(getTypeOfDamage);
_part = [_selectionName] call FUNC(selectionNameToNumber);
if (_part < 0) exitwith {};
_hitPoints = ["HitHead", "HitBody", "HitLeftArm", "HitRightArm", "HitLeftLeg", "HitRightLeg"];
// Sorting out the damage
_damageBodyParts = _unit getvariable [QGVAR(bodyPartStatus), [0,0,0,0,0,0]];
_damageBodyParts set [_part, (_damageBodyParts select _part) + _newDamage];
_unit setvariable [QGVAR(bodyPartStatus), _damageBodyParts, true];

View File

@ -63,6 +63,12 @@ if (_selectionName in GVAR(SELECTIONS)) then {
_newDamage = _damage - (_unit getHitPointDamage (GVAR(HITPOINTS) select (GVAR(SELECTIONS) find _selectionName)));
};
if ([_unit] call EFUNC(common,isPlayer)) then {
_newDamage = _newDamage / (GVAR(playerDamageThreshold) max 0.01);
} else {
_newDamage = _newDamage / (GVAR(AIDamageThreshold) max 0.01);
};
_damage = _damage - _newDamage;

View File

@ -38,7 +38,7 @@ if (_selectionName in _hitSelections) then {
// Check for vehicle crash
if (vehicle _unit != _unit && {!(vehicle _unit isKindOf "StaticWeapon")} && {isNull _source} && {_projectile == ""} && {_selectionName == ""}) then {
if (missionNamespace getvariable [QGVAR(allowVehicleCrashDamage), true]) then {
if (GVAR(enableVehicleCrashes)) then {
_selectionName = _hitSelections select (floor(random(count _hitSelections)));
_projectile = "vehiclecrash";
};

View File

@ -133,7 +133,6 @@ if (count _woundsCreated > 0) then {
};
if (USE_WOUND_EVENT_SYNC) then {
// TODO Should this be done in a single broadcast?
// Broadcast the new injuries across the net in parts. One broadcast per injury. Prevents having to broadcast one massive array of injuries.
{
["medical_propagateWound", [_unit, _x]] call EFUNC(common,globalEvent);

View File

@ -22,4 +22,14 @@ if (_local) then {
if (_unit getvariable[QGVAR(addedToUnitLoop),false]) then {
[_unit, true] call FUNC(addToInjuredCollection);
};
if ((_unit getvariable ["ACE_isUnconscious",false]) && {count (_unit getvariable [QGVAR(unconsciousArguments), []]) >= 7}) then {
private "_arguments";
_arguments = (_unit getvariable [QGVAR(unconsciousArguments), []]);
_arguments set [ 3, time];
[DFUNC(unconsciousPFH), 0.1, _arguments ] call CBA_fnc_addPerFrameHandler;
_unit setvariable [QGVAR(unconsciousArguments), nil, true];
};
};

View File

@ -27,7 +27,7 @@ if (_syncValues) then {
_unit setvariable [QGVAR(lastMomentValuesSynced), time];
};
_bloodVolume = (_unit getvariable [QGVAR(bloodVolume), 0]) + ([_unit] call FUNC(getBloodVolumeChange));
_bloodVolume = (_unit getvariable [QGVAR(bloodVolume), 100]) + ([_unit] call FUNC(getBloodVolumeChange));
_bloodVolume = _bloodVolume max 0;
_unit setvariable [QGVAR(bloodVolume), _bloodVolume, _syncValues];
@ -94,13 +94,13 @@ if (GVAR(level) >= 2) then {
if ([_unit] call EFUNC(common,isAwake)) then {
if (_bloodVolume < 60) then {
if (random(1) > 0.9) then {
[_unit] call FUNC(setUnconscious);
[_unit, true, 15 + random(20)] call FUNC(setUnconscious);
};
};
};
// Set the vitals
_heartRate = (_unit getvariable [QGVAR(heartRate), 0]) + (([_unit] call FUNC(getHeartRateChange)) * _interval);
_heartRate = (_unit getvariable [QGVAR(heartRate), 80]) + (([_unit] call FUNC(getHeartRateChange)) * _interval);
_unit setvariable [QGVAR(heartRate), _heartRate, _syncValues];
_bloodPressure = [_unit] call FUNC(getBloodPressure);
@ -136,7 +136,7 @@ if (GVAR(level) >= 2) then {
if (!(_unit getvariable [QGVAR(inCardiacArrest),false])) then {
if (_heartRate < 10 || _bloodPressureH < 30 || _bloodVolume < 20) then {
[_unit] call FUNC(setUnconscious); // safety check to ensure unconsciousness for units if they are not dead already.
[_unit, true, 10+ random(20)] call FUNC(setUnconscious); // safety check to ensure unconsciousness for units if they are not dead already.
};
if (_bloodPressureH > 260) then {

View File

@ -13,21 +13,25 @@
#include "script_component.hpp"
private ["_unit", "_allUsedMedication", "_logs"];
private ["_unit", "_allUsedMedication", "_logs", "_forceNew"];
_unit = _this select 0;
_forceNew = if (count _this > 1) then {_this select 1} else {false};
_unit setVariable [QGVAR(pain), 0, true];
_unit setVariable [QGVAR(morphine), 0, true];
_unit setVariable [QGVAR(bloodVolume), 100, true];
if (!(isnil {_unit getvariable QGVAR(triageLevel)}) && !_forceNew) exitwith {};
_unit setVariable [QGVAR(pain), 0];
_unit setVariable [QGVAR(morphine), 0];
_unit setVariable [QGVAR(bloodVolume), 100];
// tourniquets
_unit setvariable [QGVAR(tourniquets), [0,0,0,0,0,0], true];
_unit setvariable [QGVAR(tourniquets), [0,0,0,0,0,0]];
// wounds and injuries
_unit setvariable [QGVAR(openWounds), [], true];
_unit setvariable [QGVAR(bandagedWounds), [], true];
_unit setVariable [QGVAR(internalWounds), [], true];
_unit setvariable [QGVAR(openWounds), []];
_unit setvariable [QGVAR(bandagedWounds), []];
_unit setVariable [QGVAR(internalWounds), []];
_unit setvariable [QGVAR(lastUniqueWoundID), 1];
// vitals
_unit setVariable [QGVAR(heartRate), 80];
@ -39,8 +43,8 @@ _unit setVariable [QGVAR(peripheralResistance), 100];
_unit setVariable [QGVAR(fractures), []];
// triage card and logs
_unit setvariable [QGVAR(triageLevel), 0, true];
_unit setvariable [QGVAR(triageCard), [], true];
_unit setvariable [QGVAR(triageLevel), 0];
_unit setvariable [QGVAR(triageCard), []];
// IVs
_unit setVariable [QGVAR(salineIVVolume), 0];
@ -48,21 +52,21 @@ _unit setVariable [QGVAR(plasmaIVVolume), 0];
_unit setVariable [QGVAR(bloodIVVolume), 0];
// damage storage
_unit setvariable [QGVAR(bodyPartStatus), [0,0,0,0,0,0], true];
_unit setvariable [QGVAR(bodyPartStatus), [0,0,0,0,0,0]];
// airway
_unit setvariable [QGVAR(airwayStatus), 100, true];
_unit setVariable [QGVAR(airwayOccluded), false, true];
_unit setvariable [QGVAR(airwayCollapsed), false, true];
_unit setvariable [QGVAR(airwayStatus), 100];
_unit setVariable [QGVAR(airwayOccluded), false];
_unit setvariable [QGVAR(airwayCollapsed), false];
// generic medical admin
_unit setvariable [QGVAR(addedToUnitLoop), false, true];
_unit setvariable [QGVAR(inCardiacArrest), false, true];
_unit setVariable ["ACE_isUnconscious", false, true];
_unit setvariable [QGVAR(hasLostBlood), false, true];
_unit setvariable [QGVAR(isBleeding), false, true];
_unit setvariable [QGVAR(hasPain), false, true];
_unit setvariable [QGVAR(amountOfReviveLives), GVAR(amountOfReviveLives), true];
_unit setvariable [QGVAR(addedToUnitLoop), false];
_unit setvariable [QGVAR(inCardiacArrest), false];
_unit setVariable ["ACE_isUnconscious", false];
_unit setvariable [QGVAR(hasLostBlood), false];
_unit setvariable [QGVAR(isBleeding), false];
_unit setvariable [QGVAR(hasPain), false];
_unit setvariable [QGVAR(amountOfReviveLives), GVAR(amountOfReviveLives)];
// medication
_allUsedMedication = _unit getVariable [QGVAR(allUsedMedication), []];
@ -73,9 +77,9 @@ _unit setVariable [QGVAR(allUsedMedication), []];
_logs = _unit getvariable [QGVAR(allLogs), []];
{
_unit setvariable [_x, nil, true];
_unit setvariable [_x, nil];
} foreach _logs;
_unit setvariable [QGVAR(allLogs), [], true];
_unit setvariable [QGVAR(allLogs), []];
// items
[{

View File

@ -1,11 +1,10 @@
/*
* Author: Glowbal
* Enabled the vitals loop for a unit.
* Handles an wound update request.
*
* Arguments:
* 0: The Unit <OBJECT>
* 1: the last known ID <NUMBER>
* 2: Origin object <OBJECT>
* 1: Origin object <OBJECT>
*
* ReturnValue:
* <NIL>
@ -14,12 +13,11 @@
*/
#include "script_component.hpp"
private ["_unit", "_lastId", "_openWounds"];
private ["_unit", "_openWounds"];
_unit = _this select 0;
_lastId = _this select 1;
_originOfrequest = _this select 2;
_originOfrequest = _this select 1;
if (local _unit) then {
if (local _unit && !(local _originOfrequest)) then {
_openWounds = _unit getvariable [QGVAR(openWounds), []];
{
["medical_propagateWound", [_originOfrequest], [_unit, _x]] call EFUNC(common,targetEvent);

View File

@ -14,11 +14,11 @@
#include "script_component.hpp"
private [ "_target", "_caller", "_openWounds","_lastId"];
private [ "_target", "_caller", "_openWounds"];
_target = _this select 0;
_caller = _this select 1;
if (local _target || GVAR(level) < 2) exitwith {}; // if the target is local, we already got the most update to date information
if (_target getvariable [QGVAR(isWoundSynced), false]) exitwith {};
_target setvariable [QGVAR(isWoundSynced), true];
["medical_woundUpdateRequest", [_target], [_target, _lastId, _caller]] call EFUNC(common,targetEvent);
["medical_woundUpdateRequest", [_target], [_target, _caller]] call EFUNC(common,targetEvent);

View File

@ -33,7 +33,7 @@ _timeInCardiacArrest = 120 + round(random(600));
_startTime = _args select 1;
_timeInCardiacArrest = _args select 2;
_heartRate = _unit getvariable [QGVAR(heartRate), 0];
_heartRate = _unit getvariable [QGVAR(heartRate), 80];
if (_heartRate > 0 || !alive _unit) exitwith {
[(_this select 1)] call cba_fnc_removePerFrameHandler;
_unit setvariable [QGVAR(inCardiacArrest), nil,true];

View File

@ -23,7 +23,7 @@ _set = if (count _this > 1) then {_this select 1} else {true};
_minWaitingTime = if (count _this > 2) then {_this select 2} else {DEFAULT_DELAY};
if !(_set) exitwith {
_unit setvariable ["ACE_isUnconscious", false,true];
_unit setvariable ["ACE_isUnconscious", false, true];
};
if !(!(isNull _unit) && {(_unit isKindOf "CaManBase") && ([_unit] call EFUNC(common,isAwake))}) exitwith{};
@ -40,6 +40,11 @@ if (_unit == ACE_player) then {
closeDialog 0;
};
// if we have unconsciousness for AI disabled, we will kill the unit instead
if (!([_unit] call EFUNC(common,IsPlayer)) && (GVAR(enableUnsconsiousnessAI) == 0 || (GVAR(enableUnsconsiousnessAI) == 2 && random(1) <= 0.5))) exitwith {
[_unit, true] call FUNC(setDead); // force, to avoid getting into a loop in case revive is enabled.
};
// If a unit has the launcher out, it will sometimes start selecting the primairy weapon while unconscious,
// therefor we force it to select the primairy weapon before going unconscious
if ((vehicle _unit) isKindOf "StaticWeapon") then {
@ -75,66 +80,6 @@ _unit setUnitPos "DOWN";
_startingTime = time;
[{
private ["_unit", "_vehicleOfUnit","_minWaitingTime", "_oldAnimation", "_captiveSwitch", "_hasMovedOut"];
_args = _this select 0;
_unit = _args select 0;
_oldAnimation = _args select 1;
_originalPos = _args select 2;
_startingTime = _args select 3;
_minWaitingTime = _args select 4;
_hasMovedOut = _args select 5;
if (!alive _unit) exitwith {
[(_this select 1)] call cba_fnc_removePerFrameHandler;
};
// In case the unit is no longer in an unconscious state, we are going to check if we can already reset the animation
if !(_unit getvariable ["ACE_isUnconscious",false]) exitwith {
// TODO, handle this with carry instead, so we can remove the PFH here.
// Wait until the unit isn't being carried anymore, so we won't end up with wierd animations
if !(([_unit] call FUNC(isBeingCarried)) || ([_unit] call FUNC(isBeingDragged))) then {
if (vehicle _unit == _unit) then {
if (animationState _unit == "AinjPpneMstpSnonWrflDnon") then {
[_unit,"AinjPpneMstpSnonWrflDnon_rolltofront", 2] call EFUNC(common,doAnimation);
[_unit,"amovppnemstpsnonwnondnon", 1] call EFUNC(common,doAnimation);
} else {
[_unit,"amovppnemstpsnonwnondnon", 2] call EFUNC(common,doAnimation);
};
} else {
// Switch to the units original animation, assuming
// TODO: what if the unit switched vehicle?
[_unit, _oldAnimation, 2] call EFUNC(common,doAnimation);
};
// EXIT PFH
[(_this select 1)] call cba_fnc_removePerFrameHandler;
};
if (!_hasMovedOut) then {
// Reset the unit back to the previous captive state.
[_unit, QGVAR(unconscious), false] call EFUNC(common,setCaptivityStatus);
// Swhich the unit back to its original group
//Unconscious units shouldn't be put in another group #527:
// [_unit, false, "ACE_isUnconscious", side group _unit] call EFUNC(common,switchToGroupSide);
[_unit, false] call EFUNC(common,disableAI);
_unit setUnitPos _originalPos; // This is not position but stance (DOWN, MIDDLE, UP)
_unit setUnconscious false;
["medical_onUnconscious", [_unit, false]] call EFUNC(common,globalEvent);
// ensure this statement runs only once
_args set [5, true];
};
};
// Ensure we are waiting at least a minimum period before checking if we can wake up the unit again, allows for temp knock outs
if ((time - _startingTime) >= _minWaitingTime) exitwith {
if (!([_unit] call FUNC(getUnconsciousCondition))) then {
_unit setvariable ["ACE_isUnconscious", false, true];
};
};
}, 0.1, [_unit,_animState, _originalPos, _startingTime, _minWaitingTime, false] ] call CBA_fnc_addPerFrameHandler;
[DFUNC(unconsciousPFH), 0.1, [_unit,_animState, _originalPos, _startingTime, _minWaitingTime, false, vehicle _unit isKindOf "ParachuteBase"] ] call CBA_fnc_addPerFrameHandler;
["medical_onUnconscious", [_unit, true]] call EFUNC(common,globalEvent);

View File

@ -129,7 +129,7 @@ if (isNil _callbackProgress) then {
// Patient Animation
_patientAnim = getText (_config >> "animationPatient");
if (_target getvariable ["ACE_isUnconscious", false]) then {
if (_target getvariable ["ACE_isUnconscious", false] && GVAR(allowUnconsciousAnimationOnTreatment)) then {
if !(animationState _target in (getArray (_config >> "animationPatientUnconsciousExcludeOn"))) then {
_patientAnim = getText (_config >> "animationPatientUnconscious");
};
@ -149,6 +149,8 @@ if (_caller == _target) then {
_callerAnim = [getText (_config >> "animationCallerSelf"), getText (_config >> "animationCallerSelfProne")] select (stance _caller == "PRONE");
};
_caller setvariable [QGVAR(selectedWeaponOnTreatment), currentWeapon _caller];
// Cannot use secondairy weapon for animation
if (currentWeapon _caller == secondaryWeapon _caller) then {
_caller selectWeapon (primaryWeapon _caller);

View File

@ -92,7 +92,8 @@ if (USE_WOUND_EVENT_SYNC) then {
};
// Handle the reopening of bandaged wounds
if (_impact > 0 && {GVAR(enableAdvancedWounds)}) then {
[_target, _impact, _part, _mostEffectiveSpot, _mostEffectiveInjury, _bandage] call FUNC(handleBandageOpening);
// TODO temp disabled until bandaged wounds are supported by event sync.
// [_target, _impact, _part, _mostEffectiveSpot, _mostEffectiveInjury, _bandage] call FUNC(handleBandageOpening);
};
// If all wounds have been bandaged, we will reset all damage to 0, so the unit is not showing any blood on the model anymore.

View File

@ -17,7 +17,7 @@
#include "script_component.hpp"
private ["_caller", "_target","_selectionName","_className","_config","_callback", "_usersOfItems"];
private ["_caller", "_target","_selectionName","_className","_config","_callback", "_usersOfItems", "_weaponSelect"];
_args = _this select 0;
_caller = _args select 0;
@ -34,6 +34,13 @@ if (vehicle _caller == _caller) then {
};
_caller setvariable [QGVAR(treatmentPrevAnimCaller), nil];
_weaponSelect = (_caller getvariable [QGVAR(selectedWeaponOnTreatment), ""]);
if (_weaponSelect != "") then {
_caller selectWeapon _weaponSelect;
} else {
_caller action ["SwitchWeapon", _caller, _caller, 99];
};
{
(_x select 0) addItem (_x select 1);
}foreach _usersOfItems;

View File

@ -17,7 +17,7 @@
#include "script_component.hpp"
private ["_caller", "_target","_selectionName","_className","_config","_callback"];
private ["_caller", "_target","_selectionName","_className","_config","_callback", "_weaponSelect"];
_args = _this select 0;
_caller = _args select 0;
_target = _args select 1;
@ -32,6 +32,13 @@ if (vehicle _caller == _caller) then {
};
_caller setvariable [QGVAR(treatmentPrevAnimCaller), nil];
_weaponSelect = (_caller getvariable [QGVAR(selectedWeaponOnTreatment), ""]);
if (_weaponSelect != "") then {
_caller selectWeapon _weaponSelect;
} else {
_caller action ["SwitchWeapon", _caller, _caller, 99];
};
// Record specific callback
_config = (configFile >> "ACE_Medical_Actions" >> "Basic" >> _className);
if (GVAR(level) >= 2) then {

View File

@ -0,0 +1,93 @@
/*
* Author: Glowbal
* PFH logic for unconscious state
*
* Arguments:
* 0: The unit that will be put in an unconscious state <OBJECT>
*
* ReturnValue:
* nil
*
* Public: yes
*/
#include "script_component.hpp"
private ["_unit", "_vehicleOfUnit","_minWaitingTime", "_oldAnimation", "_captiveSwitch", "_hasMovedOut", "_parachuteCheck"];
_args = _this select 0;
_unit = _args select 0;
_oldAnimation = _args select 1;
_originalPos = _args select 2;
_startingTime = _args select 3;
_minWaitingTime = _args select 4;
_hasMovedOut = _args select 5;
_parachuteCheck = _args select 6;
if (!alive _unit) exitwith {
[_unit, QGVAR(unconscious), false] call EFUNC(common,setCaptivityStatus);
[_unit, false] call EFUNC(common,disableAI);
//_unit setUnitPos _originalPos;
_unit setUnconscious false;
["medical_onUnconscious", [_unit, false]] call EFUNC(common,globalEvent);
[(_this select 1)] call cba_fnc_removePerFrameHandler;
};
// In case the unit is no longer in an unconscious state, we are going to check if we can already reset the animation
if !(_unit getvariable ["ACE_isUnconscious",false]) exitwith {
// TODO, handle this with carry instead, so we can remove the PFH here.
// Wait until the unit isn't being carried anymore, so we won't end up with wierd animations
if !(([_unit] call FUNC(isBeingCarried)) || ([_unit] call FUNC(isBeingDragged))) then {
if (vehicle _unit == _unit) then {
if (animationState _unit == "AinjPpneMstpSnonWrflDnon") then {
[_unit,"AinjPpneMstpSnonWrflDnon_rolltofront", 2] call EFUNC(common,doAnimation);
[_unit,"amovppnemstpsnonwnondnon", 1] call EFUNC(common,doAnimation);
} else {
[_unit,"amovppnemstpsnonwnondnon", 2] call EFUNC(common,doAnimation);
};
} else {
// Switch to the units original animation, assuming
// TODO: what if the unit switched vehicle?
[_unit, _oldAnimation, 2] call EFUNC(common,doAnimation);
};
["medical_onUnconscious", [_unit, false]] call EFUNC(common,globalEvent);
// EXIT PFH
[(_this select 1)] call cba_fnc_removePerFrameHandler;
};
if (!_hasMovedOut) then {
// Reset the unit back to the previous captive state.
[_unit, QGVAR(unconscious), false] call EFUNC(common,setCaptivityStatus);
// Swhich the unit back to its original group
//Unconscious units shouldn't be put in another group #527:
// [_unit, false, "ACE_isUnconscious", side group _unit] call EFUNC(common,switchToGroupSide);
[_unit, false] call EFUNC(common,disableAI);
_unit setUnitPos _originalPos; // This is not position but stance (DOWN, MIDDLE, UP)
_unit setUnconscious false;
// ensure this statement runs only once
_args set [5, true];
};
};
if (_parachuteCheck) then {
if !(vehicle _unit isKindOf "ParachuteBase") then {
[_unit, [_unit] call EFUNC(common,getDeathAnim), 1, true] call EFUNC(common,doAnimation);
_args set [6, false];
};
};
if (!local _unit) exitwith {
_args set [ 4, _minWaitingTime - (time - _startingTime)];
_unit setvariable [QGVAR(unconsciousArguments), _args, true];
[(_this select 1)] call cba_fnc_removePerFrameHandler;
};
// Ensure we are waiting at least a minimum period before checking if we can wake up the unit again, allows for temp knock outs
if ((time - _startingTime) >= _minWaitingTime) exitwith {
if (!([_unit] call FUNC(getUnconsciousCondition))) then {
_unit setvariable ["ACE_isUnconscious", false, true];
};
};

View File

@ -11,4 +11,4 @@
#include "\z\ace\addons\main\script_macros.hpp"
#define USE_WOUND_EVENT_SYNC false
#define USE_WOUND_EVENT_SYNC true

View File

@ -10,6 +10,7 @@
<Polish>Pokaż imiona</Polish>
<Hungarian>Nevek mutatása</Hungarian>
<Russian>Показать имена</Russian>
<Italian>Mostra i nomi</Italian>
</Key>
<Key ID="STR_ACE_NameTags_ShowPlayerNames">
<English>Show player names</English>
@ -30,7 +31,7 @@
<German>Zeige Spielernamen nur an, wenn die Maus auf sie gerrichtet ist (benötigt Spielernamen)</German>
<French>Noms uniquement sous le curseur (si noms affichés)</French>
<Czech>Zobrazit jméno hráče jenom na kurzor (vyžaduje jména hráčů)</Czech>
<Italian>Mostra i nomi solo se puntati (richiede i nomi dei giocatori abilitati)</Italian>
<Italian>Mostra i nomi solo se puntati (richiede mostra nomi abilitato)</Italian>
<Portuguese>Mostrar nome de jogador somente no cursor (requer nome de jogadores)</Portuguese>
<Hungarian>Játékosok nevének mutatása csak a kurzoron (a nevek mutatása szükséges)</Hungarian>
<Russian>Показать имена игроков только под курсором (требует имен игроков)</Russian>
@ -44,6 +45,7 @@
<Polish>Pokaż imiona graczy tylko po przytrzymaniu klawisza (wymagana opcja Pokaż imiona graczy)</Polish>
<Hungarian>Játékosnevek mutatása csak gombnyomásra (a nevek mutatása szükséges)</Hungarian>
<Russian>Показать имена игроков только по нажатию клавиши (требует имен игроков)</Russian>
<Italian>Mostra i nomi solo se si preme il tasto (richiede mostra nomi abilitato)</Italian>
</Key>
<Key ID="STR_ACE_NameTags_ShowPlayerRanks">
<English>Show player ranks (requires player names)</English>
@ -52,7 +54,7 @@
<Spanish>Mostrar rango de los jugadores (requiere Mostrar nombres de jugadores)</Spanish>
<French>Grade des joueurs (si noms affichés)</French>
<Czech>Zobrazit hodnosti hráčů (vyžaduje jména hráčů)</Czech>
<Italian>Mostra i gradi (richiede i nomi dei giocatori abilitati)</Italian>
<Italian>Mostra i gradi (richiede mostra nomi abilitato)</Italian>
<Portuguese>Mostrar patente de jogadores (requer nome de jogadores)</Portuguese>
<Hungarian>Játékosok rendfokozatának mutatása (a nevek mutatása szükséges)</Hungarian>
<Russian>Показать звания игроков (требует имен игроков)</Russian>
@ -66,6 +68,7 @@
<Czech>Zobrazit info o posádce vozidla</Czech>
<Russian>Показать экипаж</Russian>
<Hungarian>Jármű-legénység adatainak mutatása</Hungarian>
<Italian>Mostra le informazioni sull'equipaggio del veicolo</Italian>
</Key>
<Key ID="STR_ACE_NameTags_ShowNamesForAI">
<English>Show name tags for AI units</English>
@ -76,6 +79,7 @@
<Polish>Wyświetl imiona jednostek AI</Polish>
<French>Afficher les noms des IA</French>
<Hungarian>Névcímkék mutatása MI-egységeknél</Hungarian>
<Italian>Mostra le tag nomi per le unità AI</Italian>
</Key>
<Key ID="STR_ACE_NameTags_ShowSoundWaves">
<English>Show SoundWaves (requires player names)</English>
@ -86,6 +90,7 @@
<Polish>Pokaż fale dźwiękowe (wymagana opcja Pokaż imiona graczy)</Polish>
<French>Afficher "qui parle" (si noms affichés)</French>
<Hungarian>"Hanghullámok" mutatása (a nevek mutatása szükséges)</Hungarian>
<Italian>Mostra barra movimento audio (richiede mostra nomi abilitato)</Italian>
</Key>
<Key ID="STR_ACE_NameTags_DefaultNametagColor">
<English>Default Nametag Color (Non Group Members)</English>
@ -96,6 +101,7 @@
<French>Couleur d'affichage par défaut (si dans aucun groupe)</French>
<Czech>Standardní barva jmenovek (pro nečleny jednotky)</Czech>
<Hungarian>Alap névcímke-szín (csoporton kívüli személyek)</Hungarian>
<Italian>Colore nametag di default (membri non del gruppo)</Italian>
</Key>
</Package>
</Project>

View File

@ -5,20 +5,20 @@ class CfgWeapons {
class Default;
class Binocular: Default {
forceOptics = 0; // Allow using compass with Binocular
opticsZoomMin = 0.056889; // 5.25x power
opticsZoomMax = 0.056889; // 9 px/mil
modelOptics = "\z\ace\addons\optics\models\NWD_M22_5x"; // 7° horizontal field of view
visionMode[] = {"Normal"}; // Can't use nvgs with binoculars any more than you can with scopes
// Fix AI using Binocs on short range - #18737
forceOptics = 0; // Allow using compass with Binocular
opticsZoomMin = 0.056889; // 5.25x power
opticsZoomMax = 0.056889; // 9 px/mil
modelOptics = "\z\ace\addons\optics\models\NWD_M22_5x"; // 7° horizontal field of view
visionMode[] = {"Normal"}; // Can't use nvgs with binoculars any more than you can with scopes
// Fix AI using Binocs on short range - #18737
// minRange = 300; // 300 = uses Rangefinder often (runs a few meters, stops, uses RF, repeats)
minRange = 500; //500 = seem almost never use it..?
minRangeProbab = 0.001;
minRangeProbab = 0.001;
midRange = 1000;
midRangeProbab = 0.01;
maxRange = 5000;
maxRangeProbab = 0.01;
};
};
// zooming reticle scopes
class optic_DMS: ItemCore {

View File

@ -22,6 +22,7 @@
<Polish>Napraw animację</Polish>
<French>Corriger animation</French>
<Hungarian>Animációk kijavítása</Hungarian>
<Italian>Fixa l'animazione</Italian>
</Key>
<Key ID="STR_ACE_OptionsMenu_ResetAll">
<English>Reset All</English>
@ -32,6 +33,7 @@
<Polish>Resetuj wszystko</Polish>
<French>Défaut</French>
<Hungarian>Minden visszaállítása</Hungarian>
<Italian>Resetta tutto</Italian>
</Key>
<Key ID="STR_ACE_OptionsMenu_TabColors">
<English>Colors</English>
@ -42,6 +44,7 @@
<Czech>Barvy</Czech>
<Polish>Kolory</Polish>
<Hungarian>Színek</Hungarian>
<Italian>Colori</Italian>
</Key>
<Key ID="STR_ACE_OptionsMenu_TabOptions">
<English>Options</English>
@ -64,6 +67,7 @@
<French>Valeurs</French>
<German>Werte</German>
<Hungarian>Értékek</Hungarian>
<Italian>Valori</Italian>
</Key>
<Key ID="STR_ACE_OptionsMenu_Enabled">
<English>Yes</English>
@ -98,6 +102,7 @@
<Polish>Ustawienie:</Polish>
<French>Paramètres</French>
<Hungarian>Opció:</Hungarian>
<Italian>Parametri:</Italian>
</Key>
<Key ID="STR_ACE_OptionsMenu_Export">
<English>Export</English>
@ -108,6 +113,7 @@
<Polish>Eksport</Polish>
<French>Exporter</French>
<Hungarian>Exportálás</Hungarian>
<Italian>Esporta</Italian>
</Key>
<Key ID="STR_ACE_OptionsMenu_OpenExport">
<English>Open Export Menu</English>
@ -118,6 +124,7 @@
<Polish>Otwórz menu eksportowania</Polish>
<French>Ouvrir le menu d'exportation</French>
<Hungarian>Exportálási menü megnyitása</Hungarian>
<Italian>Apri menù esportazione</Italian>
</Key>
<Key ID="STR_ACE_OptionsMenu_stringType">
<English>String input.</English>
@ -127,6 +134,7 @@
<Polish>Wpisywanie tekstu.</Polish>
<French>Entrée</French>
<Hungarian>String bevitel.</Hungarian>
<Italian>Stringa di unput.</Italian>
</Key>
<Key ID="STR_ACE_OptionsMenu_arrayType">
<English>Array. Seperate elements by using ,.</English>
@ -137,6 +145,7 @@
<French>Tableau. Séparation par ,.</French>
<Czech>Tabulka. Odděl elementy použitím ,.</Czech>
<Hungarian>Array. Válasszad el az elemeket vesszővel.</Hungarian>
<Italian>Array. Separa gli elementi usando ,.</Italian>
</Key>
<Key ID="STR_ACE_OptionsMenu_scalarType">
<English>Number</English>
@ -147,6 +156,7 @@
<Polish>Cyfra</Polish>
<French>Nombre</French>
<Hungarian>Szám</Hungarian>
<Italian>Numero</Italian>
</Key>
<Key ID="STR_ACE_optionsMenu_unknownType">
<English>Uknown input type</English>
@ -157,6 +167,7 @@
<Polish>Nieznany rodzaj danych</Polish>
<French>Type d'entrée inconnue</French>
<Hungarian>Ismeretlen beviteli típus</Hungarian>
<Italian>Input inserito sconosciuto</Italian>
</Key>
<Key ID="STR_ACE_OptionsMenu_SaveInput">
<English>Save input</English>
@ -167,6 +178,7 @@
<Polish>Zapisz dane</Polish>
<French>Sauvegarder</French>
<Hungarian>Bevitel elmentése</Hungarian>
<Italian>Salva input</Italian>
</Key>
<Key ID="STR_ACE_OptionsMenu_inClientSettings">
<English>Include Client Settings</English>
@ -177,6 +189,7 @@
<Polish>Zawrzyj ustawienia klienta</Polish>
<French>Inclure paramètres client</French>
<Hungarian>Kliens-beállítások melléklése</Hungarian>
<Italian>Includi i parametri del client</Italian>
</Key>
<Key ID="STR_ACE_OptionsMenu_exClientSettings">
<English>Exclude Client Settings</English>
@ -187,6 +200,7 @@
<Polish>Wyklucz ustawienia klienta</Polish>
<French>Exclure paramètres client</French>
<Hungarian>Kliens-beállítások elhagyása</Hungarian>
<Italian>Escludi i parametri del client</Italian>
</Key>
<Key ID="STR_ACE_OptionsMenu_settingsExported">
<English>Settings exported to clipboard</English>
@ -197,6 +211,7 @@
<Polish>Ustawienia wyeksportowano do schowka</Polish>
<French>Paramètres exportés dans le presse papier</French>
<Hungarian>Beállítások exportálva a vágólapba</Hungarian>
<Italian>Parametri esportati alla clipboard</Italian>
</Key>
</Package>
</Project>

View File

@ -14,12 +14,13 @@
* Public: No
*/
#include "script_component.hpp"
if (!hasInterface) exitWith {};
["ACE3", QGVAR(showAltimeter), localize "STR_ACE_Parachute_showAltimeter",
{
// Conditions: canInteract
if !([ACE_player, objNull, ["isNotEscorting"]] call EFUNC(common,canInteractWith)) exitWith {false};
if !([ACE_player, objNull, ["isNotEscorting", "isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false};
if (!('ACE_Altimeter' in assignedItems ace_player)) exitWith {false};
if (!(missionNamespace getVariable [QGVAR(AltimeterActive), false])) then {
[ace_player] call FUNC(showAltimeter);
@ -40,5 +41,4 @@ GVAR(PFH) = false;
}] call EFUNC(common,addEventHandler);
// don't show speed and height when in expert mode
["Parachute", {if (!cadetMode) then {_dlg = _this select 0; {(_dlg displayCtrl _x) ctrlShow false} forEach [121, 122, 1004, 1005, 1006, 1014];};}] call EFUNC(common,addInfoDisplayEventHandler); //@todo addEventHandler infoDisplayChanged with select 1 == "Parachute"
["Soldier", {if (!cadetMode) then {_dlg = _this select 0; {_ctrl = (_dlg displayCtrl _x); _ctrl ctrlSetPosition [0,0,0,0]; _ctrl ctrlCommit 0;} forEach [380, 382]};}] call EFUNC(common,addInfoDisplayEventHandler); //@todo addEventHandler infoDisplayChanged with select 1 == "Soldier"
["infoDisplayChanged", {_this call FUNC(handleInfoDisplayChanged)}] call EFUNC(common,addEventHandler);

View File

@ -18,6 +18,7 @@
ADDON = false;
PREP(doLanding);
PREP(handleInfoDisplayChanged);
PREP(hideAltimeter);
PREP(onEachFrame);
PREP(showAltimeter);

View File

@ -0,0 +1,41 @@
/*
* Author: commy2
* Hides the height and velocity display while freefalling or parachuting on higher difficulties.
*
* Arguments:
* Stuff from infoDisplayChanged eventhandler.
*
* Return Value:
* None
*
* Public: No
*/
#include "script_component.hpp"
private ["_dialog", "_type"];
_dialog = _this select 0;
_type = _this select 1;
// don't do anything in noob mode
if (cadetMode) exitWith {};
switch (_type) do {
case ("Parachute"): {
{
(_dialog displayCtrl _x) ctrlShow false;
} forEach [121, 122, 1004, 1005, 1006, 1014];
};
case ("Soldier"): {
{
private "_control";
_control = (_dialog displayCtrl _x);
// these reset ctrlShow every frame by the engine. Set height/width to 0 as work around.
_control ctrlSetPosition [0,0,0,0];
_control ctrlCommit 0;
} forEach [380, 382];
};
};
nil // switch might return true if no case was found. Just to make sure the return value matches

View File

@ -14,19 +14,24 @@
* Public: Yes
*/
#include "script_component.hpp"
private ["_unit"];
_unit = _this select 0;
(["ACE_Altimeter"] call BIS_fnc_rscLayer) cutRsc ["ACE_Altimeter", "PLAIN",0,true];
(["ACE_Altimeter"] call BIS_fnc_rscLayer) cutRsc ["ACE_Altimeter", "PLAIN", 0, true];
if (isNull (uiNamespace getVariable ["ACE_Altimeter", displayNull])) exitWith {};
GVAR(AltimeterActive) = true;
[{
if (!GVAR(AltimeterActive)) exitWith {[_this select 1] call CALLSTACK(cba_fnc_removePerFrameEventHandler);};
if (!GVAR(AltimeterActive)) exitWith {[_this select 1] call CALLSTACK(cba_fnc_removePerFrameEventHandler)};
disableSerialization;
EXPLODE_4_PVT(_this select 0,_display,_unit,_oldHeight,_prevTime);
if !("ACE_Altimeter" in assignedItems _unit) exitWith {[_this select 1] call CALLSTACK(cba_fnc_removePerFrameEventHandler);call FUNC(hideAltimeter);};
if !("ACE_Altimeter" in assignedItems _unit) exitWith {[_this select 1] call CALLSTACK(cba_fnc_removePerFrameEventHandler); call FUNC(hideAltimeter)};
private ["_height", "_hour", "_minute", "_descentRate","_HeightText", "_DecendRate", "_TimeText", "_curTime", "_timeDiff"];
private ["_height", "_hour", "_minute", "_descentRate","_HeightText", "_DecendRate", "_TimeText", "_curTime"];
_HeightText = _display displayCtrl 1100;
_DecendRate = _display displayCtrl 1000;
_TimeText = _display displayCtrl 1001;
@ -35,7 +40,8 @@ GVAR(AltimeterActive) = true;
_height = (getPosASL _unit) select 2;
_curTime = time;
_descentRate = floor ((_oldHeight - _height) / (_curTime - _prevTime));
_timeDiff = _curTime - _prevTime;
_descentRate = if(_timeDiff > 0) then {floor((_oldHeight - _height) / _timeDiff)} else {0};
_TimeText ctrlSetText (format ["%1:%2",[_hour, 2] call EFUNC(common,numberToDigitsString),[_minute, 2] call EFUNC(common,numberToDigitsString)]);
_HeightText ctrlSetText (format ["%1", floor(_height)]);

View File

@ -11,6 +11,7 @@
<Spanish>Altímetro</Spanish>
<Hungarian>Magasságmérő</Hungarian>
<Russian>Высотомер</Russian>
<Italian>Altimetro</Italian>
</Key>
<Key ID="STR_ACE_Parachute_AltimeterDisplayName">
<English>Altimeter Watch</English>
@ -21,6 +22,7 @@
<Spanish>Reloj altímetro</Spanish>
<Hungarian>Magasságmérős karóra</Hungarian>
<Russian>Часы с высотомером</Russian>
<Italian>Controlla l'altimetro</Italian>
</Key>
<Key ID="STR_ACE_Parachute_AltimeterDescription">
<English>Used to show height, descent rate and the time.</English>
@ -31,6 +33,7 @@
<Spanish>Utilizado para mostrar altura, tasa de descenso y hora.</Spanish>
<Hungarian>Mutatja a magasságot, a zuhanási sebességet, és az időt.</Hungarian>
<Russian>Используется для определения высоты, скорости снижения и времени.</Russian>
<Italian>Usato per mostrare l'altitudine, la velocità di discesa e l'ora.</Italian>
</Key>
<Key ID="STR_ACE_Parachute_NonSteerableParachute">
<English>Non-Steerable Parachute</English>
@ -41,6 +44,7 @@
<Czech>Neříditelný padák</Czech>
<Hungarian>Irányíthatatlan ejtőernyő</Hungarian>
<Russian>Неуправляемый парашют</Russian>
<Italian>Paracadute non manovrabile</Italian>
</Key>
</Package>
</Project>
</Project>

View File

@ -10,6 +10,7 @@
<Polish>Sprawdź stan amunicji przy przeładowaniu broni</Polish>
<French>Vérification des munitions au rechargement</French>
<Hungarian>Lőszer ellenőrzése a fegyver újratöltésekor</Hungarian>
<Italian>Controlla le munizioni ricaricando</Italian>
</Key>
<Key ID="STR_ACE_reload_SettingDisplayTextDesc">
<English>Check the ammo in your new magazine on magazine reload.</English>
@ -20,6 +21,7 @@
<Polish>Pokaż stan amunicji w nowym magazynku przy przeładowaniu broni</Polish>
<French>Vérification du nombre de munition au rechargement</French>
<Hungarian>A lőszer ellenőrzése az új tárad behelyezésekor újratöltés közben.</Hungarian>
<Italian>Controlla le munizioni rimanenti nel caricatore in fase di cambio caricatore.</Italian>
</Key>
<Key ID="STR_ACE_Reload_checkAmmo">
<English>Check Ammo</English>
@ -54,6 +56,7 @@
<Polish>Podłącz taśmę</Polish>
<German>Gurt anhängen</German>
<Hungarian>Töltényheveder összekötése</Hungarian>
<Italian>Attacca la tracolla</Italian>
</Key>
<Key ID="STR_ACE_Reload_LinkingBelt">
<English>Linking belt...</English>
@ -64,6 +67,7 @@
<Polish>Podłączanie taśmy...</Polish>
<German>Gurt anhängen ...</German>
<Hungarian>Töltényheveder összekötése folyamatban...</Hungarian>
<Italian>Attacco la tracolla...</Italian>
</Key>
</Package>
</Project>

View File

@ -11,6 +11,7 @@
<Polish>Załaduj wyrzutnię</Polish>
<French>Charger lanceur</French>
<Hungarian>Kilövö betöltése</Hungarian>
<Italian>Carica lanciamissili</Italian>
</Key>
<Key ID="STR_ACE_ReloadLaunchers_LoadingLauncher">
<English>Loading launcher ...</English>
@ -21,6 +22,7 @@
<Czech>Nabíjím odpalovač ...</Czech>
<Polish>Ładowanie wyrzutni ...</Polish>
<Hungarian>Kilövő betöltés alatt ...</Hungarian>
<Italian>Carico il lanciamissili ...</Italian>
</Key>
<Key ID="STR_ACE_ReloadLaunchers_LauncherLoaded">
<English>Launcher loaded</English>
@ -31,6 +33,7 @@
<Czech>Odpalovač nabit</Czech>
<Polish>Wyrzutnia załadowana</Polish>
<Hungarian>Kilövő betöltve</Hungarian>
<Italian>Lanciamissili caricato</Italian>
</Key>
<Key ID="STR_ACE_ReloadLaunchers_LoadMagazine">
<English>Load %1</English>
@ -41,6 +44,7 @@
<Czech>Nabít %1</Czech>
<Polish>Załadowano %1</Polish>
<Hungarian>%1 betöltése</Hungarian>
<Italian>Caricato %1</Italian>
</Key>
</Package>
</Project>

View File

@ -10,6 +10,7 @@
<Polish>Rozmieszczenie za 5 sekund ...</Polish>
<Czech>Respawn za 5 sekund...</Czech>
<Hungarian>Kihelyezés 5 másodperc múlva ...</Hungarian>
<Italian>Dispiegamento in 5 secondi ...</Italian>
</Key>
<Key ID="STR_ACE_Respawn_Deployed">
<English>Rallypoint deployed</English>
@ -20,6 +21,7 @@
<Polish>Punkt zbiórki rozmieszczony</Polish>
<Czech>Rallypoint umístěn</Czech>
<Hungarian>Gyülekezőpont elhelyezve</Hungarian>
<Italian>Rallypoint dispiegato</Italian>
</Key>
<Key ID="STR_ACE_Respawn_TeleportedToBase">
<English>Teleported to Base</English>
@ -30,6 +32,7 @@
<Polish>Przeteleportowano do bazy</Polish>
<Czech>Odteleportován na základnu</Czech>
<Hungarian>Bázisra teleportálva</Hungarian>
<Italian>Teleportato alla base</Italian>
</Key>
<Key ID="STR_ACE_Respawn_TeleportedToRallypoint">
<English>Teleported to Rallypoint</English>
@ -40,36 +43,43 @@
<Polish>Przeteleportowano do punktu zbiórki</Polish>
<Czech>Odteleportován na rallypoint</Czech>
<Hungarian>Gyülekezőpontra teleportálva</Hungarian>
<Italian>Teleportato al rallypoint</Italian>
</Key>
<Key ID="STR_ACE_Respawn_RallypointWestBase">
<English>Rallypoint West (Base)</English>
<German>Sammelpunkt West (Basis)</German>
<Spanish>Punto de reunión Oeste (Base)</Spanish>
<Russian>Точка сбора Синих (База)</Russian>
</Key>
<Key ID="STR_ACE_Respawn_RallypointEastBase">
<English>Rallypoint East (Base)</English>
<German>Sammelpunkt Ost (Basis)</German>
<Spanish>Punto de reunión Este (Base)</Spanish>
<Russian>Точка сбора Красных (База)</Russian>
</Key>
<Key ID="STR_ACE_Respawn_RallypointIndependentBase">
<English>Rallypoint Independent (Base)</English>
<German>Sammelpunkt Widerstand (Basis)</German>
<Spanish>Punto de reunión Independiente (Base)</Spanish>
<Russian>Точка сбора Независимых (База</Russian>
</Key>
<Key ID="STR_ACE_Respawn_RallypointWest">
<English>Rallypoint West</English>
<German>Sammelpunkt West</German>
<Spanish>Punto de reunión Oeste</Spanish>
<Russian>Точка сбора Синих</Russian>
</Key>
<Key ID="STR_ACE_Respawn_RallypointEast">
<English>Rallypoint East</English>
<German>Sammelpunkt Ost</German>
<Spanish>Punto de reunión Este</Spanish>
<Russian>Точка сбора Красных</Russian>
</Key>
<Key ID="STR_ACE_Respawn_RallypointIndependent">
<English>Rallypoint Independent</English>
<German>Sammelpunkt Widerstand</German>
<Spanish>Punto de reunión Independiente</Spanish>
<Russian>Точка сбора Независимых</Russian>
</Key>
</Package>
</Project>

View File

@ -10,6 +10,7 @@
<Hungarian>Biztonságos mód</Hungarian>
<Russian>Предохранитель</Russian>
<French>Sécurité</French>
<Italian>Sicura inserita</Italian>
</Key>
<Key ID="STR_ACE_SafeMode_TakeOffSafety">
<English>Take off Safety</English>
@ -20,6 +21,7 @@
<Hungarian>Biztonsági kapcsoló eltolása</Hungarian>
<Russian>Снять с предохранителя</Russian>
<French>Enlever sécurité</French>
<Italian>Togli la sicura</Italian>
</Key>
<Key ID="STR_ACE_SafeMode_PutOnSafety">
<English>Put on Safety</English>
@ -30,6 +32,7 @@
<Hungarian>Biztonsági kapcsoló helyretolása</Hungarian>
<Russian>Поставить на предохранитель</Russian>
<French>Sécurité mise</French>
<Italian>Inserisci la sicura</Italian>
</Key>
<Key ID="STR_ACE_SafeMode_TookOffSafety">
<English>Took off Safety</English>
@ -40,6 +43,7 @@
<Hungarian>Biztonságos mód megszüntetve</Hungarian>
<Russian>Снят с предохранителя</Russian>
<French>Sécurité enlevée</French>
<Italian>Togli la sicura</Italian>
</Key>
</Package>
</Project>

View File

@ -6,54 +6,63 @@
<Polish>Zerowanie powoli w górę</Polish>
<Russian>Малая корректировка ВВЕРХ</Russian>
<Spanish>Ajuste menor arriba</Spanish>
<Italian>Regola leggermente alzata in alto</Italian>
</Key>
<Key ID="STR_ACE_Scopes_AdjustDownMinor">
<English>Minor adjustment down</English>
<Polish>Zerowanie powoli w dół</Polish>
<Russian>Малая корректировка ВНИЗ</Russian>
<Spanish>Ajuste menor abajo</Spanish>
<Italian>Regola leggermente alzata in basso</Italian>
</Key>
<Key ID="STR_ACE_Scopes_AdjustRightMinor">
<English>Minor adjustment right</English>
<Polish>Zerowanie powoli w prawo</Polish>
<Russian>Малая корректировка ВПРАВО</Russian>
<Spanish>Ajuste menor derecha</Spanish>
<Italian>Regola leggermente il tiro a destra</Italian>
</Key>
<Key ID="STR_ACE_Scopes_AdjustLeftMinor">
<English>Minor adjustment left</English>
<Polish>Zerowanie powoli w lewo</Polish>
<Russian>Малая корректировка ВЛЕВО</Russian>
<Spanish>Ajuste menor izquierda</Spanish>
<Italian>Regola leggermete il tiro a sinistra</Italian>
</Key>
<Key ID="STR_ACE_Scopes_AdjustUpMajor">
<English>Major adjustment up</English>
<Polish>Zerowanie w górę</Polish>
<Russian>Большая корректировка ВВЕРХ</Russian>
<Spanish>Ajuste mayor arriba</Spanish>
<Italian>Regola l'alzata in alto</Italian>
</Key>
<Key ID="STR_ACE_Scopes_AdjustDownMajor">
<English>Major adjustment down</English>
<Polish>Zerowanie w dół</Polish>
<Russian>Большая корректировка ВНИЗ</Russian>
<Spanish>Ajuste mayor abajo</Spanish>
<Italian>Regola l'alzata in basso</Italian>
</Key>
<Key ID="STR_ACE_Scopes_AdjustRightMajor">
<English>Major adjustment right</English>
<Polish>Zerowanie w prawo</Polish>
<Russian>Большая корректировка ВПРАВО</Russian>
<Spanish>Ajuste mayor derecha</Spanish>
<Italian>Regola il tiro a destra</Italian>
</Key>
<Key ID="STR_ACE_Scopes_AdjustLeftMajor">
<English>Major adjustment left</English>
<Polish>Zerowanie w lewo</Polish>
<Russian>Большая корректировка ВЛЕВО</Russian>
<Spanish>Ajuste mayor izquierda</Spanish>
<Italian>Regola il tiro a sinistra</Italian>
</Key>
<Key ID="STR_ACE_Scopes_AdjustZero">
<English>Set zero adjustment</English>
<Polish>Zresetuj wyzerowanie</Polish>
<Russian>Сбросить корректировку</Russian>
<Spanish>Establecer ajuste a cero</Spanish>
<Italian>Resetta i valori del tiro</Italian>
</Key>
</Package>
</Project>

View File

@ -10,6 +10,7 @@
<Spanish>Cambiado de unidad</Spanish>
<French>Unité changée</French>
<Hungarian>Egység átváltva</Hungarian>
<Italian>Cambia unità</Italian>
</Key>
<Key ID="STR_ACE_SwitchUnits_TooCloseToEnemy">
<English>This unit is too close to the enemy.</English>
@ -20,6 +21,7 @@
<Spanish>Esta unidad está demasiado cerca del enemigo.</Spanish>
<French>Cette unité est trop proche des ennemis</French>
<Hungarian>Ez az egység túl közel van az ellenséghez.</Hungarian>
<Italian>Questa unità è troppo vicina al nemico.</Italian>
</Key>
</Package>
</Project>

View File

@ -10,6 +10,7 @@
<Czech>Odemknout vozidlo</Czech>
<Hungarian>Jármű nyitása</Hungarian>
<Russian>Открыть машину</Russian>
<Italian>Apri il veicolo</Italian>
</Key>
<Key ID="STR_ACE_Vehicle_Action_Lock">
<English>Lock Vehicle</English>
@ -20,6 +21,7 @@
<Czech>Zamknout vozidlo</Czech>
<Hungarian>Jármű zárása</Hungarian>
<Russian>Закрыть машину</Russian>
<Italian>Chiudi il veicolo</Italian>
</Key>
<Key ID="STR_ACE_Vehicle_Action_Lockpick">
<English>Lockpick Vehicle</English>
@ -30,6 +32,7 @@
<Czech>Vypáčit vozidlo</Czech>
<Hungarian>Jármű feltörése</Hungarian>
<Russian>Взломать замок</Russian>
<Italian>Scassina veicolo</Italian>
</Key>
<Key ID="STR_ACE_Vehicle_Action_LockpickInUse">
<English>Picking Lock....</English>
@ -40,6 +43,7 @@
<Czech>Páčim vozidlo...</Czech>
<Hungarian>Zár feltörése...</Hungarian>
<Russian>Взламываем замок...</Russian>
<Italian>Scassino il veicolo....</Italian>
</Key>
<Key ID="STR_ACE_Vehicle_Item_Custom_Description">
<English>A custom key that will open a specific vehicle.</English>
@ -50,6 +54,7 @@
<Czech>Vlastní klíč, který otevře konkrétní vozidlo.</Czech>
<Hungarian>Egy egyedi kulcs, ami egy meghatározott járművet nyit ki.</Hungarian>
<Russian>Ключ от конкретной машины.</Russian>
<Italian>Una chiave personalizzata che apre determinati veicoli.</Italian>
</Key>
<Key ID="STR_ACE_Vehicle_Item_Master_Description">
<English>A Master Key will open any lock, no matter what!</English>
@ -60,6 +65,7 @@
<Czech>Hlavní klíč otevře libovolný zámek, bez vyjímek!</Czech>
<Hungarian>Egy főkulcs, ami minden zárat kinyit, helyzettől függetlenül!</Hungarian>
<Russian>Универсальный ключ, открывающий любой замок.</Russian>
<Italian>Una chiave principale che apre qualsiasi serratura!</Italian>
</Key>
<Key ID="STR_ACE_Vehicle_Item_Lockpick_Description">
<English>A lockpick set that can pick the locks of most vehicles.</English>
@ -70,6 +76,7 @@
<Czech>Sada paklíčů, která dokáže odemknout zámky u většiny vozidel.</Czech>
<Hungarian>Egy tolvajkulcs-készlet, mely a legtöbb jármű zárjait fel tudja törni.</Hungarian>
<Russian>Набор отмычек, которым можно взломать почти любую машину.</Russian>
<Italian>Un grimardello per forzare la maggior parte dei veicoli</Italian>
</Key>
<Key ID="STR_ACE_Vehicle_Item_West_Description">
<English>A key that should open most WEST vehicles.</English>
@ -79,7 +86,8 @@
<Polish>Klucz, który powinien otworzyć większość pojazdów ZACHODU.</Polish>
<Czech>Klíč který by měl otevřít většinou Západních vozidel.</Czech>
<Hungarian>Egy kulcs, ami a NYUGAT egységeinek legtöbb járművét ki tudja nyitni.</Hungarian>
<Russian>Ключ для открытия большинства машин Запада.</Russian>
<Russian>Ключ для открытия большинства машин Красных.</Russian>
<Italian>Una chiave che apre la maggior parte dei veicoli WEST</Italian>
</Key>
<Key ID="STR_ACE_Vehicle_Item_East_Description">
<English>A key that should open most EAST vehicle.</English>
@ -89,7 +97,8 @@
<Polish>Klucz, który powinien otworzyć większość pojazdów WSCHODU.</Polish>
<Hungarian>Egy kulcs, ami a KELET egységeinek legtöbb járművét ki tudja nyitni.</Hungarian>
<Czech>Klíč který by měl otevřít vetšinu Východních vozidel.</Czech>
<Russian>Ключ для открытия большинства машин Востока.</Russian>
<Russian>Ключ для открытия большинства машин Синих.</Russian>
<Italian>Una chaive che apr ela maggior parte dei veicoli EAST</Italian>
</Key>
<Key ID="STR_ACE_Vehicle_Item_Indp_Description">
<English>A key that should open most INDEP vehicle.</English>
@ -100,6 +109,7 @@
<Hungarian>Egy kulcs, ami a FÜGGETLEN egységek legtöbb járművét ki tudja nyitni.</Hungarian>
<Czech>Klíč který by měl otevřít většinu Nezávislých vozidel.</Czech>
<Russian>Ключ для открытия большинства машин Независимых.</Russian>
<Italian>Una chaive che apr ela maggior parte dei veicoli INDEP</Italian>
</Key>
<Key ID="STR_ACE_Vehicle_Item_Civ_Description">
<English>A key that should open most CIV vehicle.</English>
@ -110,6 +120,7 @@
<Czech>Klíč který by měl otevřít většinu Civilních vozidel.</Czech>
<Hungarian>Egy kulcs, ami a CIVIL járművek többségét ki tudja nyitni.</Hungarian>
<Russian>Ключ для открытия большинства машин Гражданских.</Russian>
<Italian>Una chaive che apr ela maggior parte dei veicoli CIV</Italian>
</Key>
</Package>
</Project>

View File

@ -10,6 +10,7 @@
<Polish>Wyświetl tekst przy rzucie granatem</Polish>
<French>Afficher texte lors d'un lancé de grenade</French>
<Hungarian>Szöveg mutatása gránát eldobásakor</Hungarian>
<Italian>Mostra indicazioni nel lancio granate</Italian>
</Key>
<Key ID="STR_ACE_Weaponselect_SettingDisplayTextDesc">
<English>Display a hint or text on grenade throw.</English>
@ -20,6 +21,7 @@
<Polish>Wyświetla powiadomienie lub tekst przy rzucie granatem.</Polish>
<French>Afficher texte/info au lancé de grenade</French>
<Hungarian>Jelez egy súgót vagy szöveget a gránát eldobásakor.</Hungarian>
<Italian>Mostra un suggerimento quando si lanciano granate</Italian>
</Key>
<Key ID="STR_ACE_WeaponSelect_SelectPistol">
<English>Select Pistol</English>
@ -55,7 +57,7 @@
<French>Sélectionner Lanceur</French>
<Hungarian>Rakétavető Kiválasztása</Hungarian>
<Portuguese>Selecionar Lançador</Portuguese>
<Italian>Seleziona il Lanciatore</Italian>
<Italian>Seleziona il Lanciamissili</Italian>
</Key>
<Key ID="STR_ACE_WeaponSelect_SelectRifleMuzzle">
<English>Select Grenade Launcher</English>
@ -162,6 +164,7 @@
<Hungarian>Gránát: %1</Hungarian>
<Russian>Граната %1</Russian>
<French>Grenade %1</French>
<Italian>Granata %1</Italian>
</Key>
<Key ID="STR_ACE_WeaponSelect_ReadyGrenade">
<English>Ready Grenade</English>
@ -172,6 +175,7 @@
<Hungarian>Gránát előkészítése</Hungarian>
<Russian>Подготовить гранату</Russian>
<French>Grenade prête</French>
<Italian>Granata pronta</Italian>
</Key>
<Key ID="STR_ACE_WeaponSelect_SelectGrenadeFrag">
<English>Select Frag Grenade</English>
@ -194,7 +198,7 @@
<Hungarian>Nem-robbanó Gránát Kiválasztása</Hungarian>
<Czech>Zvolit Ne-Výbušný Granát</Czech>
<Portuguese>Selecionar Granada</Portuguese>
<Italian>Seleziona Altre Granate</Italian>
<Italian>Seleziona granate non a frammentazione</Italian>
<Russian>Выбрать гранату</Russian>
</Key>
<Key ID="STR_ACE_WeaponSelect_ThrowGrenade">
@ -218,6 +222,7 @@
<Czech>Žádné granáty</Czech>
<Hungarian>Nincs több gránát</Hungarian>
<Russian>Гранат не осталось</Russian>
<Italian>Granate esaurite</Italian>
</Key>
<Key ID="STR_ACE_WeaponSelect_NoFragsLeft">
<English>No frags left</English>
@ -229,7 +234,7 @@
<Czech>Už nejsou granáty</Czech>
<Portuguese>Não há granadas de fragmentação restantes</Portuguese>
<Italian>Nessuna granata a frammentazione rimanente</Italian>
<Russian>Осколочныких гранат нет</Russian>
<Russian>Осколочных гранат нет</Russian>
</Key>
<Key ID="STR_ACE_WeaponSelect_NoMiscGrenadeLeft">
<English>No misc. grenades left</English>
@ -264,6 +269,7 @@
<Polish>Wystrzel granat dymny</Polish>
<Hungarian>Füstvető eltüzelése</Hungarian>
<Russian>Запустить дымовую завесу</Russian>
<Italian>Lancia fumogeno</Italian>
</Key>
</Package>
</Project>
</Project>

View File

@ -39,6 +39,7 @@ _fnc_updateWind = {
// Update Rain
_fnc_updateRain = {
private ["_oldStrength","_rainStrength","_transitionTime","_periodPosition","_periodPercent"];
if(GVAR(enableRain)) then {
if(!isNil "ACE_RAIN_PARAMS" && {!isNil QGVAR(rain_period_start_time)}) then {
_oldStrength = ACE_RAIN_PARAMS select 0;
@ -56,6 +57,7 @@ _fnc_updateRain = {
// Update Temperature
_fnc_updateTemperature = {
private ["_time","_month","_hourlyCoef","_avgTemperature","_pS1","_pS2"];
_time = daytime;
_month = date select 1;

View File

@ -1,6 +1,5 @@
/*
* Author: Ruthberg
*
* Displays a wind info (colored arrow) in the top left corner of the screen
*
* Argument:
@ -29,13 +28,13 @@ GVAR(WindInfo) = true;
[{
private ["_windSpeed", "_windDir", "_playerDir", "_windIndex", "_windColor", "_newWindSpeed", "_windSource", "_height"];
if !(GVAR(WindInfo) && !(underwater ACE_player) && vehicle ACE_player == ACE_player) exitWith {
GVAR(WindInfo) = false;
0 cutText ["", "PLAIN"];
[_this select 1] call cba_fnc_removePerFrameHandler;
};
_windIndex = 12;
_windColor = [1, 1, 1, 1];
@ -46,7 +45,7 @@ GVAR(WindInfo) = true;
} else {
vectorMagnitude ACE_wind;
};
if (_windSpeed > 0.2) then {
_playerDir = getDir ACE_player;
_windDir = (ACE_wind select 0) atan2 (ACE_wind select 1);

View File

@ -1,6 +1,5 @@
/*
* Author: Ruthberg, esteldunedain
*
* Get the weather data for the current map
*
* Argument:

View File

@ -1,4 +1,15 @@
/*
* Author: ACE2 Team
* Calculate current wind locally from the data broadcasted by the server
*
* Argument:
* None
*
* Return value:
* Wind <ARRAY>
*/
#include "script_component.hpp"
private ["_dir","_dirInc","_dirRange","_period","_periodPercent","_periodPosition","_return","_spd","_spdInc","_spdRange"];
_return = [0,0,0];
if(!isNil "ACE_WIND_PARAMS") then {

View File

@ -1,4 +1,15 @@
/*
* Author: ACE2 Team, esteldunedain
* Calculate the wind and rain evolution on the server. Broadcast the current and next values to the clients
*
* Argument:
* None
*
* Return value:
* None
*/
#include "script_component.hpp"
private ["_gustCount","_gustDir","_gustSpeed","_gustTime","_gusts","_i","_lastRain","_maxInterval","_rainOverCast","_startDir","_startSpeed","_time","_timeTillGust","_transitionTime"];
// Rain simulation
if(GVAR(rain_period_count) > GVAR(rain_next_period)) then {

View File

@ -7,6 +7,7 @@
<Russian>Показать информацию о погоде</Russian>
<French>Afficher information du vent</French>
<Spanish>Mostrar información del viento</Spanish>
<Italian>Mostra informazioni sul vento</Italian>
</Key>
</Package>
</Project>

View File

@ -11,6 +11,7 @@
<French>Vent</French>
<German>Windinformationen</German>
<Hungarian>Szélinformáció</Hungarian>
<Italian>Informazioni sul vento</Italian>
</Key>
<Key ID="STR_ACE_WEATHER_METER_WIND_DIRECTION">
<English>Direction: %1</English>
@ -21,6 +22,7 @@
<French>Direction %1</French>
<German>Windrichtung: %1</German>
<Hungarian>Irány: %1</Hungarian>
<Italian>Direzione: %1</Italian>
</Key>
<Key ID="STR_ACE_WEATHER_METER_WIND_SPEED">
<English>Speed: %1 m/s</English>
@ -31,6 +33,7 @@
<French>Vitesse %1 m/s</French>
<German>Geschwindigkeit: %1m/s</German>
<Hungarian>Sebesség: %1 m/s</Hungarian>
<Italian>Velocità: %1 m/s</Italian>
</Key>
<Key ID="STR_ACE_WEATHER_METER_WEATHER_CATEGORY">
<English>Weather Information</English>
@ -41,6 +44,7 @@
<French>Météo</French>
<German>Wetterinformationen</German>
<Hungarian>Időjárás-Információ</Hungarian>
<Italian>Meteo</Italian>
</Key>
<Key ID="STR_ACE_WEATHER_METER_WEATHER_HUMIDITY">
<English>Humidity: %1%</English>
@ -51,6 +55,7 @@
<French>Humidité: %1%</French>
<German>Luftfeuchtigkeit: %1</German>
<Hungarian>Páratartalom: %1%</Hungarian>
<Italian>Umidità: %1%</Italian>
</Key>
</Container>
</Package>

View File

@ -200,7 +200,10 @@ def find_depbo_tools(regKey):
reg = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
try:
k = winreg.OpenKey(reg, r"Software\Mikero\pboProject")
try:
k = winreg.OpenKey(reg, r"Software\Wow6432Node\Mikero\pboProject")
except FileNotFoundError:
k = winreg.OpenKey(reg, r"Software\Mikero\pboProject")
try:
pboproject_path = winreg.QueryValueEx(k, "exe")[0]
winreg.CloseKey(k)
@ -208,7 +211,10 @@ def find_depbo_tools(regKey):
except:
print_error("ERROR: Could not find pboProject.")
k = winreg.OpenKey(reg, r"Software\Mikero\rapify")
try:
k = winreg.OpenKey(reg, r"Software\Wow6432Node\Mikero\rapify")
except FileNotFoundError:
k = winreg.OpenKey(reg, r"Software\Mikero\rapify")
try:
rapify_path = winreg.QueryValueEx(k, "exe")[0]
winreg.CloseKey(k)
@ -216,7 +222,10 @@ def find_depbo_tools(regKey):
except:
print_error("Could not find rapify.")
k = winreg.OpenKey(reg, r"Software\Mikero\MakePbo")
try:
k = winreg.OpenKey(reg, r"Software\Wow6432Node\Mikero\MakePbo")
except FileNotFoundError:
k = winreg.OpenKey(reg, r"Software\Mikero\MakePbo")
try:
makepbo_path = winreg.QueryValueEx(k, "exe")[0]
winreg.CloseKey(k)

View File

@ -1,837 +0,0 @@
#!/usr/bin/env python
# vim: set fileencoding=utf-8 :
# make.py
# An Arma 3 addon build system
###############################################################################
# The MIT License (MIT)
# Copyright (c) 2013-2014 Ryan Schultz
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
###############################################################################
__version__ = "0.3dev"
import sys
if sys.version_info[0] == 2:
print("Python 3 is required.")
sys.exit(1)
import os
import os.path
import shutil
import platform
import glob
import subprocess
import hashlib
import configparser
import json
import traceback
import time
import re
if sys.platform == "win32":
import winreg
###############################################################################
# http://akiscode.com/articles/sha-1directoryhash.shtml
# Copyright (c) 2009 Stephen Akiki
# MIT License (Means you can do whatever you want with this)
# See http://www.opensource.org/licenses/mit-license.php
# Error Codes:
# -1 -> Directory does not exist
# -2 -> General error (see stack traceback)
def get_directory_hash(directory):
directory_hash = hashlib.sha1()
if not os.path.exists (directory):
return -1
try:
for root, dirs, files in os.walk(directory):
for names in files:
path = os.path.join(root, names)
try:
f = open(path, 'rb')
except:
# You can't open the file for some reason
f.close()
continue
while 1:
# Read file in as little chunks
buf = f.read(4096)
if not buf: break
new = hashlib.sha1(buf)
directory_hash.update(new.digest())
f.close()
except:
# Print the stack traceback
traceback.print_exc()
return -2
return directory_hash.hexdigest()
# Copyright (c) André Burgaud
# http://www.burgaud.com/bring-colors-to-the-windows-console-with-python/
if sys.platform == "win32":
from ctypes import windll, Structure, c_short, c_ushort, byref
SHORT = c_short
WORD = c_ushort
class COORD(Structure):
"""struct in wincon.h."""
_fields_ = [
("X", SHORT),
("Y", SHORT)]
class SMALL_RECT(Structure):
"""struct in wincon.h."""
_fields_ = [
("Left", SHORT),
("Top", SHORT),
("Right", SHORT),
("Bottom", SHORT)]
class CONSOLE_SCREEN_BUFFER_INFO(Structure):
"""struct in wincon.h."""
_fields_ = [
("dwSize", COORD),
("dwCursorPosition", COORD),
("wAttributes", WORD),
("srWindow", SMALL_RECT),
("dwMaximumWindowSize", COORD)]
# winbase.h
STD_INPUT_HANDLE = -10
STD_OUTPUT_HANDLE = -11
STD_ERROR_HANDLE = -12
# wincon.h
FOREGROUND_BLACK = 0x0000
FOREGROUND_BLUE = 0x0001
FOREGROUND_GREEN = 0x0002
FOREGROUND_CYAN = 0x0003
FOREGROUND_RED = 0x0004
FOREGROUND_MAGENTA = 0x0005
FOREGROUND_YELLOW = 0x0006
FOREGROUND_GREY = 0x0007
FOREGROUND_INTENSITY = 0x0008 # foreground color is intensified.
BACKGROUND_BLACK = 0x0000
BACKGROUND_BLUE = 0x0010
BACKGROUND_GREEN = 0x0020
BACKGROUND_CYAN = 0x0030
BACKGROUND_RED = 0x0040
BACKGROUND_MAGENTA = 0x0050
BACKGROUND_YELLOW = 0x0060
BACKGROUND_GREY = 0x0070
BACKGROUND_INTENSITY = 0x0080 # background color is intensified.
stdout_handle = windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute
GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo
def get_text_attr():
"""Returns the character attributes (colors) of the console screen
buffer."""
csbi = CONSOLE_SCREEN_BUFFER_INFO()
GetConsoleScreenBufferInfo(stdout_handle, byref(csbi))
return csbi.wAttributes
def set_text_attr(color):
"""Sets the character attributes (colors) of the console screen
buffer. Color is a combination of foreground and background color,
foreground and background intensity."""
SetConsoleTextAttribute(stdout_handle, color)
###############################################################################
def find_bi_tools(work_drive):
"""Find BI tools."""
reg = winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER)
try:
k = winreg.OpenKey(reg, r"Software\bohemia interactive\arma 3 tools")
arma3tools_path = winreg.QueryValueEx(k, "path")[0]
winreg.CloseKey(k)
except:
raise Exception("BadTools","Arma 3 Tools are not installed correctly or the P: drive needs to be created.")
addonbuilder_path = os.path.join(arma3tools_path, "AddonBuilder", "AddonBuilder.exe")
dssignfile_path = os.path.join(arma3tools_path, "DSSignFile", "DSSignFile.exe")
dscreatekey_path = os.path.join(arma3tools_path, "DSSignFile", "DSCreateKey.exe")
cfgconvert_path = os.path.join(arma3tools_path, "CfgConvert", "CfgConvert.exe")
if os.path.isfile(addonbuilder_path) and os.path.isfile(dssignfile_path) and os.path.isfile(dscreatekey_path) and os.path.isfile(cfgconvert_path):
return [addonbuilder_path, dssignfile_path, dscreatekey_path, cfgconvert_path]
else:
raise Exception("BadTools","Arma 3 Tools are not installed correctly or the P: drive needs to be created.")
def find_depbo_tools(regKey):
"""Use registry entries to find DePBO-based tools."""
stop = False
if regKey == "HKCU":
reg = winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER)
stop = True
else:
reg = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
try:
k = winreg.OpenKey(reg, r"Software\Wow6432Node\Mikero\pboProject")
try:
pboproject_path = winreg.QueryValueEx(k, "exe")[0]
winreg.CloseKey(k)
print("Found pboproject.")
except:
print_error("ERROR: Could not find pboProject.")
k = winreg.OpenKey(reg, r"Software\Wow6432Node\Mikero\rapify")
try:
rapify_path = winreg.QueryValueEx(k, "exe")[0]
winreg.CloseKey(k)
print("Found rapify.")
except:
print_error("Could not find rapify.")
k = winreg.OpenKey(reg, r"Software\Wow6432Node\Mikero\MakePbo")
try:
makepbo_path = winreg.QueryValueEx(k, "exe")[0]
winreg.CloseKey(k)
print("Found makepbo.")
except:
print_error("Could not find makepbo.")
except:
if stop == True:
raise Exception("BadDePBO", "DePBO tools not installed correctly")
return -1
#Strip any quotations from the path due to a MikeRo tool bug which leaves a trailing space in some of its registry paths.
return [pboproject_path.strip('"'),rapify_path.strip('"'),makepbo_path.strip('"')]
def color(color):
"""Set the color. Works on Win32 and normal terminals."""
if sys.platform == "win32":
if color == "green":
set_text_attr(FOREGROUND_GREEN | get_text_attr() & 0x0070 | FOREGROUND_INTENSITY)
elif color == "red":
set_text_attr(FOREGROUND_RED | get_text_attr() & 0x0070 | FOREGROUND_INTENSITY)
elif color == "blue":
set_text_attr(FOREGROUND_BLUE | get_text_attr() & 0x0070 | FOREGROUND_INTENSITY)
elif color == "reset":
set_text_attr(FOREGROUND_GREY | get_text_attr() & 0x0070)
elif color == "grey":
set_text_attr(FOREGROUND_GREY | get_text_attr() & 0x0070)
else :
if color == "green":
sys.stdout.write('\033[92m')
elif color == "red":
sys.stdout.write('\033[91m')
elif color == "blue":
sys.stdout.write('\033[94m')
elif color == "reset":
sys.stdout.write('\033[0m')
def print_error(msg):
color("red")
print ("ERROR: " + msg)
color("reset")
def print_green(msg):
color("green")
print(msg)
color("reset")
def print_blue(msg):
color("blue")
print(msg)
color("reset")
def print_yellow(msg):
color("yellow")
print(msg)
color("reset")
###############################################################################
def main(argv):
"""Build an Arma addon suite in a directory from rules in a make.cfg file."""
print_blue(("\nmake.py for Arma, v" + __version__))
if sys.platform != "win32":
print_error("Non-Windows platform (Cygwin?). Please re-run from cmd.")
sys.exit(1)
reg = winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER)
try:
k = winreg.OpenKey(reg, r"Software\bohemia interactive\arma 3 tools")
arma3tools_path = winreg.QueryValueEx(k, "path")[0]
winreg.CloseKey(k)
except:
raise Exception("BadTools","Arma 3 Tools are not installed correctly or the P: drive needs to be created.")
# Default behaviors
test = False # Copy to Arma 3 directory?
arg_modules = False # Only build modules on command line?
make_release = False # Make zip file from the release?
release_version = 0 # Version of release
use_pboproject = True # Default to pboProject build tool
make_target = "DEFAULT" # Which section in make.cfg to use for the build
new_key = False # Make a new key and use it to sign?
quiet = False # Suppress output from build tool?
# Parse arguments
if "help" in argv or "-h" in argv or "--help" in argv:
print ("""
make.py [help] [test] [force] [key <name>] [target <name>] [release <version>]
[module name] [module name] [...]
test -- Copy result to Arma 3.
release <version> -- Make archive with <version>.
force -- Ignore cache and build all.
target <name> -- Use rules in make.cfg under heading [<name>] rather than
default [Make]
key <name> -- Use key in working directory with <name> to sign. If it does not
exist, create key.
quiet -- Suppress command line output from build tool.
If module names are specified, only those modules will be built.
Examples:
make.py force test
Build all modules (ignoring cache) and copy the mod folder to the Arma 3
directory.
make.py mymodule_gun
Only build the module named 'mymodule_gun'.
make.py force key MyNewKey release 1.0
Build all modules (ignoring cache), sign them with NewKey, and pack them
into a zip file for release with version 1.0.
If a file called $NOBIN$ is found in the module directory, that module will not be binarized.
See the make.cfg file for additional build options.
""")
sys.exit(0)
if "force" in argv:
argv.remove("force")
force_build = True
else:
force_build = False
if "test" in argv:
test = True
argv.remove("test")
if "release" in argv:
make_release = True
release_version = argv[argv.index("release") + 1]
argv.remove(release_version)
argv.remove("release")
if "target" in argv:
make_target = argv[argv.index("target") + 1]
argv.remove("target")
argv.remove(make_target)
force_build = True
if "key" in argv:
new_key = True
key_name = argv[argv.index("key") + 1]
argv.remove("key")
argv.remove(key_name)
if "quiet" in argv:
quiet = True
argv.remove("quiet")
# Get the directory the make script is in.
make_root = os.path.dirname(os.path.realpath(__file__))
make_root_parent = os.path.abspath(os.path.join(os.getcwd(), os.pardir))
os.chdir(make_root)
# Get latest commit ID
try:
gitpath = os.path.join(os.path.dirname(make_root), ".git")
assert os.path.exists(gitpath)
commit_id = subprocess.check_output(["git", "rev-parse", "HEAD"])
commit_id = str(commit_id, "utf-8")[:8]
except:
print_error("FAILED TO DETERMINE COMMIT ID.")
commit_id = "NOGIT"
cfg = configparser.ConfigParser();
try:
cfg.read(os.path.join(make_root, "make.cfg"))
# Project name (with @ symbol)
project = cfg.get(make_target, "project", fallback="@"+os.path.basename(os.getcwd()))
# Private key path
key = cfg.get(make_target, "key", fallback=None)
# Project prefix (folder path)
prefix = cfg.get(make_target, "prefix", fallback="")
# Should we autodetect modules on a complete build?
module_autodetect = cfg.getboolean(make_target, "module_autodetect", fallback=True)
# Manual list of modules to build for a complete build
modules = cfg.get(make_target, "modules", fallback=None)
# Parse it out
if modules:
modules = [x.strip() for x in modules.split(',')]
else:
modules = []
# List of directories to ignore when detecting
ignore = [x.strip() for x in cfg.get(make_target, "ignore", fallback="release").split(',')]
# BI Tools work drive on Windows
work_drive = cfg.get(make_target, "work_drive", fallback="P:\\")
# Which build tool should we use?
build_tool = cfg.get(make_target, "build_tool", fallback="addonbuilder").lower()
# Release/build directory, relative to script dir
release_dir = cfg.get(make_target, "release_dir", fallback="release")
# Project PBO file prefix (files are renamed to prefix_name.pbo)
pbo_name_prefix = cfg.get(make_target, "pbo_name_prefix", fallback=None)
# Project module Root
module_root_parent = os.path.abspath(os.path.join(os.path.join(work_drive, prefix), os.pardir))
module_root = cfg.get(make_target, "module_root", fallback=os.path.join(make_root_parent, "addons"))
print_green ("module_root: " + module_root)
if (os.path.isdir(module_root)):
os.chdir(module_root)
else:
print_error ("Directory " + module_root + " does not exist.")
sys.exit()
except:
raise
print_error("Could not parse make.cfg.")
sys.exit(1)
# See if we have been given specific modules to build from command line.
if len(argv) > 1 and not make_release:
arg_modules = True
modules = argv[1:]
# Find the tools we need.
try:
tools = find_bi_tools(work_drive)
addonbuilder = tools[0]
dssignfile = tools[1]
dscreatekey = tools[2]
cfgconvert = tools[3]
except:
print_error("Arma 3 Tools are not installed correctly or the P: drive has not been created.")
sys.exit(1)
if build_tool == "pboproject":
try:
depbo_tools = find_depbo_tools("HKLM")
if depbo_tools == -1:
depbo_tools = find_depbo_tools("HKCU")
pboproject = depbo_tools[0]
rapifyTool = depbo_tools[1]
makepboTool = depbo_tools[2]
except:
raise
print_error("Could not find dePBO tools. Download the needed tools from: https://dev.withsix.com/projects/mikero-pbodll/files")
sys.exit(1)
# Try to open and deserialize build cache file.
try:
cache = {}
with open(os.path.join(make_root, "make.cache"), 'r') as f:
cache_raw = f.read()
cache = json.loads(cache_raw)
except:
print ("No cache found.")
cache = {}
# Get list of subdirs in make root.
dirs = next(os.walk(module_root))[1]
# Autodetect what directories to build.
if module_autodetect and not arg_modules:
modules = []
for path in dirs:
# Any dir that has a config.cpp in its root is an addon to build.
config_path = os.path.join(path, 'config.cpp')
if os.path.isfile(config_path) and not path in ignore:
modules.append(path)
# Make the key specified from command line if necessary.
if new_key:
if not os.path.isfile(os.path.join(module_root, key_name + ".biprivatekey")):
print_green("\nRequested key does not exist.")
ret = subprocess.call([dscreatekey, key_name]) # Created in make_root
if ret == 0:
print_blue("Created: " + os.path.join(module_root, key_name + ".biprivatekey"))
else:
print_error("Failed to create key!")
try:
print_blue("Copying public key to release directory.")
try:
os.makedirs(os.path.join(module_root, release_dir, "Keys"))
except:
pass
shutil.copyfile(os.path.join(module_root, key_name + ".bikey"), os.path.join(module_root, release_dir, "Keys", key_name + ".bikey"))
except:
raise
print_error("Could not copy key to release directory.")
else:
print_green("\nNOTE: Using key " + os.path.join(module_root, key_name + ".biprivatekey"))
key = os.path.join(module_root, key_name + ".biprivatekey")
# For each module, prep files and then build.
for module in modules:
print_green("\nMaking " + module + "-"*max(1, (60-len(module))))
# Cache check
if module in cache:
old_sha = cache[module]
else:
old_sha = ""
#We always build ACE_common so we can properly show the correct version stamp in the RPT file.
if module == "common":
old_sha = ""
# Hash the module
new_sha = get_directory_hash(os.path.join(module_root, module))
# Check if it needs rebuilt
# print ("Hash:", new_sha)
if old_sha == new_sha:
if not force_build:
print("Module has not changed.")
# Skip everything else
continue
# Only do this if the project isn't stored directly on the work drive.
# Split the path at the drive name and see if they are on the same drive (usually P:)
if os.path.splitdrive(module_root)[0] != os.path.splitdrive(work_drive)[0]:
try:
# Remove old work drive version (ignore errors)
shutil.rmtree(os.path.join(work_drive, prefix, module), True)
# Copy module to the work drive
shutil.copytree(module, os.path.join(work_drive, prefix, module))
except:
raise
print_error("ERROR: Could not copy module to work drive. Does the module exist?")
input("Press Enter to continue...")
print("Resuming build...")
continue
#else:
#print("WARNING: Module is stored on work drive (" + work_drive + ").")
try:
# Remove the old pbo, key, and log
old = os.path.join(module_root, release_dir, project, "Addons", module) + "*"
files = glob.glob(old)
for f in files:
os.remove(f)
if pbo_name_prefix:
old = os.path.join(module_root, release_dir, project, "Addons", pbo_name_prefix+module) + "*"
files = glob.glob(old)
for f in files:
os.remove(f)
except:
raise
print_error("ERROR: Could not copy module to work drive. Does the module exist?")
input("Press Enter to continue...")
print("Resuming build...")
continue
# Build the module into a pbo
print_blue("Building: " + os.path.join(work_drive, prefix, module))
print_blue("Destination: " + os.path.join(module_root, release_dir, project, "Addons"))
# Make destination folder (if needed)
try:
os.makedirs(os.path.join(module_root, release_dir, project, "Addons"))
except:
pass
# Run build tool
build_successful = False
if build_tool == "pboproject":
try:
#PABST: Convert config (run the macro'd config.cpp through CfgConvert twice to produce a de-macro'd cpp that pboProject can read without fucking up:
shutil.copyfile(os.path.join(work_drive, prefix, module, "config.cpp"), os.path.join(work_drive, prefix, module, "config.backup"))
os.chdir("P:\\")
cmd = [os.path.join(arma3tools_path, "CfgConvert", "CfgConvert.exe"), "-bin", "-dst", os.path.join(work_drive, prefix, module, "config.bin"), os.path.join(work_drive, prefix, module, "config.cpp")]
ret = subprocess.call(cmd)
if ret != 0:
print_error("CfgConvert -bin return code == " + str(ret) + ". Usually means there is a syntax error within the config.cpp file.")
os.remove(os.path.join(work_drive, prefix, module, "config.cpp"))
shutil.copyfile(os.path.join(work_drive, prefix, module, "config.backup"), os.path.join(work_drive, prefix, module, "config.cpp"))
cmd = [os.path.join(arma3tools_path, "CfgConvert", "CfgConvert.exe"), "-txt", "-dst", os.path.join(work_drive, prefix, module, "config.cpp"), os.path.join(work_drive, prefix, module, "config.bin")]
ret = subprocess.call(cmd)
if ret != 0:
print_error("CfgConvert -txt return code == " + str(ret) + ". Usually means there is a syntax error within the config.cpp file.")
os.remove(os.path.join(work_drive, prefix, module, "config.cpp"))
shutil.copyfile(os.path.join(work_drive, prefix, module, "config.backup"), os.path.join(work_drive, prefix, module, "config.cpp"))
# Include build number
try:
configpath = os.path.join(work_drive, prefix, module, "config.cpp")
f = open(configpath, "r")
configtext = f.read()
f.close()
if configtext:
patchestext = re.search(r"class CfgPatches\n\{(.*?)\n\}", configtext, re.DOTALL).group(1)
patchestext = re.sub(r'version(.*?)="(.*?)"', r'version\1="\2-{}"'.format(commit_id), patchestext)
configtext = re.sub(r"class CfgPatches\n\{(.*?)\n\}", "class CfgPatches\n{"+patchestext+"\n}", configtext, flags=re.DOTALL)
f = open(configpath, "w")
f.write(configtext)
f.close()
else:
os.remove(os.path.join(work_drive, prefix, module, "config.cpp"))
os.rename(os.path.join(work_drive, prefix, module, "config.backup"), os.path.join(work_drive, prefix, module, "config.cpp"))
except:
raise
print_error("Failed to include build number")
continue
if os.path.isfile(os.path.join(work_drive, prefix, module, "$NOBIN$")):
print_green("$NOBIN$ Found. Proceeding with non-binarizing!")
cmd = [makepboTool, "-P","-A","-L","-N","-G", os.path.join(work_drive, prefix, module),os.path.join(module_root, release_dir, project,"Addons")]
else:
cmd = [pboproject, "-P", os.path.join(work_drive, prefix, module), "+Engine=Arma3", "-S","+Noisy", "+X", "+Clean", "+Mod="+os.path.join(module_root, release_dir, project), "-Key"]
color("grey")
if quiet:
devnull = open(os.devnull, 'w')
ret = subprocess.call(cmd, stdout=devnull)
devnull.close()
else:
ret = subprocess.call(cmd)
color("reset")
if ret == 0:
print_green("pboProject return code == " + str(ret))
# Prettyprefix rename the PBO if requested.
if pbo_name_prefix:
try:
os.rename(os.path.join(module_root, release_dir, project, "Addons", module+".pbo"), os.path.join(module_root, release_dir, project, "Addons", pbo_name_prefix+module+".pbo"))
except:
raise
print_error("Could not rename built PBO with prefix.")
# Sign result
if key:
print("Signing with " + key + ".")
if pbo_name_prefix:
ret = subprocess.call([dssignfile, key, os.path.join(module_root, release_dir, project, "Addons", pbo_name_prefix + module + ".pbo")])
else:
ret = subprocess.call([dssignfile, key, os.path.join(module_root, release_dir, project, "Addons", module + ".pbo")])
if ret == 0:
build_successful = True
else:
build_successful = True
if not build_successful:
print_error("pboProject return code == " + str(ret))
print_error("Module not successfully built/signed.")
print ("Resuming build...")
continue
#PABST: cleanup config BS (you could comment this out to see the "de-macroed" cpp
#print_green("\Pabst (restoring): " + os.path.join(work_drive, prefix, module, "config.cpp"))
os.remove(os.path.join(work_drive, prefix, module, "config.cpp"))
os.remove(os.path.join(work_drive, prefix, module, "config.bin"))
os.rename(os.path.join(work_drive, prefix, module, "config.backup"), os.path.join(work_drive, prefix, module, "config.cpp"))
# Back to the root
os.chdir(module_root)
except:
raise
print_error("Could not run Addon Builder.")
input("Press Enter to continue...")
print ("Resuming build...")
continue
elif build_tool== "addonbuilder":
# Detect $NOBIN$ and do not binarize if found.
if os.path.isfile(os.path.join(work_drive, prefix, module, "$NOBIN$")):
do_binarize = False
print("$NOBIN$ file found in module, packing only.")
else:
do_binarize = True
try:
# Call AddonBuilder
os.chdir("P:\\")
cmd = [addonbuilder, os.path.join(work_drive, prefix, module), os.path.join(make_root, release_dir, project, "Addons"), "-clear", "-project="+work_drive]
if not do_binarize:
cmd.append("-packonly")
if quiet:
previousDirectory = os.getcwd()
os.chdir(arma3tools_path)
devnull = open(os.devnull, 'w')
ret = subprocess.call(cmd, stdout=devnull)
devnull.close()
os.chdir(previousDirectory)
else:
previousDirectory = os.getcwd()
os.chdir(arma3tools_path)
print_error("Current directory - " + os.getcwd())
ret = subprocess.call(cmd)
os.chdir(previousDirectory)
print_error("Current directory - " + os.getcwd())
color("reset")
print_green("completed")
# Prettyprefix rename the PBO if requested.
if pbo_name_prefix:
try:
os.rename(os.path.join(make_root, release_dir, project, "Addons", module+".pbo"), os.path.join(make_root, release_dir, project, "Addons", pbo_name_prefix+module+".pbo"))
except:
raise
print_error("Could not rename built PBO with prefix.")
if ret == 0:
# Sign result
if key:
print("Signing with " + key + ".")
if pbo_name_prefix:
ret = subprocess.call([dssignfile, key, os.path.join(make_root, release_dir, project, "Addons", pbo_name_prefix + module + ".pbo")])
else:
ret = subprocess.call([dssignfile, key, os.path.join(make_root, release_dir, project, "Addons", module + ".pbo")])
if ret == 0:
build_successful = True
else:
build_successful = True
if not build_successful:
print_error("Module not successfully built.")
# Back to the root
os.chdir(make_root)
except:
raise
print_error("Could not run Addon Builder.")
input("Press Enter to continue...")
print ("Resuming build...")
continue
else:
print_error("Unknown build_tool " + build_tool + "!")
# Update the hash for a successfully built module
if build_successful:
cache[module] = new_sha
# Done building all modules!
# Write out the cache state
cache_out = json.dumps(cache)
with open(os.path.join(make_root, "make.cache"), 'w') as f:
f.write(cache_out)
# Delete the pboproject temp files if building a release.
if make_release and build_tool == "pboproject":
try:
shutil.rmtree(os.path.join(module_root, release_dir, project, "temp"), True)
except:
print_error("ERROR: Could not delete pboProject temp files.")
print_green("\nDone.")
# Make release
if make_release:
print_blue("\nMaking release: " + project + "-" + release_version + ".zip")
try:
# Delete all log files
for root, dirs, files in os.walk(os.path.join(module_root, release_dir, project, "Addons")):
for currentFile in files:
if currentFile.lower().endswith("log"):
os.remove(os.path.join(root, currentFile))
# Create a zip with the contents of release/ in it
shutil.make_archive(project + "-" + release_version, "zip", os.path.join(module_root, release_dir))
except:
raise
print_error("Could not make release.")
# Copy to Arma 3 folder for testing
if test:
print_blue("\nCopying to Arma 3.")
if sys.platform == "win32":
reg = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
try:
k = winreg.OpenKey(reg, r"SOFTWARE\Wow6432Node\Bohemia Interactive\Arma 3")
a3_path = winreg.EnumValue(k, 1)[1]
winreg.CloseKey(k)
except:
print_error("Could not find Arma 3's directory in the registry.")
else:
a3_path = cygwin_a3path
if os.path.exists(a3_path):
try:
shutil.rmtree(os.path.join(a3_path, project), True)
shutil.copytree(os.path.join(module_root, release_dir, project), os.path.join(a3_path, project))
except:
print_error("Could not copy files. Is Arma 3 running?")
if __name__ == "__main__":
main(sys.argv)
input("Press Enter to continue...")