Move player corpses on instance shutdown

Moves corpses to graveyard when an expired instance shuts down.
Zones without a graveyard move them to non-instance version instead.

Fixes player corpses being left inside instances that expire
before graveyards process or in instances without a graveyard
This commit is contained in:
hg
2021-01-02 19:19:31 -05:00
parent de5b7f472d
commit 6c8c81f3db
8 changed files with 118 additions and 17 deletions
+51 -16
View File
@@ -826,22 +826,7 @@ bool Corpse::Process() {
}
if (corpse_graveyard_timer.Check()) {
if (zone->HasGraveyard()) {
Save();
player_corpse_depop = true;
database.SendCharacterCorpseToGraveyard(corpse_db_id, zone->graveyard_zoneid(),
(zone->GetZoneID() == zone->graveyard_zoneid()) ? zone->GetInstanceID() : 0, zone->GetGraveyardPoint());
corpse_graveyard_timer.Disable();
auto pack = new ServerPacket(ServerOP_SpawnPlayerCorpse, sizeof(SpawnPlayerCorpse_Struct));
SpawnPlayerCorpse_Struct* spc = (SpawnPlayerCorpse_Struct*)pack->pBuffer;
spc->player_corpse_id = corpse_db_id;
spc->zone_id = zone->graveyard_zoneid();
worldserver.SendPacket(pack);
safe_delete(pack);
LogDebug("Moved [{}] player corpse to the designated graveyard in zone [{}]", this->GetName(), ZoneName(zone->graveyard_zoneid()));
corpse_db_id = 0;
}
MovePlayerCorpseToGraveyard();
corpse_graveyard_timer.Disable();
return false;
}
@@ -1643,3 +1628,53 @@ void Corpse::LoadPlayerCorpseDecayTime(uint32 corpse_db_id){
corpse_graveyard_timer.SetTimer(3000);
}
}
void Corpse::SendWorldSpawnPlayerCorpseInZone(uint32_t zone_id)
{
auto pack = std::unique_ptr<ServerPacket>(new ServerPacket(ServerOP_SpawnPlayerCorpse, sizeof(SpawnPlayerCorpse_Struct)));
SpawnPlayerCorpse_Struct* spc = reinterpret_cast<SpawnPlayerCorpse_Struct*>(pack->pBuffer);
spc->player_corpse_id = corpse_db_id;
spc->zone_id = zone_id;
worldserver.SendPacket(pack.get());
}
bool Corpse::MovePlayerCorpseToGraveyard()
{
if (IsPlayerCorpse() && zone && zone->HasGraveyard())
{
Save();
uint16_t instance_id = (zone->GetZoneID() == zone->graveyard_zoneid()) ? zone->GetInstanceID() : 0;
database.SendCharacterCorpseToGraveyard(corpse_db_id, zone->graveyard_zoneid(), instance_id, zone->GetGraveyardPoint());
SendWorldSpawnPlayerCorpseInZone(zone->graveyard_zoneid());
corpse_db_id = 0;
player_corpse_depop = true;
corpse_graveyard_timer.Disable();
LogDebug("Moved [{}] player corpse to the designated graveyard in zone [{}]", GetName(), ZoneName(zone->graveyard_zoneid()));
return true;
}
return false;
}
bool Corpse::MovePlayerCorpseToNonInstance()
{
if (IsPlayerCorpse() && zone && zone->GetInstanceID() != 0)
{
Save();
database.SendCharacterCorpseToNonInstance(corpse_db_id);
SendWorldSpawnPlayerCorpseInZone(zone->GetZoneID());
corpse_db_id = 0;
player_corpse_depop = true;
corpse_graveyard_timer.Disable();
LogDebug("Moved [{}] player corpse to non-instance version of zone [{}]", GetName(), ZoneName(zone->GetZoneID()));
return true;
}
return false;
}