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

Allow damage handler (also block only collision damage) #2758

Closed
wants to merge 6 commits into from
Closed
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
8 changes: 8 additions & 0 deletions addons/common/CfgEventHandlers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,11 @@ class Extended_Respawn_EventHandlers {
};
};
};

class Extended_Local_EventHandlers {
class All {
class ADDON {
local = QUOTE(call FUNC(handleLocal));
};
};
};
1 change: 1 addition & 0 deletions addons/common/XEH_postInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
["fixCollision", FUNC(fixCollision)] call FUNC(addEventhandler);
["fixFloating", FUNC(fixFloating)] call FUNC(addEventhandler);
["fixPosition", FUNC(fixPosition)] call FUNC(addEventhandler);
["allowDamage", FUNC(setAllowDamage)] call FUNC(addEventhandler);

["unloadPersonEvent", FUNC(unloadPersonLocal)] call FUNC(addEventhandler);

Expand Down
2 changes: 2 additions & 0 deletions addons/common/XEH_preInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ PREP(getWindDirection);
PREP(getZoom);
PREP(goKneeling);
PREP(hadamardProduct);
PREP(handleLocal);
PREP(handleModifierKey);
PREP(handleModifierKeyUp);
PREP(handleModifierKeyInit);
Expand Down Expand Up @@ -151,6 +152,7 @@ PREP(selectWeaponMode);
PREP(sendRequest);
PREP(serverLog);
PREP(setAllGear);
PREP(setAllowDamage);
PREP(setCaptivityStatus);
PREP(setDefinedVariable);
PREP(setDisableUserInputStatus);
Expand Down
22 changes: 11 additions & 11 deletions addons/common/functions/fnc__handleSyncedEvent.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Arguments [Client] :
* 0: eventName <STRING>
* 1: arguments <ARRAY>
* 2: ttl <SCALAR>
* 2: ttl <SCALAR><CODE>
*
* Return Value:
* Boolean of success <BOOL>
Expand All @@ -21,20 +21,20 @@ if (!HASH_HASKEY(GVAR(syncedEvents),_name)) exitWith {
false
};

private ["_internalData", "_eventCode"];

_internalData = HASH_GET(GVAR(syncedEvents),_name);
local _internalData = HASH_GET(GVAR(syncedEvents),_name);
_internalData params ["_eventCode", "_eventLog"];

if (isServer) then {
// Server needs to internally log it for synchronization
if (_ttl > -1) then {
_internalData = HASH_GET(GVAR(syncedEvents),_name);

private "_eventLog";
_eventLog = _internalData select 1;
_eventLog pushback [ACE_diagTime, _args, _ttl];
local _entry = [ACE_diagTime, _args, _ttl];
local _addToSync = if (typeName _ttl == "CODE") then {
[_eventCode, _entry] call _ttl;
} else {
_ttl > -1
};
if (_addToSync) then {
_eventLog pushback _entry;
};
};

_eventCode = _internalData select 0;
_args call _eventCode;
6 changes: 4 additions & 2 deletions addons/common/functions/fnc_fixCollision.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
if (!local _this) exitWith {};

// prevent collision damage, @todo allowDamage API
_this allowDamage false;
[_this, "fixCollision", 1] call FUNC(setAllowDamage);

// re-allow damage after 2 seconds
[{_this allowDamage true}, _this, 2, 0] call EFUNC(common,waitAndExecute);
[{
[_this, "fixCollision", 0] call FUNC(setAllowDamage);
}, _this, 2] call EFUNC(common,waitAndExecute);
8 changes: 7 additions & 1 deletion addons/common/functions/fnc_fixFloating.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,18 @@ _hitPointDamages = getAllHitPointsDamage _object;

// get correct format for objects without hitpoints
if (_hitPointDamages isEqualTo []) then {
_hitPointDamages = [[],[],[]];
_hitPointDamages = [[],[],[]];
};

//manualy set allowDamage true or setHitIndex does not work
_object allowDamage true;

// this prevents physx objects from floating when near other physx objects with allowDamage false
_object setDamage damage _object;

{
_object setHitIndex [_forEachIndex, _x];
} forEach (_hitPointDamages select 2);

//reset allowDamage to what it should be
[_object, "", -1] call FUNC(setAllowDamage);
25 changes: 25 additions & 0 deletions addons/common/functions/fnc_handleLocal.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Author: PabstMirror
* Called when a unit switched locality
*
* Arguments:
* 0: XEH Object <OBJECT>
* 1: Is local <BOOL>
*
* ReturnValue:
* None
*
* Public: No
*/
#include "script_component.hpp"

params ["_object", "_local"];
TRACE_2("params",_object,_local);

if (_local) then {
local _allowDamageArray = _object getVariable [QGVAR(allowDamage), []];
if (!(_allowDamageArray isEqualTo [])) then {
//If locality swiched and this unit has had setAllowDamage run, reApply the effects:
[_object, "", -1] call FUNC(setAllowDamage);
};
};
94 changes: 94 additions & 0 deletions addons/common/functions/fnc_setAllowDamage.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Author: PabstMirror
* Allows multiple sources to block all or just collision damage on people/objects
*
* Arguments:
* 0: Object (should be local) <OBJECT>
* 1: Source Reason <STRING>
* 2: State (true/false or 0 = allow all, 1 = block colision (CAManBase only + req medical), 2 = block all) <NUMBER><BOOL>
*
* Return Value:
* None
*
* Example:
* [box1, "doNotExplode", true] call ace_common_fnc_setAllowDamage;
* [guy, "preventColisionDmg", 1] call ace_common_fnc_setAllowDamage;
* [guy, "", -1] call ace_common_fnc_setAllowDamage; //Won't modifiy state and just reapply effects
*
* Public: Yes
*/
#include "script_component.hpp"

params ["_object", "_reason", "_state"];
TRACE_3("params",_object,_reason,_state);

if (!local _object) exitWith {
ACE_LOGERROR_1("setAllowDamage - obj not local - %1", _this);
["allowDamage", [_object], _this] call FUNC(targetEvent);
};

if ((typeName _state) == "BOOL") then {//Convert bool to number
_state = [2,0] select _state;
};
if ((_state == 1) && {(!(_object isKindOf "CAManBase")) || {!(["ace_medical"] call FUNC(isModLoaded))}}) then {
_state = 2; //Can't do 'blockCollision' on non man or if mod not loaded
};

local _allowDamageReasons = missionNamespace getVariable [QGVAR(allowDamageReasons), []];
(_object getVariable [QGVAR(allowDamage), [0,0]]) params ["_blockCollisionNum", "_blockDamageNum"];

local _blockCollisionArray = [_blockCollisionNum, count _allowDamageReasons] call FUNC(binarizeNumber);
local _blockDamageArray = [_blockDamageNum, count _allowDamageReasons] call FUNC(binarizeNumber);

//If there is a reason, set it in the arrays:
if (_reason != "") then {
_reason = toLower _reason;
// register new reason (these reasons are shared publicly, since units can change ownership)
if !(_reason in _allowDamageReasons) then {
_allowDamageReasons pushBack _reason;
GVAR(allowDamageReasons) = _allowDamageReasons;
publicVariable QGVAR(allowDamageReasons);
};
local _index = _allowDamageReasons find _reason;
switch (_state) do {
case (0): {
_blockCollisionArray set [_index, false];
_blockDamageArray set [_index, false];
};
case (1): {
_blockCollisionArray set [_index, true];
_blockDamageArray set [_index, false];
};
case (2): {
_blockCollisionArray set [_index, false];
_blockDamageArray set [_index, true];
};
};
};

local _newBlockCollisionNum = _blockCollisionArray call FUNC(toBitmask);
local _newBlockDamageNum = _blockDamageArray call FUNC(toBitmask);

//Update and broadcast variables if they changed:
if ((_newBlockDamageNum != _blockDamageNum) || {_newBlockCollisionNum != _blockCollisionNum}) then {
TRACE_2("Updating",_newBlockCollisionNum, _newBlockDamageNum);
_object setVariable [QGVAR(allowDamage), [_newBlockCollisionNum, _newBlockDamageNum], true];
};

if ((_object isKindOf "CAManBase") && {["ace_medical"] call FUNC(isModLoaded)}) then {
//ACE_medical already has a handleDamage installed on the Unit and we can just setVariables for it
TRACE_1("handled by ace medical", _object);
Copy link
Contributor

Choose a reason for hiding this comment

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

_object setvariable [QEGVAR(medical,allowdamage), false];


_object setvariable [QEGVAR(medical,allowDamage), (_newBlockCollisionNum > 0), true];
_object setvariable [QEGVAR(medical,allowCollisionDamage), (_newBlockCollisionNum > 0), true];
} else {
if (_newBlockDamageNum > 0) then {
TRACE_1("Blocking Damage", _object);
_object allowDamage false;
} else {
TRACE_1("Allowing Damage", _object);
_object allowDamage true;
};
};

nil
6 changes: 3 additions & 3 deletions addons/common/functions/fnc_syncedEventPFH.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ if (!isServer) exitWith {false};
_name = _x;

_data = HASH_GET(GVAR(syncedEvents),_name);
_data params ["_eventTime", "_eventLog", "_globalEventTTL"];
_data params ["_eventCode", "_eventLog", "_globalEventTTL"];

_newEventLog = [];

Expand All @@ -36,7 +36,7 @@ if (!isServer) exitWith {false};
_ttlReturn = true;

if (typeName _globalEventTTL == "CODE") then {
_ttlReturn = [_eventTime, _eventEntry] call _globalEventTTL;
_ttlReturn = [_eventCode, _eventEntry] call _globalEventTTL;
} else {
_ttlReturn = call {_globalEventTTL < 1 || {ACE_diagTime < (_eventEntry select 0) + _globalEventTTL}};
};
Expand All @@ -46,7 +46,7 @@ if (!isServer) exitWith {false};
_eventEntry params ["_time", "", "_eventTTL"];

if (typeName _eventTTL == "CODE") then {
_ttlReturn = [_eventTime, _eventEntry] call _eventTTL;
_ttlReturn = [_eventCode, _eventEntry] call _eventTTL;
} else {
_ttlReturn = call {_eventTTL < 1 || {ACE_diagTime < _time + _eventTTL}};
};
Expand Down
5 changes: 3 additions & 2 deletions addons/medical/XEH_postInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,9 @@ GVAR(lastHeartBeatSound) = ACE_time;
};

["SettingsInitialized", {
// Networked litter (need to wait for GVAR(litterCleanUpDelay) to be set)
[QGVAR(createLitter), FUNC(handleCreateLitter), GVAR(litterCleanUpDelay)] call EFUNC(common,addSyncedEventHandler);

if (GVAR(level) == 2) exitwith {
[
{(((_this select 0) getvariable [QGVAR(bloodVolume), 100]) < 65)},
Expand Down Expand Up @@ -276,8 +279,6 @@ GVAR(lastHeartBeatSound) = ACE_time;
[ACE_player] call FUNC(itemCheck);
}] call EFUNC(common,addEventHandler);

// Networked litter
[QGVAR(createLitter), FUNC(handleCreateLitter), GVAR(litterCleanUpDelay)] call EFUNC(common,addSyncedEventHandler);

if (hasInterface) then {
["PlayerJip", {
Expand Down
2 changes: 1 addition & 1 deletion addons/medical/functions/fnc_handleDamage.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ _this set [1, _selection]; // ensure that the parameters are set correctly
if (_selection != "" && {!(_selection in GVAR(SELECTIONS))}) exitWith {0}; //@todo "neck", "pelvis", "spine1", "spine2", "spine3"

// Exit if we disable damage temporarily
if !(_unit getVariable [QGVAR(allowDamage), true]) exitWith {
if ((!(_unit getVariable [QGVAR(allowDamage), true])) || {(!(_unit getVariable [QGVAR(allowCollisionDamage), true])) && {_projectile == ""}}) exitWith {
TRACE_3("ACE_DEBUG: HandleDamage damage disabled.",_selection,damage _unit,_unit);
if (_selection == "") then {
damage _unit
Expand Down