diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index 1da4723154..1b512b201f 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -1,20 +1,18 @@ #include "script_component.hpp" -#ifdef DEBUG_MODE_DRAW [ "CBA_settingsInitialized", { + ["ace_firedPlayer", LINKFUNC(fired)] call CBA_fnc_addEventHandler; + ["ace_firedNonPlayer", LINKFUNC(fired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler; + ["ace_firedNonPlayerVehicle", LINKFUNC(fired)] call CBA_fnc_addEventHandler; +#ifdef DEBUG_MODE_DRAW [QGVAR(dev_clearTraces), LINKFUNC(dev_clearTraces)] call CBA_fnc_addEventHandler; if (!hasInterface) exitWith {}; - if (!isServer) then { - ["ace_firedPlayer", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerNonLocal", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; - ["ace_firedNonPlayer", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerVehicle", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerVehicleNonLocal", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; - ["ace_firedNonPlayerVehicle", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; - }; + ["ace_firedPlayerVehicleNonLocal", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; + ["ace_firedNonPlayerVehicle", LINKFUNC(dev_fired)] call CBA_fnc_addEventHandler; GVAR(dev_drawPFEH) = [LINKFUNC(dev_drawTrace), 0] call CBA_fnc_addPerFrameHandler; [ "ace_interact_menu_newControllableObject", @@ -39,9 +37,9 @@ ] call EFUNC(interact_menu,addActionToClass); } ] call CBA_fnc_addEventHandler; +#endif } ] call CBA_fnc_addEventHandler; -#endif #ifdef LOG_FRAG_INFO [true, true, 30] call FUNC(dev_debugAmmo); diff --git a/addons/frag/XEH_preInit.sqf b/addons/frag/XEH_preInit.sqf index 68d608c87f..9e85fabe2a 100644 --- a/addons/frag/XEH_preInit.sqf +++ b/addons/frag/XEH_preInit.sqf @@ -28,7 +28,15 @@ GVAR(dev_drawPFEH) = -1; #endif if (isServer) then { - [QEGVAR(common,setShotParents), {(_this#0) setVariable [QGVAR(shotParent), [_this#1, _this#2]]}] call CBA_fnc_addEventHandler; + [ + QGVAR(explosionEvent), + { + params ["_posASL", "_velocity", "_ammo", "_shotParents"]; + [_posASL, _velocity, _ammo, _shotParents] call FUNC(doFrag); + } + ] call CBA_fnc_addEventHandler; + + [QGVAR(spallEvent), LINKFUNC(doSpallServer)] call CBA_fnc_addEventHandler; }; ADDON = true; diff --git a/addons/frag/functions/fnc_dev_fired.sqf b/addons/frag/functions/fnc_dev_fired.sqf deleted file mode 100644 index 9dbd039f46..0000000000 --- a/addons/frag/functions/fnc_dev_fired.sqf +++ /dev/null @@ -1,23 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: Lambda.Tiger - * Add fired rounds to dev track. - * - * Arguments: - * Parameters inherited from EFUNC(common,firedEH) - * - * Return Value: - * Nothing Useful - * - * Example: - * [clientFiredBIS-XEH] call ace_frag_fnc_fired - * - * Public: No - */ - -//IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); - -if (GVAR(debugOptions) && {_ammo call FUNC(shouldFrag) || {_ammo call FUNC(shouldSpall)}}) then { - [_projectile, true, [side group _unit, side group ACE_player] call BIS_fnc_sideIsFriendly] call FUNC(dev_addRound); -}; diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpallLocal.sqf similarity index 68% rename from addons/frag/functions/fnc_doSpall.sqf rename to addons/frag/functions/fnc_doSpallLocal.sqf index a516648f0b..39f85360f3 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpallLocal.sqf @@ -1,17 +1,28 @@ #include "..\script_component.hpp" /* - * Author: Jaynus, NouberNou, Lambda.Tiger, - * This function creates spalling if the hit slowed the projectile speed down enough. + * Author: Jaynus, NouberNou, Lambda.Tiger + * This function runs on every client and determines if a spall event happened. + * It is intended to be called a frame after the projectile has triggered a hit event, + * where information such as the object hit, the projectiles velocity and position on impact + * should be kept and passed to this function.If a spall event should happen, this function + * calculates the spalling parameters and then calls a server event to create the desired spall effect. * * Arguments: - * Arguments are the same as BI's "HitPart" EH: - * https://community.bistudio.com/wiki/Arma_3:_Event_Handlers#HitPart + * 0: The projectile that may be creating spall + * 1: The object the projectile hit + * 2: The 3D position (ASL) of the projectile when it hit the object + * 3: The velocity of the projectile when it hit the object + * 4: The normal of the surface of the object hit + * 5: The class name of the surface, or the bisurf path of the surface hit + * 6: The class name of the projectile that may be spalling + * 7: The spalling projectile's shot parents + * 8: The "up" vector of the projectile when it hit the object * * Return Value: * None * * Example: - * [BIS_HITPART_EH_ARGS] call ace_frag_fnc_doSpall + * [_projectile, _hitObject, _lastPosASLProjectile, _lastVelocityProjectile, _surfaceNorm, "a3\data_f\penetration\armour_plate.bisurf", "Sh_125mm_APFSDS", [0, 0, 1]] call ace_frag_fnc_doSpallLocal * * Public: No */ @@ -112,26 +123,12 @@ private _spawnSize = switch (true) do default {"_spall_huge"}; }; -private _spallSpawner = createVehicle [ - QUOTE(GLUE(ADDON,_)) + _material + _spawnSize, - ASLToATL _spallPosASL, - [], - 0, - "CAN_COLLIDE" -]; -_spallSpawner setVectorDirandUp [_lastVelocityNorm, _vectorUp]; -_spallSpawner setVelocityModelSpace [0, _speedChange * ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF, 0]; -_spallSpawner setShotParents _shotParents; - #ifdef DEBUG_MODE_FULL -systemChat ("spd: " + str speed _spallSpawner + ", spawner: " + _fragSpawnType + ", spallPow: " + str _spallPower); -#endif -#ifdef DEBUG_MODE_DRAW -_spallSpawner addEventHandler [ - "SubmunitionCreated", - { - params ["", "_submunitionProjectile"]; - _submunitionProjectile call FUNC(dev_addRound); - } -]; +systemChat ("spd: " + str (_speedChange * ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF) + ", spallPow: " + str _spallPower); #endif + +TRACE_5("Calling event:",QUOTE(GLUE(ADDON,_)) + _material + _spawnSize,_lastVelocityNorm,_vectorUp,_speedChange,_shotParents); +[ + FUNC(doSpallServer), + [QUOTE(GLUE(ADDON,_)) + _material + _spawnSize, _lastVelocityNorm, _vectorUp, _speedChange, _shotParents] +] call CBA_fnc_serverEvent; diff --git a/addons/frag/functions/fnc_doSpallServer.sqf b/addons/frag/functions/fnc_doSpallServer.sqf new file mode 100644 index 0000000000..bf4c43ce72 --- /dev/null +++ b/addons/frag/functions/fnc_doSpallServer.sqf @@ -0,0 +1,45 @@ +#include "..\script_component.hpp" +/* + * Author: Jaynus, NouberNou, Lambda.Tiger, + * This function creates the requested spalling submunition spawner at a speed and direction. + * The function is intended to create the spalling on a server via an event call by + * ace_frag_fnc_doSpallLocal. The "local" version determines whether an event has occured + * and triggers this event if it has. + * + * Arguments: + * 0: Class name of the spall spawner + * 1: Normalized 3D vector direction of the spall spawner + * 2: "Up" vector for the projectile, required for the spawner to aim out of the 2D plane + * 3: The change in velocity that spalling projectile experienced + * 4: Shot parents array for the projectile that creates spall + * + * Return Value: + * None + * + * Example: + * [QGVAR(rock_spall_tiny), [1,0,0], [0,0,1], 300, [objNull, ace_player]] call ace_frag_fnc_doSpallServer + * + * Public: No + */ +params ["_spallSpawnerName", "_lastVelocityNorm", "_vectorUp", "_speedChange", "_shotParents"]; + +private _spallSpawner = createVehicle [ + _spallSpawnerName, + ASLToATL _spallPosASL, + [], + 0, + "CAN_COLLIDE" +]; +_spallSpawner setVectorDirandUp [_lastVelocityNorm, _vectorUp]; +_spallSpawner setVelocityModelSpace [0, _speedChange * ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF, 0]; +_spallSpawner setShotParents _shotParents; + +#ifdef DEBUG_MODE_DRAW +_spallSpawner addEventHandler [ + "SubmunitionCreated", + { + params ["", "_submunitionProjectile"]; + _submunitionProjectile call FUNC(dev_addRound); + } +]; +#endif diff --git a/addons/frag/functions/fnc_fired.sqf b/addons/frag/functions/fnc_fired.sqf new file mode 100644 index 0000000000..d94ca518cc --- /dev/null +++ b/addons/frag/functions/fnc_fired.sqf @@ -0,0 +1,65 @@ +#include "..\script_component.hpp" +/* + * Author: Lambda.Tiger + * Add eventhandlers to rounds as needed + * + * Arguments: + * Parameters inherited from EFUNC(common,firedEH) + * + * Return Value: + * Nothing Useful + * + * Example: + * [clientFiredBIS-XEH] call ace_frag_fnc_fired + * + * Public: No + */ + +//IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); + +if (_ammo isEqualTo "" || {isNull _projectile} || + {_projectile getVariable [QGVAR(blacklisted), false]}) exitWith { + TRACE_2("bad ammo or projectile, or blackList",_ammo,_projectile); +}; + + +#ifdef DEBUG_MODE_DRAW +if (GVAR(debugOptions) && {true in (_ammo call FUNC(shouldFrag)) || {_ammo call FUNC(shouldSpall)}}) then { + [_projectile, "red", true] call FUNC(dev_trackObj); +}; +#endif + +if (GVAR(spallEnabled) && {_ammo call FUNC(shouldSpall)}) then { + _projectile addEventHandler [ + "HitPart", + { + params ["_projectile", "_hitObject", "", "_posASL", "_velocity", "_surfNorm", "", "", "_surfType"]; + + if (_projectile getVariable [QGVAR(blacklisted), false]) exitWith { + TRACE_2("projectile blackisted",typeOf _projectile,_projectile); + }; + + // starting v2.18 it may be faster to use the instigator parameter, the same as the second entry shotParents, to recreate _shotParent + // The "explode" EH does not get the same parameter + private _shotParent = getShotParents _projectile; + private _ammo = typeOf _projectile; + private _vectorUp = vectorUp _projectile; + /* + * Wait a frame to see what happens to the round, may result in + * multiple hits / slowdowns getting shunted to the first hit + */ + [ + FUNC(doSpallLocal), + [_projectile, _hitObject, _posASL, _velocity, _surfNorm, _surfType, _ammo, _shotParent, _vectorUp] + ] call CBA_fnc_execNextFrame; + } + ]; +}; +if !(GVAR(reflectionsEnabled) || GVAR(enabled)) exitWith { + TRACE_1("initExit No frag/reflections",_ammo); +}; + +[_projectile, _ammo] call FUNC(roundInitFrag); + +TRACE_1("initExit",_ammo);