Merge branch 'master' into hearing-use-slotitemevent

This commit is contained in:
johnb432
2024-06-05 22:28:56 +02:00
129 changed files with 3146 additions and 1776 deletions

View File

@ -382,6 +382,9 @@ switch (GVAR(currentLeftPanel)) do {
};
GVAR(currentItems) set [IDX_CURR_VEST, _item];
[GVAR(center), ""] call BIS_fnc_setUnitInsignia;
[GVAR(center), GVAR(currentInsignia)] call BIS_fnc_setUnitInsignia;
};
TOGGLE_RIGHT_PANEL_CONTAINER
@ -420,6 +423,9 @@ switch (GVAR(currentLeftPanel)) do {
};
GVAR(currentItems) set [IDX_CURR_BACKPACK, _item];
[GVAR(center), ""] call BIS_fnc_setUnitInsignia;
[GVAR(center), GVAR(currentInsignia)] call BIS_fnc_setUnitInsignia;
};
TOGGLE_RIGHT_PANEL_CONTAINER

View File

@ -15,7 +15,5 @@ private _categoryName = [format ["ACE %1", localize "str_a3_cfgmarkers_nato_art"
[LSTRING(disableArtilleryComputer_displayName), LSTRING(disableArtilleryComputer_description)],
_categoryName,
false, // default value
true, // isGlobal
{[QGVAR(disableArtilleryComputer), _this] call EFUNC(common,cbaSettings_settingChanged)},
false // Needs mission restart
true // isGlobal
] call CBA_fnc_addSetting;

View File

@ -6,8 +6,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)];
[LSTRING(ModuleSettings_enable), LSTRING(ModuleSettings_enable_Description)],
_category,
true,
1,
{[QGVAR(enable), _this] call EFUNC(common,cbaSettings_settingChanged)}
1
] call CBA_fnc_addSetting;
[
@ -16,8 +15,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)];
[LSTRING(loadTimeCoefficient), LSTRING(loadTimeCoefficient_description)],
_category,
[0, 10, 5, 1],
1,
{[QGVAR(loadTimeCoefficient), _this, true] call EFUNC(common,cbaSettings_settingChanged)}
1
] call CBA_fnc_addSetting;
[
@ -26,8 +24,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)];
[LSTRING(paradropTimeCoefficent), LSTRING(paradropTimeCoefficent_description)],
_category,
[0, 10, 2.5, 1],
1,
{[QGVAR(paradropTimeCoefficent), _this, true] call EFUNC(common,cbaSettings_settingChanged)}
1
] call CBA_fnc_addSetting;
[
@ -35,9 +32,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)];
"LIST",
[LSTRING(openAfterUnload), LSTRING(openAfterUnload_description)],
_category,
[[0, 1, 2, 3], [ELSTRING(common,never), LSTRING(unloadObject), LSTRING(paradropButton), ELSTRING(common,both)], 0],
0,
{[QGVAR(openAfterUnload), _this, true] call EFUNC(common,cbaSettings_settingChanged)}
[[0, 1, 2, 3], [ELSTRING(common,never), LSTRING(unloadObject), LSTRING(paradropButton), ELSTRING(common,both)], 0]
] call CBA_fnc_addSetting;
[
@ -45,9 +40,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)];
"CHECKBOX",
[LSTRING(carryAfterUnload), LSTRING(carryAfterUnload_description)],
_category,
true,
0,
{[QGVAR(carryAfterUnload), _this] call EFUNC(common,cbaSettings_settingChanged)}
true
] call CBA_fnc_addSetting;
[
@ -56,8 +49,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)];
[LSTRING(enableDeploy), LSTRING(enableDeploy_description)],
_category,
true,
1,
{[QGVAR(enableDeploy), _this] call EFUNC(common,cbaSettings_settingChanged)}
1
] call CBA_fnc_addSetting;
[
@ -65,7 +57,5 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)];
"CHECKBOX",
[LSTRING(ModuleSettings_enableRename), LSTRING(ModuleSettings_enableRename_Description)],
_category,
true,
0,
{[QGVAR(enableRename), _this, true] call EFUNC(common,cbaSettings_settingChanged)}
true
] call CBA_fnc_addSetting;

View File

@ -161,6 +161,7 @@ PREP(sendRequest);
PREP(serverLog);
PREP(setAimCoef);
PREP(setApproximateVariablePublic);
PREP(setDead);
PREP(setDefinedVariable);
PREP(setDisableUserInputStatus);
PREP(setHearingCapability);

View File

@ -191,6 +191,7 @@ if (isServer) then {
[QGVAR(switchMove), {(_this select 0) switchMove (_this select 1)}] call CBA_fnc_addEventHandler;
[QGVAR(setVectorDirAndUp), {(_this select 0) setVectorDirAndUp (_this select 1)}] call CBA_fnc_addEventHandler;
[QGVAR(addWeaponItem), {(_this select 0) addWeaponItem [(_this select 1), (_this select 2)]}] call CBA_fnc_addEventHandler;
[QGVAR(removeMagazinesTurret), {(_this select 0) removeMagazinesTurret [_this select 1, _this select 2]}] call CBA_fnc_addEventHandler;
[QGVAR(setVanillaHitPointDamage), {
params ["_object", "_hitPointAnddamage"];
@ -222,6 +223,9 @@ if (isServer) then {
[QGVAR(claimSafe), LINKFUNC(claimSafeServer)] call CBA_fnc_addEventHandler;
};
["CBA_SettingChanged", {
["ace_settingChanged", _this] call CBA_fnc_localEvent;
}] call CBA_fnc_addEventHandler;
//////////////////////////////////////////////////
// Set up remote execution

View File

@ -2,22 +2,33 @@
/*
* Author: commy2, johnb43
* Adds weapon to unit without taking a magazine.
* Same as CBA_fnc_addWeaponWithoutItems, but doesn't remove linked items.
* Same as CBA_fnc_addWeaponWithoutItems, but doesn't remove linked items by default.
*
* Arguments:
* 0: Unit to add the weapon to <OBEJCT>
* 0: Unit to add the weapon to <OBJECT>
* 1: Weapon to add <STRING>
* 2: If linked items should be removed or not <BOOL> (default: false)
* 3: Magazines that should be added to the weapon <ARRAY> (default: [])
* - 0: Magazine classname <STRING>
* - 1: Ammo count <NUMBER>
*
* Return Value:
* None
*
* Example:
* [player, "arifle_AK12_F"] call ace_common_fnc_addWeapon
* [player, "arifle_MX_GL_F", true, [["30Rnd_65x39_caseless_mag", 30], ["1Rnd_HE_Grenade_shell", 1]]] call ace_common_fnc_addWeapon
*
* Public: Yes
*/
params ["_unit", "_weapon"];
params [
["_unit", objNull, [objNull]],
["_weapon", "", [""]],
["_removeLinkedItems", false, [false]],
["_magazines", [], [[]]]
];
if (isNull _unit || {_weapon == ""}) exitWith {};
// Config case
private _compatibleMagazines = compatibleMagazines _weapon;
@ -45,6 +56,35 @@ private _backpackMagazines = (magazinesAmmoCargo _backpack) select {
// Add weapon
_unit addWeapon _weapon;
// This doesn't remove magazines, but linked items can't be magazines, so it's fine
if (_removeLinkedItems) then {
switch (_weapon call FUNC(getConfigName)) do {
case (primaryWeapon _unit): {
removeAllPrimaryWeaponItems _unit;
};
case (secondaryWeapon _unit): {
removeAllSecondaryWeaponItems _unit;
};
case (handgunWeapon _unit): {
removeAllHandgunItems _unit;
};
case (binocular _unit): {
removeAllBinocularItems _unit;
};
};
};
// Add magazines directly now, so that AI don't reload
if (_magazines isNotEqualTo []) then {
{
_x params [["_magazine", "", [""]], ["_ammoCount", -1, [0]]];
if (_magazine != "" && {_ammoCount > -1}) then {
_unit addWeaponItem [_weapon, [_magazine, _ammoCount], true];
};
} forEach _magazines;
};
// Add all magazines back
{
_uniform addMagazineAmmoCargo [_x select 0, 1, _x select 1];

View File

@ -1,8 +1,8 @@
#include "..\script_component.hpp"
/*
* Author: PabstMirror
* Function for handeling a cba setting being changed.
* Adds warning if global setting is changed after ace_settingsInitialized
* Function for handling a cba setting being changed.
* Adds warning if global setting is changed after ace_settingsInitialized.
*
* Arguments:
* 0: Setting Name <STRING>
@ -21,9 +21,7 @@
params ["_settingName", "_newValue", ["_canBeChanged", false]];
TRACE_2("",_settingName,_newValue);
["ace_settingChanged", [_settingName, _newValue]] call CBA_fnc_localEvent;
if (!((toLower _settingName) in CBA_settings_needRestart)) exitWith {};
if !((toLower _settingName) in CBA_settings_needRestart) exitWith {};
if (_canBeChanged) exitWith {WARNING_1("update cba setting [%1] to use correct Need Restart param",_settingName);};
if (!GVAR(settingsInitFinished)) exitWith {}; // Ignore changed event before CBA_settingsInitialized

View File

@ -143,11 +143,7 @@ if (_state) then {
_ctrl ctrlSetEventHandler ["ButtonClick", toString {
closeDialog 0;
if (["ace_medical"] call FUNC(isModLoaded)) then {
[player, "respawn_button"] call EFUNC(medical_status,setDead);
} else {
player setDamage 1;
};
[player, "respawn_button"] call FUNC(setDead);
[false] call FUNC(disableUserInput);
}];

View File

@ -0,0 +1,44 @@
#include "..\script_component.hpp"
/*
* Author: johnb43
* Kills a unit without changing visual appearance.
*
* Arguments:
* 0: Unit <ARRAY>
* 1: Reason for death (only used if ace_medical is loaded) <STRING> (default: "")
* 2: Killer (vehicle that killed unit) <ARRAY> (default: objNull)
* 3: Instigator (unit who pulled trigger) <ARRAY> (default: objNull)
*
* Return Value:
* None
*
* Example:
* [cursorObject, "", player, player] call ace_common_fnc_setDead;
*
* Public: Yes
*/
params [["_unit", objNull, [objNull]], ["_reason", "", [""]], ["_source", objNull, [objNull]], ["_instigator", objNull, [objNull]]];
if (!local _unit) exitWith {
WARNING_1("setDead executed on non-local unit - %1",_this);
};
if (["ace_medical"] call EFUNC(common,isModLoaded)) then {
[_unit, _reason, _source, _instigator] call EFUNC(medical_status,setDead);
} else {
// From 'ace_medical_status_fnc_setDead': Kill the unit without changing visual appearance
// (#8803) Reenable damage if disabled to prevent having live units in dead state
// Keep this after death event for compatibility with third party hooks
if (!isDamageAllowed _unit) then {
WARNING_1("setDead executed on unit with damage blocked - %1",_this);
_unit allowDamage true;
};
private _currentDamage = _unit getHitPointDamage "HitHead";
_unit setHitPointDamage ["HitHead", 1, true, _source, _instigator];
_unit setHitPointDamage ["HitHead", _currentDamage, true, _source, _instigator];
};

View File

@ -32,6 +32,16 @@ class Extended_InitPost_EventHandlers {
init = QUOTE((_this select 0) setMass 1e-12);
};
};
class Land_vn_canisterfuel_f {
class ADDON {
init = QUOTE(call (missionNamespace getVariable [ARR_2(QQEFUNC(refuel,makeJerryCan),{})]));
};
};
class Land_vn_fuelcan {
class ADDON {
init = QUOTE(call (missionNamespace getVariable [ARR_2(QQEFUNC(refuel,makeJerryCan),{})]));
};
};
class vn_bicycle_base {
class ADDON {
init = QUOTE(call FUNC(disableCookoff));

View File

@ -1,18 +1,19 @@
#define XEH_INHERITED class EventHandlers {class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {};}
// fuel pumps
class Land_vn_commercial_base;
class Land_vn_fuelstation_01_pump_f: Land_vn_commercial_base {
transportFuel = 0;
XEH_INHERITED;
EGVAR(refuel,hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}};
EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL;
};
class Land_vn_fuelstation_02_pump_f: Land_vn_commercial_base {
transportFuel = 0;
XEH_INHERITED;
EGVAR(refuel,hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}};
EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL;
};
class Land_vn_fuelstation_feed_f: Land_vn_commercial_base {
transportFuel = 0;
XEH_INHERITED;
EGVAR(refuel,hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}};
EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL;
};
@ -20,13 +21,47 @@ class Land_vn_fuelstation_feed_f: Land_vn_commercial_base {
// fuel objects
class Land_vn_building_b_base;
class Land_vn_usaf_fueltank_75_01: Land_vn_building_b_base {
transportFuel = 0;
EGVAR(refuel,hooks)[] = {{0, -0.4, -0.5}};
XEH_INHERITED;
EGVAR(refuel,hooks)[] = {{-2.52, -2.2, -2.05}, {2.5, 0, -1.3}};
EGVAR(refuel,fuelCargo) = 2840; // 750 * 3.785
};
class Land_vn_b_prop_fuelbladder_01: Land_vn_usaf_fueltank_75_01 {
EGVAR(refuel,hooks)[] = {{-1.75, -6.7, -1}};
EGVAR(refuel,fuelCargo) = 3785; // 1000 * 3.785
};
class Land_vn_b_prop_fuelbladder_03: Land_vn_b_prop_fuelbladder_01 {
EGVAR(refuel,hooks)[] = {{-1.55, -6.5, -1}};
};
class Land_vn_building_industrial_base;
class Land_vn_fuel_tank_stairs: Land_vn_building_industrial_base {
XEH_INHERITED;
EGVAR(refuel,hooks)[] = {{0, 0.4, -1.3}, {0, -0.4, -1.3}};
EGVAR(refuel,fuelCargo) = 10000; // reference is B_Slingload_01_Fuel_F
};
class Land_vn_object_b_base;
class Land_vn_b_prop_fueldrum_01: Land_vn_object_b_base {
transportFuel = 0;
EGVAR(refuel,hooks)[] = {{0, 0, 0.5}}; // reference is Land_FlexibleTank_01_F
XEH_INHERITED;
EGVAR(refuel,hooks)[] = {{0, 0, 0}};
EGVAR(refuel,fuelCargo) = 300; // reference is Land_FlexibleTank_01_F
};
class Land_vn_b_prop_fueldrum_02: Land_vn_b_prop_fueldrum_01 {
EGVAR(refuel,hooks)[] = {{0, -1.3, -0.15}, {2.3, 1.25, -0.15}};
EGVAR(refuel,fuelCargo) = 14100; // (23 + 24) * 300
};
class vn_b_ammobox_supply_07;
class vn_b_ammobox_supply_09: vn_b_ammobox_supply_07 { // just a pallet
XEH_INHERITED;
};
class vn_object_c_base_02;
class Land_vn_canisterfuel_f: vn_object_c_base_02 {
EGVAR(cargo,size) = 1;
EGVAR(cargo,canLoad) = 1;
EGVAR(cargo,noRename) = 1;
};
class Land_vn_object_c_base;
class Land_vn_fuelcan: Land_vn_object_c_base {
XEH_INHERITED;
EGVAR(cargo,size) = 1;
EGVAR(cargo,canLoad) = 1;
EGVAR(cargo,noRename) = 1;
};

View File

@ -1,5 +1,4 @@
#include "script_component.hpp"
// ToDo: move refuel to subconfig
#include "\z\ace\addons\refuel\defines.hpp"
#include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp"
@ -47,6 +46,8 @@ class CfgPatches {
};
};
class CBA_Extended_EventHandlers;
#include "ACE_CSW_Groups.hpp"
#include "ACE_Medical_Injuries.hpp"
#include "ACE_Triggers.hpp"

View File

@ -1,13 +1,11 @@
class CfgVehicles {
class SPE_Halftrack_base;
class SPE_US_M3_Halftrack_Fuel: SPE_Halftrack_base {
transportFuel = 0;
EGVAR(refuel,hooks)[] = {{-0.23,-2.58,-0.59}};
EGVAR(refuel,fuelCargo) = 2000;
};
class SPE_OpelBlitz_base;
class SPE_OpelBlitz_Fuel: SPE_OpelBlitz_base {
transportFuel = 0;
EGVAR(refuel,hooks)[] = {{-0.23,-2.58,-0.59}};
EGVAR(refuel,fuelCargo) = 2000;
};

View File

@ -37,6 +37,11 @@ class CfgWeapons {
ACE_twistDirection = 1;
};
class arifle_SLR_V_lxWS;
class arifle_SLR_Para_lxWS: arifle_SLR_V_lxWS {
ACE_barrelLength = 266.7;
};
// Velko R4/R5
class arifle_Velko_base_lxWS: arifle_Galat_base_lxWS {
ACE_barrelLength = 460;

View File

@ -0,0 +1,75 @@
class optic_Arco;
class optic_arco_hex_lxWS: optic_Arco {
displayName = SUBCSTRING(arco_hex_Name);
};
class optic_Holosight;
class optic_Holosight_snake_lxWS: optic_Holosight {
displayName = SUBCSTRING(holosight_snake_Name);
};
class optic_Holosight_smg;
class optic_Holosight_smg_snake_lxWS: optic_Holosight_smg {
displayName = SUBCSTRING(holosight_snake_smg_Name);
};
class optic_Hamr;
class optic_Hamr_arid_lxWS: optic_Hamr {
displayName = SUBCSTRING(hamr_arid_Name);
};
class optic_Hamr_lush_lxWS: optic_Hamr {
displayName = SUBCSTRING(hamr_lush_Name);
};
class optic_Hamr_sand_lxWS: optic_Hamr {
displayName = SUBCSTRING(hamr_sand_Name);
};
class optic_Hamr_snake_lxWS: optic_Hamr {
displayName = SUBCSTRING(hamr_snake_Name);
};
class ItemCore;
class optic_r1_high_lxWS: ItemCore {
displayName = SUBCSTRING(r1_high_black_Name);
};
class optic_r1_high_khaki_lxWS: optic_r1_high_lxWS {
displayName = SUBCSTRING(r1_high_khaki_Name);
};
class optic_r1_high_sand_lxWS: optic_r1_high_lxWS {
displayName = SUBCSTRING(r1_high_sand_Name);
};
class optic_r1_high_snake_lxWS: optic_r1_high_lxWS {
displayName = SUBCSTRING(r1_high_snake_Name);
};
class optic_r1_high_arid_lxWS: optic_r1_high_lxWS {
displayName = SUBCSTRING(r1_high_arid_Name);
};
class optic_r1_high_lush_lxWS: optic_r1_high_lxWS {
displayName = SUBCSTRING(r1_high_lush_Name);
};
class optic_r1_high_black_sand_lxWS: optic_r1_high_lxWS {
displayName = SUBCSTRING(r1_high_black_sand_Name);
};
class optic_r1_low_lxWS: optic_r1_high_lxWS {
displayName = SUBCSTRING(r1_low_black_Name);
};
class optic_r1_low_khaki_lxWS: optic_r1_high_lxWS {
displayName = SUBCSTRING(r1_low_khaki_Name);
};
class optic_r1_low_sand_lxWS: optic_r1_high_lxWS {
displayName = SUBCSTRING(r1_low_sand_Name);
};
class optic_r1_low_snake_lxWS: optic_r1_high_lxWS {
displayName = SUBCSTRING(r1_low_snake_Name);
};
class optic_r1_low_arid_lxWS: optic_r1_high_lxWS {
displayName = SUBCSTRING(r1_low_arid_Name);
};
class optic_r1_low_lush_lxWS: optic_r1_high_lxWS {
displayName = SUBCSTRING(r1_low_lush_Name);
};
class optic_DMS;
class optic_DMS_snake_lxWS: optic_DMS {
displayName = SUBCSTRING(dms_snake_Name);
};

View File

@ -0,0 +1,60 @@
class CfgVehicles {
class APC_Wheeled_01_base_F;
class APC_Wheeled_01_atgm_base_lxWS: APC_Wheeled_01_base_F {
displayName = SUBCSTRING(apc_wheeled_01_atgm_Name);
};
class APC_Wheeled_01_command_base_lxWS: APC_Wheeled_01_base_F {
displayName = SUBCSTRING(apc_wheeled_01_command_Name);
};
class APC_Wheeled_01_mortar_base_lxWS: APC_Wheeled_01_base_F {
displayName = SUBCSTRING(apc_wheeled_01_mortar_Name);
};
class Truck_02_base_F;
class Truck_02_aa_base_lxWS: Truck_02_base_F {
displayName = SUBCSTRING(truck_02_aa_Name);
};
class Truck_02_cargo_base_lxWS: Truck_02_base_F {
displayName = SUBCSTRING(truck_02_cargo_Name);
};
class Truck_02_box_base_lxWS: Truck_02_base_F {
displayName = SUBCSTRING(truck_02_repair_Name);
};
class C_Truck_02_racing_lxWS: Truck_02_box_base_lxWS {
displayName = SUBCSTRING(truck_02_racing_Name);
};
class Truck_02_Ammo_base_lxWS: Truck_02_base_F {
displayName = SUBCSTRING(truck_02_ammo_Name);
};
class Truck_02_flatbed_base_lxWS: Truck_02_cargo_base_lxWS {
displayName = SUBCSTRING(truck_02_flatbed_Name);
};
class Heli_Transport_02_base_F;
class B_UN_Heli_Transport_02_lxWS: Heli_Transport_02_base_F {
displayName = SUBCSTRING(heli_transport_02_Name);
};
class O_APC_Tracked_02_cannon_F;
class O_APC_Tracked_02_30mm_lxWS: O_APC_Tracked_02_cannon_F {
displayName = SUBCSTRING(apc_tracked_02_Name);
};
class APC_Wheeled_02_base_v2_F;
class APC_Wheeled_02_hmg_base_lxws: APC_Wheeled_02_base_v2_F {
displayName = SUBCSTRING(apc_wheeled_02_hmg_Name);
};
class APC_Wheeled_02_unarmed_base_lxws: APC_Wheeled_02_base_v2_F {
displayName = SUBCSTRING(apc_wheeled_02_unarmed_Name);
};
class O_Heli_Light_02_dynamicLoadout_F;
class B_ION_Heli_Light_02_dynamicLoadout_lxWS: O_Heli_Light_02_dynamicLoadout_F {
displayName = SUBCSTRING(heli_light_02_armed_Name);
};
class O_Heli_Light_02_unarmed_F;
class B_ION_Heli_Light_02_unarmed_lxWS: O_Heli_Light_02_unarmed_F {
displayName = SUBCSTRING(heli_light_02_unarmed_Name);
};
};

View File

@ -1,4 +1,6 @@
class CfgWeapons {
#include "Attachments.hpp"
// AA12
class sgun_aa40_base_lxWS;
class sgun_aa40_lxWS: sgun_aa40_base_lxWS {
@ -99,6 +101,12 @@ class CfgWeapons {
class arifle_SLR_V_camo_lxWS: arifle_SLR_V_lxWS {
displayName = SUBCSTRING(SLR_Camo_Name);
};
class arifle_SLR_Para_lxWS: arifle_SLR_V_lxWS {
displayName = SUBCSTRING(SLR_Para_Name);
};
class arifle_SLR_Para_snake_lxWS: arifle_SLR_Para_lxWS {
displayName = SUBCSTRING(SLR_Para_Snake_Name);
};
// Vektor R4/R5
class arifle_Velko_base_lxWS;
@ -156,4 +164,16 @@ class CfgWeapons {
class arifle_XMS_M_Sand_lxWS: arifle_XMS_M_lxWS {
displayName = SUBCSTRING(XMS_SW_Sand_Name);
};
// GM6 Lynx
class srifle_GM6_F;
class srifle_GM6_snake_lxWS: srifle_GM6_F {
displayName = SUBCSTRING(gm6_snake_Name);
};
// RPG-32
class launch_RPG32_F;
class launch_RPG32_tan_lxWS: launch_RPG32_F {
displayName = SUBCSTRING(rpg32_tan_Name);
};
};

View File

@ -19,3 +19,4 @@ class CfgPatches {
};
#include "CfgWeapons.hpp"
#include "CfgVehicles.hpp"

View File

@ -256,6 +256,12 @@
<French>FN FAL 50.00 (Jungle)</French>
<Spanish>FN FAL 50.00 (Jungla)</Spanish>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_SLR_Para_Name">
<English>FN FAL 50.00 Para</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_SLR_Para_Snake_Name">
<English>FN FAL 50.00 Para (Snake)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_Velko_R4_Name">
<English>Vektor R4</English>
<Korean>벡터 R4</Korean>
@ -448,5 +454,119 @@
<Korean>XMS SW (모래)</Korean>
<Japanese>XMS SW (サンド)</Japanese>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_gm6_snake_Name">
<English>GM6 Lynx (Snake)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_rpg32_tan_Name">
<English>RPG-32 (Sand)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_arco_hex_Name">
<English>ELCAN SpecterOS (Hex)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_holosight_snake_Name">
<English>EOTech XPS3 (Snake)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_holosight_snake_smg_Name">
<English>EOTech XPS3 SMG (Snake)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_hamr_arid_Name">
<English>Leupold Mark 4 HAMR (Arid)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_hamr_lush_Name">
<English>Leupold Mark 4 HAMR (Lush)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_hamr_sand_Name">
<English>Leupold Mark 4 HAMR (Sand)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_hamr_snake_Name">
<English>Leupold Mark 4 HAMR (Snake)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_r1_high_black_Name">
<English>Aimpoint Micro R-1 (High, Black)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_r1_high_khaki_Name">
<English>Aimpoint Micro R-1 (High, Khaki)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_r1_high_sand_Name">
<English>Aimpoint Micro R-1 (High, Sand)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_r1_high_snake_Name">
<English>Aimpoint Micro R-1 (High, Snake)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_r1_high_arid_Name">
<English>Aimpoint Micro R-1 (High, Arid)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_r1_high_lush_Name">
<English>Aimpoint Micro R-1 (High, Lush)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_r1_high_black_sand_Name">
<English>Aimpoint Micro R-1 (High, Black/Sand)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_r1_low_black_Name">
<English>Aimpoint Micro R-1 (Low, Black)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_r1_low_khaki_Name">
<English>Aimpoint Micro R-1 (Low, Khaki)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_r1_low_sand_Name">
<English>Aimpoint Micro R-1 (Low, Sand)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_r1_low_snake_Name">
<English>Aimpoint Micro R-1 (Low, Snake)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_r1_low_arid_Name">
<English>Aimpoint Micro R-1 (Low, Arid)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_r1_low_lush_Name">
<English>Aimpoint Micro R-1 (Low, Lush)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_dms_snake_Name">
<English>Burris XTR II (Snake)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_apc_wheeled_01_atgm_Name">
<English>Badger IFV (ATGM)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_apc_wheeled_01_command_Name">
<English>Badger IFV (Command)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_apc_wheeled_01_mortar_Name">
<English>Badger IFV (Mortar)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_truck_02_aa_Name">
<English>KamAZ (Zu-23-2)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_truck_02_cargo_Name">
<English>KamAZ Cargo</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_truck_02_repair_Name">
<English>KamAZ Repair</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_truck_02_racing_Name">
<English>KamAZ Racing</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_truck_02_ammo_Name">
<English>KamAZ Ammo</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_truck_02_flatbed_Name">
<English>KamAZ Flatbed</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_heli_transport_02_Name">
<English>AW101 Merlin</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_apc_tracked_02_Name">
<English>BM-2T Stalker (Bumerang-BM)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_apc_wheeled_02_hmg_Name">
<English>Otokar ARMA (HMG)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_apc_wheeled_02_unarmed_Name">
<English>Otokar ARMA (Unarmed)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_heli_light_02_armed_Name">
<English>Ka-60 Kasatka (UP)</English>
</Key>
<Key ID="STR_ACE_Compat_WS_RealisticNames_heli_light_02_unarmed_Name">
<English>Ka-60 Kasatka (UP, Unarmed)</English>
</Key>
</Package>
</Project>

View File

@ -1,12 +1,8 @@
class ACE_Settings {
class GVAR(enable) {
movedToSqf = 1;
};
class GVAR(enableAmmobox) {
movedToSQF = 1;
};
class GVAR(enableAmmoCookoff) { // For CBA Setting Switch: we can eliminate and just use (ammoCookoffDuration == 0)
class GVAR(enableAmmoCookoff) {
movedToSQF = 1;
};
class GVAR(ammoCookoffDuration) {

View File

@ -1,4 +1,3 @@
class CfgCloudlets {
class GVAR(CookOff) {
interval = 0.004;

View File

@ -1,28 +1,27 @@
class Cfg3DEN {
class Object {
class AttributeCategories {
class ace_attributes {
class Attributes {
class GVAR(enable) {
property = QGVAR(enable);
class GVAR(enable) { // setting was previously GVAR(enable), so maintain for backwards compatiblity with missions
property = QGVAR(enable); // same as above
control = "Checkbox";
displayName = CSTRING(enable_hd_name);
tooltip = CSTRING(enable_hd_tooltip);
expression = QUOTE(if !(_value) then {_this setVariable [ARR_3('%s',_value,true)];};);
displayName = CSTRING(enableFire_name);
tooltip = CSTRING(enableFire_tooltip);
expression = QUOTE(if (!_value) then {_this setVariable [ARR_3('%s',_value,true)]});
typeName = "BOOL";
condition = "objectVehicle";
defaultValue = QUOTE((GETMVAR(QGVAR(enable),0)) in [ARR_2(1,2)]);
defaultValue = QUOTE(GETMVAR(QGVAR(enableFire),true));
};
class GVAR(enableAmmoCookoff) {
property = QGVAR(enableAmmoCookoff);
control = "Checkbox";
displayName = CSTRING(enableAmmoCookoff_name);
tooltip = CSTRING(enableAmmoCookoff_tooltip);
expression = QUOTE(if !(_value) then {_this setVariable [ARR_3('%s',_value,true)];};);
expression = QUOTE(if (!_value) then {_this setVariable [ARR_3('%s',_value,true)]});
typeName = "BOOL";
condition = "objectHasInventoryCargo";
defaultValue = QUOTE(if (_this isKindOf 'ReammoBox_F') then { GETMVAR(QGVAR(enableAmmobox),true) } else { GETMVAR(QGVAR(enableAmmoCookoff),true) };);
defaultValue = QUOTE(if (_this isKindOf 'ReammoBox_F') then {GETMVAR(QGVAR(enableAmmobox),true)} else {GETMVAR(QGVAR(enableAmmoCookoff),true)});
};
};
};

View File

@ -1,4 +1,3 @@
class Extended_PreStart_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_SCRIPT(XEH_preStart));

View File

@ -1,4 +1,3 @@
class CfgSFX {
class GVAR(CookOff_low) {
name = QGVAR(cookoff_low);

View File

@ -1,4 +1,3 @@
class CfgVehicles {
class Sound;
class GVAR(Sound_low): Sound {
@ -7,7 +6,6 @@ class CfgVehicles {
scope = 1;
sound = QGVAR(CookOff_low);
};
class GVAR(Sound_mid): GVAR(Sound_low) {
sound = QGVAR(CookOff_mid);
};
@ -17,47 +15,14 @@ class CfgVehicles {
class Tank;
class Tank_F: Tank {
GVAR(ammoLocation) = "HitHull";
GVAR(cookoffSelections)[] = {"poklop_gunner","poklop_commander"};
GVAR(probability) = 0.5;
};
class MBT_02_base_F: Tank_F {
GVAR(ammoLocation) = "HitTurret";
};
class Car_F;
class Wheeled_APC_F: Car_F {
GVAR(ammoLocation) = "HitHull";
GVAR(cookoffSelections)[] = {"poklop_gunner","poklop_commander"};
GVAR(probability) = 0.8;
// big explosions for wheeled APCs (same as for tanks)
// Big explosions for wheeled APCs (same as for tanks)
explosionEffect = "FuelExplosionBig";
};
class MRAP_01_base_F: Car_F {
GVAR(engineSmokeOffset)[] = {0,-2,0};
};
class MRAP_02_base_F: Car_F {
GVAR(engineSmokeOffset)[] = {0,-2,0};
};
class MRAP_03_base_F: Car_F {
GVAR(engineSmokeOffset)[] = {0,-2,0};
};
class Quadbike_01_base_F: Car_F {
GVAR(engineSmokeOffset)[] = {0,1,0};
};
class Truck_F;
class Truck_02_base_F: Truck_F {
GVAR(engineSmokeOffset)[] = {0,-2.6,-0.1};
};
class Truck_02_MRL_base_F: Truck_02_base_F {
GVAR(engineSmokeOffset)[] = {0,0.3,-0.1};
};
};

View File

@ -1,10 +1,12 @@
PREP(handleDamageBox);
PREP(engineFire);
PREP(cookOff);
PREP(smoke);
PREP(cookOffEffect);
PREP(cookOffBox);
PREP(detonateAmmunition);
PREP(cookOffBoxLocal);
PREP(cookOffBoxServer);
PREP(cookOffLocal);
PREP(cookOffServer);
PREP(detonateAmmunitionServer);
PREP(detonateAmmunitionServerLoop);
PREP(engineFireLocal);
PREP(engineFireServer);
PREP(getVehicleAmmo);
PREP(handleDamageBox);
PREP(isMagazineFlare);
PREP(smoke);

View File

@ -1,63 +1,64 @@
#include "script_component.hpp"
[QGVAR(engineFire), LINKFUNC(engineFire)] call CBA_fnc_addEventHandler;
[QGVAR(cookOff), {
params ["_vehicle"];
if (local _vehicle) then {
_this call FUNC(cookOff);
};
}] call CBA_fnc_addEventHandler;
[QGVAR(cookOffEffect), LINKFUNC(cookOffEffect)] call CBA_fnc_addEventHandler;
[QGVAR(cookOffBoxLocal), LINKFUNC(cookOffBoxLocal)] call CBA_fnc_addEventHandler;
[QGVAR(cookOffLocal), LINKFUNC(cookOffLocal)] call CBA_fnc_addEventHandler;
[QGVAR(engineFireLocal), LINKFUNC(engineFireLocal)] call CBA_fnc_addEventHandler;
[QGVAR(smoke), LINKFUNC(smoke)] call CBA_fnc_addEventHandler;
[QGVAR(cookOffBox), LINKFUNC(cookOffBox)] call CBA_fnc_addEventHandler;
// handle cleaning up effects when vehicle is deleted mid-cookoff
[QGVAR(addCleanupHandlers), {
params ["_vehicle"];
if (isServer) then {
[QGVAR(cookOffBoxServer), LINKFUNC(cookOffBoxServer)] call CBA_fnc_addEventHandler;
[QGVAR(cookOffServer), LINKFUNC(cookOffServer)] call CBA_fnc_addEventHandler;
[QGVAR(detonateAmmunitionServer), LINKFUNC(detonateAmmunitionServer)] call CBA_fnc_addEventHandler;
[QGVAR(engineFireServer), LINKFUNC(engineFire)] call CBA_fnc_addEventHandler;
};
// Don't add a new EH if cookoff is run multiple times
if ((_vehicle getVariable [QGVAR(deletedEH), -1]) == -1) then {
private _deletedEH = _vehicle addEventHandler ["Deleted", {
params ["_vehicle"];
// Handle cleaning up effects when objects are deleted mid cook-off
["AllVehicles", "Deleted", {
{
deleteVehicle _x;
} forEach ((_this select 0) getVariable [QGVAR(effects), []]);
}, true, ["CAManBase", "StaticWeapon"], true] call CBA_fnc_addClassEventHandler;
[QGVAR(cleanupEffects), [_vehicle]] call CBA_fnc_localEvent;
}];
_vehicle setVariable [QGVAR(deletedEH), _deletedEH];
};
}] call CBA_fnc_addEventHandler;
["ReammoBox_F", "Deleted", {
{
deleteVehicle _x;
} forEach ((_this select 0) getVariable [QGVAR(effects), []]);
}, true, [], true] call CBA_fnc_addClassEventHandler;
// Raised when the flames have subsided or after the ammo of a box has finished cooking off
[QGVAR(cleanupEffects), {
params ["_vehicle", ["_effects", []]];
params ["_object"];
_effects = _effects + (_vehicle getVariable [QGVAR(effects), []]);
if (_effects isNotEqualTo []) then {
{ deleteVehicle _x } count _effects;
};
{
deleteVehicle _x;
} forEach (_object getVariable [QGVAR(effects), []]);
_object setVariable [QGVAR(effects), nil];
}] call CBA_fnc_addEventHandler;
// Ammo box damage handling
["ReammoBox_F", "init", {
(_this select 0) addEventHandler ["HandleDamage", {
if ((_this select 0) getVariable [QGVAR(enableAmmoCookoff), GVAR(enableAmmobox)]) then {
_this call FUNC(handleDamageBox);
};
}];
}, nil, nil, true] call CBA_fnc_addClassEventHandler;
// Calling this function inside curly brackets allows the usage of "exitWith", which would be broken with "HandleDamage" otherwise
(_this select 0) addEventHandler ["HandleDamage", {_this call FUNC(handleDamageBox)}];
}, true, [], true] call CBA_fnc_addClassEventHandler;
// Vehicle ammo cook-off (secondary explosions)
["AllVehicles", "Killed", {
if (!GVAR(enableAmmoCookoff) || {GVAR(ammoCookoffDuration) == 0}) exitWith {};
// secondary explosions
["AllVehicles", "killed", {
params ["_vehicle", "", "", "_useEffects"];
if (
_useEffects &&
_vehicle getVariable [QGVAR(enableAmmoCookoff), GVAR(enableAmmoCookoff)]
) then {
if (GVAR(ammoCookoffDuration) == 0) exitWith {};
([_vehicle] call FUNC(getVehicleAmmo)) params ["_mags", "_total"];
private _delay = (random MAX_AMMO_DETONATION_START_DELAY) max MIN_AMMO_DETONATION_START_DELAY;
[FUNC(detonateAmmunition), [_vehicle, _mags, _total], _delay] call CBA_fnc_waitAndExecute;
if (_useEffects && {_vehicle getVariable [QGVAR(enableAmmoCookoff), true]}) then {
// We don't need to pass source and instigator, as vehicle is already dead
[QGVAR(detonateAmmunitionServer), [
_vehicle,
false,
objNull,
objNull,
random [MIN_AMMO_DETONATION_START_DELAY, (MIN_AMMO_DETONATION_START_DELAY + MAX_AMMO_DETONATION_START_DELAY) / 2, MAX_AMMO_DETONATION_START_DELAY]
]] call CBA_fnc_serverEvent;
};
}, nil, ["Man","StaticWeapon"]] call CBA_fnc_addClassEventHandler;
}, true, ["CAManBase", "StaticWeapon"], true] call CBA_fnc_addClassEventHandler;
if (hasInterface) then {
// Plays a sound locally, so that different sounds can be used for various distances
@ -68,7 +69,7 @@ if (hasInterface) then {
private _distance = _object distance (positionCameraToWorld [0, 0, 0]);
TRACE_3("",_object,_sound,_maxDistance);
TRACE_2("",_object,_sound);
// 3 classes of distances: close, mid and far, each having different sound files
private _classDistance = switch (true) do {
@ -94,6 +95,6 @@ if (hasInterface) then {
if (!fileExists _sound) exitWith {};
// Obeys speed of sound and takes doppler effects into account
playSound3D [_sound, objNull, insideBuilding _object >= 0.5, getPosASL _object, _volume, _pitch + (random 0.2) - 0.1, _maxDistance, 0, true];
playSound3D [_sound, objNull, false, getPosASL _object, _volume, _pitch + (random 0.2) - 0.1, _maxDistance, 0, true];
}] call CBA_fnc_addEventHandler;
};

View File

@ -1,150 +0,0 @@
#include "..\script_component.hpp"
/*
* Author: tcvm
* Start a cook-off in the given vehicle.
*
* Arguments:
* 0: Vehicle <Object>
* 1: Intensity of fire <Number>
*
* Return Value:
* None
*
* Example:
* [(vehicle player), 3] call ace_cookoff_fnc_cookOff
*
* Public: No
*/
params ["_vehicle", "_intensity", ["_instigator", objNull], ["_smokeDelayEnabled", true], ["_ammoDetonationChance", 0], ["_detonateAfterCookoff", false], ["_fireSource", ""], ["_canRing", true], ["_maxIntensity", MAX_COOKOFF_INTENSITY, [0]], ["_canJet", true, [true]]];
if (GVAR(enable) == 0) exitWith {};
if !(GVAR(enableFire)) exitWith {};
if (_vehicle getVariable [QGVAR(enable), GVAR(enable)] in [0, false]) exitWith {};
// exit if cook-off enabled only for players and no players in vehicle crew found
if (_vehicle getVariable [QGVAR(enable), GVAR(enable)] isEqualTo 1 && {fullCrew [_vehicle, "", false] findIf {isPlayer (_x select 0)} == -1}) exitWith {};
TRACE_2("cooking off",_vehicle,_intensity);
TRACE_8("",_instigator,_smokeDelayEnabled,_ammoDetonationChance,_detonateAfterCookoff,_fireSource,_canRing,_maxIntensity,_canJet);
if (_vehicle getVariable [QGVAR(isCookingOff), false]) exitWith {};
_vehicle setVariable [QGVAR(isCookingOff), true, true];
[QGVAR(addCleanupHandlers), [_vehicle]] call CBA_fnc_globalEvent;
// limit maximum value of intensity to prevent very long cook-off times
_intensity = _intensity min _maxIntensity;
private _config = configOf _vehicle;
private _positions = getArray (_config >> QGVAR(cookoffSelections)) select {(_vehicle selectionPosition _x) isNotEqualTo [0,0,0]};
if (_positions isEqualTo []) then {
WARNING_1("no valid selection for cookoff found. %1",typeOf _vehicle);
{
private _pos = _vehicle selectionPosition _x;
if (_pos isEqualTo [0, 0, 0]) exitWith {};
_positions pushBack _x;
} forEach DEFAULT_COMMANDER_HATCHES;
if (_positions isEqualTo []) then {
_positions pushBack "#noselection";
};
};
private _delay = 0;
if (_smokeDelayEnabled) then {
_delay = SMOKE_TIME + random SMOKE_TIME;
};
[QGVAR(smoke), [_vehicle, _positions]] call CBA_fnc_globalEvent;
[{
params ["_vehicle", "_positions", "_intensity", "_ammoDetonationChance", "_detonateAfterCookoff", "_instigator", "_fireSource", "_canRing", "_canJet"];
_vehicle setVariable [QGVAR(intensity), _intensity];
[{
params ["_args", "_pfh"];
_args params ["_vehicle", "_positions", "_ammoDetonationChance", "_detonateAfterCookoff", "_instigator", "_fireSource", "_canRing", "_canJet"];
private _intensity = _vehicle getVariable [QGVAR(intensity), 0];
private _nextFlameTime = _vehicle getVariable [QGVAR(nextFlame), 0];
if (isNull _vehicle || {_intensity <= 1}) exitWith {
[_pfh] call CBA_fnc_removePerFrameHandler;
if (isNull _vehicle) exitWith {};
if (GVAR(destroyVehicleAfterCookoff) || _detonateAfterCookoff) exitWith {
if (_fireSource isEqualTo "") then {
_fireSource = selectRandom _positions;
};
if (_nextFlameTime <= 0) then {
_nextFlameTime = MIN_TIME_BETWEEN_FLAMES max random MAX_TIME_BETWEEN_FLAMES;
};
[{
params ["_vehicle", "_fireSource"];
if (isNull _vehicle) exitWith {};
[QGVAR(cleanupEffects), _vehicle] call CBA_fnc_globalEvent;
_vehicle setVariable [QGVAR(isCookingOff), false, true];
createVehicle ["ACE_ammoExplosionLarge", (_vehicle modelToWorld (_vehicle selectionPosition _fireSource)), [], 0 , "CAN_COLLIDE"];
_vehicle setDamage [1, true];
}, [_vehicle, _fireSource], _nextFlameTime] call CBA_fnc_waitAndExecute;
};
[QGVAR(cleanupEffects), _vehicle] call CBA_fnc_globalEvent;
_vehicle setVariable [QGVAR(isCookingOff), false, true];
};
private _lastFlameTime = _vehicle getVariable [QGVAR(lastFlame), 0];
// Wait until we are ready for the next flame
// dt = Tcurrent - Tlast
// dt >= Tnext
if ((CBA_missionTime - _lastFlameTime) >= _nextFlameTime) then {
private _ring = (0.2 > random 1);
if (!_ring && _intensity >= 2) then {
_ring = (0.7 > random 1);
};
if !(_canRing) then {
_ring = false;
};
private _time = linearConversion [0, 10, _intensity, 3, 20] + random COOKOFF_TIME;
if (_fireSource isEqualTo "") then {
_fireSource = selectRandom _positions;
};
[QGVAR(cookOffEffect), [_vehicle, _canJet, _ring, _time, _fireSource, _intensity]] call CBA_fnc_globalEvent;
_intensity = _intensity - (0.5 max random 1);
_vehicle setVariable [QGVAR(intensity), _intensity];
_vehicle setVariable [QGVAR(lastFlame), CBA_missionTime];
_vehicle setVariable [QGVAR(nextFlame), _time + (MIN_TIME_BETWEEN_FLAMES max random MAX_TIME_BETWEEN_FLAMES)];
{
[QEGVAR(fire,burn), [_x, _intensity * 1.5, _instigator]] call CBA_fnc_globalEvent;
} forEach crew _vehicle
};
if (_ammoDetonationChance > random 1) then {
private _lastExplosiveDetonationTime = _vehicle getVariable [QGVAR(lastExplosiveDetonation), 0];
private _nextExplosiveDetonation = _vehicle getVariable [QGVAR(nextExplosiveDetonation), 0];
if ((CBA_missionTime - _lastExplosiveDetonationTime) > _nextExplosiveDetonation) then {
if (_fireSource isEqualTo "") then {
_fireSource = selectRandom _positions;
};
createVehicle ["ACE_ammoExplosionLarge", (_vehicle modelToWorld (_vehicle selectionPosition _fireSource)), [], 0 , "CAN_COLLIDE"];
_vehicle setVariable [QGVAR(lastExplosiveDetonation), CBA_missionTime];
_vehicle setVariable [QGVAR(nextExplosiveDetonation), random 60];
};
};
}, 0.25, [_vehicle, _positions, _ammoDetonationChance, _detonateAfterCookoff, _instigator, _fireSource, _canRing, _canJet]] call CBA_fnc_addPerFrameHandler
}, [_vehicle, _positions, _intensity, _ammoDetonationChance, _detonateAfterCookoff, _instigator, _fireSource, _canRing, _canJet], _delay] call CBA_fnc_waitAndExecute;

View File

@ -1,74 +0,0 @@
#include "..\script_component.hpp"
/*
* Author: KoffeinFlummi, commy2, kymckay
* Start a cook-off in the given ammo box.
*
* Arguments:
* 0: Ammo box <OBJECT>
*
* Return Value:
* None
*
* Example:
* [_box] call ace_cookoff_fnc_cookOffBox
*
* Public: No
*/
params ["_box"];
if (_box getVariable [QGVAR(isCookingOff), false]) exitWith {};
_box setVariable [QGVAR(isCookingOff), true];
if (local _box) then {
[QGVAR(cookOffBox), _box] call CBA_fnc_globalEvent;
};
[{
params ["_box"];
// Box will start smoking
private _smoke = "#particlesource" createVehicleLocal [0,0,0];
_smoke setParticleClass "AmmoSmokeParticles2";
_smoke attachTo [_box, [0,0,0]];
private _effects = [_smoke];
if (isServer) then {
private _sound = createSoundSource ["Sound_Fire", position _box, [], 0];
_effects pushBack _sound;
};
[{
params ["_box", "_effects"];
// These functions are smart and do all the cooking off work
if (local _box) then {
if (GVAR(ammoCookoffDuration) == 0) exitWith {};
([_box] call FUNC(getVehicleAmmo)) params ["_mags", "_total"];
[_box, _mags, _total] call FUNC(detonateAmmunition);
// This shit is busy being on fire, magazines aren't accessible/usable
clearMagazineCargoGlobal _box;
};
// Light the fire (also handles lighting)
private _fire = "#particlesource" createVehicleLocal [0,0,0];
_fire setParticleClass "AmmoBulletCore";
_fire attachTo [_box, [0,0,0]];
_effects pushBack _fire;
[{
params ["_box", "_effects"];
{
deleteVehicle _x;
} forEach _effects;
if (local _box) then {
_box setDamage 1;
};
}, [_box, _effects], COOKOFF_TIME_BOX] call CBA_fnc_waitAndExecute; // TODO: Change so that box is alive until no ammo left, with locality in mind
}, [_box, _effects], SMOKE_TIME] call CBA_fnc_waitAndExecute;
}, _box, IGNITE_TIME] call CBA_fnc_waitAndExecute;

View File

@ -0,0 +1,52 @@
#include "..\script_component.hpp"
/*
* Author: KoffeinFlummi, commy2, kymckay, johnb43
* Spawns local cook-off effects for ammo boxes.
*
* Arguments:
* 0: Box <OBJECT>
* 1: Source <OBJECT>
* 2: Instigator <OBJECT>
* 3: Start time of the cook-off <NUMBER>
*
* Return Value:
* None
*
* Example:
* [cursorObject, player, player, CBA_missionTime + 10] call ace_cookoff_fnc_cookOffBoxLocal
*
* Public: No
*/
params ["", "", "", "_startTime"];
[{
params ["_box", "_source", "_instigator"];
// If box was deleted before smoke could be spawned, just exit
if (isNull _box) exitWith {};
private _boxPos = ASLToAGL getPosASL _box;
private _effects = [];
// Box will start smoking
if (hasInterface) then {
private _smoke = createVehicleLocal ["#particlesource", _boxPos, [], 0, "CAN_COLLIDE"];
_smoke setParticleClass "AmmoSmokeParticles2";
_smoke attachTo [_box];
_effects pushBack _smoke;
};
if (isServer) then {
private _sound = createSoundSource ["Sound_Fire", _boxPos, [], 0];
_sound attachTo [_box];
_effects pushBack _sound;
// Detonate the ammunition
[QGVAR(detonateAmmunitionServer), [_box, true, _source, _instigator, random [DETONATION_DELAY / 2, DETONATION_DELAY, DETONATION_DELAY / 2 * 3]]] call CBA_fnc_localEvent;
};
_box setVariable [QGVAR(effects), _effects];
}, _this, (_startTime - CBA_missionTime) max 0] call CBA_fnc_waitAndExecute; // This delay allows for synchronisation for JIP players

View File

@ -0,0 +1,50 @@
#include "..\script_component.hpp"
/*
* Author: KoffeinFlummi, commy2, kymckay, johnb43
* Start an ammo cook-off in the given ammo box.
*
* Arguments:
* 0: Ammo box <OBJECT>
* 1: Source <OBJECT> (default: objNull)
* 2: Instigator <OBJECT> (default: objNull)
*
* Return Value:
* None
*
* Example:
* cursorObject call ace_cookoff_fnc_cookOffBoxServer
*
* Public: No
*/
if (!isServer) exitWith {};
if (!GVAR(enableAmmobox) || {GVAR(ammoCookoffDuration) == 0}) exitWith {};
params ["_box", ["_source", objNull], ["_instigator", objNull]];
// Make sure it's a box (important, because deleted EH is assigned to ReammoBox_F only in postInit)
if !(_box isKindOf "ReammoBox_F") exitWith {};
if !(_box getVariable [QGVAR(enableAmmoCookoff), true]) exitWith {};
// Allow only 1 cook-off per box at a time
if (_box getVariable [QGVAR(isCookingOff), false]) exitWith {};
_box setVariable [QGVAR(isCookingOff), true, true];
private _delay = random [SMOKE_DELAY / 2, SMOKE_DELAY, SMOKE_DELAY / 2 * 3];
// Spawn cook-off effects on all connected machines and JIP
private _jipID = [QGVAR(cookOffBoxLocal), [
_box,
_source,
_instigator,
CBA_missionTime + _delay // Generate a globally synced timestamp
]] call CBA_fnc_globalEventJIP;
[_jipID, _box] call CBA_fnc_removeGlobalEventJIP;
_box setVariable [QGVAR(cookoffBoxJipID), _jipID];
// API
[QGVAR(cookOffBox), [_box, _source, _instigator, _delay]] call CBA_fnc_globalEvent;

View File

@ -1,200 +0,0 @@
#include "..\script_component.hpp"
/*
* Author: tcvm
* Spawn cook-off effects
*
* Arguments:
* 0: Vehicle <Object>
* 1: Spawn fire jet <Boolean>
* 2: Spawn fire ring <Boolean>
* 3: How long effect will last (Max 20 seconds) <Number>
* 4: What selection will fire originate from <String>
* 5: Cookoff intensity value <Number>
*
* Return Value:
* None
*
* Example:
* [vehicle player, true, false, 15, "commander_turret"] call ace_cookoff_fnc_cookOffEffect
*
* Public: No
*/
params ["_obj", "_jet", "_ring", "_time", "_fireSelection", "_intensity"];
private _light = "#lightpoint" createVehicleLocal [0,0,0];
_light setLightBrightness 5;
_light setLightAmbient [0.8, 0.6, 0.2];
_light setLightColor [1, 0.5, 0.2];
_light lightAttachObject [_obj, [0,0,0]];
_time = 0 max (_time min 20);
private _sound = objNull;
if (isServer) then {
// ironically biggest performance hit is this. Creating a new sound source takes up aprox 400 milliseconds.
// I dont think there is an alternative that takes into effect distance and whatever, but if you find one please fix!
if (_jet || _ring) then {
private _soundName = selectRandomWeighted [QGVAR(Sound_low), 0.1, QGVAR(Sound_mid), 0.25, QGVAR(Sound_high), 0.65];
_sound = createSoundSource [_soundName, position _obj, [], 0];
};
if (_ring) then {
private _intensity = 6;
private _radius = 1.5 * ((boundingBoxReal _obj) select 2);
[QEGVAR(fire,addFireSource), [_obj, _radius, _intensity, format [QGVAR(%1), hashValue _obj]]] call CBA_fnc_localEvent;
};
};
[{
params ["_args", "_pfh"];
_args params ["_obj", "_jet", "_ring", "_time", "_startTime", "_light", "_fireSelection", "_sound", "_intensity"];
private _elapsedTime = CBA_missionTime - _startTime;
if (_elapsedTime >= _time) exitWith {
deleteVehicle _light;
deleteVehicle _sound;
if (isServer) then {
[QEGVAR(fire,removeFireSource), [format [QGVAR(%1), hashValue _obj]]] call CBA_fnc_localEvent;
};
[_pfh] call CBA_fnc_removePerFrameHandler;
};
private _factor = (1 + (_elapsedTime / 2) min 2);
private _flameSize = 1.5;
if (_elapsedTime > (_time * (3 / 4))) then {
_factor = _factor * linearConversion [_time * (3 / 4), _time, _elapsedTime, 1, 0.5];
};
_light setLightBrightness 5 * (_factor / 5);
if (_jet) then {
private _particlePosition = (_obj selectionPosition _fireSelection) vectorAdd [-0.1 + random 0.2, -0.1 + random 0.2, 0];
drop [
["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32],
"",
"Billboard",
1,
(0.1 + (random 0.2)) * _factor,
_particlePosition,
[0, 0, 15 * (_factor / 2)],
0,
10,
7.9,
0.075,
[1.25 * _factor, 2.5 * _factor],
[[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]],
[2 + random 1],
1,
0,
"",
"",
_obj
];
// make flame push object into ground to make effect seem more "alive"
if (!isGamePaused && { local _obj }) then {
private _force = [0, 0, _factor * -(0.5 min random 1.5) * (0.3 min random 1)] vectorMultiply getMass _obj;
_obj addForce [_force, vectorUpVisual _obj];
};
};
if (_ring) then {
private _ringOrigin = (_obj selectionPosition _fireSelection) vectorAdd [-0.1 + random 0.2, -0.1 + random 0.2, -1];
drop [
["\A3\data_f\ParticleEffects\Universal\Universal",16,2,32],
"", "Billboard", 1, (0.1 + (random 0.2)) * _factor,
_ringOrigin,
[0, 20 * (_factor / 2), 0],
0, 10, 7.9, 0.075,
[1.25 * _factor, _flameSize * _factor],
[[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]],
[2 + random 1], 1, 0, "", "", _obj
];
drop [
["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32],
"", "Billboard", 1, (0.1 + (random 0.2)) * _factor,
_ringOrigin,
[0, -20 * (_factor / 2), 0],
0, 10, 7.9, 0.075,
[1.25 * _factor, _flameSize * _factor],
[[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]],
[2 + random 1], 1, 0, "", "", _obj
];
drop [
["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32],
"", "Billboard", 1, (0.1 + (random 0.2)) * _factor,
_ringOrigin,
[20 * (_factor / 2), 0, 0],
0, 10, 7.9, 0.075,
[1.25 * _factor, _flameSize * _factor],
[[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]],
[2 + random 1], 1, 0, "", "", _obj
];
drop [
["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32],
"", "Billboard", 1, (0.1 + (random 0.2)) * _factor,
[-0.1 + random 0.2, -0.1 + random 0.2, -1],
[-20 * (_factor / 2), 0, 0],
0, 10, 7.9, 0.075,
[1.25 * _factor, _flameSize * _factor],
[[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]],
[2 + random 1], 1, 0, "", "", _obj
];
private _dir = 20 * (_factor / 2);
drop [
["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32],
"", "Billboard", 1, (0.1 + (random 0.2)) * _factor,
_ringOrigin,
[_dir, _dir, 0],
0, 10, 7.9, 0.075,
[1.25 * _factor, _flameSize * _factor],
[[1, 1, 1, -2],[1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]],
[2 + random 1], 1, 0, "", "", _obj
];
_dir = -20 * (_factor / 2);
drop [
["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32],
"", "Billboard", 1, (0.1 + (random 0.2)) * _factor,
_ringOrigin,
[_dir, _dir, 0],
0, 10, 7.9, 0.075,
[1.25 * _factor, _flameSize * _factor],
[[1, 1, 1, -2],[1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]],
[2 + random 1], 1, 0, "", "", _obj
];
_dir = 20 * (_factor / 2);
drop [
["\A3\data_f\ParticleEffects\Universal\Universal",16,2,32],
"", "Billboard", 1, (0.1 + (random 0.2)) * _factor,
_ringOrigin,
[_dir, -_dir, 0],
0, 10, 7.9, 0.075,
[1.25 * _factor, _flameSize * _factor],
[[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]],
[2 + random 1], 1, 0, "", "", _obj
];
_dir = 20 * (_factor / 2);
drop [
["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32],
"", "Billboard", 1, (0.1 + (random 0.2)) * _factor,
_ringOrigin,
[-_dir, _dir, 0],
0, 10, 7.9, 0.075,
[1.25 * _factor, _flameSize * _factor],
[[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]],
[2 + random 1], 1, 0, "", "", _obj
];
};
(getVehicleTIPars _obj) params ["_tiEngine", "_tiWheels", "_tiWeapon"];
_obj setVehicleTIPars [
// formula is designed to have the temperature ramp up quickly and then level out
(_tiEngine + (_intensity * 0.01))/1.005,
(_tiWheels + (_intensity * 0.004))/1.002, // wheels//tracks are further away from burning parts
(_tiWeapon + (_intensity * 0.01))/1.005
];
}, 0, [_obj, _jet, _ring, _time, CBA_missionTime, _light, _fireSelection, _sound, _intensity]] call CBA_fnc_addPerFrameHandler;

View File

@ -0,0 +1,229 @@
#include "..\script_component.hpp"
/*
* Author: tcvm, johnb43
* Spawn cook-off fire effects.
*
* Arguments:
* 0: Vehicle <OBJECT>
* 1: Spawn fire jet <BOOL>
* 2: Spawn fire ring <BOOL>
* 3: What selection fire will originate from <STRING>
* 4: Cookoff intensity value <NUMBER>
* 5: Start time <NUMBER>
* 6: Duration of effect (max 20 seconds) <NUMBER>
*
* Return Value:
* None
*
* Example:
* [cursorObject, true, false, "commander_turret", 6, CBA_missionTime, 15] call ace_cookoff_fnc_cookOffLocal
*
* Public: No
*/
#define FLAME_SIZE 1.5
#define FIRE_INTENSITY 20
params ["_vehicle", "_jet", "_ring", "_fireSelection", "_intensity", "_startTime", "_duration"];
// Check if still valid for JIP players
if (isNull _vehicle || {CBA_missionTime - _startTime >= _duration}) exitWith {};
// Spawn light
private _light = objNull;
if (hasInterface) then {
_light = "#lightpoint" createVehicleLocal [0, 0, 0];
_light setLightBrightness 5;
_light setLightAmbient [0.8, 0.6, 0.2];
_light setLightColor [1, 0.5, 0.2];
_light lightAttachObject [_vehicle, [0, 0, 0]];
};
_duration = 0 max _duration min 20;
private _sound = objNull;
private _fireKey = "";
if (isServer) then {
// Spawn sound effect
if (_jet || _ring) then {
private _soundName = selectRandomWeighted [QGVAR(Sound_low), 0.1, QGVAR(Sound_mid), 0.25, QGVAR(Sound_high), 0.65];
_sound = createSoundSource [_soundName, ASLToAGL getPosASL _vehicle, [], 0];
_sound attachTo [_vehicle];
};
// Make the ring a source of fire
if (_ring && {["ace_fire"] call EFUNC(common,isModLoaded)}) then {
_fireKey = format [QGVAR(cookoffFire_%1), hashValue _vehicle];
[QEGVAR(fire,addFireSource), [_vehicle, FLAME_SIZE * ((boundingBoxReal _vehicle) select 2), FIRE_INTENSITY, _fireKey]] call CBA_fnc_localEvent;
};
};
[{
(_this select 0) params ["_vehicle", "_jet", "_ring", "_startTime", "_duration", "_light", "_fireSelection", "_sound", "_intensity", "_fireKey"];
private _elapsedTime = CBA_missionTime - _startTime;
// Clean up effects once effects have finished or vehicle has been deleted
if (isNull _vehicle || {_elapsedTime >= _duration}) exitWith {
(_this select 1) call CBA_fnc_removePerFrameHandler;
deleteVehicle _light;
if (isServer) then {
deleteVehicle _sound;
if (["ace_fire"] call EFUNC(common,isModLoaded)) then {
[QEGVAR(fire,removeFireSource), _fireKey] call CBA_fnc_localEvent;
};
};
};
private _factor = 1 + (_elapsedTime / 2) min 2;
if (_elapsedTime > _duration * 3 / 4) then {
_factor = _factor * linearConversion [_duration * 3 / 4, _duration, _elapsedTime, 1, 0.5];
};
// Make flame push object into ground to make effect seem more "alive"
if (_jet && !isGamePaused && {local _vehicle} && {_vehicle getVariable [QGVAR(nextForceTime), 0] <= CBA_missionTime}) then {
private _force = [0, 0, _factor * -(0.5 min random 1.5) * (0.3 min random 1)] vectorMultiply getMass _vehicle;
_vehicle addForce [_force, vectorUpVisual _vehicle];
_vehicle setVariable [QGVAR(nextForceTime), CBA_missionTime + 0.01]; // This prevents bad behaviour when setAccTime is small
};
// Don't spawn visual effects on machines without interfaces
if (!hasInterface) exitWith {};
_light setLightBrightness _factor;
if (_jet) then {
private _particlePosition = (_vehicle selectionPosition _fireSelection) vectorAdd [-0.1 + random 0.2, -0.1 + random 0.2, 0];
drop [
["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32],
"",
"Billboard",
1,
(0.1 + random 0.2) * _factor,
_particlePosition,
[0, 0, 15 * (_factor / 2)],
0,
10,
7.9,
0.075,
[1.25 * _factor, 2.5 * _factor],
[[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]],
[2 + random 1],
1,
0,
"",
"",
_vehicle
];
};
if (_ring) then {
private _ringOrigin = (_vehicle selectionPosition _fireSelection) vectorAdd [-0.1 + random 0.2, -0.1 + random 0.2, -1];
drop [
["\A3\data_f\ParticleEffects\Universal\Universal",16,2,32],
"", "Billboard", 1, (0.1 + random 0.2) * _factor,
_ringOrigin,
[0, 20 * (_factor / 2), 0],
0, 10, 7.9, 0.075,
[1.25 * _factor, FLAME_SIZE * _factor],
[[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]],
[2 + random 1], 1, 0, "", "", _vehicle
];
drop [
["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32],
"", "Billboard", 1, (0.1 + random 0.2) * _factor,
_ringOrigin,
[0, -20 * (_factor / 2), 0],
0, 10, 7.9, 0.075,
[1.25 * _factor, FLAME_SIZE * _factor],
[[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]],
[2 + random 1], 1, 0, "", "", _vehicle
];
drop [
["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32],
"", "Billboard", 1, (0.1 + random 0.2) * _factor,
_ringOrigin,
[20 * (_factor / 2), 0, 0],
0, 10, 7.9, 0.075,
[1.25 * _factor, FLAME_SIZE * _factor],
[[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]],
[2 + random 1], 1, 0, "", "", _vehicle
];
drop [
["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32],
"", "Billboard", 1, (0.1 + random 0.2) * _factor,
[-0.1 + random 0.2, -0.1 + random 0.2, -1],
[-20 * (_factor / 2), 0, 0],
0, 10, 7.9, 0.075,
[1.25 * _factor, FLAME_SIZE * _factor],
[[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]],
[2 + random 1], 1, 0, "", "", _vehicle
];
private _dir = 20 * (_factor / 2);
drop [
["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32],
"", "Billboard", 1, (0.1 + random 0.2) * _factor,
_ringOrigin,
[_dir, _dir, 0],
0, 10, 7.9, 0.075,
[1.25 * _factor, FLAME_SIZE * _factor],
[[1, 1, 1, -2],[1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]],
[2 + random 1], 1, 0, "", "", _vehicle
];
_dir = -20 * (_factor / 2);
drop [
["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32],
"", "Billboard", 1, (0.1 + (random 0.2)) * _factor,
_ringOrigin,
[_dir, _dir, 0],
0, 10, 7.9, 0.075,
[1.25 * _factor, FLAME_SIZE * _factor],
[[1, 1, 1, -2],[1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]],
[2 + random 1], 1, 0, "", "", _vehicle
];
_dir = 20 * (_factor / 2);
drop [
["\A3\data_f\ParticleEffects\Universal\Universal",16,2,32],
"", "Billboard", 1, (0.1 + (random 0.2)) * _factor,
_ringOrigin,
[_dir, -_dir, 0],
0, 10, 7.9, 0.075,
[1.25 * _factor, FLAME_SIZE * _factor],
[[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]],
[2 + random 1], 1, 0, "", "", _vehicle
];
_dir = 20 * (_factor / 2);
drop [
["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32],
"", "Billboard", 1, (0.1 + random 0.2) * _factor,
_ringOrigin,
[-_dir, _dir, 0],
0, 10, 7.9, 0.075,
[1.25 * _factor, FLAME_SIZE * _factor],
[[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]],
[2 + random 1], 1, 0, "", "", _vehicle
];
};
(getVehicleTIPars _vehicle) params ["_tiEngine", "_tiWheels", "_tiWeapon"];
// Formula is designed to have the temperature ramp up quickly and then level out
_vehicle setVehicleTIPars [
(_tiEngine + _intensity * 0.01) / 1.005,
(_tiWheels + _intensity * 0.004) / 1.002, // Wheels/tracks are further away from burning parts
(_tiWeapon + _intensity * 0.01) / 1.005
];
}, 0, [_vehicle, _jet, _ring, _startTime, _duration, _light, _fireSelection, _sound, _intensity, _fireKey]] call CBA_fnc_addPerFrameHandler;

View File

@ -0,0 +1,202 @@
#include "..\script_component.hpp"
/*
* Author: tcvm, johnb43
* Start a cook-off in the given vehicle.
* Spews flames in multiple directions at the same time (ring) or from the turret towards the sky (jet).
*
* Arguments:
* 0: Vehicle <OBJECT>
* 1: Intensity of fire <NUMBER>
* 2: Source <OBJECT> (default: objNull)
* 3: Instigator <OBJECT> (default: objNull)
* 4: Delay between smoke and fire enabled <BOOL> (default: true)
* 5: Ammo detonation chance <NUMBER> (default: 0)
* 6: Detonate after cook-off <BOOL> (default: false)
* 7: Selection for fire source <STRING> (default: "")
* 8: Can spawn fire ring <BOOL> (default: true)
* 9: Can spawn fire jet <BOOL> (default: true)
* 10: Maximum intensity <NUMBER> (default: MAX_COOKOFF_INTENSITY)
*
* Return Value:
* None
*
* Example:
* [cursorObject, 3] call ace_cookoff_fnc_cookOffServer
*
* Public: No
*/
if (!isServer) exitWith {};
if (!GVAR(enableFire) || {GVAR(cookoffDuration) == 0}) exitWith {};
params [
"_vehicle",
"_intensity",
["_source", objNull],
["_instigator", objNull],
["_delayBetweenSmokeAndFire", true],
["_ammoDetonationChance", 0],
["_detonateAfterCookoff", false],
["_fireSelection", ""],
["_canRing", true],
["_canJet", true],
["_maxIntensity", MAX_COOKOFF_INTENSITY]
];
// Make sure it's a vehicle (important, because deleted EH is assigned to AllVehicles only in postInit)
if !(_vehicle isKindOf "AllVehicles") exitWith {};
if (_vehicle isKindOf "CAManBase" || {_vehicle isKindOf "StaticWeapon"}) exitWith {};
// If under water, ignore
// underwater is not very reliable, so use model center instead
if (underwater _vehicle || {private _posASL = getPosWorld _vehicle; surfaceIsWater _posASL && {(_posASL select 2) < 0}}) exitWith {};
// Check if cook-off is disabled on vehicle specifically
if !(_vehicle getVariable [QGVAR(enable), true]) exitWith {}; // QGVAR(enable) is API
TRACE_3("cooking off",_vehicle,_intensity,_maxIntensity);
TRACE_8("",_source,_instigator,_delayBetweenSmokeAndFire,_ammoDetonationChance,_detonateAfterCookoff,_fireSelection,_canRing,_canJet);
if (_vehicle getVariable [QGVAR(isCookingOff), false]) exitWith {};
_vehicle setVariable [QGVAR(isCookingOff), true, true];
// Limit maximum value of intensity to prevent very long cook-off times
_intensity = _intensity min _maxIntensity;
private _selections = getArray (configOf _vehicle >> QGVAR(cookoffSelections)) select {(_vehicle selectionPosition _x) isNotEqualTo [0, 0, 0]};
if (_selections isEqualTo []) then {
WARNING_1("no valid selection for cookoff found. %1",typeOf _vehicle);
{
if ((_vehicle selectionPosition _x) isNotEqualTo [0, 0, 0]) then {
_selections pushBack _x;
};
} forEach DEFAULT_COMMANDER_HATCHES;
if (_selections isEqualTo []) then {
_selections pushBack "#noselection";
};
};
// Not guaranteed to be active/used, but reserve it nonetheless
private _fireJipID = format [QGVAR(cookOffLocal_%1), hashValue _vehicle];
[_fireJipID, _vehicle] call CBA_fnc_removeGlobalEventJIP;
// Spawn smoke
private _smokeJipID = [QGVAR(smoke), [_vehicle, _selections]] call CBA_fnc_globalEventJIP;
[_smokeJipID, _vehicle] call CBA_fnc_removeGlobalEventJIP;
// Save intensity for looping purposes
_vehicle setVariable [QGVAR(intensity), _intensity];
private _delay = 0;
if (_delayBetweenSmokeAndFire) then {
_delay = random [SMOKE_DELAY, 1.5 * SMOKE_DELAY, 2 * SMOKE_DELAY];
};
[{
[{
(_this select 0) params ["_vehicle", "_selections", "_ammoDetonationChance", "_detonateAfterCookoff", "_source", "_instigator", "_fireSelection", "_canRing", "_canJet", "_smokeJipID", "_fireJipID"];
if (
isNull _vehicle ||
!GVAR(enableFire) ||
{!(_vehicle getVariable [QGVAR(enable), true])} || // QGVAR(enable) is API
{GVAR(cookoffDuration) == 0} ||
{underwater _vehicle} ||
{private _posASL = getPosWorld _vehicle; surfaceIsWater _posASL && {(_posASL select 2) < 0}} // Underwater is not very reliable, so use model center instead
) exitWith {
// Effects are deleted when vehicle is deleted
(_this select 1) call CBA_fnc_removePerFrameHandler;
};
private _intensity = _vehicle getVariable [QGVAR(intensity), 0];
if (_intensity <= 1) exitWith {
(_this select 1) call CBA_fnc_removePerFrameHandler;
// Wait until the previous flame has finished
private _nextFlameTime = (_vehicle getVariable [QGVAR(endCurrentFlame), CBA_missionTime]) - CBA_missionTime + (MIN_TIME_BETWEEN_FLAMES max random MAX_TIME_BETWEEN_FLAMES);
if (_fireSelection isEqualTo "") then {
_fireSelection = selectRandom _selections;
};
[{
params ["_vehicle", "_source", "_instigator", "_detonateAfterCookoff", "_fireSelection", "_smokeJipID", "_fireJipID"];
// Effects are deleted when vehicle is deleted
if (isNull _vehicle) exitWith {};
// Remove effects from JIP
_smokeJipID call CBA_fnc_removeGlobalEventJIP;
_fireJipID call CBA_fnc_removeGlobalEventJIP;
// Remove effects
[QGVAR(cleanupEffects), _vehicle] call CBA_fnc_globalEvent;
// Reset variable, so it can cook-off again
_vehicle setVariable [QGVAR(isCookingOff), nil, true];
if (GVAR(destroyVehicleAfterCookoff) || _detonateAfterCookoff) then {
createVehicle ["ACE_ammoExplosionLarge", _vehicle modelToWorld (_vehicle selectionPosition _fireSelection), [], 0 , "CAN_COLLIDE"];
_vehicle setDamage [1, true, _source, _instigator]; // Because it's running on the server, source and instigator can be set
};
}, [_vehicle, _source, _instigator, _detonateAfterCookoff, _fireSelection, _smokeJipID, _fireJipID], _nextFlameTime] call CBA_fnc_waitAndExecute;
};
// Wait until we are ready for the next flame
if ((_vehicle getVariable [QGVAR(nextFlame), 0]) <= CBA_missionTime) then {
private _ring = false;
if (_canRing) then {
_ring = 0.2 > random 1;
if (!_ring && {_intensity >= 2}) then {
_ring = 0.7 > random 1;
};
};
private _duration = linearConversion [0, 10, _intensity, 3, 20] + random COOKOFF_TIME;
if (_fireSelection isEqualTo "") then {
_fireSelection = selectRandom _selections;
};
// Sync for JIP players
[QGVAR(cookOffLocal), [_vehicle, _canJet, _ring, _fireSelection, _intensity, CBA_missionTime, _duration], _fireJipID] call CBA_fnc_globalEventJIP;
// If there are any crew, burn them
if (["ace_fire"] call EFUNC(common,isModLoaded)) then {
// Use current intensity, in case GVAR(cookoffDuration) is very large and only 1 flameout stage happens
{
[QEGVAR(fire,burn), [_x, _intensity * 1.5, _instigator]] call CBA_fnc_globalEvent;
} forEach (crew _vehicle);
};
_intensity = (_intensity - (0.5 max random 1) / GVAR(cookoffDuration)) max 0;
_vehicle setVariable [QGVAR(intensity), _intensity];
_vehicle setVariable [QGVAR(endCurrentFlame), CBA_missionTime + _duration];
_vehicle setVariable [QGVAR(nextFlame), CBA_missionTime + _duration + (MIN_TIME_BETWEEN_FLAMES max random MAX_TIME_BETWEEN_FLAMES)];
};
if (_ammoDetonationChance > random 1 && {_vehicle getVariable [QGVAR(nextExplosiveDetonation), 0] <= CBA_missionTime}) then {
if (_fireSelection isEqualTo "") then {
_fireSelection = selectRandom _selections;
};
createVehicle ["ACE_ammoExplosionLarge", _vehicle modelToWorld (_vehicle selectionPosition _fireSelection), [], 0 , "CAN_COLLIDE"];
_vehicle setVariable [QGVAR(nextExplosiveDetonation), CBA_missionTime + random 60];
};
}, 0.25, _this] call CBA_fnc_addPerFrameHandler;
}, [_vehicle, _selections, _ammoDetonationChance, _detonateAfterCookoff, _source, _instigator, _fireSelection, _canRing, _canJet, _smokeJipID, _fireJipID], _delay] call CBA_fnc_waitAndExecute;
// API
[QGVAR(cookoff), [_vehicle, _intensity, _instigator, _smokeDelayEnabled, _ammoDetonationChance, _detonateAfterCookoff, _fireSelection, _canRing, _maxIntensity, _canJet]] call CBA_fnc_globalEvent;

View File

@ -1,132 +0,0 @@
#include "..\script_component.hpp"
/*
* Author: Glowbal
* Detonates ammunition from a vehicle until no ammo left
*
* Arguments:
* 0: vehicle <OBJECT>
* 1: Ammo Array <ARRAY>
* - 0: Magazine Classname <STRING>
* - 1: Ammo Count <NUMBER>
* 2: Total Ammo Count <NUMBER>
*
* Return Value:
* None
*
* Example:
* [_vehicle, magazinesAmmo _vehicle] call ace_cookoff_fnc_detonateAmmunition
*
* Public: No
*/
params ["_vehicle", "_magazines", "_totalAmmo"];
if (GVAR(enable) == 0) exitWith {};
if !(GVAR(enableAmmoCookoff)) exitWith {};
if (isNull _vehicle) exitWith {}; // vehicle got deleted
if (_magazines isEqualTo []) exitWith {}; // nothing to detonate anymore
if (underwater _vehicle) exitWith {};
private _magazineIndex = floor random(count _magazines);
private _magazine = _magazines select _magazineIndex;
_magazine params ["_magazineClassname", "_amountOfMagazines"];
if (_amountOfMagazines < 0) exitWith {
ERROR_1("mag with no ammo - %1",_magazine);
};
private _removed = _amountOfMagazines min floor(1 + random(6 / GVAR(ammoCookoffDuration)));
_amountOfMagazines = _amountOfMagazines - _removed;
if (_amountOfMagazines <= 0) then {
_magazines deleteAt _magazineIndex;
} else {
_magazine set [1, _amountOfMagazines]; // clear out the magazine
};
private _timeBetweenAmmoDetonation = (((random 10) / (sqrt _totalAmmo)) min MAX_TIME_BETWEEN_AMMO_DET) max 0.1;
TRACE_2("",_totalAmmo,_timeBetweenAmmoDetonation);
_totalAmmo = _totalAmmo - _removed;
private _ammo = getText (configFile >> "CfgMagazines" >> _magazineClassname >> "ammo");
private _ammoCfg = configFile >> "CfgAmmo" >> _ammo;
private _speedOfAmmo = getNumber (configFile >> "CfgMagazines" >> _magazineClassname >> "initSpeed");
private _simType = getText (_ammoCfg >> "simulation");
private _effect2pos = _vehicle selectionPosition "destructionEffect2";
private _spawnProjectile = {
params ["_vehicle", "_ammo", "_speed", "_flyAway"];
private _spawnPos = _vehicle modelToWorld [-0.2 + (random 0.4), -0.2 + (random 0.4), random 3];
if (_spawnPos select 2 < 0) then {
_spawnPos set [2, 0];
};
private _projectile = createVehicle [_ammo, _spawnPos, [], 0, "CAN_COLLIDE"];
if (_flyAway) then {
private _vectorAmmo = [(-1 + (random 2)), (-1 + (random 2)), -0.2 + (random 1)];
private _velVec = _vectorAmmo vectorMultiply _speed;
_projectile setVectorDir _velVec;
_projectile setVelocity _velVec;
} else {
_projectile setDamage 1;
};
_projectile;
};
private _speed = random (_speedOfAmmo / 10) max 1;
_simType = toLowerANSI _simType;
switch (_simType) do {
case ("shotbullet"): {
[QGVAR(playCookoffSound), [_vehicle, _simType]] call CBA_fnc_globalEvent;
if (random 1 < 0.6) then {
[_vehicle, _ammo, _speed, true] call _spawnProjectile;
};
};
case ("shotshell"): {
[QGVAR(playCookoffSound), [_vehicle, _simType]] call CBA_fnc_globalEvent;
if (random 1 < 0.15) then {
[_vehicle, _ammo, _speed, true] call _spawnProjectile;
};
};
case ("shotgrenade"): {
if (random 1 < 0.9) then {
_speed = 0;
};
[_vehicle, _ammo, _speed, random 1 < 0.5] call _spawnProjectile;
};
case ("shotrocket");
case ("shotmissile");
case ("shotsubmunitions"): {
if (random 1 < 0.1) then {
[QGVAR(playCookoffSound), [_vehicle, _simType]] call CBA_fnc_globalEvent;
[_vehicle, _ammo, _speed, random 1 < 0.3] call _spawnProjectile;
} else {
createvehicle ["ACE_ammoExplosionLarge", (_vehicle modelToWorld _effect2pos), [], 0 , "CAN_COLLIDE"];
};
};
case ("shotmine");
case ("shotdirectionalbomb"): {
if (random 1 < 0.5) then {
// Not all explosives detonate on destruction, some have scripted alternatives
private _scripted = getNumber (_ammoCfg >> "triggerWhenDestroyed") == 1;
if !(_scripted) then {
_ammo = getText (_ammoCfg >> "ace_explosives_Explosive");
};
// If a scripted alternative doesn't exist use generic explosion
if (_ammo != "") then {
[_vehicle, _ammo, 0, false] call _spawnProjectile;
} else {
createvehicle ["SmallSecondary", (_vehicle modelToWorld _effect2pos), [], 0 , "CAN_COLLIDE"];
};
};
};
case ("shotilluminating"): {
if (random 1 < 0.15) then {
[_vehicle, _ammo, _speed, random 1 < 0.3] call _spawnProjectile;
};
};
};
[FUNC(detonateAmmunition), [_vehicle, _magazines, _totalAmmo], _timeBetweenAmmoDetonation] call CBA_fnc_waitAndExecute;

View File

@ -0,0 +1,54 @@
#include "..\script_component.hpp"
/*
* Author: johnb43
* Starts detonating ammunition from an object (e.g. vehicle or crate).
*
* Arguments:
* 0: Object <OBJECT>
* 1: Destroy when finished <BOOL> (default: false)
* 2: Source <OBJECT> (default: objNull)
* 3: Instigator <OBJECT> (default: objNull)
* 4: Initial delay <NUMBER> (default: 0)
*
* Return Value:
* None
*
* Example:
* [cursorObject] call ace_cookoff_fnc_detonateAmmunitionServer
*
* Public: No
*/
if (!isServer) exitWith {};
params ["_object", ["_destroyWhenFinished", false], ["_source", objNull], ["_instigator", objNull], ["_initialDelay", 0]];
if (isNull _object) exitWith {};
// Check if the object can cook its ammo off
if (
underwater _object ||
{private _posASL = getPosWorld _object; surfaceIsWater _posASL && {(_posASL select 2) < 0}} || // Underwater is not very reliable, so use model center instead
{GVAR(ammoCookoffDuration) == 0} ||
{!([GVAR(enableAmmoCookoff), GVAR(enableAmmobox)] select (_object isKindOf "ReammoBox_F"))} ||
{!(_object getVariable [QGVAR(enableAmmoCookoff), true])}
) exitWith {};
// Don't have an object detonate its ammo twice
if (_object getVariable [QGVAR(isAmmoDetonating), false]) exitWith {};
_object setVariable [QGVAR(isAmmoDetonating), true, true];
_object setVariable [QGVAR(cookoffMagazines), _object call FUNC(getVehicleAmmo)];
// TODO: When setMagazineTurretAmmo and magazineTurretAmmo are fixed (https://feedback.bistudio.com/T79689),
// we can add gradual ammo removal during cook-off
if (GVAR(removeAmmoDuringCookoff)) then {
clearMagazineCargoGlobal _object;
{
[QEGVAR(common,removeMagazinesTurret), [_object, _x select 0, _x select 1], _object, _x select 1] call CBA_fnc_turretEvent;
} forEach (magazinesAllTurrets _object);
};
[LINKFUNC(detonateAmmunitionServerLoop), [_object, _destroyWhenFinished, _source, _instigator], _initialDelay] call CBA_fnc_waitAndExecute;

View File

@ -0,0 +1,181 @@
#include "..\script_component.hpp"
/*
* Author: Glowbal, johnb43
* Detonates ammunition from an object (e.g. vehicle or crate) until no ammo is left.
*
* Arguments:
* 0: Object <OBJECT>
* 1: Destroy when finished <BOOL>
* 2: Source <OBJECT>
* 3: Instigator <OBJECT>
*
* Return Value:
* None
*
* Example:
* [cursorObject, true, player, player] call ace_cookoff_fnc_detonateAmmunitionServerLoop
*
* Public: No
*/
params ["_object", "_destroyWhenFinished", "_source", "_instigator"];
if (isNull _object) exitWith {};
(_object getVariable QGVAR(cookoffMagazines)) params ["_magazines", "_totalAmmo"];
private _hasFinished = _totalAmmo <= 0 || {_magazines isEqualTo []};
// If the cook-off has finished or been interrupted, clean up the effects for boxes (no vehicle effects)
if (
_hasFinished ||
{underwater _object} ||
{private _posASL = getPosWorld _object; surfaceIsWater _posASL && {(_posASL select 2) < 0}} || // Underwater is not very reliable, so use model center instead
{GVAR(ammoCookoffDuration) == 0} ||
{!([GVAR(enableAmmoCookoff), GVAR(enableAmmobox)] select (_object isKindOf "ReammoBox_F"))} ||
{!(_object getVariable [QGVAR(enableAmmoCookoff), true])}
) exitWith {
// Box cook-off fire ends after the ammo has detonated (vehicle cook-off fire does not depend on the ammo detonation)
if (_object isKindOf "ReammoBox_F") then {
[QGVAR(cleanupEffects), _object] call CBA_fnc_globalEvent;
// Reset variable, so the box can cook-off again
_object setVariable [QGVAR(isCookingOff), nil, true];
// Remove cook-off effects from box
private _jipID = _object getVariable QGVAR(cookoffBoxJipID);
if (isNil "_jipID") exitWith {};
_jipID call CBA_fnc_removeGlobalEventJIP;
_object setVariable [QGVAR(cookoffBoxJipID), nil];
};
// Reset variables, so the object can detonate its ammo again
_object setVariable [QGVAR(cookoffMagazines), nil];
_object setVariable [QGVAR(isAmmoDetonating), nil, true];
// If done, destroy the object if necessary
if (_hasFinished && _destroyWhenFinished) then {
_object setDamage [1, true, _source, _instigator];
};
};
private _magazineIndex = floor random (count _magazines);
private _magazine = _magazines select _magazineIndex;
_magazine params ["_magazineClassname", "_ammoCount", "_spawnProjectile"];
// Make sure ammo is at least 0
_ammoCount = _ammoCount max 0;
// Remove some ammo, which will be detonated
private _removed = _ammoCount min floor (1 + random (6 / GVAR(ammoCookoffDuration)));
_ammoCount = _ammoCount - _removed;
if (_ammoCount <= 0) then {
_magazines deleteAt _magazineIndex;
} else {
_magazine set [1, _ammoCount]; // remove ammo that was detonated
};
private _timeBetweenAmmoDetonation = ((random 10 / sqrt _totalAmmo) min MAX_TIME_BETWEEN_AMMO_DET) max 0.1;
TRACE_2("",_totalAmmo,_timeBetweenAmmoDetonation);
_totalAmmo = _totalAmmo - _removed;
_object setVariable [QGVAR(cookoffMagazines), [_magazines, _totalAmmo]];
// Get magazine info, which is used to spawn projectiles
private _configMagazine = configFile >> "CfgMagazines" >> _magazineClassname;
private _ammo = getText (_configMagazine >> "ammo");
private _configAmmo = configFile >> "CfgAmmo" >> _ammo;
private _simType = toLower getText (_configAmmo >> "simulation");
private _speed = linearConversion [0, 1, random 1, 1, 20, true];
private _effect2pos = _object selectionPosition "destructionEffect2";
// Spawns the projectiles, making them either fly in random directions or explode
private _fnc_spawnProjectile = {
// If the magazines are inside of the cargo (inventory), don't let their projectiles escape the interior of the vehicle
if (!_spawnProjectile) exitWith {};
params ["_object", "_ammo", "_speed", "_flyAway"];
private _spawnPos = _object modelToWorld [-0.2 + random 0.4, -0.2 + random 0.4, random 3];
if (_spawnPos select 2 < 0) then {
_spawnPos set [2, 0];
};
private _projectile = createVehicle [_ammo, _spawnPos, [], 0, "CAN_COLLIDE"];
if (_flyAway) then {
private _vectorAmmo = [-1 + random 2, -1 + random 2, -0.2 + random 1];
private _vectorVelocity = _vectorAmmo vectorMultiply _speed;
_projectile setVectorDir _vectorVelocity;
_projectile setVelocity _vectorVelocity;
} else {
_projectile setDamage 1;
};
};
switch (_simType) do {
case "shotbullet": {
[QGVAR(playCookoffSound), [_object, _simType]] call CBA_fnc_globalEvent;
if (random 1 < 0.6) then {
[_object, _ammo, _speed, true] call _fnc_spawnProjectile;
};
};
case "shotshell": {
[QGVAR(playCookoffSound), [_object, _simType]] call CBA_fnc_globalEvent;
if (random 1 < 0.15) then {
[_object, _ammo, _speed, true] call _fnc_spawnProjectile;
};
};
case "shotgrenade": {
if (random 1 < 0.9) then {
_speed = 0;
};
[_object, _ammo, _speed, random 1 < 0.5] call _fnc_spawnProjectile;
};
case "shotrocket";
case "shotmissile";
case "shotsubmunitions": {
if (random 1 < 0.1) then {
[QGVAR(playCookoffSound), [_object, _simType]] call CBA_fnc_globalEvent;
[_object, _ammo, _speed, random 1 < 0.3] call _fnc_spawnProjectile;
} else {
createVehicle ["ACE_ammoExplosionLarge", _object modelToWorld _effect2pos, [], 0 , "CAN_COLLIDE"];
};
};
case "shotdirectionalbomb";
case "shotmine": {
if (random 1 < 0.5) then {
// Not all explosives detonate on destruction, some have scripted alternatives
if (getNumber (_configAmmo >> "triggerWhenDestroyed") != 1) then {
_ammo = getText (_configAmmo >> QEGVAR(explosives,explosive));
};
// If a scripted alternative doesn't exist use generic explosion
if (_ammo != "") then {
[_object, _ammo, 0, false] call _fnc_spawnProjectile;
} else {
createVehicle ["SmallSecondary", _object modelToWorld _effect2pos, [], 0 , "CAN_COLLIDE"];
};
};
};
case "shotilluminating": {
if (random 1 < 0.15) then {
[_object, _ammo, _speed, random 1 < 0.3] call _fnc_spawnProjectile;
};
};
};
// Detonate the remaining ammo after a delay
[LINKFUNC(detonateAmmunitionServerLoop), [_object, _destroyWhenFinished, _source, _instigator], _timeBetweenAmmoDetonation] call CBA_fnc_waitAndExecute;

View File

@ -1,51 +0,0 @@
#include "..\script_component.hpp"
/*
* Author: KoffeinFlummi, commy2
* Start fire in engine block of a car.
*
* Arguments:
* 0: Vehicle <Object>
*
* Return Value:
* None
*
* Example:
* (vehicle player) call ace_cookoff_fnc_engineFire
*
* Public: No
*/
params ["_vehicle"];
if (_vehicle getVariable [QGVAR(isEngineSmoking), false]) exitWith {};
_vehicle setVariable [QGVAR(isEngineSmoking), true];
if (local _vehicle) then {
[QGVAR(engineFire), _vehicle] call CBA_fnc_globalEvent;
};
private _offset = getArray (_vehicle call CBA_fnc_getObjectConfig >> QGVAR(engineSmokeOffset));
if (_offset isEqualTo []) then {
_offset = [0,0,0];
};
private _position = [
0,
(boundingBoxReal _vehicle select 1 select 1) - 2,
(boundingBoxReal _vehicle select 0 select 2) + 2
] vectorAdd _offset;
private _smoke = "#particlesource" createVehicleLocal [0,0,0];
_smoke setParticleClass "ObjectDestructionSmoke1_2Smallx";
_smoke attachTo [_vehicle, _position];
[{
(_this select 0) params ["_vehicle", "_smoke", "_time"];
if (isNull _vehicle || {!alive _vehicle} || {_vehicle getHitPointDamage "HitEngine" < 0.9} || {CBA_missionTime > _time}) then {
deleteVehicle _smoke;
_vehicle setVariable [QGVAR(isEngineSmoking), false];
[_this select 1] call CBA_fnc_removePerFrameHandler;
};
}, 5, [_vehicle, _smoke, CBA_missionTime + 240]] call CBA_fnc_addPerFrameHandler;

View File

@ -0,0 +1,81 @@
#include "..\script_component.hpp"
/*
* Author: KoffeinFlummi, commy2, johnb43
* Start fire in engine block of a car.
*
* Arguments:
* 0: Vehicle <OBJECT>
* 1: End time <NUMBER>
*
* Return Value:
* None
*
* Example:
* [cursorObject, CBA_missionTime + 10] call ace_cookoff_fnc_engineFireLocal
*
* Public: No
*/
params ["_vehicle", "_endTime"];
// For JIP players and if the time wasn't set properly
if (_endTime < CBA_missionTime) exitWith {};
private _smoke = objNull;
if (hasInterface) then {
private _hitPoints = getAllHitPointsDamage _vehicle;
// Get hitpoint for engine
private _index = (_hitPoints select 0) findIf {_x == "hitengine"};
// Get corresponding selection
private _position = if (_index != -1) then {
_vehicle selectionPosition [(_hitPoints select 1) select _index, "HitPoints", "AveragePoint"]
} else {
[0, 0, 0]
};
if (_position isEqualTo [0, 0, 0]) then {
// Get offset for engine smoke if there is one
private _offset = getArray (configOf _vehicle >> QGVAR(engineSmokeOffset));
if (_offset isEqualTo []) then {
_offset = [0, 0, 0];
};
_position = [
0,
(boundingBoxReal _vehicle select 1 select 1) - 2,
(boundingBoxReal _vehicle select 0 select 2) + 2
] vectorAdd _offset;
};
// Spawn smoke
_smoke = createVehicleLocal ["#particlesource", ASLToAGL getPosASL _vehicle, [], 0, "CAN_COLLIDE"];;
_smoke setParticleClass "ObjectDestructionSmoke1_2Smallx";
_smoke attachTo [_vehicle, _position];
};
[{
(_this select 0) params ["_vehicle", "_smoke", "_endTime"];
if (alive _vehicle && {_vehicle getHitPointDamage "HitEngine" >= 0.9} && {CBA_missionTime < _endTime}) exitWith {};
(_this select 1) call CBA_fnc_removePerFrameHandler;
deleteVehicle _smoke;
if (!isServer || {isNull _vehicle}) exitWith {};
// Reset variable, so engine can smoke again in the future
_vehicle setVariable [QGVAR(isEngineSmoking), nil, true];
private _jipID = _vehicle getVariable QGVAR(engineFireJipID);
if (isNil "_jipID") exitWith {};
_jipID call CBA_fnc_removeGlobalEventJIP;
_vehicle setVariable [QGVAR(engineFireJipID), nil];
}, 5, [_vehicle, _smoke, _endTime]] call CBA_fnc_addPerFrameHandler;

View File

@ -0,0 +1,34 @@
#include "..\script_component.hpp"
/*
* Author: KoffeinFlummi, commy2, johnb43
* Start fire in engine block of a car.
*
* Arguments:
* 0: Vehicle <OBJECT>
*
* Return Value:
* None
*
* Example:
* cursorObject call ace_cookoff_fnc_engineFireServer
*
* Public: No
*/
if (!isServer) exitWith {};
params ["_vehicle"];
// If already smoking, stop
if (_vehicle getVariable [QGVAR(isEngineSmoking), false]) exitWith {};
_vehicle setVariable [QGVAR(isEngineSmoking), true, true];
// Spawn engine fire effects on all connected machines
private _jipID = [QGVAR(engineFireLocal), [_vehicle, CBA_missionTime + random [ENGINE_FIRE_TIME / 2, ENGINE_FIRE_TIME, ENGINE_FIRE_TIME / 2 * 3]]] call CBA_fnc_globalEventJIP;
[_jipID, _vehicle] call CBA_fnc_removeGlobalEventJIP;
_vehicle setVariable [QGVAR(engineFireJipID), _jipID];
// API
[QGVAR(engineFire), [_vehicle]] call CBA_fnc_globalEvent;

View File

@ -1,65 +1,76 @@
#include "..\script_component.hpp"
/*
* Author: PabstMirror
* Gets all magazines inside of a vehicle.
* Gets all magazines inside of an object.
*
* Arguments:
* 0: Vehicle <Object>
* 0: Object <OBJECT>
*
* Return Value:
* 0: Ammo Array <ARRAY>
* - 0: Magazine Classname <STRING>
* - 1: Ammo Count <NUMBER>
* 1: Total Ammo Count <NUMBER>
* 0: Ammo array <ARRAY>
* - 0: Magazine classname <STRING>
* - 1: Ammo count <NUMBER>
* - 2: If a projectile should be spawned upon detonation <BOOL>
* 1: Total ammo count <NUMBER>
*
* Example:
* [vehicle player] call ace_cookoff_fnc_getVehicleAmmo
* cursorObject call ace_cookoff_fnc_getVehicleAmmo
*
* Public: No
*/
params ["_vehicle"];
TRACE_1("getVehicleAmmo",_vehicle);
params ["_object"];
TRACE_1("getVehicleAmmo",_object);
private _ammoToDetonate = [];
private _totalAmmo = 0;
private _cfgMagazines = configFile >> "CfgMagazines";
private _cfgAmmo = configFile >> "CfgAmmo";
private _ammo = "";
// Get ammo from turrets
{
_x params ["_mag", "_turret", "_count"];
// if the turret is an FFV seat, it takes magazines from the soldier
if (_count > 0) then {
if (_mag call FUNC(isMagazineFlare)) then {continue};
private _ammo = getText (configFile >> "CfgMagazines" >> _mag >> "ammo");
private _model = getText (configFile >> "CfgAmmo" >> _ammo >> "model");
if (_model == "\A3\weapons_f\empty") exitWith {TRACE_3("skipping",_mag,_ammo,_model);};
_ammoToDetonate pushBack [_mag, _count];
// If the turret is an FFV seat, it takes magazines from the soldier
_x params ["_magazine", "", "_count"];
if (_count > 0 && {!(_magazine call FUNC(isMagazineFlare))}) then {
_ammo = getText (_cfgMagazines >> _magazine >> "ammo");
if (getText (_cfgAmmo >> _ammo >> "model") == "\A3\weapons_f\empty") then {
TRACE_2("skipping",_magazine,_ammo);
continue;
};
_ammoToDetonate pushBack [_magazine, _count, true];
_totalAmmo = _totalAmmo + _count;
};
} forEach (magazinesAllTurrets [_vehicle, true]);
} forEach (magazinesAllTurrets [_object, true]);
// Get ammo from cargo space
{
_x params ["_mag", "_count"];
if (_count > 0) then {
if (_mag call FUNC(isMagazineFlare)) then {continue};
_ammoToDetonate pushBack [_mag, _count];
_x params ["_magazine", "_count"];
if (_count > 0 && {!(_magazine call FUNC(isMagazineFlare))}) then {
_ammoToDetonate pushBack [_magazine, _count, false];
_totalAmmo = _totalAmmo + _count;
};
} forEach (magazinesAmmoCargo _vehicle);
} forEach (magazinesAmmoCargo _object);
// Get ammo from transportAmmo / ace_rearm
private _vehCfg = configOf _vehicle;
private _configVehicle = configOf _object;
private _configSupply = (getNumber (_configVehicle >> "transportAmmo")) max (getNumber (_configVehicle >> QEGVAR(rearm,defaultSupply)));
private _configSupply = (getNumber (_vehCfg >> "transportAmmo")) max (getNumber (_vehCfg >> QEGVAR(rearm,defaultSupply)));
if (_vehicle getVariable [QEGVAR(rearm,isSupplyVehicle), (_configSupply > 0)]) then {
TRACE_1("transportAmmo vehicle - adding virtual ammo",typeOf _vehicle);
if (_object getVariable [QEGVAR(rearm,isSupplyVehicle), _configSupply > 0]) then {
TRACE_1("transportAmmo vehicle - adding virtual ammo",typeOf _object);
_ammoToDetonate pushBack ["2000Rnd_65x39_belt", 2000];
_ammoToDetonate pushBack ["2000Rnd_65x39_belt", 2000, false];
_totalAmmo = _totalAmmo + 2000;
_ammoToDetonate pushBack ["20Rnd_105mm_HEAT_MP", 100];
_ammoToDetonate pushBack ["20Rnd_105mm_HEAT_MP", 100, true];
_totalAmmo = _totalAmmo + 100;
_ammoToDetonate pushBack ["SatchelCharge_Remote_Mag", 10];
_ammoToDetonate pushBack ["SatchelCharge_Remote_Mag", 10, true];
_totalAmmo = _totalAmmo + 10;
};

View File

@ -1,13 +1,13 @@
#include "..\script_component.hpp"
/*
* Author: KoffeinFlummi, commy2
* Handles all incoming damage for boxi
* Author: KoffeinFlummi, commy2, johnb43
* Handles all incoming damage for boxes.
*
* Arguments:
* HandleDamage EH <ARRAY>
*
* Return Value:
* Damage to be inflicted. <NUMBER>
* Damage to be inflicted (can be nil) <NUMBER>
*
* Example:
* _this call ace_cookoff_fnc_handleDamageBox
@ -15,58 +15,48 @@
* Public: No
*/
params ["_vehicle", "", "_damage", "_source", "_ammo", "_hitIndex", "_shooter"];
// If cookoff for boxes is disabled, exit
if (!GVAR(enableAmmobox) || {GVAR(ammoCookoffDuration) == 0}) exitWith {};
// it's already dead, who cares?
if (damage _vehicle >= 1) exitWith {};
params ["_box", "", "_damage", "_source", "_ammo", "", "_instigator", "_hitPoint"];
// If cookoff is disabled exit
if (_vehicle getVariable [QGVAR(enable), GVAR(enable)] in [0, false]) exitWith {};
if (!local _box) exitWith {};
// get hitpoint name
private _hitpoint = "#structural";
// If it's already dead, ignore
if (!alive _box) exitWith {};
if (_hitIndex != -1) then {
_hitpoint = toLowerANSI ((getAllHitPointsDamage _vehicle param [0, []]) select _hitIndex);
};
if !(_box getVariable [QGVAR(enableAmmoCookoff), true]) exitWith {};
// get change in damage
private _oldDamage = 0;
if !(_hitPoint == "" && {_damage > 0.5}) exitWith {}; // "" means structural damage
if (_hitpoint isEqualTo "#structural") then {
_oldDamage = damage _vehicle;
private _ammoConfig = _ammo call CBA_fnc_getObjectConfig;
// Catch fire when hit by an explosive or incendiary round
if ((getNumber (_ammoConfig >> "explosive") >= 0.5) || {getNumber (_ammoConfig >> QEGVAR(vehicle_damage,incendiary)) > random 1}) then {
[QGVAR(cookOffBoxServer), [_box, _source, _instigator]] call CBA_fnc_serverEvent;
} else {
_oldDamage = _vehicle getHitIndex _hitIndex;
};
// There is a small chance of cooking a box off if it's shot by tracer ammo
if (random 1 >= _damage * 0.05) exitWith {};
if (_hitpoint == "#structural" && _damage > 0.5) then {
// Almost always catch fire when hit by an explosive
if (IS_EXPLOSIVE_AMMO(_ammo)) then {
_vehicle call FUNC(cookOffBox);
// Need magazine to check for tracers
private _magazine = if (_source == _instigator) then {
currentMagazine _source
} else {
// Need magazine to check for tracers
private _mag = "";
if (_source == _shooter) then {
_mag = currentMagazine _source;
} else {
_mag = _source currentMagazineTurret ([_shooter] call CBA_fnc_turretPath);
};
private _magCfg = configFile >> "CfgMagazines" >> _mag;
// Magazine could have changed during flight time (just ignore if so)
if (getText (_magCfg >> "ammo") == _ammo) then {
// If magazine's tracer density is high enough then low chance for cook off
private _tracers = getNumber (_magCfg >> "tracersEvery");
if (_tracers >= 1 && {_tracers <= 4}) then {
if (random 1 < _oldDamage*0.05) then {
_vehicle call FUNC(cookOffBox);
};
};
};
_source currentMagazineTurret (_source unitTurret _instigator)
};
// prevent destruction, let cook-off handle it if necessary
_damage min 0.89
} else {
_damage
private _configMagazine = configFile >> "CfgMagazines" >> _magazine;
// Magazine could have changed during flight time (just ignore if so)
if (getText (_configMagazine >> "ammo") == _ammo) then {
// If magazine's tracer density is high enough then low chance for cook off
private _tracers = getNumber (_configMagazine >> "tracersEvery");
if (_tracers >= 1 && {_tracers <= 4}) then {
[QGVAR(cookOffBoxServer), [_box, _source, _instigator]] call CBA_fnc_serverEvent;
};
};
};
// Prevent destruction, let cook-off handle it if necessary
_damage min 0.89

View File

@ -1,24 +1,22 @@
#include "..\script_component.hpp"
/*
* Author: Cyruz
* Checks if the magazine has ammo which is a flare
* Checks if the magazine's ammo are flares.
*
* Arguments:
* 0: Magazine <STRING>
*
* Return Value:
* 0: If magazine is type of flare <BOOL>
* If magazine is type of flare <BOOL>
*
* Example:
* ["3Rnd_UGL_FlareWhite_F"] call ace_cookoff_fnc_isMagazineFlare
* "3Rnd_UGL_FlareWhite_F" call ace_cookoff_fnc_isMagazineFlare
*
* Public: No
*/
params ["_magazine"];
private _ammo = getText (configFile >> "CfgMagazines" >> _magazine >> "ammo");
private _intensity = getNumber (configFile >> "CfgAmmo" >> _ammo >> "intensity");
private _flare = getNumber (configFile >> "CfgAmmo" >> _ammo >> QEGVAR(grenades,flare));
private _configAmmo = configFile >> "CfgAmmo" >> getText (configFile >> "CfgMagazines" >> _magazine >> "ammo");
_intensity != 0 || _flare == 1
getNumber (_configAmmo >> "intensity") != 0 || {getNumber (_configAmmo >> QEGVAR(grenades,flare)) == 1}

View File

@ -5,7 +5,7 @@
*
* Arguments:
* 0: Vehicle <OBJECT>
* 1. Selections for smoke to come out of <ARRAY> (default: [])
* 1: Selections for smoke to come out of <ARRAY>
*
* Return Value:
* None
@ -16,12 +16,11 @@
* Public: No
*/
params ["_vehicle", ["_positions", []]];
params ["_vehicle", "_selections"];
private _turretConfig = [_vehicle, [0]] call CBA_fnc_getTurret;
private _positionBarrelEnd = getText (_turretConfig >> "gunBeg");
private _positionBarrelEnd = getText ([_vehicle, [0]] call CBA_fnc_getTurret >> "gunBeg");
// smoke out of cannon and hatches
// Smoke out of cannon and hatches
private _smokeBarrel = "#particlesource" createVehicleLocal [0, 0, 0];
_smokeBarrel setParticleClass "MediumDestructionSmoke";
_smokeBarrel attachTo [_vehicle, [0, 0, 0], _positionBarrelEnd];
@ -29,10 +28,10 @@ _smokeBarrel attachTo [_vehicle, [0, 0, 0], _positionBarrelEnd];
private _effects = [_smokeBarrel];
{
private _position = [0, -2, 0];
if (_x isNotEqualTo "#noselection") then {
_position = _vehicle selectionPosition _x;
private _position = if (_x != "#noselection") then {
_vehicle selectionPosition _x
} else {
[0, -2, 0]
};
private _smoke = "#particlesource" createVehicleLocal [0, 0, 0];
@ -40,6 +39,6 @@ private _effects = [_smokeBarrel];
_smoke attachTo [_vehicle, _position];
_effects pushBack _smoke;
} forEach _positions;
} forEach _selections;
_vehicle setVariable [QGVAR(effects), _effects];

View File

@ -1,69 +1,71 @@
[
QGVAR(enable), "LIST",
[LSTRING(enable_hd_name), LSTRING(enable_hd_tooltip)],
LSTRING(category_displayName),
[[0, 1, 2], ["STR_A3_OPTIONS_DISABLED", ELSTRING(common,playerOnly), ELSTRING(common,playersAndAI)], 2],
true, // isGlobal
{[QGVAR(enable), _this] call EFUNC(common,cbaSettings_settingChanged)},
true // Needs mission restart
] call CBA_fnc_addSetting;
[
QGVAR(enableFire), "CHECKBOX",
QGVAR(enableFire),
"CHECKBOX",
[LSTRING(enableFire_name), LSTRING(enableFire_tooltip)],
LSTRING(category_displayName),
true, // default value
true, // isGlobal
{[QGVAR(enableFire), _this] call EFUNC(common,cbaSettings_settingChanged)},
false // Needs mission restart
true,
1
] call CBA_fnc_addSetting;
[
QGVAR(destroyVehicleAfterCookoff), "CHECKBOX",
[LSTRING(destroyVehicleAfterCookoff_name), LSTRING(destroyVehicleAfterCookoff_tooltip)],
QGVAR(cookoffDuration),
"SLIDER",
[LSTRING(cookoffDuration_name), LSTRING(cookoffDuration_tooltip)],
LSTRING(category_displayName),
false, // default value
true, // isGlobal
{[QGVAR(destroyVehicleAfterCookoff), _this] call EFUNC(common,cbaSettings_settingChanged)},
false // Needs mission restart
[0, 10, 1, 2],
1
] call CBA_fnc_addSetting;
[
QGVAR(enableAmmoCookoff), "CHECKBOX",
[LSTRING(enableAmmoCookoff_name), LSTRING(enableAmmoCookoff_tooltip)],
LSTRING(category_displayName),
true, // default value
true, // isGlobal
{[QGVAR(enableAmmoCookoff), _this] call EFUNC(common,cbaSettings_settingChanged)},
false // Needs mission restart
] call CBA_fnc_addSetting;
[
QGVAR(enableAmmobox), "CHECKBOX",
[LSTRING(enableBoxCookoff_name), LSTRING(enableBoxCookoff_tooltip)],
LSTRING(category_displayName),
true, // default value
true, // isGlobal
{[QGVAR(enableAmmobox), _this] call EFUNC(common,cbaSettings_settingChanged)},
true // Needs mission restart
] call CBA_fnc_addSetting;
[
QGVAR(ammoCookoffDuration), "SLIDER",
[LSTRING(ammoCookoffDuration_name), LSTRING(ammoCookoffDuration_tooltip)],
LSTRING(category_displayName),
[0,5,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)]
true, // isGlobal
{[QGVAR(ammoCookoffDuration), _this] call EFUNC(common,cbaSettings_settingChanged)},
true // Needs mission restart
] call CBA_fnc_addSetting;
[
QGVAR(probabilityCoef), "SLIDER",
QGVAR(probabilityCoef),
"SLIDER",
[LSTRING(probabilityCoef_name), LSTRING(probabilityCoef_tooltip)],
LSTRING(category_displayName),
[0,5,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)]
true, // isGlobal
{[QGVAR(probabilityCoef), _this] call EFUNC(common,cbaSettings_settingChanged)},
true // Needs mission restart
[0, 10, 1, 2],
1
] call CBA_fnc_addSetting;
[
QGVAR(destroyVehicleAfterCookoff),
"CHECKBOX",
[LSTRING(destroyVehicleAfterCookoff_name), LSTRING(destroyVehicleAfterCookoff_tooltip)],
LSTRING(category_displayName),
false,
1
] call CBA_fnc_addSetting;
[
QGVAR(enableAmmoCookoff),
"CHECKBOX",
[LSTRING(enableAmmoCookoff_name), LSTRING(enableAmmoCookoff_tooltip)],
LSTRING(category_displayName),
true,
1
] call CBA_fnc_addSetting;
[
QGVAR(enableAmmobox),
"CHECKBOX",
[LSTRING(enableBoxCookoff_name), LSTRING(enableBoxCookoff_tooltip)],
LSTRING(category_displayName),
true,
1
] call CBA_fnc_addSetting;
[
QGVAR(ammoCookoffDuration),
"SLIDER",
[LSTRING(ammoCookoffDuration_name), LSTRING(ammoCookoffDuration_tooltip)],
LSTRING(category_displayName),
[0, 10, 1, 2],
1
] call CBA_fnc_addSetting;
[
QGVAR(removeAmmoDuringCookoff),
"CHECKBOX",
[LSTRING(removeAmmoDuringCookoff_name), LSTRING(removeAmmoDuringCookoff_tooltip)],
LSTRING(category_displayName),
true,
1
] call CBA_fnc_addSetting;

View File

@ -16,14 +16,12 @@
#include "\z\ace\addons\main\script_macros.hpp"
#define IS_EXPLOSIVE_AMMO(ammo) (getNumber (ammo call CBA_fnc_getObjectConfig >> "explosive") > 0.5)
// Stages of cookoff in order (in seconds)
// Should be no un-synced randomness in these as the effects must be ran on each client
#define IGNITE_TIME 3
#define SMOKE_TIME 10.5
// Should be no un-synced randomness in these as the effects must be run on each client
#define SMOKE_DELAY 10.5
#define DETONATION_DELAY 3
#define COOKOFF_TIME 14 // Cook off time should be 20s at most due to length of sound files
#define COOKOFF_TIME_BOX 82.5 // Cook off time for boxes should be significant to allow time for ammo to burn
#define ENGINE_FIRE_TIME 240
#define MIN_TIME_BETWEEN_FLAMES 5
#define MAX_TIME_BETWEEN_FLAMES 15
#define MAX_TIME_BETWEEN_AMMO_DET 25
@ -32,9 +30,6 @@
#define MIN_AMMO_DETONATION_START_DELAY 1 // Min time to wait before a vehicle's ammo starts to cookoff
#define MAX_AMMO_DETONATION_START_DELAY 6 // Max time to wait before a vehicle's ammo starts to cookoff
// Delay between flame effect for players in a cooking off vehicle
#define FLAME_EFFECT_DELAY 0.4
// Common commander hatch defines for default vehicles
#define DEFAULT_COMMANDER_HATCHES ["osa_poklop_commander", "hatch_commander_axis"]

View File

@ -2,7 +2,7 @@
<Project name="ACE">
<Package name="CookOff">
<Key ID="STR_ACE_CookOff_category_displayName">
<English>ACE Cook off</English>
<English>ACE Cook-off</English>
<Spanish>ACE Detonación inducida por calor</Spanish>
<Italian>ACE Detonazione Munizioni</Italian>
<Chinese>ACE 殉爆效果</Chinese>
@ -16,158 +16,26 @@
<Portuguese>ACE Cook off</Portuguese>
<Czech>ACE Vznícení munice</Czech>
</Key>
<Key ID="STR_ACE_CookOff_enable_hd_name">
<English>Damage handling and turret effects</English>
<Spanish>Daño y efectos de torreta</Spanish>
<German>Schadensberechnung und Geschützturmeffekte</German>
<Japanese>損傷処理と砲塔の効果</Japanese>
<Russian>Обработка урона и эффектов срыва башни</Russian>
<Portuguese>Manipulação de dano e efeitos de torre</Portuguese>
<French>Dégâts et effets de tourelle</French>
<Chinese>傷害控制及炮塔效果</Chinese>
<Chinesesimp>损坏处理和炮塔效果</Chinesesimp>
<Italian>Gestione danni ed effetti torretta</Italian>
<Czech>Poškodit ovládání a efekty věže</Czech>
<Polish>Obsługa obrażeń i efekty wieży</Polish>
<Korean>피해량 조절 및 포탑에 효과 부여</Korean>
<Key ID="STR_ACE_CookOff_enableFire_name">
<English>Enable vehicle cook-off fire</English>
</Key>
<Key ID="STR_ACE_CookOff_enable_hd_tooltip">
<English>Changes damage handling for cook off and turret explosion effects</English>
<Spanish>Cambia el daño de la detonación inducida por calor y los efectos de la explosión de la torreta</Spanish>
<German>Ändert die Schadensberechnung für die Durchzündung und die Explosionseffekte des Geschützturmes</German>
<Japanese>誘爆の損傷処理と砲塔の爆発効果を変更します。</Japanese>
<Russian>Изменяет обработку урона для возгорания и эффекта срыва башни</Russian>
<Portuguese>Modifica a manipulação de dano para o cozinhamento de munição e efeitos de explosão da torre</Portuguese>
<French>Modifie la gestion des dégâts pour l'auto-inflammation et les effets d'explosion de tourelle.</French>
<Chinese>更改殉爆以及炮塔爆炸之傷害控制</Chinese>
<Chinesesimp>改变殉爆和炮塔爆炸的损坏处理效果</Chinesesimp>
<Italian>Modifica la gestione dei danni per l'esplosione di munizioni e gli effetti di esplosione della torretta</Italian>
<Czech>Změní poškození ovládání a efekty výbuchu veže</Czech>
<Polish>Zmienia obsługę obrażeń podczas samozapłonu i eksplozji wieży</Polish>
<Korean>쿡오프로 인해 피해량의 변화와 포탑 터짐현상을 결정합니다.</Korean>
<Key ID="STR_ACE_CookOff_enableFire_tooltip">
<English>Enables vehicle cook-off fire effects.\nThis doesn't include ammunition detonations.</English>
</Key>
<Key ID="STR_ACE_CookOff_enableBoxCookoff_name">
<English>Enable ammo box cook off</English>
<Spanish>Habilitar detonación inducida por calor en las cajas de munición</Spanish>
<Japanese>弾薬箱の誘爆を有効化</Japanese>
<German>Durchzündung für Munitionskisten ermöglichen</German>
<Korean>탄약 상자 쿡오프 현상 활성화</Korean>
<Polish>Aktywuj samozapłon skrzyń z amunicją</Polish>
<French>Auto-inflammation des caisses de munitions</French>
<Italian>Abilita esplosione casse munizioni</Italian>
<Chinese>開啟彈藥箱殉爆效果</Chinese>
<Chinesesimp>开启弹药箱殉爆效果</Chinesesimp>
<Russian>Разрешить детонацию ящиков с боеприпасами</Russian>
<Portuguese>Permitir cozinhar caixas de munição</Portuguese>
<Czech>Povolit vynícení munice v krabicích</Czech>
<Key ID="STR_ACE_CookOff_cookoffDuration_name">
<English>Vehicle cook-off fire duration multiplier</English>
</Key>
<Key ID="STR_ACE_CookOff_enableBoxCookoff_tooltip">
<English>Enables cooking off of ammo boxes.</English>
<Spanish>Habilita la detonación inducida por calor en las cajas de munición</Spanish>
<Japanese>弾薬箱が誘爆するようになります。</Japanese>
<German>Ermöglicht Durchzündung von Munitionskisten.</German>
<Korean>탄약 상자에 쿡오프 현상을 적용합니다.</Korean>
<Polish>Aktywuje samozapłon skrzyń z amunicją</Polish>
<French>Permet l'auto-inflammation des caisses de munitions.</French>
<Italian>Abilita l'esplosione di casse di munizioni distrutte.</Italian>
<Chinese>開啟彈藥箱殉爆效果</Chinese>
<Chinesesimp>开启弹药箱殉爆效果</Chinesesimp>
<Russian>Активирует детонацию ящиков с боеприпасами</Russian>
<Portuguese>Permitir que caixas de munição cozinhem.</Portuguese>
<Czech>Zapíná vznícení munice v krabicích.</Czech>
</Key>
<Key ID="STR_ACE_CookOff_enableAmmoCookoff_name">
<English>Enable Ammunition cook off</English>
<Spanish>Habilitar la detonación inducida por calor en la munición</Spanish>
<Japanese>弾薬の誘爆を有効化</Japanese>
<German>Durchzündung für Munition ermöglichen</German>
<Korean>탄약 쿡오프 현상 활성화</Korean>
<Polish>Aktywuj samozapłon amunicji</Polish>
<French>Auto-inflammation des munitions</French>
<Italian>Abilita Esplosione Munizioni</Italian>
<Chinese>開啟彈藥殉爆效果</Chinese>
<Chinesesimp>开启弹药殉爆效果</Chinesesimp>
<Russian>Разрешить детонацию боекомплекта</Russian>
<Portuguese>Permitir cozinhar munição</Portuguese>
<Czech>Povolit vznícení munice</Czech>
</Key>
<Key ID="STR_ACE_CookOff_enableAmmoCookoff_tooltip">
<English>Enables Ammunition cook off. Fires ammunition projectiles while vehicle is on fire and has ammunition.</English>
<Spanish>Habilita la detonación inducida por calor en la munición. Dispara proyectiles de munición mientras el vehículo está ardiendo y tiene munición</Spanish>
<Japanese>弾薬が誘爆します。車両が燃えると、搭載している弾薬が激しく燃え上がります。</Japanese>
<German>Ermöglicht Durchzündung von Munition. Feuert Projektile der Munition ab, solange das Fahrzeug brennt und Munition besitzt.</German>
<Polish>Aktywuje samozapłon amunicji. Wystrzeliwuje pociski podczas gdy pojazd płonie i posiada amunicję.</Polish>
<French>Permet l'auto-inflammation des munitions. Tire des projectiles tant que le véhicule est en feu et contient des munitions.</French>
<Italian>Abilita l'esplosione di munizioni. Spara proiettili di munizioni quando il veicolo va a fuoco e contiene ancora munizioni.</Italian>
<Chinese>開啟彈藥殉爆效果。當一台載有彈藥的載具起火時, 將會有殉爆的效果</Chinese>
<Chinesesimp>开启弹药殉爆效果。当一台载有弹药的载具起火时,将会有殉爆的效果。</Chinesesimp>
<Korean>쿡오프 현상을 활성화 합니다. 이것은 탄약에 불이 붙어 있는 동안 주변에 발사체를 발사합니다.</Korean>
<Russian>Активирует детонацию боекомплекта в горящей технике.</Russian>
<Portuguese>Permite que a munição cozinhe. Dispara projéteis de munição enquanto o veículo está em chamas e tem munição.</Portuguese>
<Czech>Zapíná vznícení munice. Vystřeluje projektily po dobu kdy vozidlo hoří a má munici.</Czech>
</Key>
<Key ID="STR_ACE_CookOff_ammoCookoffDuration_name">
<English>Ammunition cook off duration</English>
<Spanish>Duración de la detonación inducida por calor de la munición</Spanish>
<German>Munitionsdurchzündungsdauer</German>
<Polish>Czas trwania samozapłonu amunicji</Polish>
<Japanese>弾薬の誘爆持続時間</Japanese>
<French>Durée d'auto-inflammation des munitions</French>
<Italian>Durata Esplosione Munizioni</Italian>
<Chinese>彈藥殉爆效果持續時間</Chinese>
<Chinesesimp>弹药殉爆效果持续时间</Chinesesimp>
<Korean>쿡오프 지속 시간</Korean>
<Russian>Длительность детонации боеприпасов</Russian>
<Portuguese>Duração do cozinhamento de munição</Portuguese>
<Czech>Doba trvání vznícení munice</Czech>
</Key>
<Key ID="STR_ACE_CookOff_ammoCookoffDuration_tooltip">
<English>Multiplier for how long cook off lasts [Setting to 0 will disable ammo cookoff]</English>
<Spanish>Multiplicador de cuanto dura la detonación inducida por calor [Ponerlo a cero la deshabilita]</Spanish>
<German>Faktor für die Munitionsdurchzündungsdauer [0 zum Deaktivieren]</German>
<French>Multiplicateur permettant de régler la durée durant laquelle les munitions continuent d'exploser [Une valeur de 0 désactive l'auto-inflammation].</French>
<Polish>Mnożnik decydujący jak długo ma trwać samozapłon amunicji [Ustawienie na 0 spowoduje wyłącznie samozapłonu]</Polish>
<Japanese>誘爆の持続時間を乗数で設定します。[0 に設定で誘爆を無効化]</Japanese>
<Italian>Moltiplicatore della durata delle esplosioni di munizioni [Se impostato su 0 disabiliterà le esplosioni delle munizioni]</Italian>
<Chinese>設定彈藥殉爆效果會持續多久時間 [輸入0來關閉殉爆效果]</Chinese>
<Chinesesimp>设定弹药殉爆效果会持续多久时间 [输入0来关闭殉爆效果]</Chinesesimp>
<Korean>쿡오프 지속 시간의 배수 [0 이면 비활성]</Korean>
<Russian>Множитель длительности детонации [0 - отключает детонацию боеприпасов]</Russian>
<Portuguese>Multiplicação da duração do cozinhamento [0 faz com que o cozinhamento seja desativado]</Portuguese>
<Czech>Multiplikátor doby trvání vznícení munice [Nastavte 0 pro vypnutí vznícení munice]</Czech>
<Key ID="STR_ACE_CookOff_cookoffDuration_tooltip">
<English>Multiplier for how long vehicle cook-off fire lasts.\nSetting to 0 will disable vehicle cook-off fire.</English>
</Key>
<Key ID="STR_ACE_CookOff_probabilityCoef_name">
<English>Cook-off probability coefficient</English>
<Spanish>Coeficiente de probabilidad de detonación inducida por calor</Spanish>
<Japanese>誘爆の可能性係数</Japanese>
<Italian>Coefficiente Probabilità Esplosione</Italian>
<German>Faktor für Wahrscheinlichkeit der Durchzündung</German>
<Chinese>殉爆發生機率係數</Chinese>
<Chinesesimp>殉爆发生机率系数</Chinesesimp>
<French>Coefficient de probabilité d'auto-inflammation</French>
<Polish>Współczynnik prawdopodobieństwa samozapłonu</Polish>
<Russian>Коэф. вероятности детонации</Russian>
<Portuguese>Probabilidade de Cozinhar</Portuguese>
<Czech>Koeficient pravděpodobnosti vznícení munice</Czech>
<Korean>쿡오프 발생 확률 계수</Korean>
<English>Vehicle cook-off fire probability multiplier</English>
</Key>
<Key ID="STR_ACE_CookOff_probabilityCoef_tooltip">
<English>Multiplier for cook-off probability. Higher value results in higher cook-off probability</English>
<Spanish>Multiplicador de probabilidad de detonación inducida por calor. Valores más altos producen mayor probabilidad</Spanish>
<Japanese>誘爆する可能性の乗数。高い値では誘爆する可能性が高まります。</Japanese>
<Italian>Moltiplicatore per la probabilità dell'esplosione di munizioni. Un valore più alto aumenta la probabilità.</Italian>
<German>Faktor für Wahrscheinlichkeit der Durchzündung. Ein höherer Wert führt zu höherer Durchzündungswahrscheinlichkeit.</German>
<Chinese>調整殉爆發生機率係數。值越高代表越容易發生殉爆</Chinese>
<Chinesesimp>调整殉爆发生机率系数。值越高代表越容易发生殉爆。</Chinesesimp>
<French>Multiplicateur de probabilité de l'auto-inflammation. Plus la valeur est élevée, plus la probabilité de combustion est grande.</French>
<Polish>Mnożnik prawdopodobieństwa samozapłonu. Większa wartość oznacza większe prawdopodobieństwo samozapłonu</Polish>
<Russian>Множитель коэффициента вероятности детонации. Чем выше значение, тем выше вероятность</Russian>
<Portuguese>Multiplicador para a chance de cozinhamento. Valores mais altos aumentam as chances de ocorrer.</Portuguese>
<Czech>Multiplikátor pro pravděpodobnost vznícení munice. Vyšší hodnota znamená vyšší šanci vznícení munice.</Czech>
<Korean>쿡오프가 일어날 확률에 계수를 곱합니다. 더 큰 숫자는 더 높은 확률의 쿡오프를 일으킵니다.</Korean>
<English>Multiplier for vehicle cook-off fire probability. Higher value results in higher cook-off probability.\nSetting to 0 will disable vehicle cook-off fire.</English>
</Key>
<Key ID="STR_ACE_CookOff_destroyVehicleAfterCookoff_name">
<English>Destroy Vehicles After Cook-off</English>
<English>Destroy vehicles after cook-off</English>
<Korean>쿡오프 후 차량 파괴</Korean>
<Chinesesimp>殉爆发生后摧毁载具</Chinesesimp>
<Russian>Уничтожать технику после детонации</Russian>
@ -191,31 +59,52 @@
<Russian>Определяет, всегда ли транспортные средства будут уничтожаться после детонации.</Russian>
<Spanish>Controla si los vehículos siempre será destruidos despues de la detonación inducida por calor.</Spanish>
</Key>
<Key ID="STR_ACE_CookOff_enableFire_name">
<English>Enable Cook-Off Vehicle Fire</English>
<Japanese>誘爆火災を有効化</Japanese>
<French>Véhicules - Feu durant l'auto-inflammation</French>
<Russian>Вкл. горение техники от детонации</Russian>
<German>Aktiviert das in Brand setzen des Fahrzeugs während des Durchzündens der Munition</German>
<Italian>Abilita incendiamento veicoli</Italian>
<Polish>Włącz pożar pojazdu podczas samozapłonu</Polish>
<Chinesesimp>启用殉爆载具火灾</Chinesesimp>
<Korean>차량 쿡오프 화재 활성화</Korean>
<Spanish>Habilitar incendio a causa de la detonación inducida por calor</Spanish>
<Portuguese>Ativar incêndio de veículo durante cozinhamento</Portuguese>
<Key ID="STR_ACE_CookOff_enableAmmoCookoff_name">
<English>Enable vehicle ammo cook-off</English>
</Key>
<Key ID="STR_ACE_CookOff_enableFire_tooltip">
<English>Whether or not vehicles will catch on fire during cook-off</English>
<Japanese>誘爆により車両が炎上するかどうかを設定します。</Japanese>
<French>Définit si les véhicules prennent feu durant l'auto-inflammation de leurs munitions.</French>
<Russian>Будет ли техника гореть при детонации боеприпасов</Russian>
<German>Ob Fahrzeuge in Brand gesetzt werden, während deren Munition durchzündet.</German>
<Italian>Determina se veicoli cominceranno a bruciare se le loro munizioni esplodono.</Italian>
<Polish>Określa, czy pojazdy zapalą się podczas samozapłonu ich amunicji.</Polish>
<Chinesesimp>车辆在殉爆过程中是否会起火</Chinesesimp>
<Korean>쿡오프가 일어나면 차량에 불이 붙습니다.</Korean>
<Spanish>Define si los vehículos salen ardiendo despues de una detonación inducida por calor.</Spanish>
<Portuguese>Define se os veículos pegarão fogo durante o cozinhamento.</Portuguese>
<Key ID="STR_ACE_CookOff_enableAmmoCookoff_tooltip">
<English>Enables cooking off of vehicle ammunition. Fires ammunition projectiles while vehicle has ammunition remaining.\nThis doesn't include fire effects.</English>
</Key>
<Key ID="STR_ACE_CookOff_enableBoxCookoff_name">
<English>Enable ammo box cook-off</English>
<Spanish>Habilitar detonación inducida por calor en las cajas de munición</Spanish>
<Japanese>弾薬箱の誘爆を有効化</Japanese>
<German>Durchzündung für Munitionskisten ermöglichen</German>
<Korean>탄약 상자 쿡오프 현상 활성화</Korean>
<Polish>Aktywuj samozapłon skrzyń z amunicją</Polish>
<French>Auto-inflammation des caisses de munitions</French>
<Italian>Abilita esplosione casse munizioni</Italian>
<Chinese>開啟彈藥箱殉爆效果</Chinese>
<Chinesesimp>开启弹药箱殉爆效果</Chinesesimp>
<Russian>Разрешить детонацию ящиков с боеприпасами</Russian>
<Portuguese>Permitir cozinhar caixas de munição</Portuguese>
<Czech>Povolit vynícení munice v krabicích</Czech>
</Key>
<Key ID="STR_ACE_CookOff_enableBoxCookoff_tooltip">
<English>Enables cooking off of ammo boxes.\nThis doesn't include fire effects.</English>
</Key>
<Key ID="STR_ACE_CookOff_ammoCookoffDuration_name">
<English>Ammo cook-off duration multiplier</English>
</Key>
<Key ID="STR_ACE_CookOff_ammoCookoffDuration_tooltip">
<English>Multiplier for how long ammunition cook-off lasts, for both vehicles and ammo boxes.\nSetting to 0 will disable ammo cook-off for both vehicles and ammo boxes.</English>
</Key>
<Key ID="STR_ACE_CookOff_removeAmmoDuringCookoff_name">
<English>Enable ammo removal during cook-off</English>
<Japanese>誘爆中の弾薬除去を有効/無効にする</Japanese>
<French>Retirer les munitions durant l'auto-inflammation</French>
<German>Aktiviert/Deaktiviert Entfernung der Munition beim Durchzünden</German>
<Italian>Abilita rimozione munizioni dopo l'esplosione</Italian>
<Polish>Włącz/Wyłącz usuwanie amunicji podczas samozapłonu</Polish>
<Chinesesimp>启用/禁用殉爆过程中的弹药移除功能</Chinesesimp>
<Korean>쿡오프시 탄약 제거 활성화/비활성화</Korean>
<Russian>Удалять боеприпасы из-за детонации</Russian>
<Spanish>Habilita/Deshabilita ka eliminación de munición durante la detonación inducida por calor</Spanish>
</Key>
<Key ID="STR_ACE_CookOff_removeAmmoDuringCookoff_tooltip">
<English>Removes all ammo during cook-off.</English>
<French>Retire des munitions des véhicules durant une auto-inflammation.</French>
<German>Entfernt Munition während dem Durchzünden der Munition eines Fahrzeuges.</German>
</Key>
</Package>
</Project>

View File

@ -45,17 +45,12 @@ private _categoryArray = [format ["ACE %1", localize LSTRING(DisplayName)]];
[LSTRING(progressBarTimeCoefficent_displayName), LSTRING(progressBarTimeCoefficent_description)],
_categoryArray,
[0,2,1,2], // [min, max, default value, trailing decimals (-1 for whole numbers only)]
true, // isGlobal
{[QGVAR(progressBarTimeCoefficent), _this] call EFUNC(common,cbaSettings_settingChanged)},
false // Needs mission restart
true // isGlobal
] call CBA_fnc_addSetting;
[
QGVAR(dragAfterDeploy), "CHECKBOX",
[LSTRING(dragAfterDeploy_displayName), LSTRING(dragAfterDeploy_description)],
_categoryArray,
false, // default value
false, // isGlobal
{[QGVAR(dragAfterDeploy), _this] call EFUNC(common,cbaSettings_settingChanged)},
false // Needs mission restart
false // default value
] call CBA_fnc_addSetting;

View File

@ -1120,5 +1120,22 @@
<Russian>[CSW] Сумка с СПГ-9М орудием</Russian>
<Korean>[CSW] SPG-9M 발사기 가방</Korean>
</Key>
<!-- Used in rearm to remove the [CSW] prefix from magazine names, so adjust when necessary -->
<Key ID="STR_ACE_CSW_regex">
<English>^\[CSW\]</English>
<Spanish>^\[CSW\]</Spanish>
<German>^\[CSW\]</German>
<Portuguese>^\[CSW\]</Portuguese>
<French>^\[CSW\]</French>
<Japanese>^\[CSW\]</Japanese>
<Chinese>^\[CSW\]</Chinese>
<Chinesesimp>^\[班组\]</Chinesesimp>
<Italian>^\[CSW\]</Italian>
<Czech>^\[CSW\]</Czech>
<Turkish>^\[CSW\]</Turkish>
<Polish>^\[CSW\]</Polish>
<Russian>^\[CSW\]</Russian>
<Korean>^\[CSW\]</Korean>
</Key>
</Package>
</Project>

View File

@ -5,9 +5,7 @@ private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(setting_c
[LSTRING(setting_requireRopeItems_displayName)],
_category,
false, // default value
true, // isGlobal
{[QGVAR(requireRopeItems), _this] call EFUNC(common,cbaSettings_settingChanged)},
false // needRestart
true // isGlobal
] call CBA_fnc_addSetting;
[

View File

@ -21,11 +21,7 @@ params ["_player", "_thirst", "_hunger"];
// Kill unit with max thirst or hunger
if ((_thirst > 99.9 || {_hunger > 99.9}) && {random 1 < 0.5}) exitWith {
if (["ace_medical"] call EFUNC(common,isModLoaded)) then {
[_player, "Hunger/Thirst empty"] call EFUNC(medical_status,setDead);
} else {
_player setDamage 1;
};
[_player, "Hunger/Thirst empty"] call EFUNC(common,setDead);
};
// Exit if unit is not awake, below are animation based consequences

View File

@ -175,10 +175,12 @@ if (isServer) then {
};
if (_x isKindOf "ReammoBox_F") then {
if (
"ace_cookoff" call EFUNC(common,isModLoaded) &&
{GETVAR(_x,EGVAR(cookoff,enableAmmoCookoff),EGVAR(cookoff,enableAmmobox))}
(["ace_cookoff"] call EFUNC(common,isModLoaded)) &&
{EGVAR(cookoff,enableAmmobox)} &&
{EGVAR(cookoff,ammoCookoffDuration) != 0} &&
{_x getVariable [QEGVAR(cookoff,enableAmmoCookoff), true]}
) then {
_x call EFUNC(cookoff,cookOffBox);
[QEGVAR(cookOff,cookOffBoxServer), _box] call CBA_fnc_serverEvent;
} else {
_x setDamage 1;
};
@ -232,10 +234,7 @@ private _enginePosition = _vehicle modelToWorld (_vehicle selectionPosition _eng
if (_position distance _enginePosition < EFFECT_SIZE * 2) then {
_vehicle setHit [_engineSelection, 1];
if ("ace_cookoff" call EFUNC(common,isModLoaded)) then {
private _enabled = _vehicle getVariable [QEGVAR(cookoff,enable), EGVAR(cookoff,enable)];
if (_enabled in [2, true] || {_enabled isEqualTo 1 && {fullCrew [_vehicle, "", false] findIf {isPlayer (_x select 0)} != -1}}) then {
_vehicle call EFUNC(cookoff,engineFire);
};
if (["ace_cookoff"] call EFUNC(common,isModLoaded)) then {
[QEGVAR(cookoff,engineFireServer), _vehicle] call CBA_fnc_serverEvent;
};
};

View File

@ -11,7 +11,7 @@
* None
*
* Example:
* [player, target] call ace_gunbag_fnc_offGunbagCallback
* [player, cursorObject] call ace_gunbag_fnc_offGunbagCallback
*
* Public: No
*/
@ -23,39 +23,28 @@ private _gunbag = backpackContainer _target;
private _state = _gunbag getVariable [QGVAR(gunbagWeapon), []];
if (_state isEqualTo []) exitWith {
[localize LSTRING(empty)] call EFUNC(common,displayTextStructured);
[LLSTRING(empty)] call EFUNC(common,displayTextStructured);
};
_state params ["_weapon", "_items", "_magazines"];
_unit addWeapon _weapon;
[_unit, _weapon, true, _magazines] call EFUNC(common,addWeapon);
// Game will auto add magazines from player's inventory, put these back in player inventory as they will be overwritten
([_unit, _weapon] call EFUNC(common,getWeaponState)) params ["", "", "_addedMags", "_addedAmmo"];
// Add attachments
{
if (((_x select 0) != "") && {(_addedMags select _forEachIndex) != ""}) then {
TRACE_2("Re-adding mag",_x,_addedMags select _forEachIndex);
_unit addMagazine [_addedMags select _forEachIndex, _addedAmmo select _forEachIndex];
};
} forEach _magazines;
removeAllPrimaryWeaponItems _unit;
{
_unit addWeaponItem [_weapon, _x];
} forEach (_items + _magazines);
_unit addWeaponItem [_weapon, _x, true];
} forEach (_items select {_x != ""});
_unit selectWeapon _weapon;
_magazines = _magazines apply {_x select 0};
private _mass = [_weapon, _items, _magazines apply {_x select 0}] call FUNC(calculateMass);
private _mass = [_weapon, _items, _magazines] call FUNC(calculateMass);
// remove virtual load
// Remove virtual load
[_target, _gunbag, -_mass] call EFUNC(movement,addLoadToUnitContainer);
_gunbag setVariable [QGVAR(gunbagWeapon), [], true];
// play sound
// Play sound
if (["ace_backpacks"] call EFUNC(common,isModLoaded)) then {
[_target, _gunbag] call EFUNC(backpacks,backpackOpened);
};

View File

@ -1,6 +1,6 @@
#include "..\script_component.hpp"
/*
* Author: Ir0n1E and mjc4wilton
* Author: Ir0n1E, mjc4wilton
* Swap primary weapon and weapon in gunbag.
*
* Arguments:
@ -11,66 +11,49 @@
* None
*
* Example:
* [player, target] call ace_gunbag_fnc_swapGunbagCallback
* [player, cursorObject] call ace_gunbag_fnc_swapGunbagCallback
*
* Public: No
*/
params ["_unit", "_target"];
private _currentWeapon = primaryWeapon _unit; //Get Current Weapon
// Set up current weapon for storing
private _gunbag = backpackContainer _target;
private _currentItems = (getUnitLoadout _unit) select 0;
private _currentMagazines = _currentItems select [4, 2];
_currentItems deleteRange [4, 2];
//---Set up current weapon for storing
private _currentWeaponState = [_unit, _currentWeapon] call EFUNC(common,getWeaponState); //Gets weapon attachments
private _currentWeapon = _currentItems deleteAt 0;
/*
* example return value _state
* [["","","optic_Aco",""],["arifle_MX_GL_ACO_F","GL_3GL_F"],["30Rnd_65x39_caseless_mag","1Rnd_HE_Grenade_shell"],[30,1]]
*/
private _currentMass = [_currentWeapon, _currentItems, _currentMagazines apply {_x select 0}] call FUNC(calculateMass);
_currentWeaponState params ["_currentWeaponItems", "", "_currentWeaponMagazines", "_currentWeaponAmmo"]; //Extract Weapon Attachments to separate arrays
// Set up weapon in gunbag
private _newState = _gunbag getVariable [QGVAR(gunbagWeapon), []];
private _currentWeaponMass = [_currentWeapon, _currentWeaponItems, _currentWeaponMagazines] call FUNC(calculateMass);
{
_currentWeaponMagazines set [_forEachIndex, [_x, _currentWeaponAmmo select _forEachIndex]];
} forEach _currentWeaponMagazines;
//---Set up weapon in gunbag
private _newWeaponState = _gunbag getVariable [QGVAR(gunbagWeapon), []];
if (_newWeaponState isEqualTo []) exitWith {
if (_newState isEqualTo []) exitWith {
[LLSTRING(empty)] call EFUNC(common,displayTextStructured);
};
_newWeaponState params ["_newWeapon", "_newWeaponItems", "_newWeaponMagazines"];
_newState params ["_newWeapon", "_newItems", "_newMagazines"];
//---Swap Weapons
// Swap Weapons
_unit removeWeapon _currentWeapon;
_unit addWeapon _newWeapon;
// Game will auto add magazines from player's inventory, put these back in player inventory as they will be overwritten
([_unit, _newWeapon] call EFUNC(common,getWeaponState)) params ["", "", "_addedMags", "_addedAmmo"];
[_unit, _newWeapon, true, _newMagazines] call EFUNC(common,addWeapon);
// Add attachments
{
if (((_x select 0) != "") && {(_addedMags select _forEachIndex) != ""}) then {
TRACE_2("Re-adding mag",_x,_addedMags select _forEachIndex);
_unit addMagazine [_addedMags select _forEachIndex, _addedAmmo select _forEachIndex];
};
} forEach _newWeaponMagazines;
removeAllPrimaryWeaponItems _unit;
{
_unit addWeaponItem [_newWeapon, _x];
} forEach (_newWeaponItems + _newWeaponMagazines);
_unit addWeaponItem [_newWeapon, _x, true];
} forEach (_newItems select {_x != ""});
_unit selectWeapon _newWeapon;
_newWeaponMagazines = _newWeaponMagazines apply {_x select 0};
private _newMass = [_newWeapon, _newItems, _newMagazines apply {_x select 0}] call FUNC(calculateMass);
private _newWeaponMass = [_newWeapon, _newWeaponItems, _newWeaponMagazines] call FUNC(calculateMass);
// Update virtual load
[_target, _gunbag, _currentMass - _newMass] call EFUNC(movement,addLoadToUnitContainer);
// update virtual load
[_target, _gunbag, _currentWeaponMass - _newWeaponMass] call EFUNC(movement,addLoadToUnitContainer);
_gunbag setVariable [QGVAR(gunbagWeapon), [_currentWeapon, _currentWeaponItems, _currentWeaponMagazines], true]; //Replace weapon in gunbag
// Replace weapon in gunbag
_gunbag setVariable [QGVAR(gunbagWeapon), [_currentWeapon, _currentItems, _currentMagazines], true];

View File

@ -11,38 +11,32 @@
* None
*
* Example:
* [player, target] call ace_gunbag_fnc_toGunbagCallback
* [player, cursorObject] call ace_gunbag_fnc_toGunbagCallback
*
* Public: No
*/
params ["_unit", "_target"];
private _weapon = primaryWeapon _unit;
// Set up current weapon for storing
private _gunbag = backpackContainer _target;
private _items = (getUnitLoadout _unit) select 0;
private _state = [_unit, _weapon] call EFUNC(common,getWeaponState);
private _magazines = _items select [4, 2];
_items deleteRange [4, 2];
/*
* example return value _state
* [["","","optic_Aco",""],["arifle_MX_GL_ACO_F","GL_3GL_F"],["30Rnd_65x39_caseless_mag","1Rnd_HE_Grenade_shell"],[30,1]]
*/
private _weapon = _items deleteAt 0;
_state params ["_items", "", "_magazines", "_ammo"];
private _mass = [_weapon, _items, _magazines] call FUNC(calculateMass);
{
_magazines set [_forEachIndex, [_x, _ammo select _forEachIndex]];
} forEach _magazines;
private _mass = [_weapon, _items, _magazines apply {_x select 0}] call FUNC(calculateMass);
_unit removeWeapon _weapon;
// add virtual load
// Add virtual load
[_target, _gunbag, _mass] call EFUNC(movement,addLoadToUnitContainer);
_gunbag setVariable [QGVAR(gunbagWeapon), [_weapon, _items, _magazines], true];
// play sound
// Play sound
if (["ace_backpacks"] call EFUNC(common,isModLoaded)) then {
[_target, _gunbag] call EFUNC(backpacks,backpackOpened);
};

View File

@ -1,3 +1,4 @@
ACEX_PREP(blacklist);
ACEX_PREP(endMissionNoPlayers);
ACEX_PREP(handleConnectHC);
ACEX_PREP(handleDisconnect);

View File

@ -10,6 +10,21 @@
};
// Add disconnect EH
addMissionEventHandler ["HandleDisconnect", {call FUNC(handleDisconnect)}];
[QGVAR(transferGroupsRebalance), {
params ["_groups", "_owner", "_rebalance"];
if (_groups isNotEqualTo [] && {_owner > 1}) then {
{
_x setGroupOwner _owner;
} forEach _groups;
};
// Rebalance units
if (_rebalance in [REBALANCE, FORCED_REBALANCE]) then {
(_rebalance == FORCED_REBALANCE) call FUNC(rebalance);
};
}] call CBA_fnc_addEventHandler;
} else {
// Register HC (this part happens on HC only)
[QXGVAR(headlessClientJoined), [player]] call CBA_fnc_globalEvent; // Global event for API purposes

View File

@ -0,0 +1,51 @@
#include "..\script_component.hpp"
/*
* Author: johnb43
* Modifies which units are blacklisted from being transferred to HCs.
*
* Arguments:
* 0: Units <OBJECT, GROUP, ARRAY>
* 1: Add (true) or remove (false) from blacklist <BOOL> (default: true)
* 2: Owner to transfer units to <NUMBER> (default: -1)
* 3: Rebalance <NUMBER> (default: 0)
*
* Return Value:
* None
*
* Example:
* [cursorObject, true] call ace_headless_fnc_blacklist
*
* Public: Yes
*/
params [["_units", objNull, [objNull, grpNull, []]], ["_blacklist", true, [false]], ["_owner", -1, [false]], ["_rebalance", NO_REBALANCE, [0]]];
if !(_units isEqualType []) then {
_units = [_units];
};
// Make sure passed arguments are objects or groups
_units = _units select {_x isEqualType objNull || {_x isEqualType grpNull}};
_units = _units select {!isNull _x};
if (_units isEqualTo []) exitWith {};
private _transfer = _blacklist && {_owner > 1};
private _groups = [];
{
_x setVariable [QXGVAR(blacklist), _blacklist, true];
if (_transfer) then {
if (_x isEqualType objNull) then {
_groups pushBack group _x;
} else {
_groups pushBack _x;
};
};
} forEach _units;
// Try to move AI to new owner; Also takes care of rebalancing groups
if (_transfer || {_rebalance in [REBALANCE, FORCED_REBALANCE]}) then {
[QGVAR(transferGroupsRebalance), [_groups arrayIntersect _groups, _owner, _rebalance]] call CBA_fnc_serverEvent;
};

View File

@ -17,6 +17,9 @@
params ["_force"];
// Filter out any invalid entries
GVAR(headlessClients) = GVAR(headlessClients) select {!isNull _x};
GVAR(headlessClients) params [
["_HC1", objNull, [objNull]],
["_HC2", objNull, [objNull]],
@ -36,12 +39,13 @@ private _idHC2 = -1;
private _idHC3 = -1;
private _currentHC = 0;
if (!local _HC1) then {
// objNull is never local
if (!local _HC1 && !isNull _HC1) then {
_idHC1 = owner _HC1;
_currentHC = 1;
};
if (!local _HC2) then {
if (!local _HC2 && !isNull _HC2) then {
_idHC2 = owner _HC2;
if (_currentHC == 0) then {
@ -49,7 +53,7 @@ if (!local _HC2) then {
};
};
if (!local _HC3) then {
if (!local _HC3 && !isNull _HC3) then {
_idHC3 = owner _HC3;
if (_currentHC == 0) then {
@ -57,84 +61,150 @@ if (!local _HC3) then {
};
};
if (_currentHC == 0) exitWith {
TRACE_1("No Valid HC to transfer to",_currentHC);
if (XGVAR(log)) then {
INFO("No Valid HC to transfer to");
};
};
// Prepare statistics
private _numTransferredHC1 = 0;
private _numTransferredHC2 = 0;
private _numTransferredHC3 = 0;
private _units = [];
private _transfer = false;
private _previousOwner = -1;
// Transfer AI groups
{
// No transfer if empty group
private _transfer = ((units _x) isNotEqualTo []) && {!(_x getVariable [QXGVAR(blacklist), false])};
if (_transfer) then {
// No transfer if waypoints with synchronized triggers exist for the group
private _allWaypointsWithTriggers = (waypoints _x) select {(synchronizedTriggers _x) isNotEqualTo []};
if (_allWaypointsWithTriggers isNotEqualTo []) exitWith {
_units = units _x;
// No transfer if empty group or if group is blacklisted
if (_units isEqualTo [] || {_x getVariable [QXGVAR(blacklist), false]}) then {
continue;
};
// No transfer if waypoints with synchronized triggers exist for the group
if (((waypoints _x) select {(synchronizedTriggers _x) isNotEqualTo []}) isNotEqualTo []) then {
continue;
};
{
// No transfer if already transferred
if (!_force && {(owner _x) in [_idHC1, _idHC2, _idHC3]}) exitWith {
_transfer = false;
};
{
// No transfer if already transferred
if (!_force && {(owner _x) in [_idHC1, _idHC2, _idHC3]}) exitWith {
_transfer = false;
};
// No transfer if any unit in group is blacklisted
if (_x getVariable [QXGVAR(blacklist), false]) exitWith {
_transfer = false;
};
// No transfer if player or UAV in this group
if (isPlayer _x || {unitIsUAV _x}) exitWith {
_transfer = false;
};
// No transfer if player or UAV in this group
if (isPlayer _x || {unitIsUAV _x}) exitWith {
_transfer = false;
};
// No transfer if any unit in group is blacklisted
if (_x getVariable [QXGVAR(blacklist), false]) exitWith {
_transfer = false;
};
private _vehicle = objectParent _x;
private _vehicle = objectParent _x;
// No transfer if the vehicle the unit is in or if the crew in that vehicle is blacklisted
if ((_vehicle getVariable [QXGVAR(blacklist), false]) || {unitIsUAV _vehicle}) exitWith {
_transfer = false;
};
// No transfer if the vehicle the unit is in or if the crew in that vehicle is blacklisted
if ((_vehicle getVariable [QXGVAR(blacklist), false]) || {unitIsUAV _vehicle}) exitWith {
_transfer = false;
};
// Save gear if unit about to be transferred with current loadout (naked unit work-around)
if (XGVAR(transferLoadout) == 1) then {
_x setVariable [QGVAR(loadout), _x call CBA_fnc_getLoadout, true];
};
} forEach _units;
// Save gear if unit about to be transferred with current loadout (naked unit work-around)
if (XGVAR(transferLoadout) == 1) then {
_x setVariable [QGVAR(loadout), _x call CBA_fnc_getLoadout, true];
};
} forEach (units _x);
if (!_transfer) then {
continue;
};
// Round robin between HCs if load balance enabled, else pass all to one HC
if (_transfer) then {
switch (_currentHC) do {
case 1: {
private _transferred = _x setGroupOwner _idHC1;
if (_loadBalance) then {
_currentHC = [3, 2] select (!local _HC2);
};
if (_transferred) then {
_numTransferredHC1 = _numTransferredHC1 + 1;
_previousOwner = groupOwner _x;
switch (_currentHC) do {
case 1: {
if (_loadBalance) then {
// Find the next valid HC
// If none are valid, _currentHC will remain the same
if (_idHC2 != -1) then {
_currentHC = 2;
} else {
if (_idHC3 != -1) then {
_currentHC = 3;
};
};
};
case 2: {
private _transferred = _x setGroupOwner _idHC2;
if (_loadBalance) then {
_currentHC = [1, 3] select (!local _HC3);
};
if (_transferred) then {
_numTransferredHC2 = _numTransferredHC2 + 1;
// Don't transfer if it's already local to HC1
if (_previousOwner == _idHC1) exitWith {};
[QGVAR(groupTransferPre), [_x, _HC1, _previousOwner, _idHC1], [_previousOwner, _idHC1]] call CBA_fnc_targetEvent; // API
private _transferred = _x setGroupOwner _idHC1;
[QGVAR(groupTransferPost), [_x, _HC1, _previousOwner, _idHC1, _transferred], [_previousOwner, _idHC1]] call CBA_fnc_targetEvent; // API
if (_transferred) then {
_numTransferredHC1 = _numTransferredHC1 + 1;
};
};
case 2: {
if (_loadBalance) then {
// Find the next valid HC
// If none are valid, _currentHC will remain the same
if (_idHC3 != -1) then {
_currentHC = 3;
} else {
if (_idHC1 != -1) then {
_currentHC = 1;
};
};
};
case 3: {
private _transferred = _x setGroupOwner _idHC3;
if (_loadBalance) then {
_currentHC = [2, 1] select (!local _HC1);
};
if (_transferred) then {
_numTransferredHC3 = _numTransferredHC3 + 1;
// Don't transfer if it's already local to HC2
if (_previousOwner == _idHC2) exitWith {};
[QGVAR(groupTransferPre), [_x, _HC2, _previousOwner, _idHC2], [_previousOwner, _idHC2]] call CBA_fnc_targetEvent; // API
private _transferred = _x setGroupOwner _idHC2;
[QGVAR(groupTransferPost), [_x, _HC2, _previousOwner, _idHC2, _transferred], [_previousOwner, _idHC2]] call CBA_fnc_targetEvent; // API
if (_transferred) then {
_numTransferredHC2 = _numTransferredHC2 + 1;
};
};
case 3: {
if (_loadBalance) then {
// Find the next valid HC
// If none are valid, _currentHC will remain the same
if (_idHC1 != -1) then {
_currentHC = 1;
} else {
if (_idHC2 != -1) then {
_currentHC = 2;
};
};
};
default {
TRACE_1("No Valid HC to transfer to",_currentHC);
// Don't transfer if it's already local to HC3
if (_previousOwner == _idHC3) exitWith {};
[QGVAR(groupTransferPre), [_x, _HC3, _previousOwner, _idHC3], [_previousOwner, _idHC3]] call CBA_fnc_targetEvent; // API
private _transferred = _x setGroupOwner _idHC2;
[QGVAR(groupTransferPost), [_x, _HC3, _previousOwner, _idHC3, _transferred], [_previousOwner, _idHC3]] call CBA_fnc_targetEvent; // API
if (_transferred) then {
_numTransferredHC3 = _numTransferredHC3 + 1;
};
};
};

View File

@ -5,8 +5,8 @@
format ["ACE %1", LLSTRING(Module)],
false,
1,
{[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)},
true
{[QXGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)},
true // Needs mission restart
] call CBA_fnc_addSetting;
[
@ -15,8 +15,7 @@
[LSTRING(Delay), LSTRING(DelayDesc)],
format ["ACE %1", LLSTRING(Module)],
[0, 60, 15, -1],
1,
{[QGVAR(delay), _this] call EFUNC(common,cbaSettings_settingChanged)}
1
] call CBA_fnc_addSetting;
[
@ -26,8 +25,8 @@
format ["ACE %1", LLSTRING(Module)],
[[0, 1, 2], [ELSTRING(Common,Disabled), LSTRING(Instant), LSTRING(Delayed)], 0],
1,
{[QGVAR(delay), _this] call EFUNC(common,cbaSettings_settingChanged)},
true
{[QXGVAR(endMission), _this] call EFUNC(common,cbaSettings_settingChanged)},
true // Needs mission restart
] call CBA_fnc_addSetting;
[
@ -36,8 +35,7 @@
[LSTRING(Log), LSTRING(LogDesc)],
format ["ACE %1", LLSTRING(Module)],
false,
1,
{[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}
1
] call CBA_fnc_addSetting;
[
@ -47,6 +45,6 @@
format ["ACE %1", LLSTRING(Module)],
[[0, 1, 2], [ELSTRING(Common,Disabled), LSTRING(TransferLoadoutCurrent), LSTRING(TransferLoadoutConfig)], 0],
1,
{},
true // needs mission restart
{[QXGVAR(transferLoadout), _this] call EFUNC(common,cbaSettings_settingChanged)},
true // Needs mission restart
] call CBA_fnc_addSetting;

View File

@ -17,3 +17,7 @@
#include "\z\ace\addons\main\script_macros.hpp"
#define DELAY_DEFAULT 15
#define NO_REBALANCE 0
#define REBALANCE 1
#define FORCED_REBALANCE 2

View File

@ -1,4 +1,3 @@
class Extended_PreStart_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_SCRIPT(XEH_preStart));

View File

@ -5,7 +5,7 @@ class CfgVehicles {
class ACE_Equipment {
class ACE_PutInEarplugs {
displayName = CSTRING(EarPlugs_On);
condition = QUOTE(GVAR(EnableCombatDeafness) && {!([_player] call FUNC(hasEarPlugsIn)) && {'ACE_EarPlugs' in items _player}});
condition = QUOTE(GVAR(enableCombatDeafness) && {!(_player call FUNC(hasEarPlugsIn)) && {[ARR_2(_player,'ACE_EarPlugs')] call EFUNC(common,hasItem)}});
exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"};
statement = QUOTE([ARR_2(_player,true)] call FUNC(putInEarPlugs));
showDisabled = 0;
@ -13,7 +13,7 @@ class CfgVehicles {
};
class ACE_RemoveEarplugs {
displayName = CSTRING(EarPlugs_Off);
condition = QUOTE(GVAR(EnableCombatDeafness) && {[_player] call FUNC(hasEarPlugsIn)});
condition = QUOTE(GVAR(enableCombatDeafness) && {_player call FUNC(hasEarPlugsIn)});
exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"};
statement = QUOTE([ARR_2(_player,true)] call FUNC(removeEarPlugs));
showDisabled = 0;

View File

@ -80,7 +80,7 @@ class CfgWeapons {
class H_HelmetO_ocamo: H_HelmetB {
HEARING_PROTECTION_PELTOR;
}; // Defender and Assasin Helmet inherit.
}; // Defender and Assassin Helmet inherit.
class H_HelmetO_ViperSP_hex_f: H_HelmetB {
HEARING_PROTECTION_PELTOR;

View File

@ -1,4 +1,3 @@
PREP(addEarPlugs);
PREP(earRinging);
PREP(explosionNear);

View File

@ -2,9 +2,10 @@
if (isServer) then {
["CBA_settingsInitialized", {
TRACE_1("settingInit - server",GVAR(EnableCombatDeafness));
TRACE_1("settingInit - server",GVAR(enableCombatDeafness));
// Only install event handler if combat deafness is enabled
if (!GVAR(EnableCombatDeafness)) exitWith {};
if (!GVAR(enableCombatDeafness)) exitWith {};
["CAManBase", "Init", LINKFUNC(addEarPlugs), true, [], true] call CBA_fnc_addClassEventHandler;
}] call CBA_fnc_addEventHandler;
@ -26,18 +27,20 @@ GVAR(volumeAttenuation) = 1;
GVAR(lastPlayerVehicle) = objNull;
["CBA_settingsInitialized", {
TRACE_1("settingInit",GVAR(EnableCombatDeafness));
TRACE_1("settingInit",GVAR(enableCombatDeafness));
// Only run PFEH and install event handlers if combat deafness is enabled
if (!GVAR(EnableCombatDeafness)) exitWith {};
if (!GVAR(enableCombatDeafness)) exitWith {};
// Spawn volume updating process
[LINKFUNC(updateVolume), 1, [false]] call CBA_fnc_addPerFrameHandler;
[LINKFUNC(updateVolume), 1, false] call CBA_fnc_addPerFrameHandler;
[QGVAR(updateVolume), LINKFUNC(updateVolume)] call CBA_fnc_addEventHandler;
// Update veh attunation when player veh changes
["vehicle", {
params ["_player", "_vehicle"];
TRACE_2("vehicle change",_player,_vehicle);
_this call FUNC(updatePlayerVehAttenuation);
@ -48,6 +51,7 @@ GVAR(lastPlayerVehicle) = objNull;
GVAR(lastPlayerVehicle) = objNull;
TRACE_2("removed veh eh",_firedEH,GVAR(lastPlayerVehicle));
};
if ((!isNull _vehicle) && {_player != _vehicle}) then {
private _firedEH = _vehicle addEventHandler ["FiredNear", {call FUNC(firedNear)}];
_vehicle setVariable [QGVAR(firedEH), _firedEH];
@ -55,8 +59,8 @@ GVAR(lastPlayerVehicle) = objNull;
TRACE_2("added veh eh",_firedEH,GVAR(lastPlayerVehicle));
};
}, true] call CBA_fnc_addPlayerEventHandler;
["turret", LINKFUNC(updatePlayerVehAttenuation), false] call CBA_fnc_addPlayerEventHandler;
["turret", LINKFUNC(updatePlayerVehAttenuation), false] call CBA_fnc_addPlayerEventHandler;
// Reset deafness on respawn (or remote control player switch)
["unit", {
@ -83,6 +87,7 @@ GVAR(lastPlayerVehicle) = objNull;
if ((getNumber (configOf _player >> "isPlayableLogic")) == 1) exitWith {
TRACE_1("skipping playable logic",typeOf _player); // VirtualMan_F (placeable logic zeus / spectator)
};
private _firedEH = _player addEventHandler ["FiredNear", {call FUNC(firedNear)}];
_player setVariable [QGVAR(firedEH), _firedEH];
@ -99,6 +104,7 @@ GVAR(lastPlayerVehicle) = objNull;
GVAR(deafnessDV) = 0;
GVAR(deafnessPrior) = 0;
GVAR(time3) = 0;
UPDATE_HEARING_EARPLUGS call FUNC(updateHearingProtection);
}, true] call CBA_fnc_addPlayerEventHandler;
}] call CBA_fnc_addEventHandler;

View File

@ -10,15 +10,20 @@ PREP_RECOMPILE_END;
["CBA_loadoutSet", {
params ["_unit", "_loadout", "_extendedInfo"];
if (_extendedInfo getOrDefault ["ace_earplugs", false]) then {
_unit setVariable ["ACE_hasEarPlugsIn", true, true];
[QGVAR(updateVolume), [[true]], _unit] call CBA_fnc_targetEvent;
// Only force update volume if unit is a player (including remote controlled)
if (_unit call EFUNC(common,isPlayer)) then {
[QGVAR(updateVolume), true, _unit] call CBA_fnc_targetEvent;
};
};
}] call CBA_fnc_addEventHandler;
["CBA_loadoutGet", {
params ["_unit", "_loadout", "_extendedInfo"];
if (_unit getVariable ["ACE_hasEarPlugsin", false]) then {
_extendedInfo set ["ace_earplugs", true]
};

View File

@ -1,24 +1,25 @@
#include "..\script_component.hpp"
/*
* Author: KoffeinFlummi, commy2, Rocko, Rommel, Ruthberg
* Handle new sound souce near ace_player and apply hearing damage
* Handle new sound souce near ace_player and apply hearing damage.
*
* Arguments:
* 0: strength of ear ringing <NUMBER>
* 0: Strength of ear ringing <NUMBER>
*
* Return Value:
* None
*
* Example:
* [_strength] call ace_hearing_fnc_earRinging
* 10 call ace_hearing_fnc_earRinging
*
* Public: No
*/
params ["_strength"];
if (_strength < 0.05) exitWith {};
if (!isNull curatorCamera) exitWith {};
if ((!GVAR(enabledForZeusUnits)) && {player != ACE_player}) exitWith {};
if (!GVAR(enabledForZeusUnits) && {player != ACE_player}) exitWith {};
TRACE_2("adding",_strength * GVAR(damageCoefficent),GVAR(deafnessDV));

View File

@ -4,8 +4,8 @@
* Handles deafness due to explosions going off near the player.
*
* Arguments:
* 0: vehicle - Object the event handler is assigned to (player) <OBJECT>
* 1: damage - Damage inflicted to the object <NUMBER>
* 0: Unit <OBJECT>
* 1: Damage inflicted to the unit <NUMBER>
*
* Return Value:
* None
@ -22,5 +22,5 @@ TRACE_2("explosion near player",_unit,_damage);
private _strength = (0 max _damage) * 30;
// Call inmediately, as it will get pick up later anyway by the update thread
[_strength] call FUNC(earRinging);
// Call immediately, as it will get picked up later by the update thread anyway
_strength call FUNC(earRinging);

View File

@ -59,5 +59,5 @@ private _strength = _vehAttenuation * (_loudness - (_loudness / 50 * _distance))
TRACE_1("result",_strength);
// Call inmediately, as it will get pick up later anyway by the update thread
[_strength] call FUNC(earRinging);
// Call immediately, as it will get picked up later by the update thread anyway
_strength call FUNC(earRinging);

View File

@ -1,7 +1,7 @@
#include "..\script_component.hpp"
/*
* Author: PabstMirror
* Reset earplugs on respawn, and then re-add if appropriate
* Reset earplugs on respawn, and then re-add if appropriate.
*
* Arguments:
* 0: Unit <OBJECT>
@ -10,29 +10,29 @@
* None
*
* Example:
* [player] call ACE_hearing_fnc_handleRespawn;
* player call ace_hearing_fnc_handleRespawn;
*
* Public: No
*/
// Do not add or remove earplugs if gear should be preserved
if (missionNamespace getVariable [QEGVAR(respawn,savePreDeathGear), false]) exitWith {};
params ["_unit"];
TRACE_2("params",_unit,typeOf _unit);
if (!local _unit) exitWith {}; //XEH should only be called on local units
//Do not add or remove earplugs if gear should be preserved
if (missionNamespace getVariable [QEGVAR(respawn,SavePreDeathGear), false]) exitWith {};
if (!local _unit) exitWith {}; // XEH should only be called on local units
private _respawn = [0] call BIS_fnc_missionRespawnType;
//if respawn is not Group or side:
// If respawn is not group or side:
if (_respawn <= 3) then {
//Remove earplugs if they have them:
// Remove earplugs if they have them:
if (_unit getVariable ["ACE_hasEarPlugsin", false]) then {
TRACE_1("had EarPlugs in - removing",_unit);
_unit setVariable ["ACE_hasEarPlugsin", false, true];
};
};
//Re-add if they need them:
[_unit] call FUNC(addEarPlugs);
// Re-add if they need them
_unit call FUNC(addEarPlugs);

View File

@ -4,16 +4,17 @@
* Check if the unit has earplugs put in.
*
* Arguments:
* 0: Unit (player) <OBJECT>
* 0: Unit <OBJECT>
*
* Return Value:
* Have Earplugs in <BOOL>
* Has Earplugs in <BOOL>
*
* Example:
* [ace_player] call ace_hearing_fnc_hasEarPlugsIn
* player call ace_hearing_fnc_hasEarPlugsIn
*
* Public: No
*/
params ["_unit"];
_unit getVariable ["ACE_hasEarPlugsin", false]

View File

@ -10,7 +10,7 @@
* None
*
* Example:
* [player] call ACE_hearing_fnc_moduleHearing
* player call ace_hearing_fnc_moduleHearing
*
* Public: No
*/
@ -23,6 +23,8 @@ params ["_logic"];
if ((_logic getVariable "DisableEarRinging") != -1) then {
[_logic, QGVAR(DisableEarRinging), "DisableEarRinging"] call EFUNC(common,readSettingFromModule);
};
[_logic, QGVAR(enabledForZeusUnits), "enabledForZeusUnits"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(autoAddEarplugsToUnits), "autoAddEarplugsToUnits"] call EFUNC(common,readSettingFromModule);
INFO("Hearing Module Initialized.");

View File

@ -1,38 +1,35 @@
#include "..\script_component.hpp"
/*
* Author: Hope Johnson and commy2
* Author: Hope Johnson, commy2
* Puts in earplugs.
*
* Arguments:
* 0: Unit (player) <OBJECT>
* 0: Unit <OBJECT>
* 1: Display hint <BOOL> (default: false)
*
* Return Value:
* None
*
* Example:
* [ace_player, false] call ace_hearing_fnc_putInEarplugs
* [player, false] call ace_hearing_fnc_putInEarplugs
*
* Public: No
*/
params ["_player", ["_displayHint", false, [false]]];
if (!GVAR(enableCombatDeafness)) exitWith {};
if (!GVAR(EnableCombatDeafness)) exitWith {};
params ["_unit", ["_displayHint", false]];
// Plugs in inventory, putting them in
_player removeItem "ACE_EarPlugs";
_unit removeItem "ACE_EarPlugs";
_player setVariable ["ACE_hasEarPlugsIn", true, true];
_unit setVariable ["ACE_hasEarPlugsIn", true, true];
if (_displayHint) then {
[localize LSTRING(EarPlugs_Are_On)] call EFUNC(common,displayTextStructured);
[LLSTRING(EarPlugs_Are_On)] call EFUNC(common,displayTextStructured);
};
//Force an immediate fast volume update:
[[true]] call FUNC(updateVolume);
// No Earplugs in inventory, telling user
//[localize LSTRING(NoPlugs)] call EFUNC(common,displayTextStructured);
// Force an immediate volume update
true call FUNC(updateVolume);
UPDATE_HEARING_EARPLUGS call FUNC(updateHearingProtection);

View File

@ -1,39 +1,40 @@
#include "..\script_component.hpp"
/*
* Author: Hope Johnson and commy2
* Author: Hope Johnson, commy2
* Takes out earplugs.
*
* Arguments:
* 0: Unit (player) <OBJECT>
* 1: Display hint <BOOL> (default false)
* 0: Unit <OBJECT>
* 1: Display hint <BOOL> (default: false)
*
* Return Value:
* None
*
* Example:
* [ace_player, false] call ace_hearing_fnc_removeEarplugs
* [player, false] call ace_hearing_fnc_removeEarplugs
*
* Public: No
*/
params ["_player", ["_displayHint", false, [false]]];
if (!GVAR(enableCombatDeafness)) exitWith {};
if (!GVAR(EnableCombatDeafness)) exitWith {};
params ["_unit", ["_displayHint", false]];
if !([_player, "ACE_EarPlugs"] call CBA_fnc_canAddItem) exitWith { // inventory full
// Inventory full
if !([_unit, "ACE_EarPlugs"] call CBA_fnc_canAddItem) exitWith {
[LELSTRING(common,Inventory_Full)] call EFUNC(common,displayTextStructured);
};
// Plugs already in and removing them.
_player addItem "ACE_EarPlugs";
_unit addItem "ACE_EarPlugs";
_player setVariable ["ACE_hasEarPlugsIn", false, true];
_unit setVariable ["ACE_hasEarPlugsIn", false, true];
if (_displayHint) then {
[localize LSTRING(EarPlugs_Are_Off)] call EFUNC(common,displayTextStructured);
[LLSTRING(EarPlugs_Are_Off)] call EFUNC(common,displayTextStructured);
};
//Force an immediate fast volume update:
[[true]] call FUNC(updateVolume);
// Force an immediate volume update
true call FUNC(updateVolume);
UPDATE_HEARING_EARPLUGS call FUNC(updateHearingProtection);

View File

@ -1,7 +1,7 @@
#include "..\script_component.hpp"
/*
* Author: PabstMirror
* Updates the hearing protection and volume attenuation for player on earbuds/helmet change
* Updates the hearing protection and volume attenuation for player on earbuds/helmet change.
*
* Arguments:
* 0: Slot <NUMBER>
@ -15,6 +15,8 @@
* Public: No
*/
LOG("updateHearingProtection");
if (isNull ACE_player) exitWith {
GVAR(damageCoefficent) = 0;
GVAR(volumeAttenuation) = 1;
@ -26,22 +28,32 @@ TRACE_1("",_slot);
if !(_slot in [UPDATE_HEARING_EARPLUGS, TYPE_GOGGLE, TYPE_HEADGEAR]) exitWith {};
// Handle Earplugs
private _hasEarPlugsIn = [ACE_player] call FUNC(hasEarPlugsIn);
private _hasEarPlugsIn = ACE_player call FUNC(hasEarPlugsIn);
GVAR(damageCoefficent) = [1, 0.25] select _hasEarPlugsIn;
GVAR(volumeAttenuation) = [1, GVAR(EarplugsVolume)] select _hasEarPlugsIn;
GVAR(volumeAttenuation) = [1, GVAR(earplugsVolume)] select _hasEarPlugsIn;
// Handle Headgear
if (headgear ACE_player != "") then {
private _protection = getNumber (configFile >> "CfgWeapons" >> headgear ACE_player >> QGVAR(protection)) min 1;
private _headgear = headgear ACE_player;
if (_headgear != "") then {
private _heargearConfig = configFile >> "CfgWeapons" >> _headgear;
private _protection = getNumber (_heargearConfig >> QGVAR(protection)) min 1;
GVAR(damageCoefficent) = GVAR(damageCoefficent) * (1 - _protection);
private _attenuation = getNumber (configFile >> "CfgWeapons" >> headgear ACE_player >> QGVAR(lowerVolume)) min 1;
private _attenuation = getNumber (_heargearConfig >> QGVAR(lowerVolume)) min 1;
GVAR(volumeAttenuation) = GVAR(volumeAttenuation) * (1 - _attenuation);
};
// Handle Goggles
if (goggles ACE_player != "") then {
private _protection = getNumber (configFile >> "CfgGlasses" >> goggles ACE_player >> QGVAR(protection)) min 1;
private _goggles = goggles ACE_player;
if (_goggles != "") then {
private _gogglesConfig = configFile >> "CfgGlasses" >> _goggles;
private _protection = getNumber (_gogglesConfig >> QGVAR(protection)) min 1;
GVAR(damageCoefficent) = GVAR(damageCoefficent) * (1 - _protection);
private _attenuation = getNumber (configFile >> "CfgGlasses" >> goggles ACE_player >> QGVAR(lowerVolume)) min 1;
private _attenuation = getNumber (_gogglesConfig >> QGVAR(lowerVolume)) min 1;
GVAR(volumeAttenuation) = GVAR(volumeAttenuation) * (1 - _attenuation);
};

View File

@ -7,10 +7,10 @@
* None
*
* Return Value:
* Ammount that unit can hear outside <NUMBER>
* Amount that unit can hear outside <NUMBER>
*
* Example:
* [] call ace_hearing_fnc_updatePlayerVehAttenuation
* call ace_hearing_fnc_updatePlayerVehAttenuation
*
* Public: No
*/
@ -20,12 +20,14 @@ private _vehicle = vehicle ACE_player;
if (isNull _vehicle) exitWith {};
private _newAttenuation = 1;
if (ACE_player != _vehicle) then {
private _turretPath = [ACE_player] call EFUNC(common,getTurretIndex);
private _effectType = getText (configOf _vehicle >> "attenuationEffectType");
private _vehicleConfig = configOf _vehicle;
private _turretPath = _vehicle unitTurret ACE_player;
private _effectType = getText (_vehicleConfig >> "attenuationEffectType");
if (_turretPath isNotEqualTo []) then {
private _turretConfig = [(configOf _vehicle), _turretPath] call EFUNC(common,getTurretConfigPath);
private _turretConfig = [_vehicleConfig, _turretPath] call EFUNC(common,getTurretConfigPath);
if ((getNumber (_turretConfig >> "disableSoundAttenuation")) == 1) then {
_effectType = "";
@ -40,7 +42,7 @@ if (ACE_player != _vehicle) then {
case (_effectType == ""): {1};
case (_effectType == "CarAttenuation");
case (_effectType == "RHS_CarAttenuation"): { // Increase protection for armored cars
private _armor = getNumber (configOf _vehicle >> "HitPoints" >> "HitBody" >> "armor");
private _armor = getNumber (_vehicleConfig >> "HitPoints" >> "HitBody" >> "armor");
linearConversion [2, 8, _armor, 0.5, 0.3, true];};
case (_effectType == "OpenCarAttenuation"): {1};
case (_effectType == "TankAttenuation"): {0.1};

View File

@ -1,55 +1,61 @@
#include "..\script_component.hpp"
/*
* Author: commy2 and esteldunedain and Ruthberg
* Author: commy2, esteldunedain, Ruthberg
* Updates and applies the current deafness. Called every 1 sec from a PFEH.
*
* Arguments:
* 0: Args <ARRAY>
* - 0: Just update volume (skip ringing/recovery) <BOOL> (default: false)
* 0: Update volume only (skip ringing/recovery) <BOOL> (default: false)
*
* Return Value:
* None
*
* Example:
* [] call ace_hearing_fnc_updateVolume
* call ace_hearing_fnc_updateVolume
*
* Public: No
*/
if (isGamePaused) exitWith {};
if (!alive ACE_player) exitWith {
if (missionNameSpace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {};
if (missionNamespace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {};
TRACE_1("dead - removing hearing effects",ACE_player);
[QUOTE(ADDON), 1, true] call EFUNC(common,setHearingCapability);
};
(_this select 0) params [["_justUpdateVolume", false]];
params [["_updateVolumeOnly", false]];
GVAR(deafnessDV) = (GVAR(deafnessDV) min 20) max 0;
GVAR(volume) = (1 - (GVAR(deafnessDV) / 20)) max 0.05;
TRACE_3("",GVAR(volume),GVAR(deafnessDV),GVAR(deafnessDV) - GVAR(deafnessPrior));
if (!_justUpdateVolume) then {
if (!_updateVolumeOnly) then {
// Ring if we got a big increase in the last second or enough accumulated damage
if (GVAR(deafnessDV) - GVAR(deafnessPrior) > 1 ||
GVAR(deafnessDV) > 10) then {
if (CBA_missionTime - GVAR(time3) < 3) exitWith {};
if (!isGameFocused) exitWith {}; // prevent audio from stacking when tabbed out
GVAR(time3) = CBA_missionTime;
if (!isGameFocused) exitWith {};
if (GVAR(deafnessDV) > 19.75) then {
playSound (["ACE_Combat_Deafness_Heavy", "ACE_Combat_Deafness_Heavy_NoRing"] select GVAR(DisableEarRinging));
playSound (["ACE_Combat_Deafness_Heavy", "ACE_Combat_Deafness_Heavy_NoRing"] select GVAR(disableEarRinging));
} else {
playSound (["ACE_Combat_Deafness_Medium", "ACE_Combat_Deafness_Medium_NoRing"] select GVAR(DisableEarRinging));
playSound (["ACE_Combat_Deafness_Medium", "ACE_Combat_Deafness_Medium_NoRing"] select GVAR(disableEarRinging));
};
};
GVAR(deafnessPrior) = GVAR(deafnessDV);
// Hearing takes longer to return to normal after it hits rock bottom
GVAR(deafnessDV) = (GVAR(deafnessDV) - (0.5 * (GVAR(volume) max 0.1))) max 0;
GVAR(deafnessDV) = (GVAR(deafnessDV) - (0.5 * (GVAR(volume) max 0.1))) max 0;
};
if (missionNameSpace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {};
if (missionNamespace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {};
private _volume = GVAR(volume);
@ -57,8 +63,8 @@ private _volume = GVAR(volume);
_volume = _volume min GVAR(volumeAttenuation);
// Reduce volume if player is unconscious
if (ACE_player getVariable ["ACE_isUnconscious", false]) then {
_volume = _volume min GVAR(UnconsciousnessVolume);
if (lifeState ACE_player == "INCAPACITATED") then {
_volume = _volume min GVAR(unconsciousnessVolume);
};
[QUOTE(ADDON), _volume, true] call EFUNC(common,setHearingCapability);

View File

@ -2,14 +2,17 @@
// Conditions: specific
if !([ACE_player, objNull, ["isNotSwimming", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false};
if (GVAR(EnableCombatDeafness) && {!([ACE_player] call FUNC(hasEarPlugsIn))} && {[ACE_player, "ACE_EarPlugs"] call EFUNC(common,hasItem)}) exitWith {
if (GVAR(enableCombatDeafness) && {!(ACE_player call FUNC(hasEarPlugsIn))} && {[ACE_player, "ACE_EarPlugs"] call EFUNC(common,hasItem)}) exitWith {
[ACE_player, true] call FUNC(putInEarPlugs);
true
true // return
};
if (GVAR(EnableCombatDeafness) && {[ACE_player] call FUNC(hasEarPlugsIn)}) exitWith {
if (GVAR(enableCombatDeafness) && {ACE_player call FUNC(hasEarPlugsIn)}) exitWith {
[ACE_player, true] call FUNC(removeEarPlugs);
true
true // return
};
false
false // return
}] call CBA_fnc_addKeybind; // UNBOUND

View File

@ -1,7 +1,8 @@
private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)];
private _category = format ["ACE %1", LLSTRING(Module_DisplayName)];
[
QGVAR(enableCombatDeafness), "CHECKBOX",
QGVAR(enableCombatDeafness),
"CHECKBOX",
[LSTRING(EnableCombatDeafness_DisplayName), LSTRING(EnableCombatDeafness_Description)],
_category,
true,
@ -11,7 +12,8 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)];
] call CBA_fnc_addSetting;
[
QGVAR(earplugsVolume), "SLIDER",
QGVAR(earplugsVolume),
"SLIDER",
[LSTRING(earplugsVolume_DisplayName), LSTRING(earplugsVolume_Description)],
_category,
[0, 1, 0.5, 1],
@ -19,7 +21,8 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)];
] call CBA_fnc_addSetting;
[
QGVAR(unconsciousnessVolume), "SLIDER",
QGVAR(unconsciousnessVolume),
"SLIDER",
[LSTRING(unconsciousnessVolume_DisplayName), LSTRING(unconsciousnessVolume_Description)],
_category,
[0, 1, 0.4, 1],
@ -27,15 +30,16 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)];
] call CBA_fnc_addSetting;
[
QGVAR(disableEarRinging), "CHECKBOX",
QGVAR(disableEarRinging),
"CHECKBOX",
[LSTRING(DisableEarRinging_DisplayName), LSTRING(DisableEarRinging_Description)],
_category,
false,
0
false
] call CBA_fnc_addSetting;
[
QGVAR(enabledForZeusUnits), "CHECKBOX",
QGVAR(enabledForZeusUnits),
"CHECKBOX",
[LSTRING(enabledForZeusUnits_DisplayName), LSTRING(enabledForZeusUnits_Description)],
_category,
true,
@ -43,7 +47,8 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)];
] call CBA_fnc_addSetting;
[
QGVAR(autoAddEarplugsToUnits), "LIST",
QGVAR(autoAddEarplugsToUnits),
"LIST",
[LSTRING(autoAddEarplugsToUnits_DisplayName), LSTRING(autoAddEarplugsToUnits_Description)],
_category,
[[0, 1, 2], [ELSTRING(common,Disabled), LSTRING(heavyWeaponUnits), ELSTRING(common,Enabled)], 1],

View File

@ -46,9 +46,7 @@ private _categoryColors = [_category, format ["| %1 |", LELSTRING(common,subcate
QGVAR(textSize), "LIST",
LSTRING(textSize),
_category,
[[0, 1, 2, 3, 4], ["str_very_small", "str_small", "str_medium", "str_large", "str_very_large"], 2],
0,
{[QGVAR(textSize), _this] call EFUNC(common,cbaSettings_settingChanged)}
[[0, 1, 2, 3, 4], ["str_very_small", "str_small", "str_medium", "str_large", "str_very_large"], 2]
] call CBA_fnc_addSetting;
[

View File

@ -20,7 +20,7 @@
false,
true,
{[QGVAR(disableNegativeRating), _this] call EFUNC(common,cbaSettings_settingChanged)},
true
true // Needs mission restart
] call CBA_fnc_addSetting;
[

View File

@ -67,14 +67,11 @@
false,
true,
{
[QGVAR(BFT_Enabled), _this] call EFUNC(common,cbaSettings_settingChanged);
if (GVAR(BFT_Enabled) && {isNil QGVAR(BFT_markers)}) then {
GVAR(BFT_markers) = [];
[LINKFUNC(blueForceTrackingUpdate), GVAR(BFT_Interval), []] call CBA_fnc_addPerFrameHandler;
};
},
false
}
] call CBA_fnc_addSetting;
[
@ -94,9 +91,7 @@
[localize LSTRING(BFT_ShowPlayerNames_DisplayName), localize LSTRING(BFT_ShowPlayerNames_Description)],
[format ["ACE %1", localize LSTRING(Module_DisplayName)], localize LSTRING(BFT_Module_DisplayName)],
false,
true,
{[QGVAR(BFT_ShowPlayerNames), _this] call EFUNC(common,cbaSettings_settingChanged)},
false
true
] call CBA_fnc_addSetting;
[
@ -105,7 +100,5 @@
[localize LSTRING(BFT_HideAiGroups_DisplayName), localize LSTRING(BFT_HideAiGroups_Description)],
[format ["ACE %1", localize LSTRING(Module_DisplayName)], localize LSTRING(BFT_Module_DisplayName)],
false,
true,
{[QGVAR(BFT_HideAiGroups), _this] call EFUNC(common,cbaSettings_settingChanged)},
false
true
] call CBA_fnc_addSetting;

View File

@ -7,6 +7,7 @@
* 0: The unit <OBJECT>
* 1: Reason for death <STRING>
* 2: Killer <OBJECT>
* 3: Instigator <OBJECT>
*
* Return Value:
* None
@ -14,9 +15,8 @@
* Public: No
*/
params ["_unit", ["_reason", "#setDead"], ["_instigator", objNull]];
TRACE_3("setDead",_unit,_reason,_instigator);
params ["_unit", ["_reason", "#setDead"], ["_source", objNull], ["_instigator", objNull]];
TRACE_4("setDead",_unit,_reason,_source,_instigator);
// No heart rate or blood pressure to measure when dead
_unit setVariable [VAR_HEART_RATE, 0, true];
@ -38,7 +38,7 @@ if (_unitState isNotEqualTo "Dead") then {
// (#8803) Reenable damage if disabled to prevent having live units in dead state
// Keep this after death event for compatibility with third party hooks
if !(isDamageAllowed _unit) then {
if (!isDamageAllowed _unit) then {
WARNING_1("setDead executed on unit with damage blocked - %1",_this);
_unit allowDamage true;
};
@ -46,6 +46,6 @@ if !(isDamageAllowed _unit) then {
// Kill the unit without changing visual apperance
private _prevDamage = _unit getHitPointDamage "HitHead";
_unit setHitPointDamage ["HitHead", 1, true, _instigator];
_unit setHitPointDamage ["HitHead", 1, true, _source, _instigator];
_unit setHitPointDamage ["HitHead", _prevDamage];
_unit setHitPointDamage ["HitHead", _prevDamage, true, _source, _instigator];

View File

@ -15,7 +15,5 @@ private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(itemName)
[LSTRING(WaypointPrecision_DisplayName), LSTRING(WaypointPrecision_Description)],
_category,
[[1, 2, 3], [LSTRING(WaypointPrecision_medium), LSTRING(WaypointPrecision_close), LSTRING(WaypointPrecision_exact)], 2], // [values, titles, defaultIndex]
true, // isGlobal
{[QGVAR(waypointPrecision), _this] call EFUNC(common,cbaSettings_settingChanged)},
false // require mission restart
true // isGlobal
] call CBA_fnc_addSetting;

View File

@ -101,4 +101,36 @@ class CfgVehicles {
class B_Soldier_05_f; class B_Pilot_F: B_Soldier_05_f {backpack = "ACE_NonSteerableParachute";};
class I_Soldier_04_F; class I_pilot_F: I_Soldier_04_F {backpack = "ACE_NonSteerableParachute";};
class O_helipilot_F; class O_Pilot_F: O_helipilot_F {backpack = "ACE_NonSteerableParachute";};
class Plane_Base_F;
class Plane_CAS_01_base_F: Plane_Base_F {
class EjectionSystem {
EjectionParachute = "NonSteerable_Parachute_F";
};
};
class Plane_CAS_02_base_F: Plane_Base_F {
class EjectionSystem {
EjectionParachute = "NonSteerable_Parachute_F";
};
};
class Plane_Fighter_01_base_F: Plane_Base_F {
class EjectionSystem {
EjectionParachute = "NonSteerable_Parachute_F";
};
};
class Plane_Fighter_02_base_F: Plane_Base_F {
class EjectionSystem {
EjectionParachute = "NonSteerable_Parachute_F";
};
};
class Plane_Fighter_03_base_F: Plane_Base_F {
class EjectionSystem {
EjectionParachute = "NonSteerable_Parachute_F";
};
};
class Plane_Fighter_04_base_F: Plane_Base_F {
class EjectionSystem {
EjectionParachute = "NonSteerable_Parachute_F";
};
};
};

View File

@ -5,9 +5,7 @@ private _category = [LELSTRING(common,categoryUncategorized), localize "str_dn_p
"CHECKBOX",
[LSTRING(HideAltimeter), LSTRING(HideAltimeter_tooltip)],
_category,
true,
false,
{[QGVAR(hideAltimeter), _this, false] call EFUNC(common,cbaSettings_settingChanged)}
true
] call CBA_fnc_addSetting;
[

View File

@ -0,0 +1,174 @@
//attachments
class ItemCore;
class acc_flashlight: ItemCore {
displayName = CSTRING(flashlight_Name);
};
class optic_MRD: ItemCore {
displayName = CSTRING(optic_mrd_Name);
};
class optic_MRD_black: optic_MRD {
displayName = CSTRING(optic_mrd_black_Name);
};
class optic_Hamr: ItemCore {
displayName = CSTRING(optic_hamr);
};
class optic_Hamr_khk_F: optic_Hamr {
displayName = CSTRING(optic_hamr_khk);
};
class ACE_optic_Hamr_2D: optic_Hamr {
displayName = CSTRING(optic_hamr_2d);
};
class ACE_optic_Hamr_PIP: ACE_optic_Hamr_2D {
displayName = CSTRING(optic_hamr_pip);
};
class optic_Arco: ItemCore {
displayName = CSTRING(optic_arco);
};
class optic_Arco_blk_F: optic_Arco {
displayName = CSTRING(optic_arco_blk);
};
class optic_Arco_ghex_F: optic_Arco {
displayName = CSTRING(optic_arco_ghex);
};
class ACE_optic_Arco_2D: optic_Arco {
displayName = CSTRING(optic_arco_2d);
};
class ACE_optic_Arco_PIP: ACE_optic_Arco_2D {
displayName = CSTRING(optic_arco_pip);
};
class optic_Arco_lush_F: optic_Arco {
displayName = CSTRING(optic_arco_lush);
};
class optic_Arco_arid_F: optic_Arco {
displayName = CSTRING(optic_arco_arid);
};
class optic_Arco_AK_blk_F: optic_Arco_blk_F {
displayName = CSTRING(optic_arco_ak_blk);
};
class optic_Arco_AK_lush_F: optic_Arco_lush_F {
displayName = CSTRING(optic_arco_ak_lush);
};
class optic_Arco_AK_arid_F: optic_Arco_arid_F {
displayName = CSTRING(optic_arco_ak_arid);
};
class optic_ERCO_blk_f: optic_Arco {
displayName = CSTRING(optic_erco_blk);
};
class optic_ERCO_khk_f: optic_ERCO_blk_f {
displayName = CSTRING(optic_erco_khk);
};
class optic_ERCO_snd_f: optic_ERCO_blk_f {
displayName = CSTRING(optic_erco_snd);
};
class optic_LRPS: ItemCore {
displayName = CSTRING(optic_lrps);
};
class optic_LRPS_ghex_F: optic_LRPS {
displayName = CSTRING(optic_lrps_ghex);
};
class optic_LRPS_tna_F: optic_LRPS {
displayName = CSTRING(optic_lrps_tna);
};
class ACE_optic_LRPS_2D: optic_LRPS {
displayName = CSTRING(optic_lrps_2d);
};
class ACE_optic_LRPS_PIP: ACE_optic_LRPS_2D {
displayName = CSTRING(optic_lrps_pip);
};
class optic_AMS_base;
class optic_AMS: optic_AMS_base {
displayName = CSTRING(optic_ams);
};
class optic_AMS_khk: optic_AMS {
displayName = CSTRING(optic_ams_khk);
};
class optic_AMS_snd: optic_AMS {
displayName = CSTRING(optic_ams_snd);
};
class optic_KHS_base;
class optic_KHS_blk: optic_KHS_base {
displayName = CSTRING(optic_khs_blk);
};
class optic_KHS_hex: optic_KHS_blk {
displayName = CSTRING(optic_khs_hex);
};
class optic_KHS_old: ItemCore {
displayName = CSTRING(optic_khs_old);
};
class optic_KHS_tan: optic_KHS_blk {
displayName = CSTRING(optic_khs_tan);
};
class optic_DMS: ItemCore {
displayName = CSTRING(optic_dms);
};
class optic_DMS_ghex_F: optic_DMS {
displayName = CSTRING(optic_dms_ghex);
};
class optic_DMS_weathered_F: optic_DMS {
displayName = CSTRING(optic_dms_weathered);
};
class optic_DMS_weathered_Kir_F: optic_DMS_weathered_F {
displayName = CSTRING(optic_dms_weathered_kir);
};
class optic_holosight: ItemCore {
displayName = CSTRING(optic_holosight);
};
class optic_Holosight_blk_F: optic_holosight {
displayName = CSTRING(optic_holosight_blk);
};
class optic_Holosight_khk_F: optic_holosight {
displayName = CSTRING(optic_holosight_khk);
};
class optic_Holosight_lush_F: optic_holosight {
displayName = CSTRING(optic_holosight_lush);
};
class optic_Holosight_arid_F: optic_holosight {
displayName = CSTRING(optic_holosight_arid);
};
class optic_Holosight_smg: ItemCore {
displayName = CSTRING(optic_holosight_smg);
};
class optic_Holosight_smg_blk_F: optic_Holosight_smg {
displayName = CSTRING(optic_holosight_smg_blk);
};
class optic_Holosight_smg_khk_F: optic_Holosight_smg {
displayName = CSTRING(optic_holosight_smg_khk);
};
class optic_MRCO: ItemCore {
displayName = CSTRING(optic_MRCO);
};
class ACE_optic_MRCO_2D: optic_MRCO {
displayName = CSTRING(optic_MRCO_2d);
};
class ACE_optic_MRCO_PIP: ACE_optic_MRCO_2D {
displayName = CSTRING(optic_MRCO_pip);
};
class optic_Yorris: ItemCore {
displayName = CSTRING(optic_Yorris);
};
class optic_ACO: ItemCore {
displayName = CSTRING(optic_ACO);
};
class optic_ACO_grn: ItemCore {
displayName = CSTRING(optic_ACO_grn);
};
class optic_ACO_smg: ItemCore {
displayName = CSTRING(optic_ACO_smg);
};
class optic_ACO_grn_smg: ItemCore {
displayName = CSTRING(optic_ACO_grn_smg);
};

View File

@ -249,6 +249,10 @@ class CfgVehicles {
class O_Truck_02_medical_F: Truck_02_medical_base_F {
displayName = CSTRING(Truck_02_medical_Name);
};
class Truck_02_water_base_F;
class C_IDAP_Truck_02_water_F: Truck_02_water_base_F {
displayName = CSTRING(Truck_02_water_Name);
};
class I_Truck_02_transport_F: Truck_02_transport_base_F {
displayName = CSTRING(Truck_02_transport_Name);
};
@ -283,6 +287,12 @@ class CfgVehicles {
class C_Truck_02_box_F: Truck_02_box_base_F {
displayName = CSTRING(Truck_02_box_Name);
};
class C_IDAP_Truck_02_transport_F: Truck_02_transport_base_F {
displayName = CSTRING(Truck_02_transport_Name);
};
class C_IDAP_Truck_02_F: Truck_02_base_F {
displayName = CSTRING(Truck_02_covered_Name);
};
class Truck_03_base_F;
class O_Truck_03_transport_F: Truck_03_base_F {
@ -384,6 +394,9 @@ class CfgVehicles {
class I_Heli_Transport_02_F: Heli_Transport_02_base_F {
displayName = CSTRING(Heli_Transport_02_Name);
};
class C_IDAP_Heli_Transport_02_F: Heli_Transport_02_base_F {
displayName = CSTRING(Heli_Transport_02_Name);
};
// planes
class Plane_CAS_01_base_F;

View File

@ -2,6 +2,7 @@ class Mode_SemiAuto;
class Mode_FullAuto;
class CfgWeapons {
#include "Attachments.hpp"
// assault rifles
// MX
@ -707,176 +708,20 @@ class CfgWeapons {
};
};
//attachments
class ItemCore;
class acc_flashlight: ItemCore {
displayName = "UTG Defender 126";
};
class optic_Hamr: ItemCore {
displayName = CSTRING(optic_hamr);
};
class optic_Hamr_khk_F: optic_Hamr {
displayName = CSTRING(optic_hamr_khk);
};
class ACE_optic_Hamr_2D: optic_Hamr {
displayName = CSTRING(optic_hamr_2d);
};
class ACE_optic_Hamr_PIP: ACE_optic_Hamr_2D {
displayName = CSTRING(optic_hamr_pip);
};
class optic_Arco: ItemCore {
displayName = CSTRING(optic_arco);
};
class optic_Arco_blk_F: optic_Arco {
displayName = CSTRING(optic_arco_blk);
};
class optic_Arco_ghex_F: optic_Arco {
displayName = CSTRING(optic_arco_ghex);
};
class ACE_optic_Arco_2D: optic_Arco {
displayName = CSTRING(optic_arco_2d);
};
class ACE_optic_Arco_PIP: ACE_optic_Arco_2D {
displayName = CSTRING(optic_arco_pip);
};
class optic_Arco_lush_F: optic_Arco {
displayName = CSTRING(optic_arco_lush);
};
class optic_Arco_arid_F: optic_Arco {
displayName = CSTRING(optic_arco_arid);
};
class optic_Arco_AK_blk_F: optic_Arco_blk_F {
displayName = CSTRING(optic_arco_ak_blk);
};
class optic_Arco_AK_lush_F: optic_Arco_lush_F {
displayName = CSTRING(optic_arco_ak_lush);
};
class optic_Arco_AK_arid_F: optic_Arco_arid_F {
displayName = CSTRING(optic_arco_ak_arid);
};
class optic_ERCO_blk_f: optic_Arco {
displayName = CSTRING(optic_erco_blk);
};
class optic_ERCO_khk_f: optic_ERCO_blk_f {
displayName = CSTRING(optic_erco_khk);
};
class optic_ERCO_snd_f: optic_ERCO_blk_f {
displayName = CSTRING(optic_erco_snd);
};
class optic_LRPS: ItemCore {
displayName = CSTRING(optic_lrps);
};
class optic_LRPS_ghex_F: optic_LRPS {
displayName = CSTRING(optic_lrps_ghex);
};
class optic_LRPS_tna_F: optic_LRPS {
displayName = CSTRING(optic_lrps_tna);
};
class ACE_optic_LRPS_2D: optic_LRPS {
displayName = CSTRING(optic_lrps_2d);
};
class ACE_optic_LRPS_PIP: ACE_optic_LRPS_2D {
displayName = CSTRING(optic_lrps_pip);
};
class optic_AMS_base;
class optic_AMS: optic_AMS_base {
displayName = CSTRING(optic_ams);
};
class optic_AMS_khk: optic_AMS {
displayName = CSTRING(optic_ams_khk);
};
class optic_AMS_snd: optic_AMS {
displayName = CSTRING(optic_ams_snd);
};
class optic_KHS_base;
class optic_KHS_blk: optic_KHS_base {
displayName = CSTRING(optic_khs_blk);
};
class optic_KHS_hex: optic_KHS_blk {
displayName = CSTRING(optic_khs_hex);
};
class optic_KHS_old: ItemCore {
displayName = CSTRING(optic_khs_old);
};
class optic_KHS_tan: optic_KHS_blk {
displayName = CSTRING(optic_khs_tan);
};
class optic_DMS: ItemCore {
displayName = CSTRING(optic_dms);
};
class optic_DMS_ghex_F: optic_DMS {
displayName = CSTRING(optic_dms_ghex);
};
class optic_DMS_weathered_F: optic_DMS {
displayName = CSTRING(optic_dms_weathered);
};
class optic_DMS_weathered_Kir_F: optic_DMS_weathered_F {
displayName = CSTRING(optic_dms_weathered_kir);
};
class optic_holosight: ItemCore {
displayName = CSTRING(optic_holosight);
};
class optic_Holosight_blk_F: optic_holosight {
displayName = CSTRING(optic_holosight_blk);
};
class optic_Holosight_khk_F: optic_holosight {
displayName = CSTRING(optic_holosight_khk);
};
class optic_Holosight_lush_F: optic_holosight {
displayName = CSTRING(optic_holosight_lush);
};
class optic_Holosight_arid_F: optic_holosight {
displayName = CSTRING(optic_holosight_arid);
};
class optic_Holosight_smg: ItemCore {
displayName = CSTRING(optic_holosight_smg);
};
class optic_Holosight_smg_blk_F: optic_Holosight_smg {
displayName = CSTRING(optic_holosight_smg_blk);
};
class optic_Holosight_smg_khk_F: optic_Holosight_smg {
displayName = CSTRING(optic_holosight_smg_khk);
};
class optic_MRCO: ItemCore {
displayName = CSTRING(optic_MRCO);
};
class ACE_optic_MRCO_2D: optic_MRCO {
displayName = CSTRING(optic_MRCO_2d);
};
class ACE_optic_MRCO_PIP: ACE_optic_MRCO_2D {
displayName = CSTRING(optic_MRCO_pip);
};
class optic_Yorris: ItemCore {
displayName = CSTRING(optic_Yorris);
};
class optic_ACO: ItemCore {
displayName = CSTRING(optic_ACO);
};
class optic_ACO_grn: ItemCore {
displayName = CSTRING(optic_ACO_grn);
};
class optic_ACO_smg: ItemCore {
displayName = CSTRING(optic_ACO_smg);
};
class optic_ACO_grn_smg: ItemCore {
displayName = CSTRING(optic_ACO_grn_smg);
};
// APEX/Tanoa
// Type 115
class arifle_ARX_base_F;
class arifle_ARX_blk_F: arifle_ARX_base_F {
displayName = CSTRING(arifle_arx_blk_Name);
};
class arifle_ARX_ghex_F: arifle_ARX_base_F {
displayName = CSTRING(arifle_arx_ghex_Name);
};
class arifle_ARX_hex_F: arifle_ARX_base_F {
displayName = CSTRING(arifle_arx_hex_Name);
};
// QBZ-95 and variants
class arifle_CTAR_base_F;
class arifle_CTAR_blk_F: arifle_CTAR_base_F {
@ -1018,6 +863,16 @@ class CfgWeapons {
// Contact/Livonia
// CZ 581 Shotgun
class sgun_HunterShotgun_01_base_F;
class sgun_HunterShotgun_01_F: sgun_HunterShotgun_01_base_F {
displayName = CSTRING(sgun_huntershotgun_01_Name);
};
class sgun_HunterShotgun_01_sawedoff_base_F;
class sgun_HunterShotgun_01_sawedoff_F: sgun_HunterShotgun_01_sawedoff_base_F {
displayName = CSTRING(sgun_huntershotgun_sawedoff_01_Name);
};
// FNX-45 (Green)
class hgun_Pistol_heavy_01_green_F: hgun_Pistol_heavy_01_F {
displayName = CSTRING(hgun_Pistol_heavy_01_green_Name);

View File

@ -698,6 +698,10 @@
<Chinesesimp>"卡玛兹"(医疗)</Chinesesimp>
<Turkish>KamAZ Medikal</Turkish>
</Key>
<Key ID="STR_ACE_RealisticNames_Truck_02_water_Name">
<English>KamAZ Water</English>
<Portuguese>KamAZ Água</Portuguese>
</Key>
<Key ID="STR_ACE_RealisticNames_Truck_02_MRL_Name">
<English>KamAZ MRL</English>
<German>KamAS MRL</German>
@ -1655,6 +1659,14 @@
<Chinese>FNX-45戰術型手槍</Chinese>
<Chinesesimp>FNX-45 战术型</Chinesesimp>
</Key>
<Key ID="STR_ACE_RealisticNames_sgun_huntershotgun_01_Name">
<English>CZ 581</English>
<Portuguese>CZ 581</Portuguese>
</Key>
<Key ID="STR_ACE_RealisticNames_sgun_huntershotgun_sawedoff_01_Name">
<English>CZ 581 (Sawed-Off)</English>
<Portuguese>CZ 581 (Cano serrado)</Portuguese>
</Key>
<Key ID="STR_ACE_RealisticNames_hgun_Pistol_heavy_01_green_Name">
<English>FNX-45 Tactical (Green)</English>
<German>FNX-45 Tactical (Grün)</German>
@ -3056,6 +3068,18 @@
<Chinesesimp>"柏拉格" 战斗无人机</Chinesesimp>
<Turkish>Burraq UCAV</Turkish>
</Key>
<Key ID="STR_ACE_RealisticNames_arifle_arx_blk_Name">
<English>Type 115 (Black)</English>
<Portuguese>Type 115 (Preto)</Portuguese>
</Key>
<Key ID="STR_ACE_RealisticNames_arifle_arx_ghex_Name">
<English>Type 115 (Green Hex)</English>
<Portuguese>Type 115 (Verde Hex)</Portuguese>
</Key>
<Key ID="STR_ACE_RealisticNames_arifle_arx_hex_Name">
<English>Type 115 (Hex)</English>
<Portuguese>Type 115 (Hex)</Portuguese>
</Key>
<Key ID="STR_ACE_RealisticNames_arifle_CTAR_blk">
<English>QBZ-95-1 (Black)</English>
<Czech>QBZ-95-1 (Černá)</Czech>
@ -3840,6 +3864,18 @@
<Spanish>Wiesel 2 RFCV (Radar)</Spanish>
<Korean>비젤 2 RFCV (레이더)</Korean>
</Key>
<Key ID="STR_ACE_RealisticNames_flashlight_Name">
<English>UTG Defender 126</English>
<Portuguese>UTG Defender 126</Portuguese>
</Key>
<Key ID="STR_ACE_RealisticNames_optic_mrd_Name">
<English>EOTech MRDS</English>
<Portuguese>EOTech MRDS</Portuguese>
</Key>
<Key ID="STR_ACE_RealisticNames_optic_mrd_black_Name">
<English>EOTech MRDS (Black)</English>
<Portuguese>EOTech MRDS (Preto)</Portuguese>
</Key>
<Key ID="STR_ACE_RealisticNames_optic_hamr">
<English>Leupold Mark 4 HAMR</English>
<German>Leupold Mark 4 HAMR</German>

View File

@ -2,8 +2,8 @@
GVAR(hardpointGroupsCache) = [] call CBA_fnc_createNamespace;
GVAR(configTypesAdded) = [];
GVAR(magazineNameCache) = [] call CBA_fnc_createNamespace;
GVAR(originalMagazineNames) = [];
GVAR(magazineNameCache) = createHashMap;
GVAR(usedMagazineNames) = createHashMap;
[QGVAR(initSupplyVehicle), {
TRACE_1("initSupplyVehicle EH",_this); // Warning: this can run before settings are init

View File

@ -1,7 +1,7 @@
#include "..\script_component.hpp"
/*
* Author: PabstMirror
* Gets a non-ambigious display name for a magazine using displayNameShort (AP/HE)
* Author: PabstMirror, johnb43
* Gets a non-ambigious display name for a magazine using displayNameShort (AP/HE).
*
* Arguments:
* 0: Magazine Classname <STRING>
@ -10,7 +10,7 @@
* Display Name <STRING>
*
* Example:
* ["B_20mm_AP"] call ace_rearm_fnc_getMagazineName
* "60Rnd_20mm_AP_shells" call ace_rearm_fnc_getMagazineName
*
* Public: No
*/
@ -18,31 +18,31 @@
params ["_className"];
TRACE_1("getMagazineName",_className);
private _magName = GVAR(magazineNameCache) getVariable _className;
if (isNil "_magName") then {
private _displayName = getText(configFile >> "CfgMagazines" >> _className >> "displayName");
GVAR(magazineNameCache) getOrDefaultCall [_className, {
private _cfgMagazines = configFile >> "CfgMagazines";
private _displayName = getText (_cfgMagazines >> _className >> "displayName");
if (_displayName == "") then {
_displayName = _className;
WARNING_1("Magazine is missing display name [%1]",_className);
};
if ((_displayName select [0,6]) == "[CSW] ") then { _displayName = _displayName select [6]; };
// [CSW] prefix is localised
if (["ace_csw"] call EFUNC(common,isModLoaded)) then {
_displayName = trim (_displayName regexReplace [LELSTRING(csw,regex), ""]);
};
GVAR(magazineNameCache) setVariable [_className, _displayName];
GVAR(originalMagazineNames) pushBack _displayName;
// If the display name exists already, add displayNameShort to the existing entry
private _existingClassname = GVAR(usedMagazineNames) get _displayName;
if (!isNil "_existingClassname") then {
GVAR(magazineNameCache) set [_existingClassname, format ["%1: %2", _displayName, getText (_cfgMagazines >> _existingClassname >> "displayNameShort")]];
_displayName = format ["%1: %2", _displayName, getText (_cfgMagazines >> _className >> "displayNameShort")];
};
GVAR(usedMagazineNames) set [_displayName, _className];
TRACE_2("Adding to cache",_className,_displayName);
// go through all existing cache entries and update if there now are duplicates
{
private _xMagName = GVAR(magazineNameCache) getVariable _x;
if ((_xMagName == _displayName) && {({_xMagName == _x} count GVAR(originalMagazineNames)) > 1}) then {
private _xMagName = format ["%1: %2", _displayName, getText(configFile >> "CfgMagazines" >> _x >> "displayNameShort")];
GVAR(magazineNameCache) setVariable [_x, _xMagName];
TRACE_2("Using unique name",_x,_xMagName);
};
} forEach (allVariables GVAR(magazineNameCache));
_magName = GVAR(magazineNameCache) getVariable _className;
};
_magName
_displayName
}, true] // return

View File

@ -7,7 +7,7 @@ private _category = [ELSTRING(main,Category_Logistics), LLSTRING(DisplayName)];
true,
true,
{[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)},
true
true // Needs mission restart
] call CBA_fnc_addSetting;
[
@ -15,8 +15,7 @@ private _category = [ELSTRING(main,Category_Logistics), LLSTRING(DisplayName)];
[LSTRING(RearmSettings_level_DisplayName), LSTRING(RearmSettings_level_Description)],
_category,
[[0,1,2],[LSTRING(RearmSettings_vehicle), LSTRING(RearmSettings_magazine), LSTRING(RearmSettings_caliber)],0], // [values, titles, defaultIndex]
true, // isGlobal
{[QGVAR(level), _this] call EFUNC(common,cbaSettings_settingChanged)}
true // isGlobal
] call CBA_fnc_addSetting;
[
@ -24,8 +23,7 @@ private _category = [ELSTRING(main,Category_Logistics), LLSTRING(DisplayName)];
[LSTRING(RearmSettings_supply_DisplayName), LSTRING(RearmSettings_supply_Description)],
_category,
[[0,1,2],[LSTRING(RearmSettings_unlimited), LSTRING(RearmSettings_limited), LSTRING(RearmSettings_magazineSupply)],0], // [values, titles, defaultIndex]
true, // isGlobal
{[QGVAR(supply), _this] call EFUNC(common,cbaSettings_settingChanged)}
true // isGlobal
] call CBA_fnc_addSetting;
[
@ -33,6 +31,5 @@ private _category = [ELSTRING(main,Category_Logistics), LLSTRING(DisplayName)];
[LLSTRING(RearmSettings_distance_DisplayName), LLSTRING(RearmSettings_distance_Description)],
_category,
[10, 50, 20, 0],
true, // isGlobal
{[QGVAR(supply), _this] call EFUNC(common,cbaSettings_settingChanged)}
true // isGlobal
] call CBA_fnc_addSetting;

View File

@ -31,7 +31,7 @@ class GVAR(positions) {
intro[] = { /* CUP Rahmadi */ };
sara[] = { /* CUP Sahrani */
{"Land_Benzina_schnell", {{8473,9423,0},{9227,5840,0},{9433,5187,0},{10168,6423,0},{10932,9475,0},{11233,6114,0},{11756,10227,0},{12289,6833,0}}},
{"Land_Fuelstation_army", {{9568,9819,0},{19294,13879,0}}},
{"Land_Fuelstation_army", {{9568,9819,0},{19294,13879,0}}}
};
sara_dbe1[] = { /* CUP United Sahrani */
{"Land_Benzina_schnell", {{8473,9423,0},{9227,5840,0},{9433,5187,0},{10168,6423,0},{10932,9475,0},{11233,6114,0},{11756,10227,0},{12289,6833,0}}},
@ -87,4 +87,10 @@ class GVAR(positions) {
{"Land_FuelStation_01_pump_malevil_F", {{18039,18139,0}}},
{"Land_FuelStation_Feed_F", {{756,12133,0},{1239,7346,0},{1726,17469,0},{3113,10070,0},{3828,8362,0},{5668,16967,0},{7435,14185,0},{7543,12107,0},{8366,6086,0},{9672,9586,0},{11749,12255,0},{12802,10022,0},{13989,3591,0},{15198,10900,0},{19063,1654,0},{19378,18517,0}}}
};
pabst_yellowstone[] = { /* Yellowstone */
{"Land_fs_feed_F", {{3075,7426,0},{7060,3626,0},{7950,4060,0},{7974,4072,0}}},
{"Land_FuelStation_01_pump_F", {{4565,1953,0}}},
{"Land_FuelStation_01_pump_malevil_F", {{7072,3676,0}}},
{"Land_FuelStation_Feed_F", {{4678,3971,0},{6391,5174,0}}}
};
};

View File

@ -3,6 +3,14 @@
#include "\z\ace\addons\refuel\script_component.hpp"
{
if (!isArray (configFile >> QGVAR(positions) >> configName _x)) then {
WARNING_1("need configs on [%1]",configName _x);
};
} forEach ("true" configClasses (configFile >> "CfgWorldList"));
private _basePumps = [];
private _totalCount = 0;
private _posCount = 0;
@ -47,9 +55,12 @@ _basePumps sort true; // sort pump classes alphabetically
private _checkCount = 0;
{
_x params ["_class", "_positions"];
private _pumps = [];
{
_checkCount = _checkCount + count (_x nearObjects [_class, 30]);
_pumps append (_x nearObjects [_class, 30]);
} forEach _positions;
_pumps = _pumps arrayIntersect _pumps;
_checkCount = _checkCount + count _pumps;
} forEach _basePumps;
if (_checkCount != _totalCount) then {
_message = "WRONG COUNT " + str _checkCount;

View File

@ -15,8 +15,7 @@ private _category = [ELSTRING(main,Category_Logistics), "str_state_refuel"];
[LSTRING(RefuelSettings_speed_DisplayName), LSTRING(RefuelSettings_speed_Description)],
_category,
[0,25,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)]
true, // isGlobal
{[QGVAR(rate), _this] call EFUNC(common,cbaSettings_settingChanged)}
true // isGlobal
] call CBA_fnc_addSetting;
[
@ -24,8 +23,7 @@ private _category = [ELSTRING(main,Category_Logistics), "str_state_refuel"];
[LSTRING(RefuelSettings_speedCargo_DisplayName), LSTRING(RefuelSettings_speedCargo_Description)],
_category,
[0,250,10,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)]
true, // isGlobal
{[QGVAR(cargoRate), _this] call EFUNC(common,cbaSettings_settingChanged)}
true // isGlobal
] call CBA_fnc_addSetting;
[
@ -33,8 +31,7 @@ private _category = [ELSTRING(main,Category_Logistics), "str_state_refuel"];
[LSTRING(RefuelSettings_hoseLength_DisplayName)],
_category,
[0,50,12,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)]
true, // isGlobal
{[QGVAR(hoseLength), _this] call EFUNC(common,cbaSettings_settingChanged)}
true // isGlobal
] call CBA_fnc_addSetting;
[
@ -42,6 +39,5 @@ private _category = [ELSTRING(main,Category_Logistics), "str_state_refuel"];
[LSTRING(RefuelSettings_progressDuration_DisplayName), LSTRING(RefuelSettings_progressDuration_Description)],
_category,
[0, 10, 2], // [min, max, default value]
true, // isGlobal
{[QGVAR(progressDuration), _this] call EFUNC(common,cbaSettings_settingChanged)}
true // isGlobal
] call CBA_fnc_addSetting;

View File

@ -8,16 +8,14 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)];
true,
true,
{[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)},
true
true // Needs mission restart
] call CBA_fnc_addSetting;
[
QGVAR(displayTextOnRepair), "CHECKBOX",
[LSTRING(SettingDisplayTextName), LSTRING(SettingDisplayTextDesc)],
_category,
true, // default value
false, // isGlobal
{[QGVAR(displayTextOnRepair), _this] call EFUNC(common,cbaSettings_settingChanged)}
true // default value
] call CBA_fnc_addSetting;
[
@ -25,8 +23,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)];
[LSTRING(engineerSetting_Repair_name), LSTRING(engineerSetting_Repair_description)],
_category,
[[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],1], // [values, titles, defaultIndex]
true, // isGlobal
{[QGVAR(engineerSetting_repair), _this] call EFUNC(common,cbaSettings_settingChanged)}
true // isGlobal
] call CBA_fnc_addSetting;
[
@ -34,8 +31,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)];
[LSTRING(engineerSetting_Wheel_name), LSTRING(engineerSetting_Wheel_description)],
_category,
[[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],0], // [values, titles, defaultIndex]
true, // isGlobal
{[QGVAR(engineerSetting_wheel), _this] call EFUNC(common,cbaSettings_settingChanged)}
true // isGlobal
] call CBA_fnc_addSetting;
[
@ -69,8 +65,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)];
[LSTRING(repairDamageThreshold_name), LSTRING(repairDamageThreshold_description)],
_category,
[0, 1, 0.6, 1, true],
true, // isGlobal
{[QGVAR(repairDamageThreshold), _this] call EFUNC(common,cbaSettings_settingChanged)}
true // isGlobal
] call CBA_fnc_addSetting;
[
@ -78,8 +73,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)];
[LSTRING(repairDamageThreshold_Engineer_name), LSTRING(repairDamageThreshold_Engineer_description)],
_category,
[0, 1, 0.4, 1, true],
true, // isGlobal
{[QGVAR(repairDamageThreshold_engineer), _this] call EFUNC(common,cbaSettings_settingChanged)}
true // isGlobal
] call CBA_fnc_addSetting;
[
@ -87,8 +81,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)];
[LSTRING(consumeItem_ToolKit_name), LSTRING(consumeItem_ToolKit_description)],
_category,
[[0,1],[ELSTRING(common,No), ELSTRING(common,Yes)],0], // [values, titles, defaultIndex]
true, // isGlobal
{[QGVAR(consumeItem_toolKit), _this] call EFUNC(common,cbaSettings_settingChanged)}
true // isGlobal
] call CBA_fnc_addSetting;
[
@ -105,8 +98,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)];
[LSTRING(fullRepairLocation), LSTRING(fullRepairLocation_description)],
_catFullRepair,
[[0,1,2,3,4],[LSTRING(useAnywhere), LSTRING(repairVehicleOnly), LSTRING(repairFacilityOnly), LSTRING(vehicleAndFacility), ELSTRING(common,Disabled)],2], // [values, titles, defaultIndex]
true, // isGlobal
{[QGVAR(fullRepairLocation), _this] call EFUNC(common,cbaSettings_settingChanged)}
true // isGlobal
] call CBA_fnc_addSetting;
[
@ -114,8 +106,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)];
[LSTRING(engineerSetting_fullRepair_name), LSTRING(engineerSetting_fullRepair_description)],
_catFullRepair,
[[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],2], // [values, titles, defaultIndex]
true, // isGlobal
{[QGVAR(engineerSetting_fullRepair), _this] call EFUNC(common,cbaSettings_settingChanged)}
true // isGlobal
] call CBA_fnc_addSetting;
[
@ -168,8 +159,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)];
[LSTRING(autoShutOffEngineWhenStartingRepair_name), LSTRING(autoShutOffEngineWhenStartingRepair_description)],
_category,
false, // default value
true, // isGlobal
{[QGVAR(autoShutOffEngineWhenStartingRepair), _this] call EFUNC(common,cbaSettings_settingChanged)}
true // isGlobal
] call CBA_fnc_addSetting;
[

View File

@ -6,5 +6,5 @@
true,
true,
{[QGVAR(enable), _this] call EFUNC(common,cbaSettings_settingChanged)},
true
true // Needs mission restart
] call CBA_fnc_addSetting;

View File

@ -4,8 +4,5 @@ private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(Tagging)]
QGVAR(quickTag), "LIST",
[LLSTRING(QuickTag), LLSTRING(QuickTagDesc)],
_category,
[[0,1,2,3], [LELSTRING(Common,Disabled), LLSTRING(LastUsed), LLSTRING(RandomX), LLSTRING(Random)], 1], // [values, titles, defaultIndex]
false, // isGlobal
{[QGVAR(quickTag), _this] call EFUNC(common,cbaSettings_settingChanged)},
false // Needs mission restart
[[0,1,2,3], [LELSTRING(Common,Disabled), LLSTRING(LastUsed), LLSTRING(RandomX), LLSTRING(Random)], 1] // [values, titles, defaultIndex]
] call CBA_fnc_addSetting;

Some files were not shown because too many files have changed in this diff Show More