Update damage handler and improve study body

Vanilla development commits applied:

3db0fe8e7a

73a63898f1

08e18d5b52

126da2dcd3

d5fa323865

d37526fcc6

5fcca134f0

c9c1fc934d
This commit is contained in:
ebaydayz
2016-08-11 15:16:46 -04:00
parent 4019d0c351
commit 7439b87779
10 changed files with 226 additions and 179 deletions

View File

@@ -1,13 +1,11 @@
scriptName "Functions\misc\fn_damageHandler.sqf";
/***********************************************************
Modifyed by Alby
PROCESS DAMAGE TO A UNIT
- Function
- [unit, selectionName, damage, source, projectile] call fnc_usec_damageHandler;
************************************************************/
private ["_unit","_hit","_damage","_unconscious","_source","_ammo","_Viralzed","_isMinor","_isHeadHit","_isPlayer","_isBandit","_punishment","_humanityHit","_myKills","_wpst","_sourceDist","_sourceWeap","_scale","_type","_nrj","_rndPain","_hitPain","_wound","_isHit","_isbleeding","_rndBleed","_hitBleed","_isInjured","_lowBlood","_rndInfection","_hitInfection","_isCardiac","_chance","_breakaleg","_model","_isZombieHit"];
private ["_HitBy","_end","_unit","_hit","_damage","_unconscious","_source","_ammo","_Viralzed","_isMinor","_isHeadHit","_isPlayer","_isBandit","_punishment","_humanityHit","_myKills","_wpst","_sourceDist","_sourceWeap","_scale","_type","_nrj","_rndPain","_hitPain","_wound","_isHit","_isbleeding","_rndBleed","_hitBleed","_isInjured","_lowBlood","_rndInfection","_hitInfection","_isCardiac","_chance","_falling","_model","_isZombieHit"];
_unit = _this select 0;
_hit = _this select 1;
_damage = _this select 2;
@@ -15,20 +13,54 @@ _unconscious = _unit getVariable ["NORRN_unconscious", false];
_source = _this select 3;
_isPZombie = player isKindOf "PZombie_VB";
_ammo = _this select 4;
_isZombieHit = (_ammo == "zombie");
_model = typeOf player;
_Viralzed = typeOf _source in DayZ_ViralZeds;
_isMinor = (_hit in USEC_MinorWounds);
_isHeadHit = (_hit == "head_hit");
_isPlayer = (isPlayer _source);
_isZombieHit = _ammo == "zombie";
// anti-hack for local explosions (HelicopterExploSmall, HelicopterExploBig, SmallSecondary...) spawned by hackers
//diag_log [ diag_ticktime, __FILE__, _this];
_breakaleg = (((_hit == "legs") AND {(_source==_unit)}) AND {((_ammo=="") AND {(Dayz_freefall select 1 > 3)})}) /*AND {(abs(time - (Dayz_freefall select 0))<1)}*/;
if ( (!_breakaleg) AND {(((isNull _source) OR {(_unit == _source)}) AND {((_ammo == "") OR {({damage _x > 0.9} count((getposATL vehicle _unit) nearEntities [["Air", "LandVehicle", "Ship"],15]) == 0) AND (count nearestObjects [getPosATL vehicle _unit, ["TrapItems"], 30] == 0)})})}) exitWith {0};
//Ignore none part dmg.
if (_hit == "") exitwith { 0 };
_falling = (((_hit == "legs") AND {(_source==_unit)}) AND {((_ammo=="") AND {(Dayz_freefall select 1 > 3)})});
//Simple hack to help with a few issues from direct damage to physic based damage. ***until 2.0***
if (isNull dayz_getout) then {
_vehicleArray = nearestObjects [(getposATL (vehicle _unit)),["Car","Helicopter","Motorcycle","Ship"],3];
{
if ((speed _x > 10) or (speed _x < 8)) exitwith { dayz_HitBy = _x; };
} count _vehicleArray;
};
//Lets see if the player has been struck by a moving vehicle.
if (!isNull dayz_HitBy) then { _ammo = "RunOver"; };
if ((_hit == "Legs") AND {(_ammo == "RunOver")}) then { dayz_HitBy = objNull; };
//If a vehicle is moveing faster then 15 lets register some kind of direct damage rather then relying on indirect/physics damage.
if (!isNull dayz_getout && diag_tickTime - dayz_getoutTime < 5) then { _ammo = "Dragged"; };
if ((_hit == "Legs") AND {(_ammo == "Dragged")}) then { dayz_getout = objNull; };
_end = false;
if (!_falling) then {
//No _ammo type exit, indirect/physics damage.
if (_ammo == "") exitwith { _end = true; };
//If _source contains no object exit. But lets not exit if the unit returns player. Maybe its his own fault.
if (isNull _source) exitwith { _end = true; };
};
if (_end) exitwith { 0 };
//End Simple hack for damage ***until 2.0***
if (_unit == player) then {
//Set player in combat
_unit setVariable["startcombattimer", 1];
_unit setVariable["inCombat", 1, true];
if (_unit == player) then
{
if (_hit == "") then
{
if ((_source != player) and _isPlayer && alive player) then
@@ -56,8 +88,8 @@ if (_unit == player) then
{!_isPZombie});
_humanityHit = 0;
if (!_punishment && {(DayZ_LastHumanityChange + 3) < diag_tickTime}) then {
DayZ_LastHumanityChange = diag_tickTime;
if (!_punishment && {(dayz_lastHumanityChange + 3) < diag_tickTime}) then {
dayz_lastHumanityChange = diag_tickTime;
_myKills = 200 - (((player getVariable ["humanKills",0]) / 3) * 150);
// how many non bandit players have I (the shot/damaged player) killed?
// punish my killer 200 for shooting a surivor
@@ -68,7 +100,7 @@ if (_unit == player) then
};
// In the case of outrageous damage (crashes, explosions, desync repeated headshots); cap the limit on humanity lost.
[_source,_humanityHit] spawn {
[_source,_humanityHit] spawn {
private ["_source","_humanityHit"];
_source = _this select 0;
_humanityHit = _this select 1;
@@ -85,10 +117,6 @@ if (_unit == player) then
private ["_unit"];
_unit = _this select 0;
localize "str_player_tranquilized" call dayz_rollingMessages;
//systemChat format ["YOU HAVE BEEN TRANQUILISED"];
//uiSleep 2;
// 0 fadeSound 0.05;
//uiSleep 5;
[_unit,0.01] call fnc_usec_damageUnconscious;
_unit setVariable ["NORRN_unconscious", true, true];
r_player_timeout = round(random 60);
@@ -140,92 +168,30 @@ if (_unit == player) then
};
};
};
};
//Pure blood damage
_scale = 200;
_type = 0;
if ((_ammo isKindof "Grenade") or (_ammo isKindof "ShellBase") or (_ammo isKindof "TimeBombCore") or (_ammo isKindof "BombCore") or (_ammo isKindof "MissileCore") or (_ammo isKindof "RocketCore") or (_ammo isKindof "FuelExplosion") or (_ammo isKindof "GrenadeBase")) then {
_type = 1;
};
if ((_ammo isKindof "B_127x107_Ball") or (_ammo isKindof "B_127x99_Ball")) then {
_type = 2;
};
if (_damage > 0.4) then {
if (!_isZombieHit) then {
_scale = _scale + 50; //250
};
//Start body part scale
if (_isZombieHit) then {
//_scale = _scale * 3; //600 = Normal, 900 = Viral
_scale = getNumber (configFile >> "CfgVehicles" >> (typeOf _source) >> "damageScale");
if (dayz_DamageMultiplier > 1) then {
_scale = _scale * dayz_DamageMultiplier;
};
//diag_log format["%1, DamageScale: %2",__FILE__,_scaleNew];
};
if (_isHeadHit) then {
_scale = _scale * 2; //700 = Normal, 900 = Viral, 500 = wild
};
//End body part scale
if ((isPlayer _source) and !(player == _source)) then {
_scale = _scale + 800;
if (_isHeadHit) then {
_scale = _scale + 500;
};
};
switch (_type) do {
case 1: {_scale = _scale + 200};
case 2: {_scale = _scale + 200};
};
if (_unit == player) then {
//diag_log ("DAMAGE: player hit by " + (typeOf _source) + " in " + _hit + " with " + _ammo + " for " + str(_damage) + " scaled " + str(_damage * _scale) + " Conscious " + str (!_unconscious));
diag_log format["DAMAGE: player hit by %1 in %2 with %3 for %4 scaled to %5, Conscious %6",(typeOf _source),_hit,if (_ammo == "") then { "" } else { _ammo },(str(_damage)),(str(_damage * _scale)),(str (!_unconscious))];
r_player_blood = r_player_blood - (_damage * _scale);
};
};
//Record Damage to Minor parts (legs, arms)
if (_hit in USEC_MinorWounds) then {
private ["_type"];
if (_isZombieHit) then {
if (_hit == "legs") then {
[_unit,_hit,(_damage / 6)] call object_processHit;
} else {
[_unit,_hit,(_damage / 4)] call object_processHit;
};
} else {
if (_breakaleg) then {
_nrj = ((Dayz_freefall select 1)*20) / 100;
_gravity = 9.81 min (2*(Dayz_freefall select 1)/((0.00001 + (Dayz_freefall select 2))^2));
_nrj2 = _gravity * (Dayz_freefall select 1);
//diag_log [ "handler freefall", _nrj, _nrj2, Dayz_freefall];
if (random(_nrj2 / (5 * 9.81)) > 0.5) then { // freefall from 5m => 1/2 chance to get hit legs registered
diag_log[__FILE__, "Legs damage registered from freefall, damage:",_damage,"gravity:", _gravity,
"height:", (Dayz_freefall select 1), "blood loss", (_nrj2 * 25) ];
[_unit,_hit,_damage] call object_processHit;
} else {
[_unit,"arms",(_damage / 6)] call object_processHit; // prevent broken legs due to arma bugs
};
if (_nrj2 > 30) then {
(3 min (_nrj2/100)) call fnc_usec_bulletHit; // red flash
r_player_blood = 0 max (r_player_blood - (_nrj2 * 25));
};
} else {
[_unit,_hit,(_damage / 2)] call object_processHit;
};
[_unit,_hit,(_damage / 2)] call object_processHit;
dayz_lastDamageSource = switch (true) do {
case (_falling): {"fall"};
case (_isZombieHit): {"zombie"};
case (_ammo == "RunOver"): {"runover"};
case (_ammo == "Dragged"): {"eject"};
case (_ammo in MeleeAmmo): {"melee"};
case (!isNil "_wpst" && {!(_wpst select 0 in ["","Throw"])}): {"shot"};
default {"none"};
};
if (dayz_lastDamageSource != "none") then {dayz_lastDamageTime = diag_tickTime;};
};
if (_unit == player) then {
//Set player in combat
_unit setVariable["startcombattimer", 1];
_unit setVariable["inCombat", 1, true];
//Pure base blood damage
_scale = 200;
//Ammo Type Setup
_type = switch true do {
case ((_ammo isKindof "Grenade") or (_ammo isKindof "ShellBase") or (_ammo isKindof "TimeBombCore") or (_ammo isKindof "BombCore") or (_ammo isKindof "MissileCore") or (_ammo isKindof "RocketCore") or (_ammo isKindof "FuelExplosion") or (_ammo isKindof "GrenadeBase")): { 1 };
case ((_ammo isKindof "B_127x107_Ball") or (_ammo isKindof "B_127x99_Ball")): { 2 };
case (_isZombieHit): { 3 };
case (_ammo == "RunOver"): { 4 };
case (_ammo == "Dragged"): { 5 };
default { 0 };
};
//Shake the cam, frighten them!
@@ -239,13 +205,45 @@ if (_damage > 0.1) then {
};
};
if (_damage > 0.4) then {
//Pain and Infection
if (_damage > 0.4) then {
//Scale damage based on headhits.
if (_isHeadHit) then {
_scale = _scale * 2; //700 = Normal, 900 = Viral, 500 = wild
};
//End body part scale
//???????????
if ((isPlayer _source) and !(player == _source)) then {
_scale = _scale + 800;
if (_isHeadHit) then {
_scale = _scale + 500;
};
};
//Modify base scale based on the types, Allows us to modify specific types of damage if needed.
switch (_type) do {
//Explosions
case 1: {_scale = _scale + 300};
//Bullet types
case 2: {_scale = _scale + 150};
//Zombies
case 3: {_scale = getNumber (configFile >> "CfgVehicles" >> (typeOf _source) >> "damageScale"); if (dayz_DamageMultiplier > 1) then {_scale = _scale * dayz_DamageMultiplier;};};
//Dragged
case 4: {_scale = _scale - 150};
//RunOver
case 5: {_scale = 25};
};
//Display some info in the players log file.
if (_unit == player) then {
diag_log format["DAMAGE: player hit by %1 in %2 with %3 for %4 scaled to %5, Conscious %6",(typeOf _source),_hit,if (_ammo == "") then { "" } else { _ammo },(str(_damage)),(str(_damage * _scale)),(str (!_unconscious))];
r_player_blood = r_player_blood - (_damage * _scale);
//Pain and Infection
_rndPain = floor(random 10);
_hitPain = (_rndPain < _damage);
if ((_isHeadHit) or (_damage > 1.2 and _hitPain)) then {
if ((_isHeadHit) or (_hitPain)) then {
_hitPain = true;
};
@@ -253,10 +251,6 @@ if (_damage > 0.4) then {
r_player_inpain = true;
player setVariable["USEC_inPain",true,true];
};
if ((_damage > 1.5) and _isHeadHit) then {
if (_isZombieHit) then {_id = [_source,"shothead",1] spawn player_death;} else {_id = [_source,"shothead"] spawn player_death;};
};
};
//Create wound and cause bleed
@@ -265,20 +259,16 @@ if (_damage > 0.4) then {
_isbleeding = false;
_isScratched = false;
switch true do {
default {
_rndBleed = floor(random 100);
_rndBleedChance = getNumber (configFile >> "CfgVehicles" >> (typeOf _source) >> "BleedChance");
_hitBleed = (_rndBleed < _rndBleedChance);
_rndBleed = floor(random 100);
_rndBleedChance = getNumber (configFile >> "CfgVehicles" >> (typeOf _source) >> "BleedChance");
_hitBleed = (_rndBleed < _rndBleedChance);
if (_hitBleed) then {
_isbleeding = true;
};
};
if (_hitBleed) then {
_isbleeding = true;
};
if (_isZombieHit) then {
if (_type == 3) then {
if (!_isHit && _isbleeding && !_isPZombie) then {
//Create Wound
_unit setVariable["hit_"+_wound,true,true];
@@ -297,6 +287,7 @@ if (_damage > 0.4) then {
dayz_sourceBleeding = _source;
};
};
//Set ability to give blood
_lowBlood = _unit getVariable["USEC_lowBlood",false];
if (!_lowBlood) then {
@@ -308,10 +299,9 @@ if (_damage > 0.4) then {
//HitInfection from zombies
if ((!r_player_infected) and !(r_player_Sepsis select 0)) then {
if (_isZombieHit) then {
if (_type == 3) then {
_rndSepsis = floor(random 100);
_sepsisChance = getNumber (configFile >> "CfgVehicles" >> (typeOf _source) >> "sepsisChance");
//_hitInfection = (_rndInfection < _infectionChance);
if (_rndSepsis < _sepsisChance) then {
r_player_Sepsis = [true, diag_tickTime];
@@ -321,7 +311,7 @@ if (_damage > 0.4) then {
};
};
} else {
if(!_isHit && !_isPZombie) then {
if (!_isHit && !_isPZombie) then {
//Create Wound
_unit setVariable["hit_"+_wound,true,true];
PVDZ_hlt_Bleed = [_unit,_wound,_damage];
@@ -347,6 +337,39 @@ if (_damage > 0.4) then {
};
};
//Record Damage to Minor parts (legs, arms)
if (_hit in USEC_MinorWounds) then {
if (_type == 3) then {
if (_hit == "legs") then {
[_unit,_hit,(_damage / 6)] call object_processHit;
} else {
[_unit,_hit,(_damage / 4)] call object_processHit;
};
} else {
if (_falling) then {
_nrj = ((Dayz_freefall select 1)*20) / 100;
_gravity = 9.81 min (2*(Dayz_freefall select 1)/((0.00001 + (Dayz_freefall select 2))^2));
_nrj2 = _gravity * (Dayz_freefall select 1);
//diag_log [ "handler freefall", _nrj, _nrj2, Dayz_freefall];
if (random(_nrj2 / (5 * 9.81)) > 0.5) then { // freefall from 5m => 1/2 chance to get hit legs registered
diag_log[__FILE__, "Legs damage registered from freefall, damage:",_damage,"gravity:", _gravity,
"height:", (Dayz_freefall select 1), "blood loss", (_nrj2 * 25) ];
[_unit,_hit,_damage] call object_processHit;
} else {
[_unit,"arms",(_damage / 6)] call object_processHit; // prevent broken legs due to arma bugs
};
if (_nrj2 > 30) then {
(3 min (_nrj2/100)) call fnc_usec_bulletHit; // red flash
r_player_blood = 0 max (r_player_blood - (_nrj2 * 25));
};
} else {
[_unit,_hit,(_damage / 2)] call object_processHit;
};
[_unit,_hit,(_damage / 2)] call object_processHit;
};
};
if (_type == 1) then {
/*
BALISTIC DAMAGE
@@ -391,7 +414,7 @@ if (_type == 2) then {
};
};
if (_isZombieHit) then {
if (_type == 3) then {
if (!_unconscious and !_isMinor and _isHeadHit) then {
_chance = random 1;
if ((_damage > 0.8) and (_chance < 0.5)) then {