fn_explosionDamage.sqf 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. /*
  2. Author: TheTimidShade
  3. Description:
  4. Damages/destroys/throws/ragdolls any units within the killzone of the beam. Should only be executed on the server/host player.
  5. Parameters:
  6. 0: OBJECT - Impact emitter object passed from fnc_beam.
  7. 1: NUMBER - Maximum radius to deal lethal damage to units/vehicles.
  8. 2: NUMBER - Maximum radius to deal damage/ragdoll units.
  9. Returns:
  10. NONE
  11. */
  12. if (!isServer) exitWith {}; // make sure this function is only run on server
  13. params ["_impactEmitter","_maxKillRange", "_maxDamageRange"];
  14. private _ace_enabled = isClass(configFile >> "CfgPatches" >> "ace_main");
  15. _nearObjects = nearestObjects[_impactEmitter, ["Building", "House", "Man", "LandVehicle", "Air"], _maxDamageRange];
  16. {
  17. private _distance = _impactEmitter distance _x;
  18. private _dirFromTo = (getPosATL _impactEmitter) vectorFromTo (getPosATL _x);
  19. _effectCoef = if (_distance < _maxKillRange) then {1} else {
  20. private _coef = (_distance - _maxKillRange)/(_maxDamageRange - _maxKillRange); // should be 0 at maxKillRange, 1 at edge of maxDamageRange
  21. (1 - _coef)
  22. };
  23. private _throwSpeedKill = [30*_dirFromTo#0, 30*_dirFromTo#1, 5] vectorMultiply _effectCoef;
  24. private _throwSpeedDamage = [15*_dirFromTo#0, 15*_dirFromTo#1, 5] vectorMultiply _effectCoef;
  25. if (_distance <= _maxKillRange) then { // if unit is within the killzone, instantly destroy it
  26. if (!(_x isKindOf "Static")) then {[_x, _throwSpeedKill] remoteExec ["setVelocity", _x, false];}; // throw non-static objects
  27. [_x, _impactEmitter] spawn {sleep 0.001; if (_this#0 != _this#1) then {_this#0 setDamage 1};};
  28. } else { // if not, damage it depending on distance
  29. if (_distance <= _maxDamageRange) then {
  30. if (!(_x isKindOf "Static")) then {[_x, _throwSpeedDamage] remoteExec ["setVelocity", _x, false];}; // throw non-static objects
  31. private _damageToAdd = 0.5*(_effectCoef^2);
  32. if (!(_x isKindOf "Man")) then { // damage vehicles/buildings
  33. _x setDamage ((damage _x) + _damageToAdd);
  34. } else { // damage unit
  35. if (_ace_enabled) then { // check if ace is enabled, use ace damage if it is
  36. _damageRegions = ["body", "hand_l", "hand_r", "leg_l", "leg_r"];
  37. _damagePoint = selectRandom _damageRegions;
  38. [_x, _damageToAdd*2, _damagePoint, "explosive"] remoteExec ["ace_medical_fnc_addDamageToUnit", _x, false];
  39. } else {
  40. _x setDamage ((damage _x) + _damageToAdd);
  41. };
  42. if (_effectCoef >= 0.1) then { // ragdoll the unit if they are close enough to the explosion
  43. _x spawn {sleep 0.001; [_this] remoteExec ["tts_beam_fnc_ragdollUnit", _this, false];};
  44. };
  45. };
  46. };
  47. };
  48. sleep 0.0005;
  49. } foreach _nearObjects;