Files
DayZ-Epoch/SQF/dayz_code/compile/player_zombieAttack.sqf
ebaydayz 77e760fe73 Update private tags
From
e69f8d5306

Moved dog files to the \dog\ folder and pzombie files to the \pzombie\
folder. Also removed some legacy files that are no longer used.

The actions\ and compile\ folders are fully up to date now
2016-03-30 14:55:45 -04:00

334 lines
12 KiB
Plaintext

/*
Created exclusively for ArmA2:OA - DayZMod.
Please request permission to use/alter/distribute from project leader (R4Z0R49) AND the author (facoptere@gmail.com)
*/
private ["_rnd","_move","_wound","_cnt","_index","_damage","_total","_movePlayer","_start","_unit","_type","_vehicle","_speed",
"_nextPlayerPos","_distance","_viralZeds","_isVehicle","_agentPos","_playerDodged","_areaAffect","_dist","_dir","_timeout","_deg",
"_lastDodge","_dodgeAnimations","_tPos","_zPos","_hpList","_hp","_chance","_openVehicles","_strH","_dam","_cantSee","_attackanimations",
"_lastTackle","_knockdown","_vel","_t","_step","_i","_doRE","_stop"];
_unit = _this select 0;
_type = _this select 1;
_vehicle = vehicle player;
_speed = speed player;
//_nextPlayerPos = player call dayz_futurePos;
_distance = [_unit, player] call BIS_fnc_distance2D;
//_viralZeds = typeOf _unit in DayZ_ViralZeds;
_isVehicle = (_vehicle != player);
//_agentPos = getPosATL _unit;
_playerDodged = false;
if (_type != "zombie") exitWith { diag_log ("not a zombie"); }; // we deal only with zombies in this function
if (_unit distance _vehicle > 3) exitWith {}; // distance too far according to any logic dealt here //+str(_unit distance _nextPlayerPos)+"/"+str(_areaAffect)
// compute the animation move
_rnd = 0;
_dist = round(_distance*10);
switch true do {
case (((toArray(animationState player) select 5) == 112) && (_distance < 2.2)) : {
_rnd = ceil(random 4); //9
_move = "ZombieFeed" + str(_rnd);
};
case (r_player_unconscious && ((random 3) < 1)) : {
_rnd = ceil(random 4); //9
_move = "ZombieFeed" + str(_rnd);
};
case ((_isVehicle) && (_distance < 3.6)) : { // enable attack if Z is between 2.2 and 3.5. Other cases are handled in "default"
_rnd = 8;
_move = "ZombieStandingAttack" + str(_rnd);
};
case (((_speed >= 5) or (_speed <= -5)) && (_distance < 2.3)) : {
_rnd = 8;
_move = "ZombieStandingAttack" + str(_rnd);
};
default {
// attack moves depends on the distance between player and Z
// we compute the distance in 10cm slots.
switch _dist do {
case 0 : {_rnd = [ 1, 4, 9, 3, 6 ];};
case 10 : {_rnd = [ 1, 4, 9, 3, 6 ];};
case 11 : {_rnd = [ 1, 4, 9, 3, 6 ];};
case 12 : {_rnd = [ 1, 9, 3, 6 ];};
case 13 : {_rnd = [ 3, 6 ];};
case 14 : {_rnd = [ 3, 6, 7 ];};
case 15 : {_rnd = [ 7, 5, 10 ];};
case 16 : {_rnd = [ 7, 5, 10 ];};
case 17 : {_rnd = [ 7, 5, 10 ];};
case 18 : {_rnd = [ 8, 10 ];};
case 19 : {_rnd = [ 8, 10 ];};
case 20 : {_rnd = [ 8 ];};
case 21 : {_rnd = [ 8 ];};
case 22 : {_rnd = [ 8 ];};
default {
if (_dist < 10) then { _rnd = [ 1, 2, 4, 9 ]; };
if (_dist > 22) then { _rnd = [ 8 ]; };
};
};
//diag_log ("ZedAttack: : "+str(_rnd));
_rnd = _rnd call BIS_fnc_selectRandom;
_move = "ZombieStandingAttack" + str(_rnd);
//diag_log format ["Distance: %3/%1, Animation: %2", _distance, _rnd, _dist];
};
};
//Make sure zed is facing the player
_dir = [_unit,player] call BIS_Fnc_dirTo;
_unit setDir _dir;
// let's animate the Z
/*
if (local _unit) then {
_unit switchMove _move;
} else {
[objNull, _unit, rswitchMove, _move] call RE;
};
*/
[objNull, _unit, rplaymove, _move] call RE;
uiSleep 0.5;
//slow it down make sure the animation isnt running after the damage
//_timeout = diag_tickTime + 0.3;
//waitUntil { diag_tickTime >= _timeout; };
_deg = [player, _unit] call BIS_fnc_relativeDirTo;
_lastDodge = _unit getVariable ["lastDodge", 0];
//1 in 5 shots
if (((diag_tickTime - _lastDodge) == 0) or ((diag_tickTime - _lastDodge) > 10)) then {
if (((_deg > 295) && (_deg < 360)) or ((_deg > 0) && (_deg < 65))) then {
_dodgeAnimations = ["amovpknlmstpsraswrfldnon"];
if ((animationState _vehicle) in _dodgeAnimations) then {
if (dayz_dodge) exitwith {
_playerDodged = true;
dayz_dodge = false;
};
};
};
};
if (_playerDodged) exitwith {
//systemChat ("That was close!");
_lastDodge = _unit setVariable ["lastDodge", diag_tickTime];
};
_tPos = getPosASL _vehicle;
_zPos = getPosASL _unit;
// compute damage for vehicle and/or the player
if (_isVehicle) then {
if ((_unit distance player) < (3.3 * 2)) then {
_hpList = _vehicle call vehicle_getHitpoints;
_hp = _hpList call BIS_fnc_selectRandom;
_wound = getText(configFile >> "cfgVehicles" >> (typeOf _vehicle) >> "HitPoints" >> _hp >> "name");
_damage = random 0.08;
_chance = round(random 12);
if ((_chance % 4) == 0) then {
_openVehicles = ["ATV_Base_EP1", "Motorcycle", "Bicycle"];
{
if (_vehicle isKindOf _x) exitWith {
player action ["eject", _vehicle];
};
} count _openVehicles;
};
if (_wound in [ "glass1", "glass2", "glass3", "glass4", "glass5", "glass6" ]) then {
_strH = "hit_" + (_wound);
_dam = _vehicle getVariable [_strH,0];
_total = (_dam + _damage);
//handle vehicle dmg
[_vehicle, _wound, _total, _unit, "zombie", true] call fnc_veh_handleDam;
//diag_log ("Hitpoints " +str(_wound) +str(_total));
//handle player dmg
if (_total >= 1) then {
if (r_player_blood < (r_player_bloodTotal * 0.8)) then {
_cnt = count (DAYZ_woundHit select 1);
_index = floor (random _cnt);
_index = (DAYZ_woundHit select 1) select _index;
_wound = (DAYZ_woundHit select 0) select _index;
} else {
_cnt = count (DAYZ_woundHit_ok select 1);
_index = floor (random _cnt);
_index = (DAYZ_woundHit_ok select 1) select _index;
_wound = (DAYZ_woundHit_ok select 0) select _index;
};
_damage = 0.1 + random (1.2);
//diag_log ("Player_ZombieAttack: START DAM: Player Hit on " + _wound + " for " + str(_damage));
[player, _wound, _damage, _unit,"zombie"] call fnc_usec_damageHandler;
};
};
// broadcast hit noise
_pos = getPosATL player;
if ({isPlayer _x} count (_pos nearEntities ["CAManBase",40]) > 1) then {
[_unit,"hit",0,false] call dayz_zombieSpeak;
} else {
[_unit,"hit",0,true] call dayz_zombieSpeak;
};
};
} else {
// player by foot
if ((_unit distance player) <= 3) then {
//Make sure sure evrything is processed as we attack.
_damage = 0.2 + random (1.2);
//LOS check
//Zed eye to player (opersite way around).
_cantSee = [_unit,_vehicle] call dayz_losCheck;
if (!_cantSee) then {
if (r_player_blood < (r_player_bloodTotal * 0.8)) then {
_cnt = count (DAYZ_woundHit select 1);
_index = floor (random _cnt);
_index = (DAYZ_woundHit select 1) select _index;
_wound = (DAYZ_woundHit select 0) select _index;
} else {
_cnt = count (DAYZ_woundHit_ok select 1);
_index = floor (random _cnt);
_index = (DAYZ_woundHit_ok select 1) select _index;
_wound = (DAYZ_woundHit_ok select 0) select _index;
};
_unit setVariable ["speedLimit", 0, false]; //Stop the Zed
//systemChat format["ZA Start Damage Check - %1",(_unit distance player)];
_attackanimations = ["zombiestandingattack1","zombiestandingattack2","zombiestandingattack3","zombiestandingattack4","zombiestandingattack5","zombiestandingattack6","zombiestandingattack7","zombiestandingattack8","zombiestandingattack9","zombiestandingattack10","zombiefeed1","zombiefeed2","zombiefeed3","zombiefeed4","zombiefeed5"];
if ((animationState _unit) in _attackanimations) then {
if (alive _unit) then {
//Damage the player
[player, _wound, _damage, _unit, "zombie"] call fnc_usec_damageHandler;
// check Z stance. Stand up Z if it prones/kneels. make sure zed stays standing after its frist attak
if (unitPos _unit != "UP") then {_unit setUnitPos "UP";};
// broadcast hit noise
_pos = getPosATL player;
if ({isPlayer _x} count (_pos nearEntities ["CAManBase",40]) > 1) then {
[_unit,"hit",0,false] call dayz_zombieSpeak;
} else {
[_unit,"hit",0,true] call dayz_zombieSpeak;
};
// player may fall if hit
_deg = [player, _unit] call BIS_fnc_relativeDirTo;
_lastTackle = player getVariable ["lastTackle", 0];
_movePlayer = "";
//head hit, legs, pushed from back
_knockdown = ["head_hit","legs"];
if (_wound in _knockdown) then {
if (((diag_tickTime - _lastTackle) > 7) && (_speed >= 5.62)) then {
switch true do {
/*
//Removed for now
// front
case (((_deg > 315) && (_deg <= 360)) or ((_deg > 0) && (_deg < 45))) : {
//player setVelocity [(velocity player select 0) + 5 * sin direction _unit, (velocity player select 1) + 5 * cos direction _unit, (velocity player select 2) + 1];
// stop player
_vel = velocity player;
player setVelocity [-(_vel select 0), -(_vel select 1), 0];
disableUserInput true;
[diag_tickTime] call {
_t = _this select 0;
while {true} do {
if (diag_tickTime - _t > 1) exitWith {disableUserInput false;};
};
};
};
*/
// left
case (((_deg > 225) && (_deg < 315))) : {
// rotate player 'smoothly'
[_deg] spawn {
private["_step","_i"];
_step = 90 / 5;
_i = 0;
while {_i < 5} do {
player setDir ((getDir player) + _step);
_i = _i + 1;
uiSleep 0.01;
};
};
// make player dive
_movePlayer = switch (toArray(animationState player) select 17) do {
case 114 : {"ActsPercMrunSlowWrflDf_TumbleOver"}; // rifle
case 112 : {"AmovPercMsprSlowWpstDf_AmovPpneMstpSrasWpstDnon"}; // pistol
default {"ActsPercMrunSlowWrflDf_TumbleOver"};
};
};
// right
case (((_deg > 45) && (_deg < 135))) : {
[_deg] spawn {
private["_step","_i"];
_step = 90 / 5;
_i = 0;
while {_i < 5} do {
player setDir ((getDir player) - _step);
_i = _i + 1;
uiSleep 0.01;
};
};
// make player dive
_movePlayer = switch (toArray(animationState player) select 17) do {
case 114 : {"ActsPercMrunSlowWrflDf_TumbleOver"}; // rifle
case 112 : {"AmovPercMsprSlowWpstDf_AmovPpneMstpSrasWpstDnon"}; // pistol
default {"ActsPercMrunSlowWrflDf_TumbleOver"};
};
};
// rear
case (((_deg > 135) && (_deg < 225))) : {
_movePlayer = switch (toArray(animationState player) select 17) do {
case 114 : {"ActsPercMrunSlowWrflDf_TumbleOver"}; // rifle
case 112 : {"AmovPercMsprSlowWpstDf_AmovPpneMstpSrasWpstDnon"}; // pistol
default {"ActsPercMrunSlowWrflDf_TumbleOver"};
};
};
};
// Make player dive after making sure the zed can see you.
if (_movePlayer != "") then {
player setVariable ["lastTackle", diag_tickTime];
_doRE = ({isPlayer _x} count (player nearEntities ["AllVehicles",100]) > 1);
if (_doRE) then {
[nil, player, rSWITCHMOVE, _movePlayer] call RE;
} else {
player switchMove _movePlayer;
};
if (_movePlayer == "ActsPercMrunSlowWrflDf_TumbleOver") then {
[_movePlayer, _doRE] spawn {
private ["_movePlayer","_doRE"];
_movePlayer = _this select 0;
_doRE = _this select 1;
waitUntil {animationState player == _movePlayer}; // just in case
while {animationState player == _movePlayer} do {
if (speed player < 4) exitWith { /* break from loop to fix animation lockup */ };
uiSleep 0.1;
};
if (_doRE) then {
[nil, player, rSWITCHMOVE, ""] call RE;
} else {
player switchMove "";
};
};
};
//diag_log(format["%1 player tackled. Weapons: cur:""%2"" anim.state:%6 (%7)--> move: %3. Angle:%4 Delta-time:%5", __FILE__, currentWeapon player, _move, _deg, time - _lastTackle, animationState player, toArray(animationState player) select 17 ]);
};
};
};
};
};
};
}; // fi player by foot
};
//_stop = diag_tickTime;
//diag_log format ["%2 Execution Time: %1",_stop - _start, __FILE__];