From 80bbe029d49baa919f30aede609c5cca107ca0e2 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Sat, 15 Sep 2018 11:14:39 +0200 Subject: [PATCH] =?UTF-8?q?Core/Unit:=20Erm,=20so=20it=20turns=20out=20tha?= =?UTF-8?q?t=20releasing=20your=20spirit=20actually=20n=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …ever set your death state to DEAD. It stayed as CORPSE. That's wrong, of course, but we didn't notice because zombie corpses (see f50a8e5). Zombie corpses are gone, so now it caused a bug. That's fixed too. Closes #21873. (Finally.) --- src/server/game/Entities/Player/Player.cpp | 12 ++++++++---- src/server/game/Handlers/CharacterHandler.cpp | 18 ++++++++---------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 6a728510e0..9a9e17824b 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -4559,6 +4559,7 @@ void Player::BuildPlayerRepop() GetMap()->AddToMap(corpse); // convert player body to ghost + setDeathState(DEAD); SetHealth(1); SetWaterWalking(true); @@ -17722,6 +17723,10 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder* holder) GetSpellHistory()->LoadFromDB(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SPELL_COOLDOWNS)); + uint32 savedHealth = fields[55].GetUInt32(); + if (!savedHealth) + m_deathState = CORPSE; + // Spell code allow apply any auras to dead character in load time in aura/spell/item loading // Do now before stats re-calculation cleanup for ghost state unexpected auras if (!IsAlive()) @@ -17734,7 +17739,6 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder* holder) UpdateAllStats(); // restore remembered power/health values (but not more max values) - uint32 savedHealth = fields[51].GetUInt32(); SetHealth(savedHealth > GetMaxHealth() ? GetMaxHealth() : savedHealth); uint32 loadedPowers = 0; for (uint32 i = 0; i < MAX_POWERS; ++i) @@ -18064,14 +18068,14 @@ void Player::LoadCorpse(PreparedQueryResult result) if (!IsAlive()) { - if (result && !HasAtLoginFlag(AT_LOGIN_RESURRECT)) + if (HasAtLoginFlag(AT_LOGIN_RESURRECT)) + ResurrectPlayer(0.5f); + else if (result) { Field* fields = result->Fetch(); _corpseLocation.WorldRelocate(fields[0].GetUInt16(), fields[1].GetFloat(), fields[2].GetFloat(), fields[3].GetFloat(), fields[4].GetFloat()); ApplyModByteFlag(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTES_OFFSET_FLAGS, PLAYER_FIELD_BYTE_RELEASE_TIMER, !sMapStore.LookupEntry(_corpseLocation.GetMapId())->Instanceable()); } - else - ResurrectPlayer(0.5f); } RemoveAtLoginFlag(AT_LOGIN_RESURRECT); diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index b34b3d295f..d0d0077633 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -983,17 +983,8 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) pCurrChar->LoadCorpse(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION)); // setting Ghost+speed if dead - if (pCurrChar->m_deathState != ALIVE) - { - // not blizz like, we must correctly save and load player instead... - if (pCurrChar->getRace() == RACE_NIGHTELF && !pCurrChar->HasAura(20584)) - pCurrChar->CastSpell(pCurrChar, 20584, true, 0);// auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form) - - if (!pCurrChar->HasAura(8326)) - pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) - + if (pCurrChar->m_deathState == DEAD) pCurrChar->SetWaterWalking(true); - } pCurrChar->ContinueTaxiFlight(); @@ -1135,6 +1126,13 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) // Handle Login-Achievements (should be handled after loading) _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN, 1); + // if we're loading a dead player, repop them to the GY after the load is finished + if (pCurrChar->getDeathState() == CORPSE) + { + pCurrChar->BuildPlayerRepop(); + pCurrChar->RepopAtGraveyard(); + } + sScriptMgr->OnPlayerLogin(pCurrChar, firstLogin); TC_METRIC_EVENT("player_events", "Login", pCurrChar->GetName());