mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 18:51:29 +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.");
|
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) {
|
else if (sep->arg[1][0] == 0 || strcasecmp(sep->arg[1], "help") == 0) {
|
||||||
c->Message(Chat::White, "#Corpse Sub-Commands:");
|
c->Message(Chat::White, "#Corpse Sub-Commands:");
|
||||||
c->Message(Chat::White, " DeleteNPCCorpses");
|
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, " ListNPC");
|
||||||
c->Message(Chat::White, " ListPlayer");
|
c->Message(Chat::White, " ListPlayer");
|
||||||
c->Message(Chat::White, " Lock - GM locks the corpse - cannot be looted by non-GM");
|
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, " UnLock");
|
||||||
c->Message(Chat::White, " RemoveCash");
|
c->Message(Chat::White, " RemoveCash");
|
||||||
c->Message(Chat::White, " InspectLoot");
|
c->Message(Chat::White, " InspectLoot");
|
||||||
|
|||||||
@ -826,22 +826,7 @@ bool Corpse::Process() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (corpse_graveyard_timer.Check()) {
|
if (corpse_graveyard_timer.Check()) {
|
||||||
if (zone->HasGraveyard()) {
|
MovePlayerCorpseToGraveyard();
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
corpse_graveyard_timer.Disable();
|
corpse_graveyard_timer.Disable();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1643,3 +1628,53 @@ void Corpse::LoadPlayerCorpseDecayTime(uint32 corpse_db_id){
|
|||||||
corpse_graveyard_timer.SetTimer(3000);
|
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 SetConsentGuildID(uint32 guild_id) { if (IsPlayerCorpse()) { consented_guild_id = guild_id; } }
|
||||||
void AddConsentName(std::string consent_player_name);
|
void AddConsentName(std::string consent_player_name);
|
||||||
void RemoveConsentName(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 Delete();
|
||||||
void Bury();
|
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 UpdateAllTraps(bool respawn, bool repopnow = false);
|
||||||
void ClearTrapPointers();
|
void ClearTrapPointers();
|
||||||
|
|
||||||
|
int MovePlayerCorpsesToGraveyard(bool force_move_from_instance = false);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Zone;
|
friend class Zone;
|
||||||
void Depop(bool StartSpawnTimer = false);
|
void Depop(bool StartSpawnTimer = false);
|
||||||
|
|||||||
@ -1497,7 +1497,10 @@ bool Zone::Process() {
|
|||||||
{
|
{
|
||||||
expedition->RemoveAllMembers(false); // entity list will teleport clients out immediately
|
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();
|
entity_list.GateAllClientsToSafeReturn();
|
||||||
database.DeleteInstance(GetInstanceID());
|
database.DeleteInstance(GetInstanceID());
|
||||||
Instance_Shutdown_Timer = new Timer(20000); //20 seconds
|
Instance_Shutdown_Timer = new Timer(20000); //20 seconds
|
||||||
|
|||||||
@ -4300,6 +4300,18 @@ uint32 ZoneDatabase::SendCharacterCorpseToGraveyard(uint32 dbid, uint32 zone_id,
|
|||||||
return dbid;
|
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){
|
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);
|
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);
|
auto results = QueryDatabase(query);
|
||||||
|
|||||||
@ -376,6 +376,7 @@ public:
|
|||||||
uint32 GetCharacterCorpseID(uint32 char_id, uint8 corpse);
|
uint32 GetCharacterCorpseID(uint32 char_id, uint8 corpse);
|
||||||
uint32 GetCharacterCorpseItemAt(uint32 corpse_id, uint16 slotid);
|
uint32 GetCharacterCorpseItemAt(uint32 corpse_id, uint16 slotid);
|
||||||
uint32 GetPlayerCorpseTimeLeft(uint8 corpse, uint8 type);
|
uint32 GetPlayerCorpseTimeLeft(uint8 corpse, uint8 type);
|
||||||
|
void SendCharacterCorpseToNonInstance(uint32 corpse_db_id);
|
||||||
|
|
||||||
/* Faction */
|
/* Faction */
|
||||||
bool GetNPCFactionList(uint32 npcfaction_id, int32* faction_id, int32* value, uint8* temp, int32* primary_faction = 0);
|
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