From 3ed4a95c146a4187a3ee2e0549367b0c0ab46e6a Mon Sep 17 00:00:00 2001 From: ebaydayz Date: Wed, 23 Mar 2016 19:52:04 -0400 Subject: [PATCH] Rework death messages MPHit does not always fire when a player is killed: https://community.bistudio.com/wiki/ArmA_2:_Event_Handlers#MPHit Using either MPHit or MPKilled is not a good idea here. There is already a local 'killed' event handler which fires on player death (player_death.sqf). That script sends a PV (priority message) to the server which triggers server_playerDied. That means fnc_plyrHit needed to finish sending its data to the server via public setVariables (non-priority messages) before server_playerDied executed. Triggering both these scripts at the same time was a bad idea. Instead of sending the data to the server via setVariable I just included it in PVDZ_plr_Death. This also lets us pass extra information from the damage handler like ammo type, cause of death, etc. Still need to test, but it should be more reliable and performant than fnc_playerHit called from MPHit or MPKilled. --- CHANGE LOG 1.0.6.txt | 2 +- SQF/dayz_code/compile/fn_damageHandler.sqf | 25 +-- SQF/dayz_code/compile/player_death.sqf | 24 ++- SQF/dayz_code/compile/zombie_generate.sqf | 2 +- SQF/dayz_code/init/variables.sqf | 1 - SQF/dayz_code/system/player_monitor.fsm | 3 +- SQF/dayz_epoch_b/stringtable.xml | 48 ++++++ SQF/dayz_server/compile/fnc_plyrHit.sqf | 38 ----- .../compile/server_onPlayerDisconnect.sqf | 117 ++++++-------- SQF/dayz_server/compile/server_playerDied.sqf | 145 +++++++----------- .../compile/server_playerSetup.sqf | 4 - SQF/dayz_server/compile/server_playerSync.sqf | 14 +- SQF/dayz_server/init/Epoch_Init.sqf | 10 -- SQF/dayz_server/init/server_functions.sqf | 1 - 14 files changed, 188 insertions(+), 246 deletions(-) delete mode 100644 SQF/dayz_server/compile/fnc_plyrHit.sqf diff --git a/CHANGE LOG 1.0.6.txt b/CHANGE LOG 1.0.6.txt index 66a24f244..21235b6e2 100644 --- a/CHANGE LOG 1.0.6.txt +++ b/CHANGE LOG 1.0.6.txt @@ -76,7 +76,6 @@ [FIXED] Only first kill showing on death boards #1362 #1124 @vbawol @icomrade [FIXED] Crossbow quivers not working #1355 @icomrade [FIXED] Crash_spawner & Supply_drop modules spawning inaccessible loot piles #1408 #1390 @Uro1 -[FIXED] Undefined variable "_weapon" in fnc_plyrHit.sqf when killer is driving a vehicle #1420 @ebaydayz [FIXED] Fire cleanup diag_log error in server_functions.sqf #1421 @ebaydayz [FIXED] NearestObjects position error in server_playerSync.sqf #1425 @ebaydayz [FIXED] Corrected ClassName type for CH53_DZE and BAF_Merlin_DZE. @Cinjun @@ -101,6 +100,7 @@ [FIXED] Safes and lockboxes wiped when opening after restart and locking not being logged to RPT @ebaydayz #1413 #1503 [FIXED] Duplicate objectUIDs occasionally causing vehicles to swap classes or be deleted across restarts @ebaydayz #1504 [FIXED] DZE_BuildingLimit now counts buildables only instead of all object types. Thanks jOoPs @ebaydayz +[FIXED] Reworked death messages. Fixed messages not always showing, undefined errors and wrong distance bug. Added bled out, killed by zombie, etc. MPHit event handler (fnc_plyrHit) is no longer needed. @ebaydayz [UPDATED] .hpp files updated in dayz_epoch_b CfgLootPos > CfgBuildingPos. @Uro1 [UPDATED] .bat files updated in Config-Examples @Raziel23x diff --git a/SQF/dayz_code/compile/fn_damageHandler.sqf b/SQF/dayz_code/compile/fn_damageHandler.sqf index 6fb4fe495..d4805b46c 100644 --- a/SQF/dayz_code/compile/fn_damageHandler.sqf +++ b/SQF/dayz_code/compile/fn_damageHandler.sqf @@ -7,7 +7,7 @@ scriptName "Functions\misc\fn_damageHandler.sqf"; - 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"]; +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"]; _unit = _this select 0; _hit = _this select 1; _damage = _this select 2; @@ -15,6 +15,7 @@ _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); @@ -124,7 +125,7 @@ if (_unit == player) then _sourceDist = round(_unit distance _source); _sourceWeap = switch (true) do { case ((vehicle _source) != _source) : { format ["in %1",getText(configFile >> "CfgVehicles" >> (typeOf (vehicle _source)) >> "displayName")] }; - case (_ammo == "zombie") : { _ammo }; + case (_isZombieHit) : { _ammo }; case (_wpst select 0 == "Throw") : { format ["with %1 thrown", _wpst select 3] }; case (["Horn", currentWeapon _source] call fnc_inString) : {"with suspicious vehicle "+str((getposATL _source) nearEntities [["Air", "LandVehicle", "Ship"],5])}; case (["Melee", _wpst select 0] call fnc_inString) : { format ["with %2%1",_wpst select 0, if (_sourceDist>6) then {"suspicious weapon "} else {""}] }; @@ -132,7 +133,7 @@ if (_unit == player) then case (_wpst select 0 != "") : { format ["with %1/%2 ", _wpst select 0, _ammo, _wpst select 4] }; default { "with suspicious weapon" }; }; - if (_ammo != "zombie") then { // don't log any zombie wounds, even from remote zombies + if (!_isZombieHit) then { // don't log any zombie wounds, even from remote zombies PVDZ_sec_atp = [_unit, _source, _sourceWeap, _sourceDist]; publicVariableServer "PVDZ_sec_atp"; }; @@ -151,11 +152,11 @@ if ((_ammo isKindof "B_127x107_Ball") or (_ammo isKindof "B_127x99_Ball")) then }; if (_damage > 0.4) then { - if (_ammo != "zombie") then { + if (!_isZombieHit) then { _scale = _scale + 50; //250 }; //Start body part scale - if (_ammo == "zombie") then { + if (_isZombieHit) then { //_scale = _scale * 3; //600 = Normal, 900 = Viral _scale = getNumber (configFile >> "CfgVehicles" >> (typeOf _source) >> "damageScale"); if (dayz_DamageMultiplier > 1) then { @@ -190,7 +191,7 @@ if (_damage > 0.4) then { //Record Damage to Minor parts (legs, arms) if (_hit in USEC_MinorWounds) then { private ["_type"]; - if (_ammo == "zombie") then { + if (_isZombieHit) then { if (_hit == "legs") then { [_unit,_hit,(_damage / 6)] call object_processHit; } else { @@ -252,7 +253,7 @@ if (_damage > 0.4) then { }; if ((_damage > 1.5) and _isHeadHit) then { - _id = [_source,"shothead"] spawn player_death; + if (_isZombieHit) then {_id = [_source,"shothead",1] spawn player_death;} else {_id = [_source,"shothead"] spawn player_death;}; }; }; @@ -274,7 +275,7 @@ if (_damage > 0.4) then { }; }; - if (_ammo == "zombie") then { + if (_isZombieHit) then { if (!_isHit && _isbleeding && !_isPZombie) then { //Create Wound @@ -290,7 +291,7 @@ if (_damage > 0.4) then { if (!_isInjured) then { _unit setVariable["USEC_injured",true,true]; - if ((_unit == player) and (_ammo != "zombie")) then { + if ((_unit == player) and (!_isZombieHit)) then { dayz_sourceBleeding = _source; }; }; @@ -305,7 +306,7 @@ if (_damage > 0.4) then { //HitInfection from zombies if ((!r_player_infected) and !(r_player_Sepsis select 0)) then { - if (_ammo == "zombie") then { + if (_isZombieHit) then { _rndSepsis = floor(random 100); _sepsisChance = getNumber (configFile >> "CfgVehicles" >> (typeOf _source) >> "sepsisChance"); //_hitInfection = (_rndInfection < _infectionChance); @@ -328,7 +329,7 @@ if (_damage > 0.4) then { _isInjured = _unit getVariable["USEC_injured",false]; if (!_isInjured) then { _unit setVariable["USEC_injured",true,true]; - if ((_unit == player) and (_ammo != "zombie")) then { + if ((_unit == player) and (!_isZombieHit)) then { dayz_sourceBleeding = _source; }; }; @@ -387,7 +388,7 @@ if (_type == 2) then { }; }; -if (_ammo == "zombie") then { +if (_isZombieHit) then { if (!_unconscious and !_isMinor and _isHeadHit) then { _chance = random 1; if ((_damage > 0.8) and (_chance < 0.5)) then { diff --git a/SQF/dayz_code/compile/player_death.sqf b/SQF/dayz_code/compile/player_death.sqf index a2cb1c625..15bd3acfb 100644 --- a/SQF/dayz_code/compile/player_death.sqf +++ b/SQF/dayz_code/compile/player_death.sqf @@ -1,8 +1,8 @@ -private ["_display","_body","_playerID","_array","_source","_method","_isBandit","_punishment","_humanityHit","_myKills","_humanity","_kills","_killsV","_myGroup"]; +private ["_pos","_display","_body","_playerID","_array","_source","_method","_isBandit","_punishment","_humanityHit","_myKills","_humanity","_kills","_killsV","_myGroup","_model"]; disableSerialization; if (deathHandled) exitWith {}; deathHandled = true; -if (alive player) then {dayz_playerName = name player;}; +_bodyName = if (alive player) then {name player} else {"unknown"}; //Prevent client freezes _display = findDisplay 49; @@ -28,8 +28,26 @@ if (dayz_onBack != "") then { */ }; _infected = if (r_player_infected && DZE_PlayerZed) then {1} else {0}; +_killerMethod = "unknown"; +_killerName = "unknown"; +_killerDist = 0; +if (count _this > 0) then { + _killerObj = _this select 0; + _killerMethod = _this select 1; + + if (!isNull _killerObj) then { + if (!isNull _body) then {_killerDist = _body distance _killerObj;}; + _killerVehicle = vehicle _killerObj; + _killerWeapon = if (_killerVehicle != _killerObj) then {typeOf _killerVehicle} else {currentWeapon _killerObj}; + if (alive _killerObj) then { + _killerName = if (isPlayer _killerObj) then {name _killerObj} else {"AI"}; + }; + }; + if (count _this > 2) then {_killerMethod = "zombie";}; +}; +if (isNil "_killerWeapon") then {_killerWeapon = "unknown weapon";}; //Send Death Notice -PVDZ_plr_Death = [dayz_characterID,0,_body,_playerID,_infected,toArray dayz_playerName]; // Send as array to avoid publicVariable value restrictions +PVDZ_plr_Death = [dayz_characterID,0,_body,_playerID,toArray _bodyName,_infected,toArray _killerName,toArray _killerWeapon,_killerDist,toArray _killerMethod]; //Send name as array to avoid publicVariable value restrictions publicVariableServer "PVDZ_plr_Death"; _id = [player,20,true,getPosATL player] call player_alertZombies; diff --git a/SQF/dayz_code/compile/zombie_generate.sqf b/SQF/dayz_code/compile/zombie_generate.sqf index 77215b2a9..2b18fd8a0 100644 --- a/SQF/dayz_code/compile/zombie_generate.sqf +++ b/SQF/dayz_code/compile/zombie_generate.sqf @@ -78,7 +78,7 @@ if ((_maxlocalspawned < _maxControlledZombies) && (dayz_CurrentNearByZombies < d if (_tooClose) exitwith { diag_log "Zombie_Generate: was too close to player."; }; if (count _unitTypes == 0) then { - _unitTypes = getArray (configFile >> "CfgLoot" >> "Buildings" >> "Default" >> "zombieClass"); + _unitTypes = if (DZE_MissionLootTable) then {getArray (missionConfigFile >> "CfgLoot" >> "Buildings" >> "Default" >> "zombieClass")} else {getArray (configFile >> "CfgLoot" >> "Buildings" >> "Default" >> "zombieClass")}; }; // lets create an agent diff --git a/SQF/dayz_code/init/variables.sqf b/SQF/dayz_code/init/variables.sqf index 6a426cb05..212a72478 100644 --- a/SQF/dayz_code/init/variables.sqf +++ b/SQF/dayz_code/init/variables.sqf @@ -660,7 +660,6 @@ if (!isDedicated) then { deathHandled = false; dayz_firstGroup = group player; dayz_originalPlayer = player; - dayz_playerName = "Unknown"; dayz_sourceBleeding = objNull; dayz_clientPreload = false; dayz_authed = false; diff --git a/SQF/dayz_code/system/player_monitor.fsm b/SQF/dayz_code/system/player_monitor.fsm index 71710924a..4fc8599f4 100644 --- a/SQF/dayz_code/system/player_monitor.fsm +++ b/SQF/dayz_code/system/player_monitor.fsm @@ -620,7 +620,6 @@ class FSM " };" \n "};" \n "" \n - "dayz_playerName = name player;" \n "_model call player_switchModel;" \n "" \n "gear_done= true;" \n @@ -1972,7 +1971,7 @@ class FSM "_nearestCity = nearestLocations [getPos player, [""NameCityCapital"",""NameCity"",""NameVillage"",""NameLocal""],1000];" \n "Dayz_logonTown = ""Wilderness"";" \n "if (count _nearestCity > 0) then {Dayz_logonTown = text (_nearestCity select 0)};" \n - "[_world,Dayz_logonTown,format[localize ""str_player_06"",dayz_Survived]] spawn { uiSleep 5; _this spawn BIS_fnc_infoText;};" \n + "[_world,Dayz_logonTown,format[localize ""str_player_06"",dayz_Survived]] spawn {uiSleep 5; _this spawn BIS_fnc_infoText;};" \n "dayz_myPosition = getPosATL player;" \n "Dayz_loginCompleted = true;" \n "" \n diff --git a/SQF/dayz_epoch_b/stringtable.xml b/SQF/dayz_epoch_b/stringtable.xml index 462b80e83..a4f87e5c9 100644 --- a/SQF/dayz_epoch_b/stringtable.xml +++ b/SQF/dayz_epoch_b/stringtable.xml @@ -3901,5 +3901,53 @@ Vous serez automatiquement rejoindre le jeu en %1 secondes. Appuyez sur ESC pour annuler et quitter le hall. Budete auto-zapojit do hry za %1 sekund. Stisknutím klávesy ESC zrušit a nechat lobby. + + radiation + strahlung + излучение + radiación + radiation + záření + + + being crushed + quetsch + раздавливания + ser aplastado + être écrasé + rozdrcení + + + %1 was killed by a zombie + %1 wurde von einem zombie getötet + %1 был убит зомби + %1 murió a manos de un zombi + %1 a été tué par un zombie + %1 byl zabit zombie + + + %1 committed suicide + %1 selbstmord + %1 покончил с собой + %1 se suicidó + %1 suicidé + %1 spáchal sebevraždu + + + %1 died from %2 + %1 starb %2 + %1 умерли от %2 + %1 murió de %2 + %1 %2 de mort + %1 zemřelo %2 + + + %1 was killed by %2 with a %3 from %4m + %1 wurde von %2 mit einer %3 von %4m getötet + %1 был убит %2 с %3 от %4м + %1 murió a manos de %2 con un %3 de %4m + %1 a été tué par %2 avec un %3 de %4m + %1 byl zabit %2 na %3 z %4m + \ No newline at end of file diff --git a/SQF/dayz_server/compile/fnc_plyrHit.sqf b/SQF/dayz_server/compile/fnc_plyrHit.sqf deleted file mode 100644 index 49c44beb5..000000000 --- a/SQF/dayz_server/compile/fnc_plyrHit.sqf +++ /dev/null @@ -1,38 +0,0 @@ -private ["_victim", "_attacker","_weapon","_distance","_damage"]; -_victim = _this select 0; -_attacker = _this select 1; -_damage = _this select 2; - -if (!isPlayer _victim || !isPlayer _attacker) exitWith {}; -if ((owner _victim) == (owner _attacker)) exitWith { - _victim setVariable["AttackedBy", _victim, true]; -}; - -_weapon = weaponState _attacker; -if (!isNil "_weapon") then { - if (count _weapon != 0) then { - if (_weapon select 0 == "Throw") then - { - _weapon = _weapon select 3; - } - else - { - _weapon = _weapon select 0; - }; - }; -}; - -_vehicle = typeOf (vehicle _attacker); -if ((getText (configFile >> "CfgVehicles" >> _vehicle >> "vehicleClass")) in ["CarW","Car","CarD","Armored","Ship","Support","Air","ArmouredW","ArmouredD","SupportWoodland_ACR"]) then { - _weapon = getText (configFile >> "CfgVehicles" >> _vehicle >> "displayName"); -}; - -_distance = _victim distance _attacker; - -diag_log format["PHIT: %1 was hit by %2 with %3 from %4m with %5 dmg", _victim, _attacker, _weapon, _distance, _damage]; - -_victim setVariable["AttackedBy", _attacker, true]; -_victim setVariable["AttackedByName", (name _attacker), true]; -//_victim setVariable["AttackedByWeapon", (currentWeapon _attacker), true]; -_victim setVariable["AttackedByWeapon", _weapon, true]; -_victim setVariable["AttackedFromDistance", _distance, true]; diff --git a/SQF/dayz_server/compile/server_onPlayerDisconnect.sqf b/SQF/dayz_server/compile/server_onPlayerDisconnect.sqf index c957bf82d..8eeb0d785 100644 --- a/SQF/dayz_server/compile/server_onPlayerDisconnect.sqf +++ b/SQF/dayz_server/compile/server_onPlayerDisconnect.sqf @@ -1,106 +1,83 @@ -private ["_invehicle","_isplayernearby","_playerObj","_myGroup","_PUID","_id","_playerUID","_playerName","_characterID","_timeout","_message","_magazines","_playerPos"]; +private ["_playerObj","_myGroup","_playerUID","_playerPos","_playerName","_puid","_timeout","_message"]; + _playerUID = _this select 0; _playerName = _this select 1; _playerObj = nil; _playerPos = []; +//Search all players for the object that matches our playerUID { - _PUID = [_x] call FNC_GetPlayerUID; - if (_PUID == _playerUID) exitWith { _playerObj = _x; _playerPos = getPosATL _playerObj;}; -} count playableUnits; - -if (isNil "_playerObj") then { - diag_log format["nil player object attempting PV, :%1", _this]; - - // fall back to using PV for now so we have a better chance at finding the player - _playerObj = call compile format["PVDZE_player%1",_playerUID]; -}; + _puid = [_x] call FNC_GetPlayerUID; + if (_puid == _playerUID) exitWith {_playerObj = _x; _playerPos = getPosATL _playerObj;}; +} count playableUnits; +//If for some reason the playerObj does not exist, exit the disconnect system. if (isNil "_playerObj") exitWith { diag_log format["%1: nil player object, _this:%2", __FILE__, _this]; }; -_PUID = [_playerObj] call FNC_GetPlayerUID; -diag_log format["get: %1 (%2), sent: %3 (%4)",typeName _PUID, _PUID, typeName _playerUID, _playerUID]; -_characterID = _playerObj getVariable["characterID", "?"]; -_lastDamage = _playerObj getVariable["noatlf4",0]; -_Sepsis = _playerObj getVariable["USEC_Sepsis",false]; +_puid = [_playerObj] call FNC_GetPlayerUID; +diag_log format["get: %1 (%2), sent: %3 (%4)",typeName _puid, _puid, typeName _playerUID, _playerUID]; -if (_characterID != "?") exitwith { - _playerPos = getPosATL _playerObj; - //_characterID = _playerObj getVariable ["CharacterID","0"]; - _timeout = _playerObj getVariable["combattimeout",0]; +//If the playerObj exists run all sync systems +_characterID = _playerObj getVariable ["characterID", "?"]; +_lastDamage = _playerObj getVariable ["noatlf4",0]; +_sepsis = _playerObj getVariable ["USEC_Sepsis",false]; +_lastDamage = round(diag_ticktime - _lastDamage); - //If the player has sepsis before logging off lets give them infected status. - if (_Sepsis) then { - _playerObj setVariable["USEC_infected",true,true]; - }; +//Readded Logout debug info. +diag_log format["Player UID#%1 CID#%2 %3 as %4, logged off at %5%6", + getPlayerUID _playerObj, _characterID, _playerObj call fa_plr2str, typeOf _playerObj, + _playerPos call fa_coor2str, + if ((_lastDamage > 5 && (_lastDamage < 30)) && {(alive _playerObj) && (_playerObj distance (getMarkerpos "respawn_west") >= 2000)}) then {" while in combat ("+str(_lastDamage)+" seconds left)"} else {""} +]; +//Make sure we know the ID of the object before we try and sync any info to the DB +if (_characterID != "?") exitWith { + //If the player has sepsis before logging off give them infected status. + if (_sepsis) then {_playerObj setVariable ["USEC_infected",true,true];}; + //Record Player Login/LogOut [_playerUID,_characterID,2] call dayz_recordLogin; - _invehicle = false; - - if (vehicle _playerObj != _playerObj) then { - _playerObj action ["eject", vehicle _playerObj]; - _invehicle = true; - diag_log format["LOGOUT IN VEHICLE: %1 at location %2", _playerName,(getPosATL _playerObj)]; - }; - + //If the player object is inside a vehicle eject the player. + if (vehicle _playerObj != _playerObj) then {_playerObj action ["eject",vehicle _playerObj];}; + + //Punish combat log + _timeout = _playerObj getVariable["combattimeout",0]; if ((_timeout - time) > 0) then { - - _playerObj setVariable["NORRN_unconscious",true, true]; - _playerObj setVariable["unconsciousTime",150,true]; - - diag_log format["COMBAT LOGGED: %1 (%2) at location %3", _playerName,_timeout,(getPosATL _playerObj)]; - //diag_log format["SET UNCONCIOUSNESS: %1", _playerName]; - - // Message whole server when player combat logs + _playerObj setVariable ["NORRN_unconscious",true,true]; // Set status to unconscious + _playerObj setVariable ["unconsciousTime",150,true]; // Set knock out timer to 150 seconds + //_playerObj setVariable ["USEC_injured",true]; // Set status to bleeding + //_playerObj setVariable ["USEC_BloodQty",3000]; // Set blood to 3000 + diag_log format["PLAYER COMBAT LOGGED: %1(%4) (timeout: %2) at location %3",_playerName,_timeout,_playerPos,_playerUID]; _message = format["PLAYER COMBAT LOGGED: %1",_playerName]; - [nil, nil, rTitleText, _message, "PLAIN"] call RE; + [nil, nil, rTitleText, _message, "PLAIN"] call RE; // Message whole server }; - diag_log format["DISCONNECT: %1 (%2) Object: %3, _characterID: %4 at loc %5", _playerName,_playerUID,_playerObj,_characterID, (getPosATL _playerObj)]; - - _id = [_playerUID,_characterID,2] spawn dayz_recordLogin; - + //If player object is alive sync and remove the body. If ghosting is active add the player id to the array. if (alive _playerObj) then { - - //[_playerObj,nil,true] call server_playerSync; - - _isplayernearby = (DZE_BackpackGuard && !_invehicle && ({(isPlayer _x) && (alive _x)} count (_playerPos nearEntities ["AllVehicles", 5]) > 1)); - - // prevent saving more than 20 magazine items - _magazines = [(magazines _playerObj),20] call array_reduceSize; - - [_playerObj,_magazines,true,true,_isplayernearby] call server_playerSync; - + [_playerObj,nil,true] call server_playerSync; + if (dayz_enableGhosting) then { //diag_log format["GhostPlayers: %1, ActivePlayers: %2",dayz_ghostPlayers,dayz_activePlayers]; - if (!(_playerUID in dayz_ghostPlayers)) then { + if !(_playerUID in dayz_ghostPlayers) then { dayz_ghostPlayers set [count dayz_ghostPlayers, _playerUID]; dayz_activePlayers set [count dayz_activePlayers, [_playerUID,diag_ticktime]]; - //diag_log format["playerID %1 added to ghost list",_playerUID]; }; }; - - // remove player - _playerObj call dayz_removePlayerOnDisconnect; }; - //Update Vehicle - { - [_x,"gear"] call server_updateObject; - } count (nearestObjects [_playerPos, DayZ_GearedObjects, 10]); + + //Scan the area near the player logout position and save all objects. + {[_x,"gear"] call server_updateObject} count (nearestObjects [_playerPos,DayZ_GearedObjects,10]); }; -if (isNull _playerObj) then { diag_log("Player Object does not esist"); }; +if (isNull _playerObj) then {diag_log "server_onPlayerDisconnect called with Null player object";}; - -//Lets remove the object. -if (!isNull _playerObj) then { +//Remove the object. +if (!isNull _playerObj) then { _myGroup = group _playerObj; deleteVehicle _playerObj; deleteGroup _myGroup; -}; - +}; \ No newline at end of file diff --git a/SQF/dayz_server/compile/server_playerDied.sqf b/SQF/dayz_server/compile/server_playerDied.sqf index f9d7ab17c..ddb6b5eb6 100644 --- a/SQF/dayz_server/compile/server_playerDied.sqf +++ b/SQF/dayz_server/compile/server_playerDied.sqf @@ -1,113 +1,76 @@ #include "\z\addons\dayz_server\compile\server_toggle_debug.hpp" -private ["_characterID","_minutes","_newObject","_playerID","_infected","_victim","_victimName","_killer","_killerName","_weapon","_distance","_message","_loc_message","_key","_death_record"]; + +private ["_characterID","_minutes","_newObject","_playerID","_key","_pos","_infected","_killerName","_killerWeapon","_distance","_message","_killerMethod"]; //[unit, weapon, muzzle, mode, ammo, magazine, projectile] -_characterID = _this select 0; -_minutes = _this select 1; -_newObject = _this select 2; -_playerID = _this select 3; -_infected = _this select 4; -_victimName = toString (_this select 5); // Sent as array to avoid publicVariable value restrictions -_victim = _newObject; -_newObject setVariable ["bodyName", _victimName, true]; +_characterID = _this select 0; +_minutes = _this select 1; +_newObject = _this select 2; +_playerID = _this select 3; +_playerName = toString (_this select 4); //Sent as array to avoid publicVariable value restrictions +_infected = _this select 5; +_killerName = toString (_this select 6); +_killerWeapon = toString (_this select 7); +_distance = _this select 8; +_killerMethod = toString (_this select 9); -_killer = _victim getVariable["AttackedBy", "nil"]; -_killerName = _victim getVariable["AttackedByName", "nil"]; - -// when a zombie kills a player _killer, _killerName && _weapon will be "nil" -// we can use this to determine a zombie kill && send a customized message for that. right now no killmsg means it was a zombie. -if ((typeName _killer) != "STRING") then -{ - _weapon = _victim getVariable["AttackedByWeapon", "nil"]; - _distance = _victim getVariable["AttackedFromDistance", "nil"]; - - if ((owner _victim) == (owner _killer)) then - { - _message = format["%1 killed himself",_victimName]; - _loc_message = format["PKILL: %1 killed himself", _victimName]; - } - else - { - _message = format["%1 was killed by %2 with weapon %3 from %4m",_victimName, _killerName, _weapon, _distance]; - _loc_message = format["PKILL: %1 was killed by %2 with weapon %3 from %4m", _victimName, _killerName, _weapon, _distance]; - }; - - diag_log _loc_message; - - if(DZE_DeathMsgGlobal) then { - [nil, nil, rspawn, [_killer, _message], { (_this select 0) globalChat (_this select 1) }] call RE; - }; - /* needs customRemoteMessage - if(DZE_DeathMsgGlobal) then { - customRemoteMessage = ['globalChat', _message, _killer]; - publicVariable "customRemoteMessage"; - }; - */ - if(DZE_DeathMsgSide) then { - [nil, nil, rspawn, [_killer, _message], { (_this select 0) sideChat (_this select 1) }] call RE; - }; - if(DZE_DeathMsgTitleText) then { - [nil,nil,"per",rTITLETEXT,_message,"PLAIN DOWN"] call RE; - }; - - // build array to store death messages to allow viewing at message board in trader citys. - _death_record = [ - _victimName, - _killerName, - _weapon, - _distance, - ServerCurrentTime - ]; - PlayerDeaths set [count PlayerDeaths,_death_record]; - - // Cleanup - _victim setVariable["AttackedBy", "nil", true]; - _victim setVariable["AttackedByName", "nil", true]; - _victim setVariable["AttackedByWeapon", "nil", true]; - _victim setVariable["AttackedFromDistance", "nil", true]; -}; - -// Might not be the best way... -/* -if (isnil "dayz_disco") then { - dayz_disco = []; -}; -*/ +//Mark player as dead so we bypass the ghost system dayz_died set [count dayz_died, _playerID]; -// dayz_disco = dayz_disco - [_playerID]; -_newObject setVariable["processedDeath",diag_tickTime]; -_newObject setVariable ["bodyName", _victimName, true]; +_newObject setVariable ["processedDeath",diag_tickTime]; +_newObject setVariable ["bodyName",_playerName,true]; _pos = getPosATL _newObject; -if (_pos select 2 < 0.1) then { _pos set [2,0]; }; -_newObject setVariable [ "deathPos", _pos]; -if (typeName _minutes == "STRING") then -{ - _minutes = parseNumber _minutes; -}; +// force to follow the terrain slope in sched_corpses.sqf +if (_pos select 2 < 0.1) then {_pos set [2,0];}; +_newObject setVariable ["deathPos",_pos]; -diag_log ("PDEATH: Player Died " + _playerID); +if (typeName _minutes == "STRING") then {_minutes = parseNumber _minutes;}; -if (_characterID != "0") then -{ +if (_characterID != "0") then { _key = format["CHILD:202:%1:%2:%3:",_characterID,_minutes,_infected]; - #ifdef DZE_SERVER_DEBUG_HIVE - diag_log ("HIVE: WRITE: "+ str(_key)); - #endif + //diag_log ("HIVE: WRITE: "+ str(_key)); _key call server_hiveWrite; -} -else -{ - deleteVehicle _newObject; }; + #ifdef PLAYER_DEBUG diag_log format ["Player UID#%3 CID#%4 %1 as %5 died at %2", - _newObject call fa_plr2str, (getPosATL _newObject) call fa_coor2str, + _newObject call fa_plr2str, _pos call fa_coor2str, getPlayerUID _newObject,_characterID, typeOf _newObject ]; #endif + + +// EPOCH DEATH MESSAGES +if (_killerWeapon == "Throw") then {_killerWeapon = "Grenade";}; +if (_killerMethod in ["starve","dehyd","sick","bled","crushed","rad","zombie"]) then { + if (_killerMethod == "zombie") then { + _message = format[localize "str_player_death_zombie",_playerName]; + } else { + _methodStr = localize format["str_death_%1",_killerMethod]; + _message = format[localize "str_player_death_message",_playerName,_methodStr]; + }; +} else { + if (_killerName == _playerName) then { + _message = format[localize "str_player_death_suicide",_playerName]; + } else { + _message = format[localize "str_player_death_killed",_playerName,_killerName,_killerWeapon,_distance]; + }; +}; + +if ((_killerWeapon != "unknown weapon") or {_killerMethod != "unknown"} or {_killerName != "unknown"}) then { + diag_log _message; + //if (DZE_DeathMsgGlobal) then {customRemoteMessage = ['globalChat',_message,_newObject]; publicVariable "customRemoteMessage";}; + if (DZE_DeathMsgGlobal) then {[nil,nil,rspawn,[_newObject,_message],{(_this select 0) globalChat (_this select 1)}] call RE;}; + if (DZE_DeathMsgSide) then {[nil,nil,rspawn,[_newObject,_message],{(_this select 0) sideChat (_this select 1)}] call RE;}; + if (DZE_DeathMsgTitleText) then {[nil,nil,"per",rTITLETEXT,_message,"PLAIN DOWN"] call RE;}; + + // Store death messages to allow viewing at message board in trader citys. + PlayerDeaths set [count PlayerDeaths,[_playerName,_killerName,_killerWeapon,_distance,ServerCurrentTime]]; +}; + + _newObject setDamage 1; _newObject setOwner 0; //dead_bodyCleanup set [count dead_bodyCleanup,_newObject]; \ No newline at end of file diff --git a/SQF/dayz_server/compile/server_playerSetup.sqf b/SQF/dayz_server/compile/server_playerSetup.sqf index 797e984ab..834eedbec 100644 --- a/SQF/dayz_server/compile/server_playerSetup.sqf +++ b/SQF/dayz_server/compile/server_playerSetup.sqf @@ -12,10 +12,6 @@ if (isNull _playerObj) exitWith { diag_log ("SETUP INIT FAILED: Exiting, player object null: " + str(_playerObj)); }; -//Add MPHit event handler -// diag_log("Adding MPHit EH for " + str(_playerObj)); -//_playerObj addMPEventHandler ["MPHit", {_this spawn fnc_plyrHit;}]; - if (_playerID == "") then { _playerID = [_playerObj] call FNC_GetPlayerUID; }; diff --git a/SQF/dayz_server/compile/server_playerSync.sqf b/SQF/dayz_server/compile/server_playerSync.sqf index 41dab46b0..a43b4bba4 100644 --- a/SQF/dayz_server/compile/server_playerSync.sqf +++ b/SQF/dayz_server/compile/server_playerSync.sqf @@ -1,4 +1,4 @@ -private ["_empty","_name","_playerwasNearby","_character","_magazines","_force","_characterID","_charPos","_isInVehicle","_timeSince","_humanity","_debug","_distance","_isNewMed","_isNewPos","_isNewGear","_playerPos","_playerGear","_playerBackp","_medical","_distanceFoot","_lastPos","_backpack","_kills","_killsB","_killsH","_headShots","_lastTime","_timeGross","_timeLeft","_currentWpn","_currentAnim","_config","_onLadder","_isTerminal","_currentModel","_modelChk","_muzzles","_temp","_currentState","_array","_key","_pos","_forceGear","_friendlies"]; +private ["_name","_character","_magazines","_force","_characterID","_charPos","_isInVehicle","_timeSince","_humanity","_debug","_distance","_isNewMed","_isNewPos","_isNewGear","_playerPos","_playerGear","_playerBackp","_medical","_distanceFoot","_lastPos","_backpack","_kills","_killsB","_killsH","_headShots","_lastTime","_timeGross","_timeLeft","_currentWpn","_currentAnim","_config","_onLadder","_isTerminal","_currentModel","_modelChk","_muzzles","_temp","_currentState","_array","_key","_pos","_forceGear","_friendlies"]; _character = _this select 0; @@ -9,11 +9,6 @@ _Achievements = _character getVariable "Achievements"; //_force = _this select 2; _forceGear = _this select 3; _force = true; -_playerwasNearby = false; - -if ((count _this) > 4) then { - _playerwasNearby = _this select 4; -}; if (isNull _character) exitWith { diag_log ("Player is Null FAILED: Exiting, player sync: " + str(_character)); @@ -107,12 +102,7 @@ if (_characterID != "0") then { _playerGear = [weapons _character,_magazines]; //diag_log ("playerGear: " +str(_playerGear)); _backpack = unitBackpack _character; - if(_playerwasNearby) then { - _empty = [[],[]]; - _playerBackp = [typeOf _backpack,_empty,_empty]; - } else { - _playerBackp = [typeOf _backpack,getWeaponCargo _backpack,getMagazineCargo _backpack]; - }; + _playerBackp = [typeOf _backpack,getWeaponCargo _backpack,getMagazineCargo _backpack]; }; if (_isNewMed || _force) then { diff --git a/SQF/dayz_server/init/Epoch_Init.sqf b/SQF/dayz_server/init/Epoch_Init.sqf index 018b0f999..9397bd1c8 100644 --- a/SQF/dayz_server/init/Epoch_Init.sqf +++ b/SQF/dayz_server/init/Epoch_Init.sqf @@ -627,16 +627,6 @@ dayz_perform_purge_player = { // _this = nil; }; - -dayz_removePlayerOnDisconnect = { - if(!isNull(_this)) then { - _group = group _this; - _this removeAllMPEventHandlers "mphit"; - deleteVehicle _this; - deleteGroup (group _this); - }; -}; - server_timeSync = { //Send request private ["_hour","_minute","_date","_key","_result","_outcome"]; diff --git a/SQF/dayz_server/init/server_functions.sqf b/SQF/dayz_server/init/server_functions.sqf index 79c82ba2f..ab5a64389 100644 --- a/SQF/dayz_server/init/server_functions.sqf +++ b/SQF/dayz_server/init/server_functions.sqf @@ -27,7 +27,6 @@ server_playerSync = compile preprocessFileLineNumbers "\z\addons\dayz_server\ //server_spawnCrashSite = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\server_spawnCrashSite.sqf"; server_spawnEvents = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\server_spawnEvent.sqf"; //server_weather = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\server_weather.sqf"; -fnc_plyrHit = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\fnc_plyrHit.sqf"; server_deaths = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\server_playerDeaths.sqf"; server_maintainArea = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\server_maintainArea.sqf"; zombie_findOwner = compile preprocessFileLineNumbers "\z\addons\dayz_server\compile\zombie_findOwner.sqf";