mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 14:41:28 +00:00
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:
parent
de5b7f472d
commit
6c8c81f3db
@ -4840,6 +4840,10 @@ void command_corpse(Client *c, const Seperator *sep)
|
||||
c->Message(Chat::White, "Insufficient status to depop player corpse.");
|
||||
|
||||
}
|
||||
else if (strcasecmp(sep->arg[1], "moveallgraveyard") == 0) {
|
||||
int count = entity_list.MovePlayerCorpsesToGraveyard(true);
|
||||
c->Message(Chat::White, "Moved [%d] player corpse(s) to zone graveyard", count);
|
||||
}
|
||||
else if (sep->arg[1][0] == 0 || strcasecmp(sep->arg[1], "help") == 0) {
|
||||
c->Message(Chat::White, "#Corpse Sub-Commands:");
|
||||
c->Message(Chat::White, " DeleteNPCCorpses");
|
||||
@ -4847,6 +4851,7 @@ void command_corpse(Client *c, const Seperator *sep)
|
||||
c->Message(Chat::White, " ListNPC");
|
||||
c->Message(Chat::White, " ListPlayer");
|
||||
c->Message(Chat::White, " Lock - GM locks the corpse - cannot be looted by non-GM");
|
||||
c->Message(Chat::White, " MoveAllGraveyard - move all player corpses to zone's graveyard or non-instance");
|
||||
c->Message(Chat::White, " UnLock");
|
||||
c->Message(Chat::White, " RemoveCash");
|
||||
c->Message(Chat::White, " InspectLoot");
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -79,6 +79,9 @@ class Corpse : public Mob {
|
||||
void SetConsentGuildID(uint32 guild_id) { if (IsPlayerCorpse()) { consented_guild_id = guild_id; } }
|
||||
void AddConsentName(std::string consent_player_name);
|
||||
void RemoveConsentName(std::string consent_player_name);
|
||||
void SendWorldSpawnPlayerCorpseInZone(uint32_t zone_id);
|
||||
bool MovePlayerCorpseToGraveyard();
|
||||
bool MovePlayerCorpseToNonInstance();
|
||||
|
||||
void Delete();
|
||||
void Bury();
|
||||
|
||||
@ -5225,3 +5225,43 @@ void EntityList::GateAllClientsToSafeReturn()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int EntityList::MovePlayerCorpsesToGraveyard(bool force_move_from_instance)
|
||||
{
|
||||
if (!zone)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int moved_count = 0;
|
||||
|
||||
for (auto it = corpse_list.begin(); it != corpse_list.end();)
|
||||
{
|
||||
bool moved = false;
|
||||
if (it->second && it->second->IsPlayerCorpse())
|
||||
{
|
||||
if (zone->HasGraveyard())
|
||||
{
|
||||
moved = it->second->MovePlayerCorpseToGraveyard();
|
||||
}
|
||||
else if (force_move_from_instance && zone->GetInstanceID() != 0)
|
||||
{
|
||||
moved = it->second->MovePlayerCorpseToNonInstance();
|
||||
}
|
||||
}
|
||||
|
||||
if (moved)
|
||||
{
|
||||
safe_delete(it->second);
|
||||
free_ids.push(it->first);
|
||||
it = corpse_list.erase(it);
|
||||
++moved_count;
|
||||
}
|
||||
else
|
||||
{
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
return moved_count;
|
||||
}
|
||||
|
||||
@ -537,6 +537,8 @@ public:
|
||||
void UpdateAllTraps(bool respawn, bool repopnow = false);
|
||||
void ClearTrapPointers();
|
||||
|
||||
int MovePlayerCorpsesToGraveyard(bool force_move_from_instance = false);
|
||||
|
||||
protected:
|
||||
friend class Zone;
|
||||
void Depop(bool StartSpawnTimer = false);
|
||||
|
||||
@ -1497,7 +1497,10 @@ bool Zone::Process() {
|
||||
{
|
||||
expedition->RemoveAllMembers(false); // entity list will teleport clients out immediately
|
||||
}
|
||||
// todo: move corpses to non-instanced version of dz at same coords (if no graveyard)
|
||||
|
||||
// instance shutting down, move corpses to graveyard or non-instanced zone at same coords
|
||||
entity_list.MovePlayerCorpsesToGraveyard(true);
|
||||
|
||||
entity_list.GateAllClientsToSafeReturn();
|
||||
database.DeleteInstance(GetInstanceID());
|
||||
Instance_Shutdown_Timer = new Timer(20000); //20 seconds
|
||||
|
||||
@ -4300,6 +4300,18 @@ uint32 ZoneDatabase::SendCharacterCorpseToGraveyard(uint32 dbid, uint32 zone_id,
|
||||
return dbid;
|
||||
}
|
||||
|
||||
void ZoneDatabase::SendCharacterCorpseToNonInstance(uint32 corpse_db_id)
|
||||
{
|
||||
if (corpse_db_id != 0)
|
||||
{
|
||||
auto query = fmt::format(SQL(
|
||||
UPDATE character_corpses SET instance_id = 0 WHERE id = {};
|
||||
), corpse_db_id);
|
||||
|
||||
QueryDatabase(query);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 ZoneDatabase::GetCharacterCorpseDecayTimer(uint32 corpse_db_id){
|
||||
std::string query = StringFormat("SELECT(UNIX_TIMESTAMP() - UNIX_TIMESTAMP(time_of_death)) FROM `character_corpses` WHERE `id` = %d AND NOT `time_of_death` = 0", corpse_db_id);
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
@ -376,6 +376,7 @@ public:
|
||||
uint32 GetCharacterCorpseID(uint32 char_id, uint8 corpse);
|
||||
uint32 GetCharacterCorpseItemAt(uint32 corpse_id, uint16 slotid);
|
||||
uint32 GetPlayerCorpseTimeLeft(uint8 corpse, uint8 type);
|
||||
void SendCharacterCorpseToNonInstance(uint32 corpse_db_id);
|
||||
|
||||
/* Faction */
|
||||
bool GetNPCFactionList(uint32 npcfaction_id, int32* faction_id, int32* value, uint8* temp, int32* primary_faction = 0);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user