Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ACE No Med scripted damage compatibilities #140

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions addons/compat_ace_fire/$PBOPREFIX$
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just putting the comment here so it has a focused discussion.

I looked into the ace code to check what is going on. Yeah you need to overwrite and replace the functions, which i frankly do not really like, yet there is no other option right now other than doing some execNextFrame fuckery, which is also fairly ugly.

I will test those changes once i get the chance, but i also would suggest that ACE should get some PR to allow easier handling of these things. So this compats are a lot easier and clearer. I might get on that as well once i get some free time.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
z\diw_armor_plates\addons\compat_ace_fire
1 change: 1 addition & 0 deletions addons/compat_ace_fire/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[QPATHTOF(functions\fnc_burnSimulation.sqf), QUOTE(DOUBLES(REPLACEMOD,fnc_burnSimulation))] call CBA_fnc_compileFunction;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is going on here, why not just use the normal prep macro?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaces an ace function, using the normal prep would just create a new one not used by ace.

15 changes: 15 additions & 0 deletions addons/compat_ace_fire/XEH_preInit.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include "script_component.hpp"
ADDON = false;

GVAR(aceMedicalLoaded) = isClass(configFile >> "CfgPatches" >> "ace_medical_engine");
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can also exit out early if ace is loaded, as that is already handled by ace itself

if (isClass(configFile >> "CfgPatches" >> "ace_medical") && {!GVAR(aceMedicalLoaded)}) exitWith {
INFO("PreInit: Disabled --> old ACE medical loaded");
};

if (GVAR(aceMedicalLoaded)) exitWith {
//#include "initSettingsACE.inc.sqf"
};

#include "initSettings.inc.sqf"

ADDON = true;
6 changes: 6 additions & 0 deletions addons/compat_ace_fire/XEH_preStart.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include "script_component.hpp"
if (isClass(configFile >> "CfgPatches" >> "ace_medical") && {!isClass(configFile >> "CfgPatches" >> "ace_medical_engine")}) exitWith {
INFO("PreStart: Disabled --> old ACE medical loaded");
};
#include "XEH_PREP.hpp"
call compile preprocessFileLineNumbers format["%1\XEH_preStart.sqf",REPLACEPATH];
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question here, doesn't this run on its own.

28 changes: 28 additions & 0 deletions addons/compat_ace_fire/config.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "script_component.hpp"

class CfgPatches {
class ADDON {
name = COMPONENT_NAME;
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"diw_armor_plates_main",QUOTE(REPLACEMOD)};
author = "Alien314";
authors[] = {"Alien314","ACE-Team"};
url = "";
VERSION_CONFIG;
skipWhenMissingDependencies = 1;
};
};

class Extended_PreInit_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_SCRIPT(XEH_preInit));
};
};

class Extended_PreStart_EventHandlers {
class REPLACEMOD {
init = QUOTE(call COMPILE_SCRIPT(XEH_preStart));
};
};
190 changes: 190 additions & 0 deletions addons/compat_ace_fire/functions/fnc_burnSimulation.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
#include "..\script_component.hpp"
/*
* Author: tcvm, johnb43
* Simulates fire intensity over time on burning units.
* Arbitrary values to ignite people. Assumed maximum is "10".
*
* Arguments:
* 0: Unit <OBJECT>
* 1: Instigator <OBJECT>
*
* Return Value:
* None
*
* Example:
* [player, player] call ace_fire_fnc_burnSimulation
*
* Public: No
*/

params ["_unit", "_instigator"];

[{
params ["_args", "_pfhID"];
_args params ["_unit", "_instigator"];

if (isNull _unit) exitWith {
//TRACE_1("unit is null",_unit);

_pfhID call CBA_fnc_removePerFrameHandler;
};

// Locality has changed
if (!local _unit) exitWith {
//TRACE_1("unit is no longer local",_unit);

_pfhID call CBA_fnc_removePerFrameHandler;

["ace_fire_burnSimulation", [_unit, _instigator], _unit] call CBA_fnc_targetEvent;
};

// If the unit is invulnerable, in water or if the fire has died out, stop burning the unit
if (
!(_unit call ace_fire_fnc_isBurning) ||
{!(isDamageAllowed _unit && {_unit getVariable ["ace_medical_allowDamage", true]})} ||
{private _eyePos = eyePos _unit; surfaceIsWater _eyePos && {(_eyePos select 2) < 0.1}}
) exitWith {
//TRACE_3("unit is no longer burning, invulnerable or in water",_unit,_unit call FUNC(isBurning),isDamageAllowed _unit && {_unit getVariable [ARR_2(QEGVAR(medical,allowDamage),true)]});

// Remove global effects
(_unit getVariable ["ace_fire_jipID", ""]) call CBA_fnc_removeGlobalEventJIP;

// Update globally that the unit isn't burning anymore
_unit setVariable ["ace_fire_intensity", nil, true];

_pfhID call CBA_fnc_removePerFrameHandler;

if (!isNil {_unit getVariable "ace_fire_stopDropRoll"} && {!isPlayer _unit}) then {
_unit setUnitPos "AUTO";

_unit setVariable ["ace_fire_stopDropRoll", nil, true];
};
};

if (isGamePaused) exitWith {};

private _intensity = _unit getVariable ["ace_fire_intensity", 0];

// Propagate fire to other units (alive or dead) if it's intense
if (_intensity >= BURN_THRESHOLD_INTENSE) then {
//TRACE_2("check for other units",_unit,_intensity);

{
private _distancePercent = 1 - ((_unit distance _x) / BURN_PROPAGATE_DISTANCE);
private _adjustedIntensity = _intensity * _distancePercent;

// Don't burn if intensity is too low or already burning with higher intensity
if (BURN_MIN_INTENSITY > _adjustedIntensity || {(_x getVariable ["ace_fire_intensity", 0]) > _adjustedIntensity}) then {
continue;
};

["ace_fire_burn", [_x, _adjustedIntensity, _instigator], _x] call CBA_fnc_targetEvent;

//TRACE_3("propagate fire",_x,_intensity,_adjustedIntensity);
} forEach nearestObjects [_unit, ["CAManBase"], BURN_PROPAGATE_DISTANCE];
};

// Update intensity/fire reactions
if (CBA_missionTime >= _unit getVariable ["ace_fire_intensityUpdate", 0]) then {
//TRACE_2("update intensity",_unit,_intensity);

_unit setVariable ["ace_fire_intensityUpdate", CBA_missionTime + INTENSITY_UPDATE];

_intensity = _intensity - INTENSITY_LOSS - (rain / 10);

if (_unit call ace_common_fnc_isAwake) then {
if (_unit call ace_common_fnc_isPlayer) then {
// Decrease intensity of burn if rolling around
if ((animationState _unit) in PRONE_ROLLING_ANIMS) then {
_intensity = _intensity * INTENSITY_DECREASE_MULT_ROLLING;
};
} else {
private _sdr = _unit getVariable ["ace_fire_stopDropRoll", false];

private _vehicle = objectParent _unit;

if (isNull _vehicle && {_sdr || {0.05 > random 1}}) then {
_unit setVariable ["ace_fire_stopDropRoll", true, true];

if (!_sdr) then {
//TRACE_1("stop, drop, roll!",_unit);

_unit setUnitPos "DOWN";
doStop _unit;
};

// Queue up a bunch of animations
for "_i" from 0 to 2 do {
[_unit, selectRandom ["amovppnemstpsnonwnondnon_amovppnemevasnonwnondl", "amovppnemstpsnonwnondnon_amovppnemevasnonwnondr"], 0] call ace_common_fnc_doAnimation;
};

_intensity = _intensity - (1 / _intensity);
} else {
// Make the unit leave the vehicle
if (_vehicle != _unit) then {
//TRACE_1("Ejecting",_unit);

_unit leaveVehicle _vehicle;
unassignVehicle _unit;

_unit action ["Eject", _vehicle];
};

_unit disableAI "TARGET";
_unit disableAI "AUTOTARGET";

// Run away, erraticly
if (leader group _unit != _unit) then {
[_unit] join grpNull;
};

_unit doMove ((getPosATL _unit) getPos [20 + random 35, floor (random 360)]);
_unit setSpeedMode "FULL";
_unit setSuppression 1;
};
};

// Play screams and throw weapon (if enabled)
_unit call ace_fire_fnc_burnReaction;
};

// Keep pain around unconsciousness limit to allow for more fun interactions
private _painPercieved = (0 max ((_unit getVariable ["ace_medical_pain", 0]) - (_unit getVariable ["ace_medical_painSuppress", 0])) min 1);
private _painUnconscious = missionNamespace getVariable ["ace_medical_painUnconsciousThreshold", 0];
private _damageToAdd = [0.15, _intensity / BURN_MAX_INTENSITY] select (!alive _unit || {_painPercieved < _painUnconscious + random 0.2});

if (missionNamespace getVariable ["ace_medical_enabled", false]) then {
if (!isNull _instigator) then {
_unit setVariable ["ace_medical_lastDamageSource", _instigator];
_unit setVariable ["ace_medical_lastInstigator", _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];

// Use event directly, as ace_medical_fnc_addDamageToUnit requires unit to be alive
["ace_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];
_damageToAdd = _damageToAdd * GVAR(fireMult);

if (EGVAR(main,enable)) exitWith {
{
if (GVAR(ignoreArmor)) then {
private _vest = vestContainer _unit;
private _plates = _vest getVariable [QEGVAR(main,plates), []];
_vest setVariable [QEGVAR(main,plates), []];
[{params ["_vest","_plates"]; _vest setVariable [QEGVAR(main,plates), _plates];}, [_vest,_plates]] call CBA_fnc_execNextFrame;
};
[_unit, _damageToAdd, _x, _instigator] call EFUNC(main,receiveDamage);
} forEach _bodyParts;
};

{
_unit setHitPointDamage [_x, (_unit getHitPointDamage _x) + _damageToAdd, true, _instigator, _instigator];
} forEach _bodyParts;
};

_unit setVariable ["ace_fire_intensity", _intensity, true]; // Globally sync intensity across all clients to make sure simulation is deterministic
};
}, BURN_PROPAGATE_UPDATE, [_unit, _instigator]] call CBA_fnc_addPerFrameHandler;
19 changes: 19 additions & 0 deletions addons/compat_ace_fire/initSettings.inc.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
private _header = LELSTRING(main,category);
private _category = [_header, LLSTRING(subCategoryCompat)];

[
QGVAR(ignoreArmor), "CHECKBOX",
[LLSTRING(ignoreArmor), LLSTRING(ignoreArmor_desc)],
_category,
false,
true
] call CBA_fnc_addSetting;

[
QGVAR(fireMult), "SLIDER",
[LLSTRING(nonMedBurnMult), LLSTRING(nonMedBurnMult_desc)],
_category,
[0, 10, 0.2, 2, false],
true,
{[QGVAR(fireMult), _this, true] call ace_common_fnc_cbaSettings_settingChanged}
] call CBA_fnc_addSetting;
31 changes: 31 additions & 0 deletions addons/compat_ace_fire/script_component.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#define COMPONENT compat_ace_fire
#define COMPONENT_BEAUTIFIED ACE Fire Compat
#define REPLACEMOD ace_fire
#define REPLACEPATH "z\ace\addons\fire"

#include "\z\diw_armor_plates\addons\main\script_mod.hpp"

#include "\z\diw_armor_plates\addons\main\script_macros.hpp"

#define PRONE_ROLLING_ANIMS [\
"amovppnemstpsnonwnondnon_amovppnemevasnonwnondl",\
"amovppnemstpsnonwnondnon_amovppnemevasnonwnondr",\
"amovppnemstpsraswrfldnon_amovppnemevaslowwrfldl",\
"amovppnemstpsraswrfldnon_amovppnemevaslowwrfldr",\
"amovppnemstpsraswpstdnon_amovppnemevaslowwpstdl",\
"amovppnemstpsraswpstdnon_amovppnemevaslowwpstdr",\
"amovppnemstpsoptwbindnon_amovppnemevasoptwbindl",\
"amovppnemstpsoptwbindnon_amovppnemevasoptwbindr"\
]

#define BURN_MAX_INTENSITY 10
#define BURN_MIN_INTENSITY 1

#define INTENSITY_DECREASE_MULT_PAT_DOWN 0.8
#define INTENSITY_DECREASE_MULT_ROLLING INTENSITY_DECREASE_MULT_PAT_DOWN

#define INTENSITY_LOSS 0.02
#define INTENSITY_UPDATE 2
#define BURN_PROPAGATE_UPDATE 1
#define BURN_PROPAGATE_DISTANCE 2
#define BURN_THRESHOLD_INTENSE 3
20 changes: 20 additions & 0 deletions addons/compat_ace_fire/stringtable.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<Project name="diw_armor_plates">
<Package name="compat_ace_fire">
<Key ID="STR_diw_armor_plates_compat_ace_fire_subCategoryCompat">
<English>Compatibility</English>
</Key>
<Key ID="STR_diw_armor_plates_compat_ace_fire_ignoreArmor">
<English>ACE Fire Ignore Armor</English>
</Key>
<Key ID="STR_diw_armor_plates_compat_ace_fire_ignoreArmor_desc">
<English>Whether fire damage should ignore armor plates.</English>
</Key>
<Key ID="STR_diw_armor_plates_compat_ace_fire_nonMedBurnMult">
<English>ACE Fire Burn Damage Multiplier</English>
</Key>
<Key ID="STR_diw_armor_plates_compat_ace_fire_nonMedBurnMult_desc">
<English>Fire can randomly hit multiple parts, use this to tune it. (Default: 0.2)</English>
</Key>
</Package>
</Project>
1 change: 1 addition & 0 deletions addons/compat_ace_overpressure/$PBOPREFIX$
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
z\diw_armor_plates\addons\compat_ace_overpressure
2 changes: 2 additions & 0 deletions addons/compat_ace_overpressure/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[QPATHTOF(functions\fnc_overpressureDamage.sqf), QUOTE(DOUBLES(REPLACEMOD,fnc_overpressureDamage))] call CBA_fnc_compileFunction;
[QPATHTOF(functions\fnc_firedEHBB.sqf), QUOTE(DOUBLES(REPLACEMOD,fnc_firedEHBB))] call CBA_fnc_compileFunction;
15 changes: 15 additions & 0 deletions addons/compat_ace_overpressure/XEH_preInit.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include "script_component.hpp"
ADDON = false;

GVAR(aceMedicalLoaded) = isClass(configFile >> "CfgPatches" >> "ace_medical_engine");
if (isClass(configFile >> "CfgPatches" >> "ace_medical") && {!GVAR(aceMedicalLoaded)}) exitWith {
INFO("PreInit: Disabled --> old ACE medical loaded");
};

if (GVAR(aceMedicalLoaded)) exitWith {
//#include "initSettingsACE.inc.sqf"
};

#include "initSettings.inc.sqf"

ADDON = true;
6 changes: 6 additions & 0 deletions addons/compat_ace_overpressure/XEH_preStart.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include "script_component.hpp"
if (isClass(configFile >> "CfgPatches" >> "ace_medical") && {!isClass(configFile >> "CfgPatches" >> "ace_medical_engine")}) exitWith {
INFO("PreStart: Disabled --> old ACE medical loaded");
};
#include "XEH_PREP.hpp"
call compile preprocessFileLineNumbers format["%1\XEH_preStart.sqf",REPLACEPATH];
28 changes: 28 additions & 0 deletions addons/compat_ace_overpressure/config.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "script_component.hpp"

class CfgPatches {
class ADDON {
name = COMPONENT_NAME;
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"diw_armor_plates_main",QUOTE(REPLACEMOD)};
author = "Alien314";
authors[] = {"Alien314","ACE-Team"};
url = "";
VERSION_CONFIG;
skipWhenMissingDependencies = 1;
};
};

class Extended_PreInit_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_SCRIPT(XEH_preInit));
};
};

class Extended_PreStart_EventHandlers {
class REPLACEMOD {
init = QUOTE(call COMPILE_SCRIPT(XEH_preStart));
};
};
Loading
Loading