Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# Changelog for Armor Modifier - ACE 25.6.2025

1.0.6.0
- Added compatibility with upcoming ACE 3.20.0

# Changelog for Armor Modifier - ACE 9.2.2025

1.0.5.0
Expand Down
2 changes: 2 additions & 0 deletions addons/main/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
PREP(getHitpointArmor);
PREP(getItemArmor);
PREP(handleDamage);
2 changes: 2 additions & 0 deletions addons/main/XEH_preInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ ADDON = false;
// CBA Settings
#include "initSettings.inc.sqf"

GVAR(armorCache) = createHashMap;

ADDON = true;
51 changes: 51 additions & 0 deletions addons/main/functions/fnc_getHitpointArmor.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include "..\script_component.hpp"
/*
* Author: Pterolatypus, LinkIsGrim
* (This file is a copy from ACE3 3.19 with minor simplifications)
* Checks a unit's equipment to calculate the total armor on a hitpoint.
*
* Arguments:
* 0: Unit <OBJECT>
* 1: Hitpoint <STRING>
*
* Return Value:
* Total armor and scaled armor for the given hitpoint <ARRAY of NUMBERs>
*
* Example:
* [player, "HitChest"] call armor_modifier_ace_main_fnc_getHitpointArmor
*
* Public: No
*/

params ["_unit", "_hitpoint"];

private _uniform = uniform _unit;
// If unit is naked, use its underwear class instead
if (_uniform isEqualTo "") then {
_uniform = getText (configOf _unit >> "nakedUniform");
};

private _gear = [
_uniform,
vest _unit,
headgear _unit
];

private _rags = _gear joinString "$";
private _var = format [QGVAR(armorCache$%1), _hitpoint];
_unit getVariable [_var, ["", 0, 0]] params ["_prevRags", "_armor"];

if (_rags != _prevRags) then {
_armor = 0;

{
_armor = _armor + ([_x, _hitpoint] call FUNC(getItemArmor));
} forEach _gear;

// Armor should be at least 1 to prevent dividing by 0
_armor = _armor max 1;

_unit setVariable [_var, [_rags, _armor]];
};

_armor // return
47 changes: 47 additions & 0 deletions addons/main/functions/fnc_getItemArmor.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include "..\script_component.hpp"
/*
* Author: Pterolatypus, LinkIsGrim
* Returns the regular and scaled armor values the given item provides to a particular hitpoint, either from a cache or by reading the item config.
*
* Arguments:
* 0: Item Class <STRING>
* 1: Hitpoint <STRING>
*
* Return Value:
* Regular and scaled item armor for the given hitpoint <ARRAY of NUMBERs>
*
* Example:
* ["V_PlateCarrier_rgr", "HitChest"] call armor_modifier_ace_main_fnc_getItemArmor
*
* Public: No
*/

params ["_item", "_hitpoint"];

GVAR(armorCache) getOrDefaultCall [_this joinString "$", {
TRACE_2("Cache miss",_item,_hitpoint);
private _armor = 0;

if !("" in [_item, _hitpoint]) then {
private _itemInfo = configFile >> "CfgWeapons" >> _item >> "ItemInfo";
private _itemType = getNumber (_itemInfo >> "type");

if (_itemType == TYPE_UNIFORM) then {
private _unitCfg = configFile >> "CfgVehicles" >> getText (_itemInfo >> "uniformClass");
_armor = if (_hitpoint == "#structural") then {
// TODO: I'm not sure if this should be multiplied by the base armor value or not
getNumber (_unitCfg >> "armorStructural")
} else {
getNumber (_unitCfg >> "armor") * (1 max getNumber (_unitCfg >> "HitPoints" >> _hitpoint >> "armor"))
};
} else {
private _condition = format ["getText (_x >> 'hitpointName') == '%1'", _hitpoint];
private _entry = configProperties [_itemInfo >> "HitpointsProtectionInfo", _condition] param [0, configNull];
if (!isNull _entry) then {
_armor = getNumber (_entry >> "armor");
};
};
};

_armor // return
}, true]
7 changes: 1 addition & 6 deletions addons/main/functions/fnc_handleDamage.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,8 @@ if (_context != 2 && {_context == 4 || _newDamage == 0}) exitWith {
// Get scaled armor value of hitpoint and calculate damage before armor
// We scale using passThrough to handle explosive-resistant armor properly (#9063)
// We need realDamage to determine which limb was hit correctly
[_unit, _hitpoint] call ace_medical_engine_fnc_getHitpointArmor params ["_armor", "_armorScaled"];
private _armor = [_unit, _hitpoint] call FUNC(getHitpointArmor);
private _realDamage = _newDamage * _armor;
if (!_structuralDamage) then {
private _armorCoef = _armor/_armorScaled;
private _damageCoef = linearConversion [0, 1, ace_medical_engine_damagePassThroughEffect, 1, _armorCoef];
_newDamage = _newDamage * _damageCoef;
};
TRACE_6("Received hit",_hitpoint,_ammo,_newDamage,_realDamage,_directHit,_context);

// Drowning doesn't fire the EH for each hitpoint so the "ace_hdbracket" code never runs
Expand Down
2 changes: 2 additions & 0 deletions addons/main/script_macros.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@
#define PRIORITY_RIGHT_LEG (1 + random 1)
#define PRIORITY_STRUCTURAL 1

#define TYPE_UNIFORM 801

#define GET_NUMBER(config,default) (if (isNumber (config)) then {getNumber (config)} else {default})
2 changes: 1 addition & 1 deletion addons/main/script_version.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#define MAJOR 1
#define MINOR 0
#define PATCHLVL 5
#define PATCHLVL 6
#define BUILD 0