Merge branch 'master' into pr/7984

This commit is contained in:
johnb432 2024-07-22 09:29:28 +02:00
commit 8ea8771192
70 changed files with 905 additions and 756 deletions

View File

@ -101,6 +101,17 @@ if (_item isEqualType objNull) then {
// Some objects below water will take damage over time, eventually becoming "water logged" and unfixable (because of negative z attach)
[_item, "blockDamage", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set);
// Prevent UAVs from firing
private _UAVCrew = _item call EFUNC(common,getVehicleUAVCrew);
if (_UAVCrew isNotEqualTo []) then {
{
[_x, true] call EFUNC(common,disableAiUAV);
} forEach _UAVCrew;
_item setVariable [QGVAR(isUAV), _UAVCrew, true];
};
};
};

View File

@ -43,6 +43,7 @@ PREP(deviceKeyFindValidIndex);
PREP(deviceKeyRegisterNew);
PREP(deprecateComponent);
PREP(disableAI);
PREP(disableAiUAV);
PREP(disableUserInput);
PREP(displayIcon);
PREP(displayText);

View File

@ -133,6 +133,30 @@
_object lockInventory (_set > 0);
}] call CBA_fnc_addEventHandler;
[QGVAR(disableAiUAV), {
params ["_unit", "_disable"];
if (_disable) then {
private _features = ["AUTOTARGET", "TARGET", "WEAPONAIM"/*, "FIREWEAPON"*/, "RADIOPROTOCOL"]; // TODO: Uncomment in 2.18
// Save current status
_unit setVariable [QGVAR(featuresAiUAV), _features apply {[_x, _unit checkAIFeature _x]}];
{
_unit enableAIFeature [_x, false];
} forEach _features;
} else {
// Restore previous status
private _features = _unit getVariable [QGVAR(featuresAiUAV), []];
{
_unit enableAIFeature [_x select 0, _x select 1];
} forEach _features;
_unit setVariable [QGVAR(featuresAiUAV), nil];
};
}] call CBA_fnc_addEventHandler;
//Add a fix for BIS's zeus remoteControl module not reseting variables on DC when RC a unit
//This variable is used for isPlayer checks
if (isServer) then {

View File

@ -0,0 +1,45 @@
#include "..\script_component.hpp"
/*
* Author: johnb43
* Disables/Enables UAV AI crew members, can be run on any machine and is applied globally.
*
* Arguments:
* 0: Unit <OBJECT>
* 1: Disable AI <BOOL>
*
* Return Value:
* None
*
* Example:
* [cursorObject, true] call ace_common_fnc_disableAiUAV
*
* Public: No
*/
params [["_unit", objNull, [objNull]], ["_disable", true, [false]]];
// Allow disabling of Zeus remote controlled units
if (!alive _unit || {isPlayer _unit} || {!unitIsUAV _unit}) exitWith {};
if (_disable) then {
// Ignore if already disabled
if (!isNil "_jipID") exitWith {};
// Disable shooting and targeting on every machine
// Give predefined JIP ID, in case of simultaneous executions on different machines
private _jipID = [QGVAR(disableAiUAV), [_unit, _disable], QGVAR(disableAiUAV_) + hashValue _unit] call CBA_fnc_globalEventJIP;
[_jipID, _unit] call CBA_fnc_removeGlobalEventJIP;
_unit setVariable [QGVAR(disableAiUavJipID), _jipID, true];
} else {
// Restore shooting and targeting to each client's individual state prior to disabling
private _jipID = _unit getVariable QGVAR(disableAiUavJipID);
if (isNil "_jipID") exitWith {};
_jipID call CBA_fnc_removeGlobalEventJIP;
_unit setVariable [QGVAR(disableAiUavJipID), nil, true];
[QGVAR(disableAiUAV), [_unit, _disable]] call CBA_fnc_globalEvent;
};

View File

@ -1,34 +1,45 @@
#include "..\script_component.hpp"
/*
* Author: commy2
* Author: commy2, johnb43
* Get the available firing modes of a weapon. Will ignore the AI helper modes.
*
* Arguments:
* 0: Weapon <STRING>
* 1: Muzzle <STRING> (default: weapon)
*
* Return Value:
* Firing Modes <ARRAY>
*
* Example:
* ["gun"] call ace_common_fnc_getWeaponModes
* "arifle_AK12_F" call ace_common_fnc_getWeaponModes
*
* Public: Yes
*/
params [["_weapon", "", [""]]];
params [["_weapon", "", [""]], ["_muzzle", nil, [""]]];
private _config = configFile >> "CfgWeapons" >> _weapon;
if (!isNil "_muzzle") then {
_config = _config >> _muzzle
};
if (!isClass _config) exitWith {
[] // return
};
private _modes = [];
{
if (getNumber (_config >> _x >> "showToPlayer") == 1) then {
_modes pushBack _x;
};
if (_x == "this") then {
_modes pushBack _weapon;
_modes pushBack (configName _config);
} else {
if (isClass (_config >> _x)) then {
_modes pushBack (configName (_config >> _x));
};
};
};
} forEach getArray (_config >> "modes");
_modes
_modes // return

View File

@ -108,19 +108,7 @@ class CfgWeapons {
EGVAR(overpressure,offset) = 1.65;
};
class H_HelmetB;
class rhs_tsh4: H_HelmetB {
HEARING_PROTECTION_VICCREW;
};
class rhs_6b47_bare;
class rhs_6b48: rhs_6b47_bare {
HEARING_PROTECTION_VICCREW;
};
class rhs_zsh7a: H_HelmetB {
HEARING_PROTECTION_VICCREW;
};
class rhs_zsh7a;
class rhs_zsh7a_alt: rhs_zsh7a {
ACE_Protection = 1;
};
@ -133,22 +121,6 @@ class CfgWeapons {
ACE_Protection = 1;
};
class rhs_gssh18: H_HelmetB {
HEARING_PROTECTION_EARMUFF;
};
class rhs_6b47;
class rhs_6b47_6m2: rhs_6b47 {
HEARING_PROTECTION_PELTOR;
};
class rhs_6b47_6m2_1: rhs_6b47 {
HEARING_PROTECTION_PELTOR;
};
class rhs_6m2: H_HelmetB {
HEARING_PROTECTION_PELTOR;
};
class rhs_weap_d81;
class rhs_weap_2a70: rhs_weap_d81 { // "Low pressure" 100mm cannon
EGVAR(overpressure,range) = 15;

View File

@ -0,0 +1,28 @@
class CfgWeapons {
class H_HelmetB;
class rhs_tsh4: H_HelmetB {
HEARING_PROTECTION_VICCREW;
};
class rhs_zsh7a: H_HelmetB {
HEARING_PROTECTION_VICCREW;
};
class rhs_gssh18: H_HelmetB {
HEARING_PROTECTION_EARMUFF;
};
class rhs_6m2: H_HelmetB {
HEARING_PROTECTION_PELTOR;
};
class rhs_6b47;
class rhs_6b47_6m2: rhs_6b47 {
HEARING_PROTECTION_PELTOR;
};
class rhs_6b47_6m2_1: rhs_6b47 {
HEARING_PROTECTION_PELTOR;
};
class rhs_6b47_bare;
class rhs_6b48: rhs_6b47_bare {
HEARING_PROTECTION_VICCREW;
};
};

View File

@ -0,0 +1,19 @@
#include "script_component.hpp"
#include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp"
class CfgPatches {
class SUBADDON {
addonRootClass = QUOTE(COMPONENT);
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {
"rhs_main_loadorder",
"ace_hearing"
};
skipWhenMissingDependencies = 1;
VERSION_CONFIG;
};
};
#include "CfgWeapons.hpp"

View File

@ -0,0 +1,3 @@
#define SUBCOMPONENT hearing
#define SUBCOMPONENT_BEAUTIFIED Hearing
#include "..\script_component.hpp"

View File

@ -1,5 +1,4 @@
#include "script_component.hpp"
#include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp"
class CfgPatches {
class ADDON {
@ -7,7 +6,7 @@ class CfgPatches {
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"rhs_main_loadorder"};
requiredAddons[] = {"ace_common", "rhs_main_loadorder"};
author = ECSTRING(common,ACETeam);
authors[] = {"Ruthberg", "GitHawk", "BaerMitUmlaut", "commy2", "Skengman2"};
url = ECSTRING(main,URL);

View File

@ -6,7 +6,7 @@ class CfgPatches {
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"rhsgref_main_loadorder"};
requiredAddons[] = {"ace_common", "rhsgref_main_loadorder"};
skipWhenMissingDependencies = 1;
author = ECSTRING(common,ACETeam);
authors[] = {"PabstMirror", "Ruthberg", "Anton"};

View File

@ -6,7 +6,7 @@ class CfgPatches {
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"rhssaf_main_loadorder"};
requiredAddons[] = {"ace_common", "rhssaf_main_loadorder"};
skipWhenMissingDependencies = 1;
author = ECSTRING(common,ACETeam);
authors[] = {};

View File

@ -206,170 +206,7 @@ class CfgWeapons {
EGVAR(overpressure,offset) = 0.9;
};
// Fast Helmets
class rhsusf_opscore_01;
class rhsusf_opscore_ut_pelt_nsw: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_aor1_pelt: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_aor1_pelt_nsw: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_bk_pelt: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_fg_pelt: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_fg_pelt_nsw: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_fg_pelt_cam: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_paint_pelt: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_paint_pelt_nsw: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_paint_pelt_nsw_cam: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_aor2_pelt: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_aor2_pelt_nsw: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_ut_pelt: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_ut_pelt_cam: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_ut_pelt_nsw_cam: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_mc_pelt: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_mc_pelt_nsw: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_cover;
class rhsusf_opscore_mc_cover_pelt_nsw: rhsusf_opscore_cover {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_mc_cover_pelt: rhsusf_opscore_cover {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_mc_cover_pelt_cam: rhsusf_opscore_cover {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_rg_cover_pelt: rhsusf_opscore_cover {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_coy_cover_pelt: rhsusf_opscore_cover {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_mar_01;
class rhsusf_opscore_mar_ut_pelt: rhsusf_opscore_mar_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_mar_fg_pelt: rhsusf_opscore_mar_01 {
HEARING_PROTECTION_PELTOR;
};
// ACH Helmets
class rhsusf_ach_helmet_ocp;
class rhsusf_ach_bare_des_headset: rhsusf_ach_helmet_ocp {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_ach_bare_des_headset_ess: rhsusf_ach_helmet_ocp {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_ach_bare_headset: rhsusf_ach_helmet_ocp {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_ach_bare_headset_ess: rhsusf_ach_helmet_ocp {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_ach_bare_semi_headset: rhsusf_ach_helmet_ocp {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_ach_bare_semi_headset_ess: rhsusf_ach_helmet_ocp {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_ach_bare_tan_headset: rhsusf_ach_helmet_ocp {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_ach_bare_tan_headset_ess: rhsusf_ach_helmet_ocp {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_ach_bare_wood_headset: rhsusf_ach_helmet_ocp {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_ach_bare_wood_headset_ess: rhsusf_ach_helmet_ocp {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_ach_helmet_headset_ocp: rhsusf_ach_helmet_ocp {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_ach_helmet_headset_ess_ocp: rhsusf_ach_helmet_ocp {
HEARING_PROTECTION_PELTOR;
};
// ACVC Helmets
class rhsusf_cvc_helmet: rhsusf_opscore_01 {
HEARING_PROTECTION_VICCREW;
};
// MICH Helmets
class rhsusf_mich_bare;
class rhsusf_mich_bare_alt: rhsusf_mich_bare {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_mich_bare_norotos;
class rhsusf_mich_bare_norotos_alt: rhsusf_mich_bare_norotos {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_mich_bare_norotos_arc;
class rhsusf_mich_bare_norotos_arc_alt: rhsusf_mich_bare_norotos_arc {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_mich_bare_semi;
class rhsusf_mich_bare_alt_semi: rhsusf_mich_bare_semi {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_mich_bare_norotos_semi;
class rhsusf_mich_bare_norotos_alt_semi: rhsusf_mich_bare_norotos_semi {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_mich_bare_norotos_arc_semi: rhsusf_mich_bare_norotos_alt_semi {
HEARING_PROTECTION_OPEN;
};
class rhsusf_mich_bare_norotos_arc_alt_semi: rhsusf_mich_bare_norotos_arc_semi {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_mich_bare_tan;
class rhsusf_mich_bare_alt_tan: rhsusf_mich_bare_tan {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_mich_bare_norotos_tan;
class rhsusf_mich_bare_norotos_alt_tan: rhsusf_mich_bare_norotos_tan {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_mich_bare_norotos_arc_tan;
class rhsusf_mich_bare_norotos_arc_alt_tan: rhsusf_mich_bare_norotos_arc_tan {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_hgu56p: rhsusf_opscore_01 {
HEARING_PROTECTION_VICCREW;
};
class rhsusf_hgu56p;
class rhsusf_hgu56p_visor: rhsusf_hgu56p {
ACE_Protection = 1;
};
@ -420,13 +257,9 @@ class CfgWeapons {
class rhsusf_hgu56p_mask_black_skull: rhsusf_hgu56p_visor_mask_black_skull {
ACE_Protection = 0;
};
class rhsusf_ihadss: rhsusf_opscore_01 {
HEARING_PROTECTION_VICCREW;
};
class H_HelmetB;
class RHS_jetpilot_usaf: H_HelmetB {
ACE_Protection = 1;
HEARING_PROTECTION_VICCREW;
};
};

View File

@ -0,0 +1,174 @@
class CfgWeapons {
// Fast Helmets
class rhsusf_opscore_01;
class rhsusf_opscore_ut_pelt_nsw: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_aor1_pelt: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_aor1_pelt_nsw: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_bk_pelt: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_fg_pelt: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_fg_pelt_nsw: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_fg_pelt_cam: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_paint_pelt: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_paint_pelt_nsw: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_paint_pelt_nsw_cam: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_aor2_pelt: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_aor2_pelt_nsw: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_ut_pelt: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_ut_pelt_cam: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_ut_pelt_nsw_cam: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_mc_pelt: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_mc_pelt_nsw: rhsusf_opscore_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_cover;
class rhsusf_opscore_mc_cover_pelt_nsw: rhsusf_opscore_cover {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_mc_cover_pelt: rhsusf_opscore_cover {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_mc_cover_pelt_cam: rhsusf_opscore_cover {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_rg_cover_pelt: rhsusf_opscore_cover {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_coy_cover_pelt: rhsusf_opscore_cover {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_mar_01;
class rhsusf_opscore_mar_ut_pelt: rhsusf_opscore_mar_01 {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_opscore_mar_fg_pelt: rhsusf_opscore_mar_01 {
HEARING_PROTECTION_PELTOR;
};
// ACH Helmets
class rhsusf_ach_helmet_ocp;
class rhsusf_ach_bare_des_headset: rhsusf_ach_helmet_ocp {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_ach_bare_des_headset_ess: rhsusf_ach_helmet_ocp {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_ach_bare_headset: rhsusf_ach_helmet_ocp {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_ach_bare_headset_ess: rhsusf_ach_helmet_ocp {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_ach_bare_semi_headset: rhsusf_ach_helmet_ocp {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_ach_bare_semi_headset_ess: rhsusf_ach_helmet_ocp {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_ach_bare_tan_headset: rhsusf_ach_helmet_ocp {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_ach_bare_tan_headset_ess: rhsusf_ach_helmet_ocp {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_ach_bare_wood_headset: rhsusf_ach_helmet_ocp {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_ach_bare_wood_headset_ess: rhsusf_ach_helmet_ocp {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_ach_helmet_headset_ocp: rhsusf_ach_helmet_ocp {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_ach_helmet_headset_ess_ocp: rhsusf_ach_helmet_ocp {
HEARING_PROTECTION_PELTOR;
};
// ACVC Helmets
class rhsusf_cvc_helmet: rhsusf_opscore_01 {
HEARING_PROTECTION_VICCREW;
};
// MICH Helmets
class rhsusf_mich_bare;
class rhsusf_mich_bare_alt: rhsusf_mich_bare {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_mich_bare_norotos;
class rhsusf_mich_bare_norotos_alt: rhsusf_mich_bare_norotos {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_mich_bare_norotos_arc;
class rhsusf_mich_bare_norotos_arc_alt: rhsusf_mich_bare_norotos_arc {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_mich_bare_semi;
class rhsusf_mich_bare_alt_semi: rhsusf_mich_bare_semi {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_mich_bare_norotos_semi;
class rhsusf_mich_bare_norotos_alt_semi: rhsusf_mich_bare_norotos_semi {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_mich_bare_norotos_arc_semi: rhsusf_mich_bare_norotos_alt_semi {
HEARING_PROTECTION_OPEN;
};
class rhsusf_mich_bare_norotos_arc_alt_semi: rhsusf_mich_bare_norotos_arc_semi {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_mich_bare_tan;
class rhsusf_mich_bare_alt_tan: rhsusf_mich_bare_tan {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_mich_bare_norotos_tan;
class rhsusf_mich_bare_norotos_alt_tan: rhsusf_mich_bare_norotos_tan {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_mich_bare_norotos_arc_tan;
class rhsusf_mich_bare_norotos_arc_alt_tan: rhsusf_mich_bare_norotos_arc_tan {
HEARING_PROTECTION_PELTOR;
};
class rhsusf_hgu56p: rhsusf_opscore_01 {
HEARING_PROTECTION_VICCREW;
};
class rhsusf_ihadss: rhsusf_opscore_01 {
HEARING_PROTECTION_VICCREW;
};
class H_HelmetB;
class RHS_jetpilot_usaf: H_HelmetB {
HEARING_PROTECTION_VICCREW;
};
};

View File

@ -0,0 +1,19 @@
#include "script_component.hpp"
#include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp"
class CfgPatches {
class SUBADDON {
addonRootClass = QUOTE(COMPONENT);
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {
"rhsusf_main_loadorder",
"ace_hearing"
};
skipWhenMissingDependencies = 1;
VERSION_CONFIG;
};
};
#include "CfgWeapons.hpp"

View File

@ -0,0 +1,3 @@
#define SUBCOMPONENT hearing
#define SUBCOMPONENT_BEAUTIFIED Hearing
#include "..\script_component.hpp"

View File

@ -1,5 +1,4 @@
#include "script_component.hpp"
#include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp"
class CfgPatches {
class ADDON {
@ -7,7 +6,7 @@ class CfgPatches {
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"rhsusf_main_loadorder"};
requiredAddons[] = {"ace_common", "rhsusf_main_loadorder"};
skipWhenMissingDependencies = 1;
author = ECSTRING(common,ACETeam);
authors[] = {"Ruthberg", "GitHawk", "BaerMitUmlaut", "Fyuran"};

View File

@ -3,11 +3,13 @@ class Extended_PreStart_EventHandlers {
init = QUOTE(call COMPILE_SCRIPT(XEH_preStart));
};
};
class Extended_PreInit_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_SCRIPT(XEH_preInit));
};
};
class Extended_PostInit_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_SCRIPT(XEH_postInit));

View File

@ -4,7 +4,7 @@ class CfgVehicles {
class ACE_Actions {
class ACE_Dogtag {
displayName = CSTRING(itemName);
condition = QUOTE([ARR_2(_player,_target)] call FUNC(canTakeDogtag));
condition = QUOTE([ARR_2(_player,_target)] call FUNC(canCheckDogtag));
statement = "";
exceptions[] = {"isNotSwimming", "isNotInside"};
showDisabled = 0;

View File

@ -16,8 +16,8 @@ class CfgWeapons {
author = ECSTRING(common,ACETeam);
scope = 0;
displayName = CSTRING(itemName);
model = QUOTE(PATHTOF(data\ace_dogtag.p3d));
picture = QUOTE(PATHTOF(data\dogtagSingle.paa));
model = QPATHTOF(data\ace_dogtag.p3d);
picture = QPATHTOF(data\dogtagSingle.paa);
class ItemInfo: CBA_MiscItem_ItemInfo {
mass = 0; //too small to for 1 ?
};

View File

@ -1,13 +1,11 @@
PREP(addDogtagActions);
PREP(addDogtagItem);
PREP(bloodType);
PREP(canCheckDogtag);
PREP(canTakeDogtag);
PREP(checkDogtag);
PREP(disableFactionDogtags);
PREP(getDogtagData);
PREP(getDogtagItem);
PREP(showDogtag);
PREP(ssn);
PREP(takeDogtag);
PREP(disableFactionDogtags);

View File

@ -1,9 +1,5 @@
#include "script_component.hpp"
[QGVAR(showDogtag), LINKFUNC(showDogtag)] call CBA_fnc_addEventHandler;
[QGVAR(getDogtagItem), LINKFUNC(getDogtagItem)] call CBA_fnc_addEventHandler;
[QGVAR(addDogtagItem), LINKFUNC(addDogtagItem)] call CBA_fnc_addEventHandler;
if (hasInterface || isServer) then {
[QGVAR(broadcastDogtagInfo), {
GVAR(dogtagsData) set _this;
@ -18,69 +14,29 @@ if (hasInterface || isServer) then {
[QGVAR(broadcastDogtagInfo), [_x, _y], _clientOwner] call CBA_fnc_ownerEvent;
} forEach GVAR(dogtagsData);
}] call CBA_fnc_addEventHandler;
[QGVAR(getDogtagItem), LINKFUNC(getDogtagItem)] call CBA_fnc_addEventHandler;
} else {
// To be here, hasInterface must be true
[QGVAR(requestSyncDogtagDataJIP), clientOwner] call CBA_fnc_serverEvent;
};
};
// Add actions and event handlers only if ace_medical is enabled
// - Adding actions via config would create a dependency
["CBA_settingsInitialized", {
if !(GETEGVAR(medical,enabled,false)) exitWith {};
if (hasInterface) then {
private _checkTagAction = [
"ACE_CheckDogtag",
format ["%1: %2", localize LSTRING(itemName), localize LSTRING(checkDogtag)],
QPATHTOF(data\dogtag_icon_ca.paa),
{[_player,_target] call FUNC(checkDogtag)},
{!isNil {_target getVariable QGVAR(dogtagData)}}
] call EFUNC(interact_menu,createAction);
["ACE_bodyBagObject", 0, ["ACE_MainActions"], _checkTagAction, true] call EFUNC(interact_menu,addActionToClass);
private _takeTagAction = [
"ACE_TakeDogtag",
format ["%1: %2", localize LSTRING(itemName), localize LSTRING(takeDogtag)],
QPATHTOF(data\dogtag_icon_ca.paa),
{[_player,_target] call FUNC(takeDogtag)},
{(!isNil {_target getVariable QGVAR(dogtagData)}) && {((_target getVariable [QGVAR(dogtagTaken), objNull]) != _target)}}
] call EFUNC(interact_menu,createAction);
["ACE_bodyBagObject", 0, ["ACE_MainActions"], _takeTagAction, true] call EFUNC(interact_menu,addActionToClass);
};
if (isServer) then {
["ace_placedInBodyBag", {
params ["_target", "_bodyBag", "_isGrave"];
if (_isGrave) exitWith {};
TRACE_2("ace_placedInBodyBag eh",_target,_bodyBag);
private _dogTagData = [_target] call FUNC(getDogtagData);
_bodyBag setVariable [QGVAR(dogtagData), _dogTagData, true];
if ((_target getVariable [QGVAR(dogtagTaken), objNull]) == _target) then {
_bodyBag setVariable [QGVAR(dogtagTaken), _bodyBag, true];
};
}] call CBA_fnc_addEventHandler;
};
}] call CBA_fnc_addEventHandler;
// If the arsenal is loaded, show the custom names for dog tags when in the arsenal
if (["ace_arsenal"] call EFUNC(common,isModLoaded)) then {
if (hasInterface) then {
// If the arsenal is loaded, show the custom names for dog tags when in the arsenal
if (["ace_arsenal"] call EFUNC(common,isModLoaded)) then {
[QEGVAR(arsenal,rightPanelFilled), {
params ["_display", "_leftPanelIDC", "_rightPanelIDC"];
if (_leftPanelIDC in [2010, 2012, 2014] && {_rightPanelIDC == 38}) then {
LOG("passed");
if !(_leftPanelIDC in [2010, 2012, 2014] && {_rightPanelIDC == 38}) exitWith {};
private _rightPanel = _display displayCtrl 15;
private _cfgWeapons = configFile >> "CfgWeapons";
private _item = "";
private _dogtagData = [];
TRACE_1("passed",_rightPanel);
for "_i" from 0 to (lnbSize _rightPanel select 0) - 1 do {
_item = _rightPanel lnbData [_i, 0];
private _item = _rightPanel lnbData [_i, 0];
if (_item isKindOf ["ACE_dogtag", _cfgWeapons]) then {
private _name = (GVAR(dogtagsData) getOrDefault [_item, []]) param [0, ""];
@ -93,12 +49,11 @@ if (["ace_arsenal"] call EFUNC(common,isModLoaded)) then {
_rightPanel lnbSetText [[_i, 1], [LLSTRING(itemName), ": ", _name] joinString ""];
};
};
};
}] call CBA_fnc_addEventHandler;
};
};
// Add context menu option
[
// Add context menu option
[
"ACE_dogtag",
["GROUND", "CARGO", "CONTAINER"],
LLSTRING(checkItem),
@ -113,7 +68,52 @@ if (["ace_arsenal"] call EFUNC(common,isModLoaded)) then {
false
}
] call CBA_fnc_addItemContextMenuOption;
] call CBA_fnc_addItemContextMenuOption;
};
// Disable dogtags for civilians
// Add actions and event handlers only if ace_medical is enabled
// - Adding actions via config would create a dependency
["CBA_settingsInitialized", {
if !(GETEGVAR(medical,enabled,false)) exitWith {};
if (hasInterface) then {
private _checkTagAction = [
"ACE_CheckDogtag",
format ["%1: %2", LLSTRING(itemName), LLSTRING(checkDogtag)],
QPATHTOF(data\dogtag_icon_ca.paa),
{[_player, _target] call FUNC(checkDogtag)},
{!isNil {_target getVariable QGVAR(dogtagData)}}
] call EFUNC(interact_menu,createAction);
["ACE_bodyBagObject", 0, ["ACE_MainActions"], _checkTagAction, true] call EFUNC(interact_menu,addActionToClass);
private _takeTagAction = [
"ACE_TakeDogtag",
format ["%1: %2", LLSTRING(itemName), LLSTRING(takeDogtag)],
QPATHTOF(data\dogtag_icon_ca.paa),
{[_player, _target] call FUNC(takeDogtag)},
{(!isNil {_target getVariable QGVAR(dogtagData)}) && {((_target getVariable [QGVAR(dogtagTaken), objNull]) != _target)}}
] call EFUNC(interact_menu,createAction);
["ACE_bodyBagObject", 0, ["ACE_MainActions"], _takeTagAction, true] call EFUNC(interact_menu,addActionToClass);
};
if (isServer) then {
["ace_placedInBodyBag", {
params ["_target", "_bodyBag", "_isGrave"];
if (_isGrave) exitWith {};
TRACE_2("ace_placedInBodyBag eh",_target,_bodyBag);
private _dogtagData = _target call FUNC(getDogtagData);
_bodyBag setVariable [QGVAR(dogtagData), _dogtagData, true];
if ((_target getVariable [QGVAR(dogtagTaken), objNull]) == _target) then {
_bodyBag setVariable [QGVAR(dogtagTaken), _bodyBag, true];
};
}] call CBA_fnc_addEventHandler;
};
}] call CBA_fnc_addEventHandler;
// Disable dog tags for civilians
"CIV_F" call FUNC(disableFactionDogtags);

View File

@ -1,7 +1,7 @@
#include "..\script_component.hpp"
/*
* Author: SzwedzikPL, mharis001
* Returns children actions for checking dogtags in player's inventory.
* Returns children actions for checking dog tags in the player's inventory.
*
* Arguments:
* 0: Player <OBJECT>
@ -10,7 +10,7 @@
* Actions <ARRAY>
*
* Example:
* [_player] call ace_dogtags_fnc_addDogtagActions
* player call ace_dogtags_fnc_addDogtagActions
*
* Public: No
*/
@ -23,14 +23,21 @@ private _fnc_getActions = {
{
private _config = _cfgWeapons >> _x;
if (getNumber (_config >> QGVAR(tagID)) > 0) then {
private _displayName = getText (_config >> "displayName");
private _picture = getText (_config >> "picture");
private _action = [_x, _displayName, _picture, {
[GVAR(dogtagsData) getOrDefault [_this select 2, []]] call FUNC(showDogtag);
}, {true}, {}, _x] call EFUNC(interact_menu,createAction);
_actions pushBack [_action, [], _player];
if (getNumber (_config >> QGVAR(tagID)) > 0) then {
_actions pushBack [
[
_x,
getText (_config >> "displayName"),
getText (_config >> "picture"),
{[GVAR(dogtagsData) getOrDefault [_this select 2, []]] call FUNC(showDogtag)},
{true},
{},
_x
] call EFUNC(interact_menu,createAction),
[],
_player
];
};
} forEach (_player call EFUNC(common,uniqueItems));

View File

@ -1,38 +0,0 @@
#include "..\script_component.hpp"
/*
* Author: SzwedzikPL
* Adds dogtag item to unit (triggered by server).
*
* Arguments:
* 0: Item class <STRING>
* 1: Dogtag data <ARRAY>
*
* Return Value:
* None
*
* Example:
* ["itemClass", ["name", "610-27-5955", "A POS"]] call ace_dogtags_fnc_addDogtagItem
*
* Public: No
*/
params ["_item", "_dogtagData"];
if (_item == "") exitWith {};
// Verify that the unit has inventory space, otherwise drop the dogtag on the ground
[ace_player, _item, true] call CBA_fnc_addItem;
_dogtagData params ["_name"];
// If data doesn't exist or body has no name, set name as "unknown"
if (_name == "") then {
_name = LELSTRING(common,unknown);
};
private _displayText = format [localize LSTRING(takeDogtagSuccess), _name];
// display message
[{
[_this, 2.5] call EFUNC(common,displayTextStructured);
}, _displayText, DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute;

View File

@ -1,16 +1,16 @@
#include "..\script_component.hpp"
/*
* Author: commy2
* Reports a blood type depending on the units name.
* Reports a blood type depending on the unit's name.
*
* Arguments:
* 0: Name of a unit <STRING>
* 0: Unit name <STRING>
*
* Return Value:
* A random blood type <STRING>
*
* Example:
* _bloodType = ["name"] call ace_dogtags_fnc_bloodType
* "name" call ace_dogtags_fnc_bloodType
*
* Public: No
*/

View File

@ -1,26 +1,26 @@
#include "..\script_component.hpp"
/*
* Author: SzwedzikPL
* Checks if dogtag can be checked.
* Checks if the target's dog tag can be checked by the unit.
*
* Arguments:
* 0: Player <OBJECT>
* 0: Player (not used) <OBJECT>
* 1: Target <OBJECT>
*
* Return Value:
* True if dogtag can be checked <BOOL>
* If dog tag can be checked <BOOL>
*
* Example:
* _canCheck = [player, unit] call ace_dogtags_fnc_canCheckDogtag
* [player, cursorObject] call ace_dogtags_fnc_canCheckDogtag
*
* Public: No
*/
params ["_player", "_target"];
params ["", "_target"];
if (isNull _target) exitWith {false};
// check if disabled for faction
// Check if disabled for faction
if ((faction _target) in GVAR(disabledFactions)) exitWith {false};
!(_target call EFUNC(common,isAwake))

View File

@ -1,17 +1,17 @@
#include "..\script_component.hpp"
/*
* Author: SzwedzikPL
* Checks if dogtag can be taken.
* Checks if the target's dog tag can be taken by the unit.
*
* Arguments:
* 0: Player <OBJECT>
* 1: Target <OBJECT>
*
* Return Value:
* True if dogtag can be taken <BOOL>
* If dog tag can be taken <BOOL>
*
* Example:
* _canTake = [player, unit] call ace_dogtags_fnc_canTakeDogtag
* [player, cursorObject] call ace_dogtags_fnc_canTakeDogtag
*
* Public: No
*/
@ -20,7 +20,10 @@ params ["_player", "_target"];
if (isNull _target) exitWith {false};
// check if disabled for faction
// Check if disabled for faction
if ((faction _target) in GVAR(disabledFactions)) exitWith {false};
!(_target call EFUNC(common,isAwake)) && {_player canAdd ["ACE_dogtag_1", 1/*, true*/]} // Todo: Uncomment in 2.18
// CBA_fnc_canAddItem doesn't account for mass 0 items and unit not having any containers
!(_target call EFUNC(common,isAwake)) && {(uniform _player + vest _player + backpack _player) != ""} && {[_player, "ACE_dogtag_1"] call CBA_fnc_canAddItem}
// Todo: Use code below in 2.18
// _player canAdd ["ACE_dogtag_1", 1, true]

View File

@ -1,7 +1,7 @@
#include "..\script_component.hpp"
/*
* Author: SzwedzikPL
* Checks unit dogtag.
* Checks the unit's dog tag.
*
* Arguments:
* 0: Player <OBJECT>
@ -11,17 +11,17 @@
* None
*
* Example:
* [player, unit] call ace_dogtags_fnc_checkDogtag
* [player, cursorObject] call ace_dogtags_fnc_checkDogtag
*
* Public: No
*/
params ["_player", "_target"];
// animation
// Animation
_player call EFUNC(common,goKneeling);
// sound
// Sound
private _position = _target modelToWorldWorld (_target selectionPosition "neck");
playSound3D [
@ -34,10 +34,8 @@ playSound3D [
50
];
// display dogtag
// Display dog tag
private _doubleTags = (_target getVariable [QGVAR(dogtagTaken), objNull]) != _target;
private _dogTagData = [_target] call FUNC(getDogTagData);
private _dogtagData = _target call FUNC(getDogtagData);
[{
[QGVAR(showDogtag), _this] call CBA_fnc_localEvent;
}, [_dogTagData, _doubleTags], DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute;
[LINKFUNC(showDogtag), [_dogtagData, _doubleTags], DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute;

View File

@ -1,7 +1,7 @@
#include "..\script_component.hpp"
/*
* Author: commy2
* Disable this faction from using dogtags.
* Disables this faction from using dog tags.
*
* Arguments:
* 0: Faction <STRING>

View File

@ -1,19 +1,19 @@
#include "..\script_component.hpp"
/*
* Author: esteldunedain
* Get unit dogtag data.
* Gets unit's dog tag data.
*
* Arguments:
* 0: Target <OBJECT>
*
* Return Value:
* Dogtag Data <ARRAY>
* Dog tag Data <ARRAY>
* 0: Name <STRING>
* 1: SSN <STRING>
* 2: Blood Type <STRING>
*
* Example:
* _dogtagData = [unit, player] call ace_dogtags_fnc_getDogtagData
* player call ace_dogtags_fnc_getDogtagData
*
* Public: No
*/
@ -21,17 +21,20 @@
params ["_target"];
// Check if the data was already created
private _dogTagData = _target getVariable QGVAR(dogtagData);
if (!isNil "_dogTagData") exitWith {_dogTagData};
private _dogtagData = _target getVariable QGVAR(dogtagData);
if (!isNil "_dogtagData") exitWith {_dogtagData};
// Create dog tag data once for the unit: nickname, code (eg. 135-13-900) and blood type
private _targetName = [_target, false, true] call EFUNC(common,getName);
private _dogTagData = [
private _dogtagData = [
_targetName,
_targetName call FUNC(ssn),
_targetName call FUNC(bloodType)
];
// Store it
_target setVariable [QGVAR(dogtagData), _dogTagData, true];
_dogTagData
_target setVariable [QGVAR(dogtagData), _dogtagData, true];
_dogtagData

View File

@ -1,7 +1,8 @@
#include "..\script_component.hpp"
/*
* Author: SzwedzikPL
* Server: creates new dogtag item and send it to client.
* Server: Creates a new dog tag item and sends it to client.
* It broacasts the dog tag info to all machines with interfaces.
*
* Arguments:
* 0: Player <OBJECT>
@ -11,12 +12,12 @@
* None
*
* Example:
* [player, unit] call ace_dogtags_fnc_getDogtagItem
* [player, cursorObject] call ace_dogtags_fnc_getDogtagItem
*
* Public: No
*/
if(!isServer) exitWith {};
if (!isServer) exitWith {};
params ["_player", "_target"];
TRACE_2("getDogtagItem",_player,_target);
@ -28,7 +29,20 @@ if (GVAR(idCounter) > 999) exitWith {ERROR("Ran out of IDs");};
private _dogTagData = [_target] call FUNC(getDogTagData);
private _item = format ["ACE_dogtag_%1", GVAR(idCounter)];
[QGVAR(addDogtagItem), [_item, _dogTagData], [_player]] call CBA_fnc_targetEvent;
// Broadcast data globally, so that clients can use it where needed
[QGVAR(broadcastDogtagInfo), [_item, _dogTagData]] call CBA_fnc_globalEvent;
// Dog tags have no mass, so no need to check if it can fit in container, but check if unit has an inventory at all
[_player, _item, true] call CBA_fnc_addItem;
private _name = _dogtagData param [0, ""];
// If data doesn't exist or body has no name, set name as "unknown"
if (_name == "") then {
_name = LELSTRING(common,unknown);
};
// Display message
[{
[QEGVAR(common,displayTextStructured), [_this select 0, 2.5], _this select 1] call CBA_fnc_targetEvent;
}, [format [LLSTRING(takeDogtagSuccess), _name], _player], DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute;

View File

@ -1,10 +1,10 @@
#include "..\script_component.hpp"
/*
* Author: SzwedzikPL
* Shows dogtag.
* Shows dog tag.
*
* Arguments:
* 0: Dogtag data <ARRAY>
* 0: Dog tag data <ARRAY>
* 1: Display as double tag <BOOLEAN>
*
* Return Value:
@ -27,8 +27,10 @@ if (_doubleTags) then {
} else {
(QGVAR(tag) call BIS_fnc_rscLayer) cutRsc [QGVAR(singleTag), "PLAIN", 1, true];
};
private _display = uiNamespace getvariable [QGVAR(tag), displayNull];
if(isNull _display) exitWith {};
private _display = uiNamespace getVariable [QGVAR(tag), displayNull];
if (isNull _display) exitWith {};
private _control = _display displayCtrl 1001;
_dogtagData params ["_name", "_code", "_bloodType"];

View File

@ -1,16 +1,16 @@
#include "..\script_component.hpp"
/*
* Author: kymckay
* Reports a social security number generated from the units name.
* Reports a social security number generated from the unit's name.
*
* Arguments:
* 0: Name of a unit <STRING>
* 0: Unit name <STRING>
*
* Return Value:
* A random three/two/four format social security number <STRING>
*
* Example:
* _ssn = ["AAA"] call ace_dogtags_fnc_ssn
* "name" call ace_dogtags_fnc_ssn
*
* Public: No
*/
@ -18,19 +18,20 @@
params ["_name"];
private _chars = toArray _name;
private _length = count _chars;
// Warning, for strings containing non-latin characters, `_count _name` != `_count _chars`
private _length = count _chars;
_chars pushBack _length;
_length = _length + 1;
private _remainder = 0;
private _nums = [0,0,0,0,0,0,0,0,0];
private _nums = [0, 0, 0, 0, 0, 0, 0, 0, 0];
for "_index" from 0 to (8 max _length) do {
private _inputChar = _chars select (_index % _length);
_nums set [(_index % 9), ((_nums select (_index % 9)) + _inputChar + _remainder) % 10];
_nums set [_index % 9, ((_nums select (_index % 9)) + _inputChar + _remainder) % 10];
_remainder = (_inputChar + _remainder) % 256;
};
([_nums select [0,3],_nums select [3,2], _nums select [5,4]] apply { _x joinString "" }) joinString "-"
([_nums select [0, 3], _nums select [3, 2], _nums select [5, 4]] apply { _x joinString "" }) joinString "-"

View File

@ -1,8 +1,8 @@
#include "..\script_component.hpp"
/*
* Author: SzwedzikPL
* If dogtag is not already taken triggers event on server.
* If dogtag already taken displays info about it.
* If the dog tag hasn't already been taken, it triggers an event on the server.
* If the dog tag has already been taken, it displays info about it.
*
* Arguments:
* 0: Player <OBJECT>
@ -12,17 +12,17 @@
* None
*
* Example:
* [player, unit] call ace_dogtags_fnc_takeDogtag
* [player, cursorObject] call ace_dogtags_fnc_takeDogtag
*
* Public: No
*/
params ["_player", "_target"];
// animation
// Animation
_player call EFUNC(common,goKneeling);
// sound
// Sound
private _position = _target modelToWorldWorld (_target selectionPosition "neck");
playSound3D [
@ -35,12 +35,11 @@ playSound3D [
50
];
// display message
// Display message
if ((_target getVariable [QGVAR(dogtagTaken), objNull]) == _target) then {
[{
[_this, 2.5] call EFUNC(common,displayTextStructured);
}, localize LSTRING(dogtagAlreadyTaken), DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute;
[EFUNC(common,displayTextStructured), [LLSTRING(dogtagAlreadyTaken), 2.5], DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute;
} else {
_target setVariable [QGVAR(dogtagTaken), _target, true];
[QGVAR(getDogtagItem), [_player, _target]] call CBA_fnc_serverEvent;
};

View File

@ -20,8 +20,9 @@ params ["_unit", "_target"];
TRACE_2("params",_unit,_target);
// If in ViV cargo, unload it first
if (!isNull isVehicleCargo _target) then {
objNull setVehicleCargo _target;
// Warn user if it failed to unload (shouldn't happen)
if (!isNull isVehicleCargo _target && {!(objNull setVehicleCargo _target)}) then {
WARNING_1("ViV Unload Failed %1",_target);
};
// Get attachTo offset and direction
@ -65,10 +66,10 @@ private _UAVCrew = _target call EFUNC(common,getVehicleUAVCrew);
if (_UAVCrew isNotEqualTo []) then {
{
_target deleteVehicleCrew _x;
[_x, true] call EFUNC(common,disableAiUAV);
} forEach _UAVCrew;
_target setVariable [QGVAR(isUAV), true, true];
_target setVariable [QGVAR(isUAV), _UAVCrew, true];
};
// Check everything

View File

@ -73,8 +73,8 @@ if (_unit getHitPointDamage "HitLegs" >= 0.5) exitWith {
_idPFH call CBA_fnc_removePerFrameHandler;
};
// Drop static if crew is in it (UAV crew deletion may take a few frames)
if (_target isKindOf "StaticWeapon" && {!(_target getVariable [QGVAR(isUAV), false])} && {(crew _target) isNotEqualTo []}) exitWith {
// Drop static if either non-UAV crew or new UAV crew is in it (ignore saved UAV crew)
if (_target isKindOf "StaticWeapon" && {((crew _target) - (_target getVariable [QGVAR(isUAV), []])) isNotEqualTo []}) exitWith {
TRACE_2("static weapon crewed",_unit,_target);
[_unit, _target] call FUNC(dropObject_carry);

View File

@ -20,8 +20,9 @@ params ["_unit", "_target"];
TRACE_2("params",_unit,_target);
// If in ViV cargo, unload it first
if (!isNull isVehicleCargo _target) then {
objNull setVehicleCargo _target;
// Warn user if it failed to unload (shouldn't happen)
if (!isNull isVehicleCargo _target && {!(objNull setVehicleCargo _target)}) then {
WARNING_1("ViV Unload Failed %1",_target);
};
// Get attachTo offset and direction.
@ -78,10 +79,10 @@ private _UAVCrew = _target call EFUNC(common,getVehicleUAVCrew);
if (_UAVCrew isNotEqualTo []) then {
{
_target deleteVehicleCrew _x;
[_x, true] call EFUNC(common,disableAiUAV);
} forEach _UAVCrew;
_target setVariable [QGVAR(isUAV), true, true];
_target setVariable [QGVAR(isUAV), _UAVCrew, true];
};
// Check everything

View File

@ -51,8 +51,8 @@ if (_unit distance _target > 10 && {(CBA_missionTime - _startTime) >= 1}) exitWi
_idPFH call CBA_fnc_removePerFrameHandler;
};
// Drop static if crew is in it (UAV crew deletion may take a few frames)
if (_target isKindOf "StaticWeapon" && {!(_target getVariable [QGVAR(isUAV), false])} && {(crew _target) isNotEqualTo []}) exitWith {
// Drop static if either non-UAV crew or new UAV crew is in it (ignore saved UAV crew)
if (_target isKindOf "StaticWeapon" && {((crew _target) - (_target getVariable [QGVAR(isUAV), []])) isNotEqualTo []}) exitWith {
TRACE_2("static weapon crewed",_unit,_target);
[_unit, _target] call FUNC(dropObject);

View File

@ -80,16 +80,16 @@ if (_unit getVariable ["ACE_isUnconscious", false]) then {
[_unit, "unconscious", 2] call EFUNC(common,doAnimation);
};
// Recreate UAV crew (add a frame delay or this may cause the vehicle to be moved to [0,0,0])
if (_target getVariable [QGVAR(isUAV), false]) then {
_target setVariable [QGVAR(isUAV), nil, true];
// Reenable UAV crew
private _UAVCrew = _target getVariable [QGVAR(isUAV), []];
[{
params ["_target"];
if (!alive _target) exitWith {};
TRACE_2("restoring uav crew",_target,getPosASL _target);
createVehicleCrew _target;
}, [_target]] call CBA_fnc_execNextFrame;
if (_UAVCrew isNotEqualTo []) then {
// Reenable AI
{
[_x, false] call EFUNC(common,disableAiUAV);
} forEach _UAVCrew;
_target setVariable [QGVAR(isUAV), nil, true];
};
// Fixes not being able to move when in combat pace

View File

@ -59,11 +59,12 @@ if (_target isKindOf "CAManBase" || {animationState _unit in CARRY_ANIMATIONS})
_unit removeWeapon "ACE_FakePrimaryWeapon";
// Reselect weapon and re-enable sprint
private _previousWeaponIndex = _unit getVariable [QGVAR(previousWeapon), -1];
_unit setVariable [QGVAR(previousWeapon), nil, true];
private _previousWeaponState = _unit getVariable QGVAR(previousWeapon);
if (_previousWeaponIndex != -1) then {
_unit action ["SwitchWeapon", _unit, _unit, _previousWeaponIndex];
if (!isNil "_previousWeaponState") then {
_unit selectWeapon _previousWeaponState;
_unit setVariable [QGVAR(previousWeapon), nil, true];
};
[_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set);
@ -86,16 +87,16 @@ if !(_target isKindOf "CAManBase") then {
[QEGVAR(common,fixFloating), _target, _target] call CBA_fnc_targetEvent;
};
// Recreate UAV crew (add a frame delay or this may cause the vehicle to be moved to [0,0,0])
if (_target getVariable [QGVAR(isUAV), false]) then {
_target setVariable [QGVAR(isUAV), nil, true];
// Reenable UAV crew
private _UAVCrew = _target getVariable [QGVAR(isUAV), []];
[{
params ["_target"];
if (!alive _target) exitWith {};
TRACE_2("restoring uav crew",_target,getPosASL _target);
createVehicleCrew _target;
}, [_target]] call CBA_fnc_execNextFrame;
if (_UAVCrew isNotEqualTo []) then {
// Reenable AI
{
[_x, false] call EFUNC(common,disableAiUAV);
} forEach _UAVCrew;
_target setVariable [QGVAR(isUAV), nil, true];
};
// Reset mass

View File

@ -11,7 +11,7 @@
* Weight <NUMBER>
*
* Example:
* [cursorTarget] call ace_dragging_fnc_getWeight
* cursorTarget call ace_dragging_fnc_getWeight
*
* Public: No
*/
@ -23,19 +23,20 @@ if (GVAR(weightCoefficient) == 0) exitWith {0};
private _weight = loadAbs _object;
if !(GVAR(skipContainerWeight)) then {
if (!GVAR(skipContainerWeight)) then {
// Add the mass of the object itself
// getMass handles PhysX mass, this should be 0 for SupplyX containers and WeaponHolders
// Use originalMass in case we're checking weight for a carried object
_weight = _weight + ((_object getVariable [QGVAR(originalMass), getMass _object]));
_weight = _weight + (_object getVariable [QGVAR(originalMass), getMass _object]);
};
// Contents of backpacks get counted twice (https://github.com/acemod/ACE3/pull/8457#issuecomment-1062522447 and https://feedback.bistudio.com/T167469)
// This is a workaround until that is fixed on BI's end
{
// Fixed in https://feedback.bistudio.com/T167469 on 2.16 profiling branch and for 2.18 stable
if ((productVersion select 3) < 152017) then {
{
_x params ["", "_container"];
_weight = _weight - (loadAbs _container);
} forEach (everyContainer _object);
} forEach (everyContainer _object);
};
// Mass in Arma isn't an exact amount but rather a volume/weight value
// This attempts to work around that by making it a usable value (sort of)

View File

@ -50,7 +50,7 @@ if (_target isKindOf "CAManBase") then {
};
// Select primary, otherwise the carry animation actions don't work
_unit selectWeapon _primaryWeapon;
_unit selectWeapon _primaryWeapon; // This turns off lasers/lights
// Move a bit closer and adjust direction when trying to pick up a person
[QEGVAR(common,setDir), [_target, getDir _unit + 180], _target] call CBA_fnc_targetEvent;
@ -62,10 +62,11 @@ if (_target isKindOf "CAManBase") then {
_timer = CBA_missionTime + 10;
} else {
// Select no weapon and stop sprinting
private _previousWeaponIndex = [_unit] call EFUNC(common,getFiremodeIndex);
_unit setVariable [QGVAR(previousWeapon), _previousWeaponIndex, true];
if (currentWeapon _unit != "") then {
_unit setVariable [QGVAR(previousWeapon), (weaponState _unit) select [0, 3], true];
_unit action ["SwitchWeapon", _unit, _unit, 299];
};
[_unit, "AmovPercMstpSnonWnonDnon", 0] call EFUNC(common,doAnimation);

View File

@ -46,7 +46,10 @@ if (!GVAR(dragAndFire)) then {
_primaryWeapon = "ACE_FakePrimaryWeapon";
};
// Keep the laser/light on if the weapon is already selected
if (currentWeapon _unit != _primaryWeapon) then {
_unit selectWeapon _primaryWeapon;
};
} else { // Making sure the unit is holding a primary weapon or handgun
private _handgunWeapon = handgunWeapon _unit;

View File

@ -1,24 +1,24 @@
#include "script_component.hpp"
[QGVAR(burn), LINKFUNC(burn)] call CBA_fnc_addEventHandler;
[QGVAR(burnEffects), LINKFUNC(burnEffects)] call CBA_fnc_addEventHandler;
[QGVAR(burnSimulation), LINKFUNC(burnSimulation)] call CBA_fnc_addEventHandler;
["CBA_settingsInitialized", {
TRACE_1("settingsInitialized",GVAR(enabled));
[QGVAR(playScream), {
if (!GVAR(enabled)) exitWith {};
[QGVAR(burn), LINKFUNC(burn)] call CBA_fnc_addEventHandler;
[QGVAR(burnEffects), LINKFUNC(burnEffects)] call CBA_fnc_addEventHandler;
[QGVAR(burnSimulation), LINKFUNC(burnSimulation)] call CBA_fnc_addEventHandler;
[QGVAR(playScream), {
params ["_scream", "_source"];
// Only play sound if enabled in settings and enabled for the unit
if (GVAR(enableScreams) && {_source getVariable [QGVAR(enableScreams), true]}) then {
_source say3D _scream;
};
}] call CBA_fnc_addEventHandler;
}] call CBA_fnc_addEventHandler;
if (!isServer) exitWith {};
["CBA_settingsInitialized", {
TRACE_1("settingsInit",GVAR(enabled));
if (!GVAR(enabled)) exitWith {};
if (!isServer) exitWith {};
GVAR(fireSources) = createHashMap;

View File

@ -0,0 +1,20 @@
#include "script_component.hpp"
class CfgPatches {
class SUBADDON {
name = COMPONENT_NAME;
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"ace_medical_engine"};
skipWhenMissingDependencies = 1;
author = ECSTRING(common,ACETeam);
authors[] = {};
url = ECSTRING(main,URL);
VERSION_CONFIG;
addonRootClass = QUOTE(ADDON);
};
};
#include "ACE_Medical_Treatment_Actions.hpp"

View File

@ -0,0 +1,3 @@
#define SUBCOMPONENT medical_engine
#define SUBCOMPONENT_BEAUTIFIED Medical Engine
#include "..\script_component.hpp"

View File

@ -1,20 +1,12 @@
#include "script_component.hpp"
#pragma hemtt flag pe23_ignore_has_include
#if __has_include("\z\ace\addons\nomedical\script_component.hpp")
#define PATCH_SKIP "No Medical"
#endif
#ifdef PATCH_SKIP
ACE_PATCH_NOT_LOADED(ADDON,PATCH_SKIP)
#else
class CfgPatches {
class ADDON {
name = COMPONENT_NAME;
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"ace_common", "ace_medical_engine"};
requiredAddons[] = {"ace_common"};
author = ECSTRING(common,ACETeam);
authors[] = {"commy2", "tcvm"};
url = ECSTRING(main,URL);
@ -25,7 +17,4 @@ class CfgPatches {
#include "CfgEventHandlers.hpp"
#include "CfgSounds.hpp"
#include "CfgVehicles.hpp"
#include "ACE_Medical_Treatment_Actions.hpp"
#include "RscTitles.hpp"
#endif

View File

@ -148,6 +148,10 @@ params ["_unit", "_instigator"];
_unit call FUNC(burnReaction);
};
// Keep pain around unconsciousness limit to allow for more fun interactions
private _damageToAdd = [0.15, _intensity / BURN_MAX_INTENSITY] select (!alive _unit || {GET_PAIN_PERCEIVED(_unit) < (PAIN_UNCONSCIOUS + random 0.2)});
if (GETEGVAR(medical,enabled,false)) then {
if (!isNull _instigator) then {
_unit setVariable [QEGVAR(medical,lastDamageSource), _instigator];
_unit setVariable [QEGVAR(medical,lastInstigator), _instigator];
@ -156,11 +160,15 @@ params ["_unit", "_instigator"];
// Common burn areas are the hands and face https://www.ncbi.nlm.nih.gov/pubmed/16899341/
private _bodyPart = ["Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg"] selectRandomWeighted [0.77, 0.5, 0.8, 0.8, 0.3, 0.3];
// Keep pain around unconciousness limit to allow for more fun interactions
private _damageToAdd = [0.15, _intensity / BURN_MAX_INTENSITY] select (!alive _unit || {GET_PAIN_PERCEIVED(_unit) < (PAIN_UNCONSCIOUS + random 0.2)});
// Use event directly, as ace_medical_fnc_addDamageToUnit requires unit to be alive
[QEGVAR(medical,woundReceived), [_unit, [[_damageToAdd, _bodyPart, _damageToAdd]], _instigator, "burn"]] call CBA_fnc_localEvent;
} else {
private _bodyParts = [["HitFace", "HitNeck", "HitHead"], ["HitPelvis", "HitAbdomen", "HitDiaphragm", "HitChest", "HitBody"], ["HitArms", "HitHands"], ["HitLegs"]] selectRandomWeighted [0.77, 0.5, 0.8, 0.3];
{
_unit setHitPointDamage [_x, (_unit getHitPointDamage _x) + _damageToAdd, true, _instigator, _instigator];
} forEach _bodyParts;
};
_unit setVariable [QGVAR(intensity), _intensity, true]; // Globally sync intensity across all clients to make sure simulation is deterministic
};

View File

@ -5,7 +5,7 @@
LSTRING(Category_DisplayName),
true,
1,
{[QGVAR(fireEnabled), _this] call EFUNC(common,cbaSettings_settingChanged)},
{[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)},
true // Needs mission restart
] call CBA_fnc_addSetting;

View File

@ -16,7 +16,14 @@
#endif
#include "\z\ace\addons\main\script_macros.hpp"
#pragma hemtt flag pe23_ignore_has_include
#if __has_include("\z\ace\addons\medical_engine\script_macros_medical.hpp")
#include "\z\ace\addons\medical_engine\script_macros_medical.hpp"
#else
#define GET_PAIN_PERCEIVED(var) 0
#define PAIN_UNCONSCIOUS 1
#endif
#define FIRE_MANAGER_PFH_DELAY 0.25
#define FLARE_SIZE_MODIFIER 5

View File

@ -10,7 +10,7 @@
* Can Push <BOOL>
*
* Example:
* [target] call ace_interaction_fnc_canPush
* cursorObject call ace_interaction_fnc_canPush
*
* Public: No
*/
@ -19,4 +19,5 @@ params ["_target"];
alive _target &&
{getMass _target <= 2600 || getNumber (configOf _target >> QGVAR(canPush)) == 1} &&
{vectorMagnitude velocity _target < 3}
{vectorMagnitude velocity _target < 3} &&
{isNull isVehicleCargo _target} // Check if vehicle is loaded as ViV cargo

View File

@ -11,7 +11,6 @@
*
* Public: No
*/
if (missionNamespace getVariable [QGVAR(disableSeatLocking), false]) exitWith {};
params ["_unit"];
private _vehicle = objectParent _unit;
@ -20,6 +19,13 @@ TRACE_3("lockUnconsciousSeat",_unit,_vehicle,lifeState _unit);
if (isNull _vehicle) exitWith {};
if (alive _unit && {lifeState _unit != "INCAPACITATED"}) exitWith {};
private _disable = missionNamespace getVariable [QGVAR(disableSeatLocking), false];
if (_disable isEqualTo true || {
_disable isEqualType [] && {
(_disable findIf {_vehicle isKindOf _x}) != -1
}
}) exitWith {};
switch (true) do {
case (_unit isEqualTo (driver _vehicle)): {
_vehicle lockDriver true;

View File

@ -11,7 +11,7 @@
* None
*
* Example:
* [bob, mortar] call ace_mk6mortar_fnc_handlePlayerVehicleChanged;
* [player, cursorObject] call ace_mk6mortar_fnc_handlePlayerVehicleChanged
*
* Public: No
*/
@ -24,48 +24,44 @@ if !(_newVehicle isKindOf "Mortar_01_base_F") exitWith {};
private _tubeWeaponName = (weapons _newVehicle) select 0;
private _fireModes = getArray (configFile >> "CfgWeapons" >> _tubeWeaponName >> "modes");
//Restore last firemode:
private _lastFireMode = _newVehicle getVariable [QGVAR(lastFireMode), -1];
if (_lastFireMode != -1) then {
_player action ["SwitchWeapon", _newVehicle, _player, _lastFireMode];
// Restore last firemode
private _lastSavedWeaponsInfo = _newVehicle getVariable QGVAR(lastFireMode);
if (!isNil "_lastSavedWeaponsInfo") then {
_newVehicle selectWeaponTurret [_lastSavedWeaponsInfo select 0, [0], _lastSavedWeaponsInfo select 1, _lastSavedWeaponsInfo select 2];
};
[{
params ["_args", "_pfID"];
_args params ["_mortarVeh", "_fireModes"];
params ["_mortarVeh", "_pfhID"];
if ((vehicle ACE_player) != _mortarVeh) then {
[_pfID] call CBA_fnc_removePerFrameHandler;
} else {
if ((vehicle ACE_player) != _mortarVeh) exitWith {
_pfhID call CBA_fnc_removePerFrameHandler;
};
private _useMils = _mortarVeh getVariable [QGVAR(useMils), true];
//Compute: 'charge' from weaponstate
private _currentFireMode = (weaponState [_mortarVeh, [0]]) select 2;
private _currentChargeMode = _fireModes find _currentFireMode;
//Save firemode on vehicle:
_mortarVeh setVariable [QGVAR(lastFireMode), _currentChargeMode];
// Save firemode ('charge' from weaponstate) on vehicle
_mortarVeh setVariable [QGVAR(lastFireMode), (weaponState [_mortarVeh, [0]]) select [0, 3]];
if (shownArtilleryComputer && {!GVAR(allowComputerRangefinder)}) then {
//Don't like this solution, but it works
// Don't like this solution, but it works
closeDialog 0;
[parseText "Computer Disabled"] call EFUNC(common,displayTextStructured);
};
private _display = uiNamespace getVariable ["ACE_Mk6_RscWeaponRangeArtillery", displayNull];
if (isNull _display) exitWith {}; //It may be null for the first frame
//Hud should hidden in 3rd person
if (isNull _display) exitWith {}; // It may be null for the first frame
// Hud should hidden in 3rd person
private _notGunnerView = cameraView != "GUNNER";
private _useMils = _mortarVeh getVariable [QGVAR(useMils), true];
// Get aiming values from ace_artillerytables
// Note: it also handles displaying the "charge" level
private _realAzimuth = missionNamespace getVariable [QEGVAR(artillerytables,predictedAzimuth), -1];
private _realElevation = missionNamespace getVariable [QEGVAR(artillerytables,predictedElevation), -1];
//Update Heading Display:
if (_notGunnerView || (!GVAR(allowCompass))) then {
// Update Heading Display
if (_notGunnerView || !GVAR(allowCompass)) then {
(_display displayCtrl 80156) ctrlSetText "";
} else {
if (_useMils) then {
@ -75,7 +71,7 @@ if (_lastFireMode != -1) then {
};
};
//Update CurrentElevation Display
// Update CurrentElevation Display
if (_notGunnerView) then {
(_display displayCtrl 80175) ctrlSetText "";
} else {
@ -86,12 +82,12 @@ if (_lastFireMode != -1) then {
};
};
//Update ElevationNeeded Display:
if (_notGunnerView || (!GVAR(allowComputerRangefinder))) then {
// Update ElevationNeeded Display
if (_notGunnerView || !GVAR(allowComputerRangefinder)) then {
(_display displayCtrl 80176) ctrlSetText "";
} else {
private _elevDeg = parseNumber ctrlText (_display displayCtrl 176);
if (_elevDeg <= 0) then { //Bad data means "----" out of range
if (_elevDeg <= 0) then { // Bad data means "----" out of range
(_display displayCtrl 80176) ctrlSetText (ctrlText (_display displayCtrl 176));
} else {
_elevDeg = _elevDeg + (_realElevation - (parseNumber ctrlText (_display displayCtrl 175)));
@ -102,5 +98,4 @@ if (_lastFireMode != -1) then {
};
};
};
};
}, 0, [_newVehicle, _fireModes]] call CBA_fnc_addPerFrameHandler;
}, 0, _newVehicle] call CBA_fnc_addPerFrameHandler;

View File

@ -2,9 +2,8 @@
if (!hasInterface) exitWith {};
["ACE3 Movement", QGVAR(mount), [localize LSTRING(KeybindName), localize LSTRING(KeybindDescription)], "", {
["ACE3 Movement", QGVAR(mount), [LLSTRING(KeybindName), LLSTRING(KeybindDescription)], "", {
if (!dialog) then {
[] call FUNC(getInNearest);
call FUNC(getInNearest);
};
false
}] call CBA_fnc_addKeybind;

View File

@ -1,131 +1,125 @@
#include "..\script_component.hpp"
/*
* Author: Kingsley
* Mount the player in the vehicle they are directly looking at based on their distance.
* Mounts the player in the vehicle they are directly looking at based on their distance.
*
* Arguments:
* 0: Target <OBJECT>(Optional)
* 0: Target <OBJECT> (default: objNull)
*
* Return Value:
* None
*
* Example:
* [] call ace_quickmount_fnc_getInNearest;
* call ace_quickmount_fnc_getInNearest
*
* Public: No
*/
if (!GVAR(enabled) ||
if (
!GVAR(enabled) ||
{isNull ACE_player} ||
{vehicle ACE_player != ACE_player} ||
{!alive ACE_player} ||
{ACE_player getVariable ["ace_unconscious", false]}
{!isNull objectParent ACE_player} ||
{!(ACE_player call EFUNC(common,isAwake))}
) exitWith {};
params [["_interactionTarget", objNull, [objNull]]];
TRACE_1("getInNearest",_interactionTarget);
params [["_target", objNull, [objNull]]];
TRACE_1("getInNearest",_target);
private _start = ACE_player modelToWorldVisualWorld (ACE_player selectionPosition "pilot");
private _end = (_start vectorAdd (getCameraViewDirection ACE_player vectorMultiply GVAR(distance)));
private _objects = lineIntersectsSurfaces [_start, _end, ACE_player];
private _target = (_objects param [0, []]) param [2, objNull];
if ((isNull _target) && {alive _interactionTarget}) then {
_end = _start vectorAdd ((_start vectorFromTo (aimPos _interactionTarget)) vectorMultiply GVAR(distance));
_objects = lineIntersectsSurfaces [_start, _end, ACE_player];
TRACE_1("2nd ray attempt at interaction target aim pos",_objects);
// If target is not defined (e.g. keybind was used), search for valid target
if (isNull _target) then {
private _start = ACE_player modelToWorldVisualWorld (ACE_player selectionPosition "pilot");
private _end = (_start vectorAdd (getCameraViewDirection ACE_player vectorMultiply GVAR(distance)));
private _objects = lineIntersectsSurfaces [_start, _end, ACE_player];
_target = (_objects param [0, []]) param [2, objNull];
};
if (locked _target in [2,3] || {!simulationEnabled _target}) exitWith {
[localize LSTRING(VehicleLocked)] call EFUNC(common,displayTextStructured);
true
if (!alive _target) exitWith {};
if (locked _target >= 2 || {!simulationEnabled _target}) exitWith {
[LLSTRING(VehicleLocked)] call EFUNC(common,displayTextStructured);
};
TRACE_2("",_target,typeOf _target);
if (!isNull _target &&
{alive _target} &&
{{_target isKindOf _x} count ["Air","LandVehicle","Ship","StaticMortar"] > 0} &&
{([ACE_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith))} &&
{speed _target <= GVAR(speed)}
) then {
if (
(speed _target > GVAR(speed)) ||
{["Air", "LandVehicle", "Ship", "StaticMortar"] findIf {_target isKindOf _x} == -1} ||
{!([ACE_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith))}
) exitWith {};
private _seats = ["driver", "gunner", "commander", "cargo"];
private _sortedSeats = [_seats select GVAR(priority)];
_seats deleteAt GVAR(priority);
_sortedSeats append _seats;
if (GVAR(priority) > 3 || GVAR(priority) < 0) then {
GVAR(priority) = 0;
};
private _fullCrew = fullCrew [_target, "", true];
private _seats = ["Driver", "Gunner", "Commander", "Cargo"];
private _sortedSeats = [_seats select GVAR(priority)];
_seats deleteAt GVAR(priority);
_sortedSeats append _seats;
private _hasAction = false;
scopeName "SearchForSeat";
private _hasAction = false;
scopeName "SearchForSeat";
{
{
private _desiredRole = _x;
{
_x params ["_unit", "_role", "_cargoIndex", "_turretPath"];
if ((isNull _unit) || {!alive _unit}) then {
private _effectiveRole = toLowerANSI _role;
if (!alive _unit) then {
private _effectiveRole = _role;
if ((_effectiveRole in ["driver", "gunner"]) && {unitIsUAV _target}) exitWith {}; // Ignoring UAV Driver/Gunner
if ((_effectiveRole == "driver") && {(getNumber (configOf _target >> "hasDriver")) == 0}) exitWith {}; // Ignoring Non Driver (static weapons)
// Seats can be locked independently of the main vehicle
if ((_role == "driver") && {lockedDriver _target}) exitWith {TRACE_1("lockedDriver",_x);};
if ((_effectiveRole == "driver") && {lockedDriver _target}) exitWith {TRACE_1("lockedDriver",_x);};
if ((_cargoIndex >= 0) && {_target lockedCargo _cargoIndex}) exitWith {TRACE_1("lockedCargo",_x);};
if ((_turretPath isNotEqualTo []) && {_target lockedTurret _turretPath}) exitWith {TRACE_1("lockedTurret",_x);};
if (_effectiveRole == "turret") then {
private _turretConfig = [_target, _turretPath] call CBA_fnc_getTurret;
if (getNumber (_turretConfig >> "isCopilot") == 1) exitWith {
_effectiveRole = "driver";
};
if (
_cargoIndex >= 0 // FFV
|| {"" isEqualTo getText (_turretConfig >> "gun")} // turret without weapon
_cargoIndex >= 0 || // FFV
{getText (_turretConfig >> "gun") == ""} // Turret without weapon
) exitWith {
_effectiveRole = "cargo";
};
_effectiveRole = "gunner"; // door gunners / 2nd turret
_effectiveRole = "gunner"; // Door gunners / 2nd turret
};
TRACE_2("",_effectiveRole,_x);
if (_effectiveRole != _desiredRole) exitWith {};
if (_turretPath isNotEqualTo []) then {
// Using GetInTurret seems to solve problems with incorrect GetInEH params when gunner/commander
ACE_player action ["GetInTurret", _target, _turretPath];
TRACE_3("Geting In Turret",_x,_role,_turretPath);
TRACE_3("Getting In Turret",_x,_role,_turretPath);
} else {
if (_cargoIndex > -1) then {
// GetInCargo expects the index of the seat in the "cargo" array from fullCrew
// See description: https://community.bistudio.com/wiki/fullCrew
private _cargoActionIndex = -1;
{
if ((_x select 2) == _cargoIndex) exitWith {_cargoActionIndex = _forEachIndex};
} forEach (fullCrew [_target, "cargo", true]);
private _cargoActionIndex = (fullCrew [_target, "cargo", true]) findIf {(_x select 2) == _cargoIndex};
ACE_player action ["GetInCargo", _target, _cargoActionIndex];
TRACE_4("Geting In Cargo",_x,_role,_cargoActionIndex,_cargoIndex);
TRACE_4("Getting In Cargo",_x,_role,_cargoActionIndex,_cargoIndex);
} else {
ACE_player action ["GetIn" + _role, _target];
TRACE_2("Geting In",_x,_role);
TRACE_2("Getting In",_x,_role);
};
};
_hasAction = true;
breakTo "SearchForSeat";
};
} forEach (fullCrew [_target, "", true]);
} forEach _sortedSeats;
} forEach _fullCrew;
} forEach _sortedSeats;
if (!_hasAction) then {
if (!_hasAction) then {
TRACE_1("no empty seats",_hasAction);
[localize LSTRING(VehicleFull)] call EFUNC(common,displayTextStructured);
};
[LLSTRING(VehicleFull)] call EFUNC(common,displayTextStructured);
};
true

View File

@ -28,7 +28,9 @@
#define REARM_HOLSTER_WEAPON \
_unit setVariable [QGVAR(selectedWeaponOnRearm), currentWeapon _unit]; \
if (currentWeapon _unit != "") then { \
_unit setVariable [QGVAR(selectedWeaponOnRearm), (weaponState _unit) select [0, 3]]; \
}; \
TRACE_2("REARM_HOLSTER_WEAPON",_unit,currentWeapon _unit); \
_unit action ["SwitchWeapon", _unit, _unit, 299];

View File

@ -149,10 +149,15 @@ if (_callbackProgress == "") then {
// Player Animation
private _callerAnim = [getText (_config >> "animationCaller"), getText (_config >> "animationCallerProne")] select (stance _caller == "PRONE");
private _loopAnim = (getNumber (_config >> "loopAnimation")) isEqualTo 1;
_caller setVariable [QGVAR(selectedWeaponOnrepair), currentWeapon _caller];
private _currentWeapon = currentWeapon _caller;
if (_currentWeapon != "") then {
_caller setVariable [QGVAR(selectedWeaponOnrepair), (weaponState _caller) select [0, 3]];
};
// Cannot use secondairy weapon for animation
if (currentWeapon _caller == secondaryWeapon _caller) then {
if (_currentWeapon == secondaryWeapon _caller) then {
_caller selectWeapon (primaryWeapon _caller);
};

View File

@ -38,9 +38,11 @@ if (vehicle _caller == _caller && {!(_caller call EFUNC(common,isSwimming))}) th
_caller setVariable [QGVAR(repairCurrentAnimCaller), nil];
_caller setVariable [QGVAR(repairPrevAnimCaller), nil];
private _weaponSelect = (_caller getVariable [QGVAR(selectedWeaponOnrepair), ""]);
if (_weaponSelect != "") then {
private _weaponSelect = _caller getVariable QGVAR(selectedWeaponOnrepair);
if (!isNil "_weaponSelect") then {
_caller selectWeapon _weaponSelect;
_caller setVariable [QGVAR(selectedWeaponOnrepair), nil];
} else {
_caller action ["SwitchWeapon", _caller, _caller, 299];
};

View File

@ -38,9 +38,11 @@ if (vehicle _caller == _caller && {!(_caller call EFUNC(common,isSwimming))}) th
_caller setVariable [QGVAR(repairCurrentAnimCaller), nil];
_caller setVariable [QGVAR(repairPrevAnimCaller), nil];
private _weaponSelect = (_caller getVariable [QGVAR(selectedWeaponOnrepair), ""]);
if (_weaponSelect != "") then {
private _weaponSelect = _caller getVariable QGVAR(selectedWeaponOnrepair);
if (!isNil "_weaponSelect") then {
_caller selectWeapon _weaponSelect;
_caller setVariable [QGVAR(selectedWeaponOnrepair), nil];
} else {
_caller action ["SwitchWeapon", _caller, _caller, 299];
};

View File

@ -21,7 +21,7 @@ params ["_unit"];
// Saves the gear when the player! (and only him) is killed
if (ACE_player == _unit && {GVAR(SavePreDeathGear)}) then {
_unit setVariable [QGVAR(unitGear), [_unit] call CBA_fnc_getLoadout];
_unit setVariable [QGVAR(activeWeaponAndMuzzle), [currentWeapon _unit, currentMuzzle _unit, currentWeaponMode _unit]];
_unit setVariable [QGVAR(activeWeaponAndMuzzle), (weaponState _unit) select [0, 3]];
[QGVAR(saveGear), _unit] call CBA_fnc_localEvent;
};

View File

@ -5,7 +5,8 @@
*
* Arguments:
* 0: Unit <OBJECT>
* 1: All Gear based on return value of ACE_common_fnc_getAllGear <ARRAY>
* 1: All Gear based on return value of ace_common_fnc_getAllGear <ARRAY>
* 2: All weapon info needed for restoring previous weapon status <ARRAY>
*
* Return Value:
* None
@ -19,36 +20,12 @@
params ["_unit", "_allGear", "_activeWeaponAndMuzzle"];
TRACE_3("restoreGear",_unit,count _allGear,_activeWeaponAndMuzzle);
// restore all gear
// Restore all gear
if (!isNil "_allGear") then {
[_unit, _allGear] call CBA_fnc_setLoadout;
};
// restore the last active weapon, muzzle and weaponMode
// Restore the last active weapon, muzzle and weapon mode
if (!isNil "_activeWeaponAndMuzzle") then {
// @todo, replace this with CBA_fnc_selectWeapon after next CBA update
_activeWeaponAndMuzzle params ["_activeWeapon", "_activeMuzzle", "_activeWeaponMode"];
if (
(_activeMuzzle != "") &&
{_activeMuzzle != _activeWeapon} &&
{_activeMuzzle in getArray (configFile >> "CfgWeapons" >> _activeWeapon >> "muzzles")}
) then {
_unit selectWeapon _activeMuzzle;
} else {
if (_activeWeapon != "") then {
_unit selectWeapon _activeWeapon;
};
};
if (currentWeapon _unit != "") then {
private _index = 0;
while {
_index < 299 && {currentWeaponMode _unit != _activeWeaponMode}
} do {
_unit action ["SwitchWeapon", _unit, _unit, _index];
_index = _index + 1;
};
};
_unit selectWeapon _activeWeaponAndMuzzle;
};

View File

@ -4,7 +4,7 @@
* Gets a random animations from the list.
*
* Arguments:
* None
* 0: Object to get animation pool from <OBJECT> (default: objNull)
*
* Return Value:
* Random Animation <STRING>
@ -15,8 +15,16 @@
* Public: No
*/
// Select random animation from Animations Pool
selectRandom [
params [["_object", objNull, [objNull]]];
private _animations = [];
if (!isNull _object) then {
_animations = getArray (configOf _object >> QGVAR(animations));
};
if (_animations isEqualTo []) then {
_animations = [
QGVAR(HubSittingChairA_idle1),
QGVAR(HubSittingChairA_idle2),
QGVAR(HubSittingChairA_idle3),
@ -41,4 +49,8 @@ selectRandom [
QGVAR(HubSittingChairUC_idle2),
QGVAR(HubSittingChairUC_idle3),
QGVAR(HubSittingChairUC_move1)
]
];
};
// Select random animation from Animations Pool
selectRandom _animations

View File

@ -48,7 +48,7 @@ if (_multiSitting) then {
};
// Get random animation and perform it (before moving player to ensure correct placement)
[_player, call FUNC(getRandomAnimation), 2] call EFUNC(common,doAnimation); // Correctly places when using non-transitional animations
[_player, [_seat] call FUNC(getRandomAnimation), 2] call EFUNC(common,doAnimation); // Correctly places when using non-transitional animations
[_player, "", 1] call EFUNC(common,doAnimation); // Correctly applies animation's config values (such as disallow throwing of grenades, intercept keybinds... etc).
TRACE_2("Sit pos and dir",_sitPosition,_sitDirection);

View File

@ -35,3 +35,5 @@ if !(toLowerANSI (_filename select [count _filename - 4]) in [".wav", ".ogg", ".
};
playSound3D [_filename, objNull, false, _position, _volume, _soundPitch, _distance];
nil // return

View File

@ -18,35 +18,23 @@
params ["_unit", "_weapon"];
if (_weapon == "") exitWith {};
if (_weapon == "" || {!(_unit hasWeapon _weapon)}) exitWith {};
private _currentWeaponMode = (_unit weaponState _weapon) select 2;
private _muzzle = (_weapon call EFUNC(common,getWeaponMuzzles)) select 0;
if (currentWeapon _unit != _weapon) exitWith {
_unit selectWeapon _weapon;
_unit selectWeapon [_weapon, _muzzle, _currentWeaponMode];
};
// unlock safety
// Unlock safety
if (_weapon in (_unit getVariable [QEGVAR(safemode,safedWeapons), []])) exitWith {
[_unit, _weapon, _weapon] call EFUNC(safemode,unlockSafety);
};
private _muzzles = [_weapon] call EFUNC(common,getWeaponMuzzles);
private _modes = [_weapon] call EFUNC(common,getWeaponModes);
private _modes = _weapon call EFUNC(common,getWeaponModes);
private _index = (_modes find currentWeaponMode _unit) + 1;
_unit selectWeapon [_weapon, _muzzle, _modes select (((_modes find _currentWeaponMode) + 1) % (count _modes))];
if (_index > count _modes - 1) then {_index = 0};
private _muzzle = _muzzles select 0;
private _mode = _modes select _index;
_index = 0;
while {
_index < 299 && {currentMuzzle _unit != _muzzle || {currentWeaponMode _unit != _mode}}
} do {
_unit action ["SwitchWeapon", _unit, _unit, _index];
_index = _index + 1;
};
// play fire mode selector sound
// Play fire mode selector sound
[_unit, _weapon] call FUNC(playChangeFiremodeSound);

View File

@ -18,32 +18,22 @@
params ["_unit", "_weapon"];
if (_weapon == "") exitWith {};
if (_weapon == "" || {!(_unit hasWeapon _weapon)}) exitWith {};
private _muzzles = _weapon call EFUNC(common,getWeaponMuzzles);
if (currentWeapon _unit != _weapon) exitWith {
if (count _muzzles > 1) then {
if (count _muzzles <= 1) exitWith {};
// unlock safety
/*if (_weapon in (_unit getVariable [QEGVAR(safemode,safedWeapons), []])) exitWith {
[_unit, _weapon, _muzzles select 1] call EFUNC(safemode,unlockSafety);
};*/
private _muzzle = (_unit weaponState _weapon) select 1;
_unit selectWeapon (_muzzles select 1);
};
private _index = if (currentWeapon _unit == _weapon) then {
(((_muzzles find currentMuzzle _unit) + 1) % (count _muzzles)) max 1
} else {
1
};
private _index = (_muzzles find currentMuzzle _unit) + 1;
if (_index > count _muzzles - 1) then {_index = 1};
private _muzzle = _muzzles select _index;
_index = 0;
while {
_index < 299 && {currentMuzzle _unit != _muzzle}
} do {
_unit action ["SwitchWeapon", _unit, _unit, _index];
_index = _index + 1;
};
_unit selectWeapon [_weapon, _muzzle, ([_weapon, _muzzle] call EFUNC(common,getWeaponModes)) select 0];
nil // return

View File

@ -240,6 +240,7 @@ ACE_plasmaIV_250 | Plasma IV (250ml) | ACE_ItemCore |
ACE_salineIV | Saline IV (1000ml) | ACE_ItemCore |
ACE_salineIV_500 | Saline IV (500ml) | ACE_ItemCore |
ACE_salineIV_250 | Saline IV (250ml) | ACE_ItemCore |
ACE_suture | Suture | ACE_ItemCore |
ACE_surgicalKit | Surgical Kit | ACE_ItemCore |
ACE_tourniquet | Tourniquet (CAT) | ACE_ItemCore |
ACE_medicalSupplyCrate | Simple ACE Medical Supply Crate | ammo box |

View File

@ -241,3 +241,10 @@ The damage elements are sorted in descending order according to how much damage
Some of ACE Medical's underlying behavior, primarily related to damage handling and the vitals loop, can be fine-tuned by editing `ace_medical_const_` variables, found in [script_macros_medical.hpp](https://github.com/acemod/ACE3/blob/master/addons/medical_engine/script_macros_medical.hpp).
Modification of those values should be done by advanced users only. Values and variable names are subject to change without prior warning. Modifying values mid-mission may lead to undefined behavior. Expect minimal support.
### 5.1 Disable seat locking for unconscious
ACE will lock the seat of an unconscious or dead unit to prevent automatic unloading. This can be disabled by setting:
```sqf
ace_medical_engine_disableSeatLocking = true; // disable on everything
ace_medical_engine_disableSeatLocking = ["ship"]; // disable just on boats
```

View File

@ -29,6 +29,7 @@ class CfgVehicles {
acex_sitting_sitDirection = 180; // Direction relative to object
acex_sitting_sitPosition[] = {0, -0.1, -0.45}; // Position relative to object (may behave weird with certain objects)
acex_sitting_interactPosition[] = {0, -0.1, -0.45};
ace_sitting_animations[] = {"ace_sitting_HubSittingChairA_idle1"}; // Overwrite random animation pool
XEH_ENABLED; // Enable XEH (only necessary if XEH is not yet enabled for this class or the one this inherits from)
};
};