From 77c0eb3998cafb1406c3e893aca583965261b92d Mon Sep 17 00:00:00 2001 From: Alex King <89047260+Kinglykrab@users.noreply.github.com> Date: Sat, 13 Jan 2024 01:02:44 -0500 Subject: [PATCH] [Character] Convert Character Corpses to Repositories (#3941) * asdsa * Final push * Update character_corpses_repository.h * Update character_corpses_repository.h * Update zonedb.cpp * Update zonedb.cpp * Final push * Update character_corpses_repository.h --- .../base_character_corpse_items_repository.h | 1 + .../base/base_character_corpses_repository.h | 1 + .../character_corpses_repository.h | 173 ++- common/shareddb.cpp | 34 +- common/shareddb.h | 2 +- world/adventure.cpp | 69 +- zone/client.h | 2 +- zone/client_packet.cpp | 129 ++- zone/client_process.cpp | 2 +- zone/corpse.cpp | 4 +- zone/embparser_api.cpp | 10 +- zone/gm_commands/show/buried_corpse_count.cpp | 2 +- zone/lua_client.cpp | 4 +- zone/lua_client.h | 2 +- zone/lua_general.cpp | 12 +- zone/perl_client.cpp | 2 +- zone/questmgr.cpp | 23 +- zone/questmgr.h | 6 +- zone/zonedb.cpp | 1021 ++++++++--------- zone/zonedb.h | 51 +- 20 files changed, 819 insertions(+), 731 deletions(-) diff --git a/common/repositories/base/base_character_corpse_items_repository.h b/common/repositories/base/base_character_corpse_items_repository.h index 13bdc483d..a7689c6eb 100644 --- a/common/repositories/base/base_character_corpse_items_repository.h +++ b/common/repositories/base/base_character_corpse_items_repository.h @@ -16,6 +16,7 @@ #include "../../strings.h" #include + class BaseCharacterCorpseItemsRepository { public: struct CharacterCorpseItems { diff --git a/common/repositories/base/base_character_corpses_repository.h b/common/repositories/base/base_character_corpses_repository.h index ec8c7e53d..ea666ebfe 100644 --- a/common/repositories/base/base_character_corpses_repository.h +++ b/common/repositories/base/base_character_corpses_repository.h @@ -16,6 +16,7 @@ #include "../../strings.h" #include + class BaseCharacterCorpsesRepository { public: struct CharacterCorpses { diff --git a/common/repositories/character_corpses_repository.h b/common/repositories/character_corpses_repository.h index c228b15e1..910e4021e 100644 --- a/common/repositories/character_corpses_repository.h +++ b/common/repositories/character_corpses_repository.h @@ -1,6 +1,7 @@ #ifndef EQEMU_CHARACTER_CORPSES_REPOSITORY_H #define EQEMU_CHARACTER_CORPSES_REPOSITORY_H +#include #include "../database.h" #include "../strings.h" #include "base/base_character_corpses_repository.h" @@ -44,29 +45,191 @@ public: */ // Custom extended repository methods here - static int BuryInstance(Database& db, uint16 instance_id) { + static int BuryCorpse(Database& db, uint32 corpse_id) + { auto results = db.QueryDatabase( fmt::format( - "UPDATE {} SET is_buried = 1, instance_id = 0 WHERE instance_id = {}", + "UPDATE `{}` SET `is_buried` = 1 WHERE `{}` = {}", + TableName(), + PrimaryKey(), + corpse_id + ) + ); + + return results.Success() ? results.RowsAffected() : 0; + } + + static int BuryDecayedCorpses(Database& db) + { + auto results = db.QueryDatabase( + fmt::format( + "UPDATE `{}` SET `is_buried` = 1 WHERE `is_buried` = 0 AND (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(time_of_death)) > {} AND time_of_death != 0", + TableName(), + RuleI(Character, CorpseDecayTimeMS) / 1000 + ) + ); + + return results.Success() ? results.RowsAffected() : 0; + } + + static int BuryInstance(Database& db, uint16 instance_id) + { + auto results = db.QueryDatabase( + fmt::format( + "UPDATE `{}` SET is_buried = 1, instance_id = 0 WHERE instance_id = {}", TableName(), instance_id ) ); - return (results.Success() ? results.RowsAffected() : 0); + return results.Success() ? results.RowsAffected() : 0; } static int BuryInstances(Database& db, const std::string& joined_instance_ids) { auto results = db.QueryDatabase( fmt::format( - "UPDATE {} SET is_buried = 1, instance_id = 0 WHERE instance_id IN ({})", + "UPDATE `{}` SET is_buried = 1, instance_id = 0 WHERE instance_id IN ({})", TableName(), joined_instance_ids ) ); - return (results.Success() ? results.RowsAffected() : 0); + return results.Success() ? results.RowsAffected() : 0; + } + + static uint32 GetDecayTimer(Database& db, uint32 corpse_id) + { + auto results = db.QueryDatabase( + fmt::format( + "SELECT (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(time_of_death)) FROM `{}` WHERE `{}` = {} AND `time_of_death` != 0", + TableName(), + PrimaryKey(), + corpse_id + ) + ); + + if (!results.Success() || !results.RowCount()) { + return 0; + } + + auto row = results.begin(); + + return Strings::ToUnsignedInt(row[0]); + } + + static uint32 ResurrectCorpse(Database& db, uint32 corpse_id) + { + auto results = db.QueryDatabase( + fmt::format( + "UPDATE `{}` SET `is_rezzed` = 1 WHERE `{}` = {}", + TableName(), + PrimaryKey(), + corpse_id + ) + ); + + return results.Success() ? results.RowsAffected() : 0; + } + + static void SendAdventureCorpsesToGraveyard( + Database& db, + uint32 graveyard_zone_id, + uint16 instance_id, + const glm::vec4& position + ) + { + db.QueryDatabase( + fmt::format( + "UPDATE `{}` SET `zone_id` = {}, `instance_id` = 0, `x` = {:.2f}, `y` = {:.2f}, `z` = {:.2f}`, `heading` = {:.2f}, `was_at_graveyard` = 1 WHERE `instance_id` = {}", + TableName(), + graveyard_zone_id, + position.x, + position.y, + position.z, + position.w, + instance_id + ) + ); + } + + static int SendToGraveyard( + Database& db, + uint32 corpse_id, + uint32 zone_id, + uint16 instance_id, + const glm::vec4& position + ) + { + db.QueryDatabase( + fmt::format( + "UPDATE `{}` SET `zone_id` = {}, `instance_id` = {}, `x` = {:.2f}, `y` = {:.2f}, `z` = {:.2f}`, `heading` = {:.2f}, `was_at_graveyard` = 1 WHERE `{}` = {}", + TableName(), + zone_id, + instance_id, + position.x, + position.y, + position.z, + position.w, + PrimaryKey(), + corpse_id + ) + ); + + return corpse_id; + } + + static void SendToNonInstance(Database& db, uint32 corpse_id) + { + db.QueryDatabase( + fmt::format( + "UPDATE `{}` SET `instance_id` = 0 WHERE `{}` = {}", + TableName(), + PrimaryKey(), + corpse_id + ) + ); + } + + static uint32 SetGuildConsentID(Database& db, uint32 character_id, uint32 guild_consent_id) + { + auto results = db.QueryDatabase( + fmt::format( + "UPDATE `{}` SET `guild_consent_id` = {} WHERE `charid` = {}", + TableName(), + guild_consent_id, + character_id + ) + ); + + return results.Success() ? results.RowsAffected() : 0; + } + + static int UnburyCorpse( + Database& db, + uint32 corpse_id, + uint32 zone_id, + uint16 instance_id, + const glm::vec4& position + ) + { + auto results = db.QueryDatabase( + fmt::format( + "UPDATE `{}` SET `is_buried` = 0, `zone_id` = {}, `instance_id` = {}, `x` = {:.2f}, `y` = {:.2f}, `z` = {:.2f}, `heading` = {:.2f}, `time_of_death` = {}, `was_at_graveyard` = 0 WHERE `{}` = {}", + TableName(), + zone_id, + instance_id, + position.x, + position.y, + position.z, + position.w, + std::time(nullptr), + PrimaryKey(), + corpse_id + ) + ); + + return results.Success() ? results.RowsAffected() : 0; } }; diff --git a/common/shareddb.cpp b/common/shareddb.cpp index ebf07027f..84b68ebfa 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -45,6 +45,7 @@ #include "path_manager.h" #include "repositories/loottable_repository.h" #include "repositories/character_item_recast_repository.h" +#include "repositories/character_corpses_repository.h" namespace ItemField { @@ -1667,27 +1668,18 @@ EQ::ItemInstance* SharedDatabase::CreateBaseItem(const EQ::ItemData* item, int16 return inst; } -int32 SharedDatabase::DeleteStalePlayerCorpses() { - if(RuleB(Zone, EnableShadowrest)) { - const std::string query = StringFormat( - "UPDATE `character_corpses` SET `is_buried` = 1 WHERE `is_buried` = 0 AND " - "(UNIX_TIMESTAMP() - UNIX_TIMESTAMP(time_of_death)) > %d AND NOT time_of_death = 0", - (RuleI(Character, CorpseDecayTimeMS) / 1000)); - const auto results = QueryDatabase(query); - if (!results.Success()) - return -1; - - return results.RowsAffected(); - } - - const std::string query = StringFormat( - "DELETE FROM `character_corpses` WHERE (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(time_of_death)) > %d " - "AND NOT time_of_death = 0", (RuleI(Character, CorpseDecayTimeMS) / 1000)); - const auto results = QueryDatabase(query); - if (!results.Success()) - return -1; - - return results.RowsAffected(); +int SharedDatabase::DeleteStalePlayerCorpses() { + return ( + RuleB(Zone, EnableShadowrest) ? + CharacterCorpsesRepository::BuryDecayedCorpses(*this) : + CharacterCorpsesRepository::DeleteWhere( + *this, + fmt::format( + "(UNIX_TIMESTAMP() - UNIX_TIMESTAMP(time_of_death)) > {} AND time_of_death != 0", + RuleI(Character, CorpseDecayTimeMS) / 1000 + ) + ) + ); } bool SharedDatabase::GetCommandSettings(std::map>> &command_settings) diff --git a/common/shareddb.h b/common/shareddb.h index 55bc6b32f..eec5aab2b 100644 --- a/common/shareddb.h +++ b/common/shareddb.h @@ -72,7 +72,7 @@ public: bool SetGMSpeed(uint32 account_id, uint8 gmspeed); uint8 GetGMSpeed(uint32 account_id); bool SetHideMe(uint32 account_id, uint8 hideme); - int32 DeleteStalePlayerCorpses(); + int DeleteStalePlayerCorpses(); void LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct *message); void SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct *message); bool GetCommandSettings(std::map>> &command_settings); diff --git a/world/adventure.cpp b/world/adventure.cpp index 457118b3d..8f571fdb0 100644 --- a/world/adventure.cpp +++ b/world/adventure.cpp @@ -1,3 +1,4 @@ +#include #include "../common/global_define.h" #include "../common/servertalk.h" #include "../common/extprofile.h" @@ -12,6 +13,7 @@ #include "clientlist.h" #include "cliententry.h" #include "../common/zone_store.h" +#include "../common/repositories/character_corpses_repository.h" extern ZSList zoneserver_list; extern ClientList client_list; @@ -370,54 +372,53 @@ void Adventure::Finished(AdventureWinStatus ws) void Adventure::MoveCorpsesToGraveyard() { - if(GetTemplate()->graveyard_zone_id == 0) - { + if (GetTemplate()->graveyard_zone_id == 0) { return; } - std::list dbid_list; - std::list charid_list; + glm::vec4 position; - std::string query = StringFormat("SELECT id, charid FROM character_corpses WHERE instance_id=%d", GetInstanceID()); - auto results = database.QueryDatabase(query); - if(!results.Success()) + float x = GetTemplate()->graveyard_x + emu_random.Real(-GetTemplate()->graveyard_radius, GetTemplate()->graveyard_radius); + float y = GetTemplate()->graveyard_y + emu_random.Real(-GetTemplate()->graveyard_radius, GetTemplate()->graveyard_radius); + float z = GetTemplate()->graveyard_z; - for(auto row = results.begin(); row != results.end(); ++row) { - dbid_list.push_back(Strings::ToInt(row[0])); - charid_list.push_back(Strings::ToInt(row[1])); - } + position.x = x; + position.y = y; + position.z = z; + position.w = 0.0f; - for (auto &elem : dbid_list) { - float x = GetTemplate()->graveyard_x + emu_random.Real(-GetTemplate()->graveyard_radius, GetTemplate()->graveyard_radius); - float y = GetTemplate()->graveyard_y + emu_random.Real(-GetTemplate()->graveyard_radius, GetTemplate()->graveyard_radius); - float z = GetTemplate()->graveyard_z; + CharacterCorpsesRepository::SendAdventureCorpsesToGraveyard(database, GetTemplate()->graveyard_zone_id, GetInstanceID(), position); - query = StringFormat("UPDATE character_corpses " - "SET zone_id = %d, instance_id = 0, " - "x = %f, y = %f, z = %f WHERE instance_id = %d", - GetTemplate()->graveyard_zone_id, - x, y, z, GetInstanceID()); - database.QueryDatabase(query); - } + const auto& l = CharacterCorpsesRepository::GetWhere( + database, + fmt::format( + "`instance_id` = {}", + GetInstanceID() + ) + ); + + for (const auto& e : l) { + auto pack = new ServerPacket(ServerOP_DepopAllPlayersCorpses, sizeof(ServerDepopAllPlayersCorpses_Struct)); + + auto d = (ServerDepopAllPlayersCorpses_Struct*) pack->pBuffer; + + d->CharacterID = e.charid; + d->InstanceID = 0; + d->ZoneID = GetTemplate()->graveyard_zone_id; - auto c_iter = charid_list.begin(); - for (auto iter = dbid_list.begin(); iter != dbid_list.end(); ++iter, ++c_iter) - { - auto pack = - new ServerPacket(ServerOP_DepopAllPlayersCorpses, sizeof(ServerDepopAllPlayersCorpses_Struct)); - ServerDepopAllPlayersCorpses_Struct *dpc = (ServerDepopAllPlayersCorpses_Struct*)pack->pBuffer; - dpc->CharacterID = (*c_iter); - dpc->InstanceID = 0; - dpc->ZoneID = GetTemplate()->graveyard_zone_id; zoneserver_list.SendPacket(0, GetInstanceID(), pack); + delete pack; pack = new ServerPacket(ServerOP_SpawnPlayerCorpse, sizeof(SpawnPlayerCorpse_Struct)); - SpawnPlayerCorpse_Struct* spc = (SpawnPlayerCorpse_Struct*)pack->pBuffer; - spc->player_corpse_id = (*iter); - spc->zone_id = GetTemplate()->graveyard_zone_id; + + auto spc = (SpawnPlayerCorpse_Struct*) pack->pBuffer; + + spc->player_corpse_id = e.id; + spc->zone_id = GetTemplate()->graveyard_zone_id; zoneserver_list.SendPacket(spc->zone_id, 0, pack); + delete pack; } } diff --git a/zone/client.h b/zone/client.h index a69db86fd..f5416fecc 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1451,7 +1451,7 @@ public: void DepopAllCorpses(); void DepopPlayerCorpse(uint32 dbid); void BuryPlayerCorpses(); - uint32 GetCorpseCount() { return database.GetCharacterCorpseCount(CharacterID()); } + int64 GetCorpseCount() { return database.GetCharacterCorpseCount(CharacterID()); } uint32 GetCorpseID(int corpse) { return database.GetCharacterCorpseID(CharacterID(), corpse); } uint32 GetCorpseItemAt(int corpse_id, int slot_id) { return database.GetCharacterCorpseItemAt(corpse_id, slot_id); } void SuspendMinion(int value); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 5fe13c526..54e4574d1 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -63,9 +63,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "gm_commands/object_manipulation.h" #include "client.h" #include "../common/repositories/account_repository.h" +#include "../common/repositories/character_corpses_repository.h" #include "../common/events/player_event_logs.h" #include "../common/repositories/character_stats_record_repository.h" +#include "dialogue_window.h" extern QueryServ* QServ; extern Zone* zone; @@ -6821,73 +6823,96 @@ void Client::Handle_OP_GMSearchCorpse(const EQApplicationPacket *app) // Could make this into a rule, although there is a hard limit since we are using a popup, of 4096 bytes that can // be displayed in the window, including all the HTML formatting tags. // - const int maxResults = 10; + const int max_results = 10; - if (app->size < sizeof(GMSearchCorpse_Struct)) - { + if (app->size < sizeof(GMSearchCorpse_Struct)) { LogDebug("OP_GMSearchCorpse size lower than expected: got [{}] expected at least [{}]", app->size, sizeof(GMSearchCorpse_Struct)); DumpPacket(app); return; } - GMSearchCorpse_Struct *gmscs = (GMSearchCorpse_Struct *)app->pBuffer; - gmscs->Name[63] = '\0'; + auto s = (GMSearchCorpse_Struct *) app->pBuffer; + s->Name[63] = '\0'; - auto escSearchString = new char[129]; - database.DoEscapeString(escSearchString, gmscs->Name, strlen(gmscs->Name)); + const auto& l = CharacterCorpsesRepository::GetWhere( + database, + fmt::format( + "`charname` LIKE '%{}%' ORDER BY `charname` LIMIT {}", + Strings::Escape(s->Name), + max_results + ) + ); - std::string query = StringFormat("SELECT charname, zone_id, x, y, z, time_of_death, is_rezzed, is_buried " - "FROM character_corpses WheRE charname LIKE '%%%s%%' ORDER BY charname LIMIT %i", - escSearchString, maxResults); - safe_delete_array(escSearchString); - auto results = database.QueryDatabase(query); - if (!results.Success()) { + if (l.empty()) { + Message( + Chat::White, + fmt::format( + "No corpses were found matching '{}'.", + s->Name + ).c_str() + ); return; } - if (results.RowCount() == 0) - return; - - if (results.RowCount() == maxResults) - Message(Chat::Red, "Your search found too many results; some are not displayed."); - else - Message(Chat::Yellow, "There are %i corpse(s) that match the search string '%s'.", results.RowCount(), gmscs->Name); - - char charName[64], time_of_death[20]; - - std::string popupText = ""; - - for (auto row = results.begin(); row != results.end(); ++row) { - - strn0cpy(charName, row[0], sizeof(charName)); - - uint32 ZoneID = Strings::ToInt(row[1]); - float CorpseX = Strings::ToFloat(row[2]); - float CorpseY = Strings::ToFloat(row[3]); - float CorpseZ = Strings::ToFloat(row[4]); - - strn0cpy(time_of_death, row[5], sizeof(time_of_death)); - - bool corpseRezzed = Strings::ToInt(row[6]); - bool corpseBuried = Strings::ToInt(row[7]); - - popupText += StringFormat("", - charName, zone_store.GetZoneName(ZoneID, true), CorpseX, CorpseY, CorpseZ, time_of_death, - corpseRezzed ? "Yes" : "No", corpseBuried ? "Yes" : "No"); - - if (popupText.size() > 4000) { - Message(Chat::Red, "Unable to display all the results."); - break; - } - + if (l.size() == max_results) { + Message(Chat::White, "Your search found too many results; some are not displayed."); + } else { + Message( + Chat::White, + fmt::format( + "{} Corpse{} were found matching '{}'.", + l.size(), + l.size() != 1 ? "s" : "", + s->Name + ).c_str() + ); } - popupText += "
NameZoneXYZDate" - "RezzedBuried
 " - "
%s%s%8.0f%8.0f%8.0f%s%s%s
"; + std::string popup_text = DialogueWindow::TableRow( + DialogueWindow::TableCell("Name") + + DialogueWindow::TableCell("Zone") + + DialogueWindow::TableCell("Position") + + DialogueWindow::TableCell("Date") + + DialogueWindow::TableCell("Resurrected") + + DialogueWindow::TableCell("Buried") + ); - SendPopupToClient("Corpses", popupText.c_str()); + for (const auto& e : l) { + popup_text += DialogueWindow::TableRow( + DialogueWindow::TableCell(e.charname) + + DialogueWindow::TableCell( + fmt::format( + "{} ({})", + zone_store.GetZoneLongName(e.zone_id, true), + e.zone_id + ) + ) + + DialogueWindow::TableCell( + fmt::format( + "{:.2f}, {:.2f}, {:.2f}, {:.2f}", + e.x, + e.y, + e.z, + e.heading + ) + ) + + DialogueWindow::TableCell(std::to_string(e.time_of_death)) + + DialogueWindow::TableCell( + e.is_rezzed ? + DialogueWindow::ColorMessage("forest_green", "Y") : + DialogueWindow::ColorMessage("red_1", "N") + ) + + DialogueWindow::TableCell( + e.is_buried ? + DialogueWindow::ColorMessage("forest_green", "Y") : + DialogueWindow::ColorMessage("red_1", "N") + ) + ); + } + popup_text = DialogueWindow::Table(popup_text); + + SendPopupToClient("Corpses", popup_text.c_str()); } void Client::Handle_OP_GMServers(const EQApplicationPacket *app) diff --git a/zone/client_process.cpp b/zone/client_process.cpp index f1d4a5886..9e7673ce1 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -1024,7 +1024,7 @@ void Client::OPRezzAnswer(uint32 Action, uint32 SpellID, uint16 ZoneID, uint16 I { // Mark the corpse as rezzed in the database, just in case the corpse has buried, or the zone the // corpse is in has shutdown since the rez spell was cast. - database.MarkCorpseAsRezzed(PendingRezzDBID); + database.MarkCorpseAsResurrected(PendingRezzDBID); LogSpells("Player [{}] got a [{}] Rezz spellid [{}] in zone[{}] instance id [{}]", name, (uint16)spells[SpellID].base_value[0], SpellID, ZoneID, InstanceID); diff --git a/zone/corpse.cpp b/zone/corpse.cpp index a3646299f..e65d2f876 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -2058,8 +2058,10 @@ bool Corpse::MovePlayerCorpseToGraveyard() { Save(); + glm::vec4 graveyard_point = zone->GetGraveyardPoint(); + uint16_t instance_id = (zone->GetZoneID() == zone->graveyard_zoneid()) ? zone->GetInstanceID() : 0; - database.SendCharacterCorpseToGraveyard(corpse_db_id, zone->graveyard_zoneid(), instance_id, zone->GetGraveyardPoint()); + database.SendCharacterCorpseToGraveyard(corpse_db_id, zone->graveyard_zoneid(), instance_id, graveyard_point); SendWorldSpawnPlayerCorpseInZone(zone->graveyard_zoneid()); corpse_db_id = 0; diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index 440e0bd77..dd85ebdbd 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -982,17 +982,17 @@ bool Perl__summonallplayercorpses(uint32 char_id, float dest_x, float dest_y, fl return quest_manager.summonallplayercorpses(char_id, position); } -int Perl__getplayercorpsecount(uint32 char_id) +int64 Perl__getplayercorpsecount(uint32 character_id) { - return quest_manager.getplayercorpsecount(char_id); + return quest_manager.getplayercorpsecount(character_id); } -int Perl__getplayercorpsecountbyzoneid(uint32 char_id, uint32 zone_id) +int64 Perl__getplayercorpsecountbyzoneid(uint32 character_id, uint32 zone_id) { - return quest_manager.getplayercorpsecountbyzoneid(char_id, zone_id); + return quest_manager.getplayercorpsecountbyzoneid(character_id, zone_id); } -int Perl__getplayerburiedcorpsecount(uint32 char_id) +int64 Perl__getplayerburiedcorpsecount(uint32 char_id) { return quest_manager.getplayerburiedcorpsecount(char_id); } diff --git a/zone/gm_commands/show/buried_corpse_count.cpp b/zone/gm_commands/show/buried_corpse_count.cpp index 863abc18a..55cec83dd 100644 --- a/zone/gm_commands/show/buried_corpse_count.cpp +++ b/zone/gm_commands/show/buried_corpse_count.cpp @@ -8,7 +8,7 @@ void ShowBuriedCorpseCount(Client *c, const Seperator *sep) t = c->GetTarget()->CastToClient(); } - const uint32 corpse_count = database.GetCharacterBuriedCorpseCount(t->CharacterID()); + const int64 corpse_count = database.GetCharacterBuriedCorpseCount(t->CharacterID()); c->Message( Chat::White, diff --git a/zone/lua_client.cpp b/zone/lua_client.cpp index 811163417..b4445c62e 100644 --- a/zone/lua_client.cpp +++ b/zone/lua_client.cpp @@ -1436,7 +1436,7 @@ void Lua_Client::EndSharedTask(bool send_fail) { self->EndSharedTask(send_fail); } -int Lua_Client::GetCorpseCount() { +int64 Lua_Client::GetCorpseCount() { Lua_Safe_Call_Int(); return self->GetCorpseCount(); } @@ -3427,7 +3427,7 @@ luabind::scope lua_register_client() { .def("GetClientMaxLevel", (int(Lua_Client::*)(void))&Lua_Client::GetClientMaxLevel) .def("GetClientVersion", (int(Lua_Client::*)(void))&Lua_Client::GetClientVersion) .def("GetClientVersionBit", (uint32(Lua_Client::*)(void))&Lua_Client::GetClientVersionBit) - .def("GetCorpseCount", (int(Lua_Client::*)(void))&Lua_Client::GetCorpseCount) + .def("GetCorpseCount", (int64(Lua_Client::*)(void))&Lua_Client::GetCorpseCount) .def("GetCorpseID", (int(Lua_Client::*)(int))&Lua_Client::GetCorpseID) .def("GetCorpseItemAt", (int(Lua_Client::*)(int,int))&Lua_Client::GetCorpseItemAt) .def("GetDiscSlotBySpellID", (int(Lua_Client::*)(int32))&Lua_Client::GetDiscSlotBySpellID) diff --git a/zone/lua_client.h b/zone/lua_client.h index 4df40f75a..ff47ed478 100644 --- a/zone/lua_client.h +++ b/zone/lua_client.h @@ -361,7 +361,7 @@ public: void LockSharedTask(bool lock); void EndSharedTask(); void EndSharedTask(bool send_fail); - int GetCorpseCount(); + int64 GetCorpseCount(); int GetCorpseID(int corpse); int GetCorpseItemAt(int corpse, int slot); void AssignToInstance(int instance_id); diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index da3352c16..fe9c92325 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -579,16 +579,16 @@ void lua_summon_all_player_corpses(uint32 char_id, float x, float y, float z, fl quest_manager.summonallplayercorpses(char_id, glm::vec4(x, y, z, h)); } -int lua_get_player_corpse_count(uint32 char_id) { - return database.CountCharacterCorpses(char_id); +int64 lua_get_player_corpse_count(uint32 character_id) { + return database.CountCharacterCorpses(character_id); } -int lua_get_player_corpse_count_by_zone_id(uint32 char_id, uint32 zone_id) { - return database.CountCharacterCorpsesByZoneID(char_id, zone_id); +int64 lua_get_player_corpse_count_by_zone_id(uint32 character_id, uint32 zone_id) { + return database.CountCharacterCorpsesByZoneID(character_id, zone_id); } -int lua_get_player_buried_corpse_count(uint32 char_id) { - return quest_manager.getplayerburiedcorpsecount(char_id); +int64 lua_get_player_buried_corpse_count(uint32 character_id) { + return quest_manager.getplayerburiedcorpsecount(character_id); } bool lua_bury_player_corpse(uint32 char_id) { diff --git a/zone/perl_client.cpp b/zone/perl_client.cpp index e66fa134d..bc270b59e 100644 --- a/zone/perl_client.cpp +++ b/zone/perl_client.cpp @@ -1413,7 +1413,7 @@ void Perl_Client_EndSharedTask(Client* self, bool send_fail) return self->EndSharedTask(send_fail); } -uint32_t Perl_Client_GetCorpseCount(Client* self) // @categories Account and Character, Corpse +int64_t Perl_Client_GetCorpseCount(Client* self) // @categories Account and Character, Corpse { return self->GetCorpseCount(); } diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index a9f5e7939..24c3a728e 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -2101,28 +2101,17 @@ bool QuestManager::summonallplayercorpses(uint32 char_id, const glm::vec4& posit return true; } -int QuestManager::getplayercorpsecount(uint32 char_id) { - if (char_id > 0) { - return database.CountCharacterCorpses(char_id); - } - return 0; +int64 QuestManager::getplayercorpsecount(uint32 character_id) { + return character_id ? database.CountCharacterCorpses(character_id) : 0; } -int QuestManager::getplayercorpsecountbyzoneid(uint32 char_id, uint32 zone_id) { - if (char_id > 0 && zone_id > 0) { - return database.CountCharacterCorpsesByZoneID(char_id, zone_id); - } - return 0; +int64 QuestManager::getplayercorpsecountbyzoneid(uint32 character_id, uint32 zone_id) { + return (character_id && zone_id) ? database.CountCharacterCorpsesByZoneID(character_id, zone_id) : 0; } -uint32 QuestManager::getplayerburiedcorpsecount(uint32 char_id) { - uint32 Result = 0; - - if(char_id > 0) { - Result = database.GetCharacterBuriedCorpseCount(char_id); - } - return Result; +int64 QuestManager::getplayerburiedcorpsecount(uint32 character_id) { + return character_id ? database.GetCharacterBuriedCorpseCount(character_id) : 0; } bool QuestManager::buryplayercorpse(uint32 char_id) diff --git a/zone/questmgr.h b/zone/questmgr.h index 6650e30da..c16154e4a 100644 --- a/zone/questmgr.h +++ b/zone/questmgr.h @@ -193,9 +193,9 @@ public: void sethp(int64 hpperc); bool summonburiedplayercorpse(uint32 char_id, const glm::vec4& position); bool summonallplayercorpses(uint32 char_id, const glm::vec4& position); - uint32 getplayerburiedcorpsecount(uint32 char_id); - int getplayercorpsecount(uint32 char_id); - int getplayercorpsecountbyzoneid(uint32 char_id, uint32 zone_id); + int64 getplayerburiedcorpsecount(uint32 char_id); + int64 getplayercorpsecount(uint32 character_id); + int64 getplayercorpsecountbyzoneid(uint32 character_id, uint32 zone_id); bool buryplayercorpse(uint32 char_id); void forcedooropen(uint32 doorid, bool altmode); void forcedoorclose(uint32 doorid, bool altmode); diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 9e2165405..1b05c28c2 100755 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -45,6 +45,9 @@ #include "../common/repositories/merc_subtypes_repository.h" #include "../common/repositories/npc_types_tint_repository.h" #include "../common/repositories/merchantlist_temp_repository.h" +#include "../common/repositories/character_data_repository.h" +#include "../common/repositories/character_corpses_repository.h" +#include "../common/repositories/character_corpse_items_repository.h" #include #include @@ -3678,269 +3681,229 @@ bool ZoneDatabase::GetFactionIdsForNPC(uint32 nfl_id, std::listrandom.Real(-20, 20); + position.y += zone->random.Real(-20, 20); -uint32 ZoneDatabase::SendCharacterCorpseToGraveyard(uint32 dbid, uint32 zone_id, uint16 instance_id, const glm::vec4& position) { - - double xcorpse = (position.x + zone->random.Real(-20,20)); - double ycorpse = (position.y + zone->random.Real(-20,20)); - - std::string query = StringFormat("UPDATE `character_corpses` " - "SET `zone_id` = %u, `instance_id` = 0, " - "`x` = %1.1f, `y` = %1.1f, `z` = %1.1f, `heading` = %1.1f, " - "`was_at_graveyard` = 1 " - "WHERE `id` = %d", - zone_id, xcorpse, ycorpse, position.z, position.w, dbid); - QueryDatabase(query); - return dbid; + return CharacterCorpsesRepository::SendToGraveyard(*this, corpse_id, zone_id, instance_id, position); } -void ZoneDatabase::SendCharacterCorpseToNonInstance(uint32 corpse_db_id) +void ZoneDatabase::SendCharacterCorpseToNonInstance(uint32 corpse_id) { - if (corpse_db_id != 0) - { - auto query = fmt::format(SQL( - UPDATE character_corpses SET instance_id = 0 WHERE id = {}; - ), corpse_db_id); + CharacterCorpsesRepository::SendToNonInstance(*this, corpse_id); +} - QueryDatabase(query); +uint32 ZoneDatabase::GetCharacterCorpseDecayTimer(uint32 corpse_id) +{ + return CharacterCorpsesRepository::GetDecayTimer(*this, corpse_id); +} + +uint32 ZoneDatabase::UpdateCharacterCorpse( + uint32 corpse_id, + uint32 character_id, + const std::string& name, + uint32 zone_id, + uint16 instance_id, + const CharacterCorpseEntry& c, + const glm::vec4& position, + uint32 guild_consent_id, + bool is_resurrected +) +{ + auto e = CharacterCorpsesRepository::FindOne(*this, corpse_id); + + e.charname = name; + e.zone_id = zone_id; + e.instance_id = instance_id; + e.charid = character_id; + e.x = position.x; + e.y = position.y; + e.z = position.z; + e.heading = position.w; + e.guild_consent_id = guild_consent_id; + e.is_locked = c.locked; + e.exp = c.exp; + e.size = c.size; + e.level = c.level; + e.race = c.race; + e.gender = c.gender; + e.class_ = c.class_; + e.deity = c.deity; + e.texture = c.texture; + e.helm_texture = c.helmtexture; + e.copper = c.copper; + e.silver = c.silver; + e.gold = c.gold; + e.platinum = c.plat; + e.hair_color = c.haircolor; + e.beard_color = c.beardcolor; + e.eye_color_1 = c.eyecolor1; + e.eye_color_2 = c.eyecolor2; + e.hair_style = c.hairstyle; + e.face = c.face; + e.beard = c.beard; + e.drakkin_heritage = c.drakkin_heritage; + e.drakkin_details = c.drakkin_details; + e.drakkin_tattoo = c.drakkin_tattoo; + e.wc_1 = c.item_tint.Head.Color; + e.wc_2 = c.item_tint.Chest.Color; + e.wc_3 = c.item_tint.Arms.Color; + e.wc_4 = c.item_tint.Wrist.Color; + e.wc_5 = c.item_tint.Hands.Color; + e.wc_6 = c.item_tint.Legs.Color; + e.wc_7 = c.item_tint.Feet.Color; + e.wc_8 = c.item_tint.Primary.Color; + e.wc_9 = c.item_tint.Secondary.Color; + + CharacterCorpsesRepository::UpdateOne(*this, e); + + return corpse_id; +} + +uint32 ZoneDatabase::UpdateCharacterCorpseConsent(uint32 character_id, uint32 guild_consent_id) +{ + return CharacterCorpsesRepository::SetGuildConsentID(*this, character_id, guild_consent_id); +} + +void ZoneDatabase::MarkCorpseAsResurrected(uint32 corpse_id) +{ + CharacterCorpsesRepository::ResurrectCorpse(*this, corpse_id); +} + +uint32 ZoneDatabase::SaveCharacterCorpse( + uint32 character_id, + const std::string& name, + uint32 zone_id, + uint16 instance_id, + const CharacterCorpseEntry& corpse, + const glm::vec4& position, + uint32 guild_consent_id +) +{ + auto e = CharacterCorpsesRepository::NewEntity(); + + e.charname = name; + e.zone_id = zone_id; + e.instance_id = instance_id; + e.charid = character_id; + e.x = position.x; + e.y = position.y; + e.z = position.z; + e.heading = position.w; + e.guild_consent_id = guild_consent_id; + e.is_locked = corpse.locked; + e.exp = corpse.exp; + e.size = corpse.size; + e.level = corpse.level; + e.race = corpse.race; + e.gender = corpse.gender; + e.class_ = corpse.class_; + e.deity = corpse.deity; + e.texture = corpse.texture; + e.helm_texture = corpse.helmtexture; + e.copper = corpse.copper; + e.silver = corpse.silver; + e.gold = corpse.gold; + e.platinum = corpse.plat; + e.hair_color = corpse.haircolor; + e.beard_color = corpse.beardcolor; + e.eye_color_1 = corpse.eyecolor1; + e.eye_color_2 = corpse.eyecolor2; + e.hair_style = corpse.hairstyle; + e.face = corpse.face; + e.beard = corpse.beard; + e.drakkin_heritage = corpse.drakkin_heritage; + e.drakkin_tattoo = corpse.drakkin_tattoo; + e.drakkin_details = corpse.drakkin_details; + e.wc_1 = corpse.item_tint.Head.Color; + e.wc_2 = corpse.item_tint.Chest.Color; + e.wc_3 = corpse.item_tint.Arms.Color; + e.wc_4 = corpse.item_tint.Wrist.Color; + e.wc_5 = corpse.item_tint.Hands.Color; + e.wc_6 = corpse.item_tint.Legs.Color; + e.wc_7 = corpse.item_tint.Feet.Color; + e.wc_8 = corpse.item_tint.Primary.Color; + e.wc_9 = corpse.item_tint.Secondary.Color; + + e = CharacterCorpsesRepository::InsertOne(*this, e); + + std::vector v; + + v.reserve(corpse.items.size()); + + auto i = CharacterCorpseItemsRepository::NewEntity(); + + for (const auto& item : corpse.items) { + i.corpse_id = e.id; + i.equip_slot = item.equip_slot; + i.item_id = item.item_id; + i.charges = item.charges; + i.aug_1 = item.aug_1; + i.aug_2 = item.aug_2; + i.aug_3 = item.aug_3; + i.aug_4 = item.aug_4; + i.aug_5 = item.aug_5; + i.aug_6 = item.aug_6; + i.attuned = item.attuned; + i.custom_data = item.custom_data; + i.ornamenticon = item.ornamenticon; + i.ornamentidfile = item.ornamentidfile; + i.ornament_hero_model = item.ornament_hero_model; + + v.emplace_back(i); } + + if (!v.empty()) { + CharacterCorpseItemsRepository::ReplaceMany(*this, v); + } + + return e.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); - auto results = QueryDatabase(query); - auto& row = results.begin(); - if (results.Success() && results.RowsAffected() != 0) - return Strings::ToUnsignedInt(row[0]); - - return 0; -} - -uint32 ZoneDatabase::UpdateCharacterCorpse(uint32 db_id, uint32 char_id, const char* char_name, uint32 zone_id, uint16 instance_id, const CharacterCorpseEntry& corpse, const glm::vec4& position, uint32 guild_id, bool is_rezzed) { - std::string query = StringFormat("UPDATE `character_corpses` " - "SET `charname` = '%s', `zone_id` = %u, `instance_id` = %u, `charid` = %d, " - "`x` = %1.1f,`y` = %1.1f,`z` = %1.1f, `heading` = %1.1f, `guild_consent_id` = %u, " - "`is_locked` = %d, `exp` = %u, `size` = %f, `level` = %u, " - "`race` = %u, `gender` = %u, `class` = %u, `deity` = %u, " - "`texture` = %u, `helm_texture` = %u, `copper` = %u, " - "`silver` = %u, `gold` = %u, `platinum` = %u, `hair_color` = %u, " - "`beard_color` = %u, `eye_color_1` = %u, `eye_color_2` = %u, " - "`hair_style` = %u, `face` = %u, `beard` = %u, `drakkin_heritage` = %u, " - "`drakkin_tattoo` = %u, `drakkin_details` = %u, `wc_1` = %u, " - "`wc_2` = %u, `wc_3` = %u, `wc_4` = %u, `wc_5` = %u, `wc_6` = %u, " - "`wc_7` = %u, `wc_8` = %u, `wc_9` = %u " - "WHERE `id` = %u", - Strings::Escape(char_name).c_str(), zone_id, instance_id, char_id, - position.x, position.y, position.z, position.w, guild_id, - corpse.locked, corpse.exp, corpse.size, corpse.level, corpse.race, - corpse.gender, corpse.class_, corpse.deity, corpse.texture, - corpse.helmtexture, corpse.copper, corpse.silver, corpse.gold, - corpse.plat, corpse.haircolor, corpse.beardcolor, corpse.eyecolor1, - corpse.eyecolor2, corpse.hairstyle, corpse.face, corpse.beard, - corpse.drakkin_heritage, corpse.drakkin_tattoo, corpse.drakkin_details, - corpse.item_tint.Head.Color, corpse.item_tint.Chest.Color, corpse.item_tint.Arms.Color, - corpse.item_tint.Wrist.Color, corpse.item_tint.Hands.Color, corpse.item_tint.Legs.Color, - corpse.item_tint.Feet.Color, corpse.item_tint.Primary.Color, corpse.item_tint.Secondary.Color, - db_id); - auto results = QueryDatabase(query); - - return db_id; -} - -uint32 ZoneDatabase::UpdateCharacterCorpseConsent(uint32 charid, uint32 guildid) +uint32 ZoneDatabase::GetCharacterBuriedCorpseCount(uint32 character_id) { - std::string query = fmt::format("UPDATE `character_corpses` SET `guild_consent_id` = '{}' WHERE charid = '{}'", guildid, charid); - auto results = QueryDatabase(query); - return results.RowsAffected(); -} - -void ZoneDatabase::MarkCorpseAsRezzed(uint32 db_id) { - std::string query = StringFormat("UPDATE `character_corpses` SET `is_rezzed` = 1 WHERE `id` = %i", db_id); - auto results = QueryDatabase(query); -} - -uint32 ZoneDatabase::SaveCharacterCorpse(uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, const CharacterCorpseEntry& corpse, const glm::vec4& position, uint32 guildid) { - /* Dump Basic Corpse Data */ - std::string query = StringFormat( - "INSERT INTO `character_corpses` " - "SET `charname` = '%s', " - "`zone_id` = %u, " - "`instance_id` = %u, " - "`charid` = %d, " - "`x` = %1.1f, " - "`y` = %1.1f, " - "`z` = %1.1f, " - "`heading` = %1.1f, " - "`guild_consent_id` = %u, " - "`time_of_death` = NOW(), " - "`is_buried` = 0, " - "`is_locked` = %d, " - "`exp` = %u, " - "`size` = %f, " - "`level` = %u, " - "`race` = %u, " - "`gender` = %u, " - "`class` = %u, " - "`deity` = %u, " - "`texture` = %u, " - "`helm_texture` = %u, " - "`copper` = %u, " - "`silver` = %u, " - "`gold` = %u, " - "`platinum` = %u, " - "`hair_color` = %u, " - "`beard_color` = %u, " - "`eye_color_1` = %u, " - "`eye_color_2` = %u, " - "`hair_style` = %u, " - "`face` = %u, " - "`beard` = %u, " - "`drakkin_heritage` = %u, " - "`drakkin_tattoo` = %u, " - "`drakkin_details` = %u, " - "`wc_1` = %u, " - "`wc_2` = %u, " - "`wc_3` = %u, " - "`wc_4` = %u, " - "`wc_5` = %u, " - "`wc_6` = %u, " - "`wc_7` = %u, " - "`wc_8` = %u, " - "`wc_9` = %u ", - Strings::Escape(charname).c_str(), - zoneid, - instanceid, - charid, - position.x, - position.y, - position.z, - position.w, - guildid, - corpse.locked, - corpse.exp, - corpse.size, - corpse.level, - corpse.race, - corpse.gender, - corpse.class_, - corpse.deity, - corpse.texture, - corpse.helmtexture, - corpse.copper, - corpse.silver, - corpse.gold, - corpse.plat, - corpse.haircolor, - corpse.beardcolor, - corpse.eyecolor1, - corpse.eyecolor2, - corpse.hairstyle, - corpse.face, - corpse.beard, - corpse.drakkin_heritage, - corpse.drakkin_tattoo, - corpse.drakkin_details, - corpse.item_tint.Head.Color, - corpse.item_tint.Chest.Color, - corpse.item_tint.Arms.Color, - corpse.item_tint.Wrist.Color, - corpse.item_tint.Hands.Color, - corpse.item_tint.Legs.Color, - corpse.item_tint.Feet.Color, - corpse.item_tint.Primary.Color, - corpse.item_tint.Secondary.Color + return CharacterCorpsesRepository::Count( + *this, + fmt::format( + "`charid` = {} AND `is_buried` = 1", + character_id + ) ); - auto results = QueryDatabase(query); - uint32 last_insert_id = results.LastInsertedID(); - - std::string corpse_items_query; - /* Dump Items from Inventory */ - uint8 first_entry = 0; - for(auto &item : corpse.items) - { - if (first_entry != 1){ - corpse_items_query = StringFormat("REPLACE INTO `character_corpse_items` \n" - " (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, aug_6, attuned, custom_data, ornamenticon, ornamentidfile, ornament_hero_model) \n" - " VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, '%s', %u, %u, %u) \n", - last_insert_id, - item.equip_slot, - item.item_id, - item.charges, - item.aug_1, - item.aug_2, - item.aug_3, - item.aug_4, - item.aug_5, - item.aug_6, - item.attuned, - item.custom_data.c_str(), - item.ornamenticon, - item.ornamentidfile, - item.ornament_hero_model - ); - first_entry = 1; - } - else{ - corpse_items_query = corpse_items_query + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, '%s', %u, %u, %u) \n", - last_insert_id, - item.equip_slot, - item.item_id, - item.charges, - item.aug_1, - item.aug_2, - item.aug_3, - item.aug_4, - item.aug_5, - item.aug_6, - item.attuned, - item.custom_data.c_str(), - item.ornamenticon, - item.ornamentidfile, - item.ornament_hero_model - ); - } - } - - if (!corpse_items_query.empty()) - QueryDatabase(corpse_items_query); - - return last_insert_id; } -uint32 ZoneDatabase::GetCharacterBuriedCorpseCount(uint32 char_id) { - std::string query = StringFormat("SELECT COUNT(*) FROM `character_corpses` WHERE `charid` = '%u' AND `is_buried` = 1", char_id); - auto results = QueryDatabase(query); - - for (auto& row = results.begin(); row != results.end(); ++row) { - return Strings::ToInt(row[0]); - } - return 0; +int64 ZoneDatabase::GetCharacterCorpseCount(uint32 character_id) +{ + return CharacterCorpsesRepository::Count( + *this, + fmt::format( + "`charid` = {}", + character_id + ) + ); } -uint32 ZoneDatabase::GetCharacterCorpseCount(uint32 char_id) { - std::string query = StringFormat("SELECT COUNT(*) FROM `character_corpses` WHERE `charid` = '%u'", char_id); - auto results = QueryDatabase(query); +uint32 ZoneDatabase::GetCharacterCorpseID(uint32 character_id, uint8 corpse_limit) +{ + const auto& l = CharacterCorpsesRepository::GetWhere( + *this, + fmt::format( + "`charid` = {} LIMIT {}, 1", + character_id, + corpse_limit + ) + ); - for (auto& row = results.begin(); row != results.end(); ++row) { - return Strings::ToInt(row[0]); - } - return 0; + return l.empty() ? 0 : l[0].id; } -uint32 ZoneDatabase::GetCharacterCorpseID(uint32 char_id, uint8 corpse) { - std::string query = StringFormat("SELECT `id` FROM `character_corpses` WHERE `charid` = '%u' limit %d, 1", char_id, corpse); - - auto results = QueryDatabase(query); - auto& row = results.begin(); - - if (row != results.end()) - return Strings::ToUnsignedInt(row[0]); - else - return 0; -} - -uint32 ZoneDatabase::GetCharacterCorpseItemAt(uint32 corpse_id, uint16 slot_id) { +uint32 ZoneDatabase::GetCharacterCorpseItemAt(uint32 corpse_id, uint16 slot_id) +{ Corpse* c = LoadCharacterCorpse(corpse_id); uint32 item_id = 0; @@ -3952,370 +3915,322 @@ uint32 ZoneDatabase::GetCharacterCorpseItemAt(uint32 corpse_id, uint16 slot_id) return item_id; } -bool ZoneDatabase::LoadCharacterCorpseData(uint32 corpse_id, CharacterCorpseEntry& corpse){ - std::string query = StringFormat( - "SELECT \n" - "is_locked, \n" - "exp, \n" - "size, \n" - "`level`, \n" - "race, \n" - "gender, \n" - "class, \n" - "deity, \n" - "texture, \n" - "helm_texture, \n" - "copper, \n" - "silver, \n" - "gold, \n" - "platinum, \n" - "hair_color, \n" - "beard_color, \n" - "eye_color_1, \n" - "eye_color_2, \n" - "hair_style, \n" - "face, \n" - "beard, \n" - "drakkin_heritage,\n" - "drakkin_tattoo, \n" - "drakkin_details, \n" - "wc_1, \n" - "wc_2, \n" - "wc_3, \n" - "wc_4, \n" - "wc_5, \n" - "wc_6, \n" - "wc_7, \n" - "wc_8, \n" - "wc_9 \n" - "FROM \n" - "character_corpses\n" - "WHERE `id` = %u LIMIT 1\n", - corpse_id +bool ZoneDatabase::LoadCharacterCorpseData(uint32 corpse_id, CharacterCorpseEntry& corpse) +{ + const auto& e = CharacterCorpsesRepository::FindOne(*this, corpse_id); + + corpse.locked = e.is_locked; + corpse.exp = e.exp; + corpse.size = e.size; + corpse.level = e.level; + corpse.race = e.race; + corpse.gender = e.gender; + corpse.class_ = e.class_; + corpse.deity = e.deity; + corpse.texture = e.texture; + corpse.helmtexture = e.helm_texture; + corpse.copper = e.copper; + corpse.silver = e.silver; + corpse.gold = e.gold; + corpse.plat = e.platinum; + corpse.haircolor = e.hair_color; + corpse.beardcolor = e.beard_color; + corpse.eyecolor1 = e.eye_color_1; + corpse.eyecolor2 = e.eye_color_2; + corpse.hairstyle = e.hair_style; + corpse.face = e.face; + corpse.beard = e.beard; + corpse.drakkin_heritage = e.drakkin_heritage; + corpse.drakkin_tattoo = e.drakkin_tattoo; + corpse.drakkin_details = e.drakkin_details; + corpse.item_tint.Head.Color = e.wc_1; + corpse.item_tint.Chest.Color = e.wc_2; + corpse.item_tint.Arms.Color = e.wc_3; + corpse.item_tint.Wrist.Color = e.wc_4; + corpse.item_tint.Hands.Color = e.wc_5; + corpse.item_tint.Legs.Color = e.wc_6; + corpse.item_tint.Feet.Color = e.wc_7; + corpse.item_tint.Primary.Color = e.wc_8; + corpse.item_tint.Secondary.Color = e.wc_9; + + const auto& l = CharacterCorpseItemsRepository::GetWhere( + *this, + fmt::format( + "`corpse_id` = {}", + corpse_id + ) ); - auto results = QueryDatabase(query); - uint16 i = 0; - for (auto& row = results.begin(); row != results.end(); ++row) { - corpse.locked = Strings::ToInt(row[i++]); // is_locked, - corpse.exp = Strings::ToUnsignedInt(row[i++]); // exp, - corpse.size = Strings::ToInt(row[i++]); // size, - corpse.level = Strings::ToInt(row[i++]); // `level`, - corpse.race = Strings::ToInt(row[i++]); // race, - corpse.gender = Strings::ToInt(row[i++]); // gender, - corpse.class_ = Strings::ToInt(row[i++]); // class, - corpse.deity = Strings::ToInt(row[i++]); // deity, - corpse.texture = Strings::ToInt(row[i++]); // texture, - corpse.helmtexture = Strings::ToInt(row[i++]); // helm_texture, - corpse.copper = Strings::ToUnsignedInt(row[i++]); // copper, - corpse.silver = Strings::ToUnsignedInt(row[i++]); // silver, - corpse.gold = Strings::ToUnsignedInt(row[i++]); // gold, - corpse.plat = Strings::ToUnsignedInt(row[i++]); // platinum, - corpse.haircolor = Strings::ToInt(row[i++]); // hair_color, - corpse.beardcolor = Strings::ToInt(row[i++]); // beard_color, - corpse.eyecolor1 = Strings::ToInt(row[i++]); // eye_color_1, - corpse.eyecolor2 = Strings::ToInt(row[i++]); // eye_color_2, - corpse.hairstyle = Strings::ToInt(row[i++]); // hair_style, - corpse.face = Strings::ToInt(row[i++]); // face, - corpse.beard = Strings::ToInt(row[i++]); // beard, - corpse.drakkin_heritage = Strings::ToUnsignedInt(row[i++]); // drakkin_heritage, - corpse.drakkin_tattoo = Strings::ToUnsignedInt(row[i++]); // drakkin_tattoo, - corpse.drakkin_details = Strings::ToUnsignedInt(row[i++]); // drakkin_details, - corpse.item_tint.Head.Color = Strings::ToUnsignedInt(row[i++]); // wc_1, - corpse.item_tint.Chest.Color = Strings::ToUnsignedInt(row[i++]); // wc_2, - corpse.item_tint.Arms.Color = Strings::ToUnsignedInt(row[i++]); // wc_3, - corpse.item_tint.Wrist.Color = Strings::ToUnsignedInt(row[i++]); // wc_4, - corpse.item_tint.Hands.Color = Strings::ToUnsignedInt(row[i++]); // wc_5, - corpse.item_tint.Legs.Color = Strings::ToUnsignedInt(row[i++]); // wc_6, - corpse.item_tint.Feet.Color = Strings::ToUnsignedInt(row[i++]); // wc_7, - corpse.item_tint.Primary.Color = Strings::ToUnsignedInt(row[i++]); // wc_8, - corpse.item_tint.Secondary.Color = Strings::ToUnsignedInt(row[i++]); // wc_9 - } - query = StringFormat( - "SELECT \n" - "equip_slot, \n" - "item_id, \n" - "charges, \n" - "aug_1, \n" - "aug_2, \n" - "aug_3, \n" - "aug_4, \n" - "aug_5, \n" - "aug_6, \n" - "attuned, \n" - "custom_data, \n" - "ornamenticon, \n" - "ornamentidfile, \n" - "ornament_hero_model \n" - "FROM \n" - "character_corpse_items \n" - "WHERE `corpse_id` = %u\n" - , - corpse_id - ); - results = QueryDatabase(query); - i = 0; - uint16 r = 0; - for (auto& row = results.begin(); row != results.end(); ++row) { - CharacterCorpseItemEntry item; - item.equip_slot = Strings::ToInt(row[r++]); // equip_slot, - item.item_id = Strings::ToUnsignedInt(row[r++]); // item_id, - item.charges = Strings::ToInt(row[r++]); // charges, - item.aug_1 = Strings::ToInt(row[r++]); // aug_1, - item.aug_2 = Strings::ToInt(row[r++]); // aug_2, - item.aug_3 = Strings::ToInt(row[r++]); // aug_3, - item.aug_4 = Strings::ToInt(row[r++]); // aug_4, - item.aug_5 = Strings::ToInt(row[r++]); // aug_5, - item.aug_6 = Strings::ToInt(row[r++]); // aug_6, - item.attuned = Strings::ToInt(row[r++]) > 0 ? true : false; // attuned, - - if (row[r]) { - item.custom_data = row[r++]; - } - else { - r++; - } - - item.ornamenticon = Strings::ToUnsignedInt(row[r++]); - item.ornamentidfile = Strings::ToUnsignedInt(row[r++]); - item.ornament_hero_model = Strings::ToUnsignedInt(row[r++]); + for (const auto& e : l) { + CharacterCorpseItemEntry item{ + .item_id = e.item_id, + .equip_slot = static_cast(e.equip_slot), + .charges = static_cast(e.charges), + .aug_1 = e.aug_1, + .aug_2 = e.aug_2, + .aug_3 = e.aug_3, + .aug_4 = e.aug_4, + .aug_5 = e.aug_5, + .aug_6 = static_cast(e.aug_6), + .attuned = e.attuned == 1, + .custom_data = e.custom_data, + .ornamenticon = e.ornamenticon, + .ornamentidfile = e.ornamentidfile, + .ornament_hero_model = e.ornament_hero_model + }; corpse.items.emplace_back(std::move(item)); - r = 0; - i++; } return true; } -Corpse* ZoneDatabase::SummonBuriedCharacterCorpses(uint32 char_id, uint32 dest_zone_id, uint16 dest_instance_id, const glm::vec4& position) { - Corpse* corpse = nullptr; - std::string query = StringFormat("SELECT `id`, `charname`, `time_of_death`, `is_rezzed`, `guild_consent_id` " - "FROM `character_corpses` " - "WHERE `charid` = '%u' AND `is_buried` = 1 " - "ORDER BY `time_of_death` LIMIT 1", - char_id); - auto results = QueryDatabase(query); +Corpse* ZoneDatabase::SummonBuriedCharacterCorpses( + uint32 character_id, + uint32 zone_id, + uint16 instance_id, + const glm::vec4& position +) +{ + Corpse* c = nullptr; - for (auto& row = results.begin(); row != results.end(); ++row) { - corpse = Corpse::LoadCharacterCorpseEntity( - Strings::ToUnsignedInt(row[0]), // uint32 in_dbid - char_id, // uint32 in_charid - row[1], // char* in_charname + const auto& l = CharacterCorpsesRepository::GetWhere( + *this, + fmt::format( + "`charid` = {} AND `is_buried` = 1 ORDER BY `time_of_death` LIMIT 1", + character_id + ) + ); + + for (const auto& e : l) { + c = Corpse::LoadCharacterCorpseEntity( + e.id, + e.charid, + e.charname, position, - row[2], // char* time_of_death - Strings::ToInt(row[3]) == 1, // bool rezzed - false, // bool was_at_graveyard - Strings::ToUnsignedInt(row[4]) // uint32 guild_consent_id + std::to_string(e.time_of_death), + e.is_rezzed == 1, + RuleB(Zone, EnableShadowrest) ? 0 : e.was_at_graveyard, + e.guild_consent_id ); - if (!corpse) - continue; - entity_list.AddCorpse(corpse); - corpse->SetDecayTimer(RuleI(Character, CorpseDecayTimeMS)); - corpse->Spawn(); - if (!UnburyCharacterCorpse(corpse->GetCorpseDBID(), dest_zone_id, dest_instance_id, position)) - LogError("Unable to unbury a summoned player corpse for character id [{}]", char_id); + if (!c) { + continue; + } + + entity_list.AddCorpse(c); + c->SetDecayTimer(RuleI(Character, CorpseDecayTimeMS)); + c->Spawn(); + + if (!UnburyCharacterCorpse(c->GetCorpseDBID(), zone_id, instance_id, position)) { + LogError("Unable to unbury a summoned player corpse_id [{}] for character_id [{}]", e.id, character_id); + } } - return corpse; + return c; } -bool ZoneDatabase::SummonAllCharacterCorpses(uint32 char_id, uint32 dest_zone_id, uint16 dest_instance_id, const glm::vec4& position) { - Corpse* corpse = nullptr; - int CorpseCount = 0; +bool ZoneDatabase::SummonAllCharacterCorpses( + uint32 character_id, + uint32 zone_id, + uint16 instance_id, + const glm::vec4& position +) +{ + Corpse* c = nullptr; + int64 corpse_count = 0; - std::string query = StringFormat( - "UPDATE character_corpses SET zone_id = %i, instance_id = %i, x = %f, y = %f, z = %f, heading = %f, is_buried = 0, was_at_graveyard = 0 WHERE charid = %i", - dest_zone_id, dest_instance_id, position.x, position.y, position.z, position.w, char_id + auto l = CharacterCorpsesRepository::GetWhere( + *this, + fmt::format( + "`charid` = {}", + character_id + ) ); - auto results = QueryDatabase(query); - query = StringFormat( - "SELECT `id`, `charname`, `time_of_death`, `is_rezzed`, `guild_consent_id` FROM `character_corpses` WHERE `charid` = '%u'" - "ORDER BY time_of_death", - char_id); - results = QueryDatabase(query); + for (auto& e : l) { + e.zone_id = zone_id; + e.instance_id = instance_id; + e.x = position.x; + e.y = position.y; + e.z = position.z; + e.heading = position.w; + e.is_buried = 0; + e.was_at_graveyard = 0; - for (auto& row = results.begin(); row != results.end(); ++row) { - corpse = Corpse::LoadCharacterCorpseEntity( - Strings::ToUnsignedInt(row[0]), - char_id, - row[1], + c = Corpse::LoadCharacterCorpseEntity( + e.id, + e.charid, + e.charname, position, - row[2], - Strings::ToInt(row[3]) == 1, - false, - Strings::ToUnsignedInt(row[4])); + std::to_string(e.time_of_death), + e.is_rezzed == 1, + RuleB(Zone, EnableShadowrest) ? 0 : e.was_at_graveyard, + e.guild_consent_id + ); - if (corpse) { - entity_list.AddCorpse(corpse); - corpse->SetDecayTimer(RuleI(Character, CorpseDecayTimeMS)); - corpse->Spawn(); - ++CorpseCount; - } - else{ - LogError("Unable to construct a player corpse for character id [{}]", char_id); + if (c) { + entity_list.AddCorpse(c); + c->SetDecayTimer(RuleI(Character, CorpseDecayTimeMS)); + c->Spawn(); + ++corpse_count; + } else { + LogError("Unable to construct a player corpse_id [{}] for character_id [{}]", e.id, character_id); } } - return (CorpseCount > 0); + CharacterCorpsesRepository::ReplaceMany(*this, l); + + return corpse_count > 0; } -int ZoneDatabase::CountCharacterCorpses(uint32 char_id) { - std::string query = fmt::format( - SQL( - SELECT - COUNT(*) - FROM - character_corpses - WHERE - charid = '{}' - ), - char_id +int64 ZoneDatabase::CountCharacterCorpses(uint32 character_id) +{ + return CharacterCorpsesRepository::Count( + *this, + fmt::format( + "`charid` = {}", + character_id + ) ); - auto results = QueryDatabase(query); - for (auto& row = results.begin(); row != results.end(); ++row) { - return Strings::ToInt(row[0]); - } - return 0; } -int ZoneDatabase::CountCharacterCorpsesByZoneID(uint32 char_id, uint32 zone_id) { - std::string query = fmt::format( - SQL( - SELECT - COUNT(*) - FROM - character_corpses - WHERE - charid = '{}' - AND - zone_id = '{}' - ), - char_id, - zone_id +int64 ZoneDatabase::CountCharacterCorpsesByZoneID(uint32 character_id, uint32 zone_id) +{ + return CharacterCorpsesRepository::Count( + *this, + fmt::format( + "`charid` = {} AND `zone_id` = {}", + character_id, + zone_id + ) ); - auto results = QueryDatabase(query); - for (auto& row = results.begin(); row != results.end(); ++row) { - return Strings::ToInt(row[0]); +} + +bool ZoneDatabase::UnburyCharacterCorpse(uint32 corpse_id, uint32 zone_id, uint16 instance_id, const glm::vec4& position) +{ + return CharacterCorpsesRepository::UnburyCorpse(*this, corpse_id, zone_id, instance_id, position); +} + +Corpse* ZoneDatabase::LoadCharacterCorpse(uint32 corpse_id) +{ + const auto& e = CharacterCorpsesRepository::FindOne(*this, corpse_id); + + Corpse* c = 0; + + if (!e.id) { + return c; } - return 0; -} -bool ZoneDatabase::UnburyCharacterCorpse(uint32 db_id, uint32 new_zone_id, uint16 new_instance_id, const glm::vec4& position) { - std::string query = StringFormat("UPDATE `character_corpses` " - "SET `is_buried` = 0, `zone_id` = %u, `instance_id` = %u, " - "`x` = %f, `y` = %f, `z` = %f, `heading` = %f, " - "`time_of_death` = Now(), `was_at_graveyard` = 0 " - "WHERE `id` = %u", - new_zone_id, new_instance_id, - position.x, position.y, position.z, position.w, db_id); - auto results = QueryDatabase(query); - if (results.Success() && results.RowsAffected() != 0) - return true; + glm::vec4 position = glm::vec4(e.x, e.y, e.z, e.heading); - return false; -} - -Corpse* ZoneDatabase::LoadCharacterCorpse(uint32 player_corpse_id) { - Corpse* NewCorpse = 0; - std::string query = StringFormat( - "SELECT `id`, `charid`, `charname`, `x`, `y`, `z`, `heading`, `time_of_death`, `is_rezzed`, `was_at_graveyard`, `guild_consent_id` FROM `character_corpses` WHERE `id` = '%u' LIMIT 1", - player_corpse_id + c = Corpse::LoadCharacterCorpseEntity( + e.id, + e.charid, + e.charname, + position, + std::to_string(e.time_of_death), + e.is_rezzed == 1, + RuleB(Zone, EnableShadowrest) ? 0 : e.was_at_graveyard, + e.guild_consent_id ); - auto results = QueryDatabase(query); - for (auto& row = results.begin(); row != results.end(); ++row) { - auto position = glm::vec4(Strings::ToFloat(row[3]), Strings::ToFloat(row[4]), Strings::ToFloat(row[5]), Strings::ToFloat(row[6])); - NewCorpse = Corpse::LoadCharacterCorpseEntity( - Strings::ToUnsignedInt(row[0]), // id uint32 in_dbid - Strings::ToUnsignedInt(row[1]), // charid uint32 in_charid - row[2], // char_name - position, - row[7], // time_of_death char* time_of_death - Strings::ToInt(row[8]) == 1, // is_rezzed bool rezzed - Strings::ToInt(row[9]), // was_at_graveyard bool was_at_graveyard - Strings::ToUnsignedInt(row[10]) // guild_consent_id uint32 guild_consent_id - ); - entity_list.AddCorpse(NewCorpse); - } - return NewCorpse; + + entity_list.AddCorpse(c); + + return c; } -bool ZoneDatabase::LoadCharacterCorpses(uint32 zone_id, uint16 instance_id) { - std::string query; - if (!RuleB(Zone, EnableShadowrest)){ - query = StringFormat("SELECT id, charid, charname, x, y, z, heading, time_of_death, is_rezzed, was_at_graveyard, guild_consent_id FROM character_corpses WHERE zone_id='%u' AND instance_id='%u'", zone_id, instance_id); - } - else{ - query = StringFormat("SELECT id, charid, charname, x, y, z, heading, time_of_death, is_rezzed, 0 as was_at_graveyard, guild_consent_id FROM character_corpses WHERE zone_id='%u' AND instance_id='%u' AND is_buried=0", zone_id, instance_id); - } +bool ZoneDatabase::LoadCharacterCorpses(uint32 zone_id, uint16 instance_id) +{ + const auto& l = CharacterCorpsesRepository::GetWhere( + *this, + fmt::format( + "`zone_id` = {} AND `instance_id` = {}{}", + zone_id, + instance_id, + RuleB(Zone, EnableShadowrest) ? " AND `is_buried` = 0" : "" + ) + ); + + for (const auto& e : l) { + glm::vec4 position = glm::vec4(e.x, e.y, e.z, e.heading); - auto results = QueryDatabase(query); - for (auto& row = results.begin(); row != results.end(); ++row) { - auto position = glm::vec4(Strings::ToFloat(row[3]), Strings::ToFloat(row[4]), Strings::ToFloat(row[5]), Strings::ToFloat(row[6])); entity_list.AddCorpse( - Corpse::LoadCharacterCorpseEntity( - Strings::ToUnsignedInt(row[0]), // id uint32 in_dbid - Strings::ToUnsignedInt(row[1]), // charid uint32 in_charid - row[2], // char_name + Corpse::LoadCharacterCorpseEntity( + e.id, + e.charid, + e.charname, position, - row[7], // time_of_death char* time_of_death - Strings::ToInt(row[8]) == 1, // is_rezzed bool rezzed - Strings::ToInt(row[9]), - Strings::ToUnsignedInt(row[10])) // guild_consent_id uint32 guild_consent_id + std::to_string(e.time_of_death), + e.is_rezzed == 1, + RuleB(Zone, EnableShadowrest) ? 0 : e.was_at_graveyard, + e.guild_consent_id + ) ); } - LogInfo("Loaded [{}] player corpse(s)", Strings::Commify(results.RowCount())); - return true; } -uint32 ZoneDatabase::GetFirstCorpseID(uint32 char_id) { - std::string query = StringFormat("SELECT `id` FROM `character_corpses` WHERE `charid` = '%u' AND `is_buried` = 0 ORDER BY `time_of_death` LIMIT 1", char_id); - auto results = QueryDatabase(query); - for (auto& row = results.begin(); row != results.end(); ++row) { - return Strings::ToInt(row[0]); +uint32 ZoneDatabase::GetFirstCorpseID(uint32 character_id) +{ + const auto& l = CharacterCorpsesRepository::GetWhere( + *this, + fmt::format( + "`charid` = {} AND `is_buried` = 0 ORDER BY `time_of_death` LIMIT 1", + character_id + ) + ); + + if (l.empty()) { + return 0; } - return 0; + + return l[0].id; } -bool ZoneDatabase::DeleteItemOffCharacterCorpse(uint32 db_id, uint32 equip_slot, uint32 item_id){ - std::string query = StringFormat("DELETE FROM `character_corpse_items` WHERE `corpse_id` = %u AND equip_slot = %u AND item_id = %u", db_id, equip_slot, item_id); - auto results = QueryDatabase(query); - if (results.Success() && results.RowsAffected() != 0){ - return true; - } - return false; +bool ZoneDatabase::DeleteItemOffCharacterCorpse(uint32 corpse_id, uint32 slot_id, uint32 item_id) +{ + return CharacterCorpseItemsRepository::DeleteWhere( + *this, + fmt::format( + "`corpse_id` = {} AND `equip_slot` = {} AND `item_id` = {}", + corpse_id, + slot_id, + item_id + ) + ); } -bool ZoneDatabase::BuryCharacterCorpse(uint32 db_id) { - std::string query = StringFormat("UPDATE `character_corpses` SET `is_buried` = 1 WHERE `id` = %u", db_id); - auto results = QueryDatabase(query); - if (results.Success() && results.RowsAffected() != 0){ - return true; - } - return false; +bool ZoneDatabase::BuryCharacterCorpse(uint32 corpse_id) +{ + return CharacterCorpsesRepository::BuryCorpse(*this, corpse_id); } -bool ZoneDatabase::BuryAllCharacterCorpses(uint32 char_id) { - std::string query = StringFormat("SELECT `id` FROM `character_corpses` WHERE `charid` = %u", char_id); - auto results = QueryDatabase(query); - for (auto& row = results.begin(); row != results.end(); ++row) { - BuryCharacterCorpse(Strings::ToInt(row[0])); - return true; +bool ZoneDatabase::BuryAllCharacterCorpses(uint32 character_id) +{ + const auto& l = CharacterCorpsesRepository::GetWhere( + *this, + fmt::format( + "`charid` = {}", + character_id + ) + ); + + if (l.empty()) { + return false; } - return false; + + for (const auto& e : l) { + BuryCharacterCorpse(e.id); + } + + return true; } -bool ZoneDatabase::DeleteCharacterCorpse(uint32 db_id) { - std::string query = StringFormat("DELETE FROM `character_corpses` WHERE `id` = %d", db_id); - auto results = QueryDatabase(query); - if (results.Success() && results.RowsAffected() != 0) - return true; - - return false; +bool ZoneDatabase::DeleteCharacterCorpse(uint32 corpse_id) +{ + return CharacterCorpsesRepository::DeleteOne(*this, corpse_id); } double ZoneDatabase::GetAAEXPModifier(uint32 character_id, uint32 zone_id, int16 instance_version) const { diff --git a/zone/zonedb.h b/zone/zonedb.h index 07ed6547e..562a58671 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -476,32 +476,31 @@ public: bool RestoreCharacterInvSnapshot(uint32 character_id, uint32 timestamp); /* Corpses */ - bool DeleteItemOffCharacterCorpse(uint32 db_id, uint32 equip_slot, uint32 item_id); - bool LoadCharacterCorpseData(uint32 corpse_id, CharacterCorpseEntry &corpse); - Corpse* LoadCharacterCorpse(uint32 player_corpse_id); - Corpse* SummonBuriedCharacterCorpses(uint32 char_id, uint32 dest_zoneid, uint16 dest_instanceid, const glm::vec4& position); - void MarkCorpseAsRezzed(uint32 dbid); - bool GetDecayTimes(npcDecayTimes_Struct* npcCorpseDecayTimes); - bool BuryCharacterCorpse(uint32 dbid); - bool BuryAllCharacterCorpses(uint32 charid); - bool DeleteCharacterCorpse(uint32 dbid); - bool SummonAllCharacterCorpses(uint32 char_id, uint32 dest_zoneid, uint16 dest_instanceid, const glm::vec4& position); - int CountCharacterCorpses(uint32 char_id); - int CountCharacterCorpsesByZoneID(uint32 char_id, uint32 zone_id); - bool UnburyCharacterCorpse(uint32 dbid, uint32 new_zoneid, uint16 dest_instanceid, const glm::vec4& position); - bool LoadCharacterCorpses(uint32 iZoneID, uint16 iInstanceID); - uint32 GetCharacterCorpseDecayTimer(uint32 corpse_db_id); - uint32 GetCharacterBuriedCorpseCount(uint32 char_id); - uint32 SendCharacterCorpseToGraveyard(uint32 dbid, uint32 zoneid, uint16 instanceid, const glm::vec4& position); - uint32 SaveCharacterCorpse(uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, const CharacterCorpseEntry& corpse, const glm::vec4& position, uint32 guildid); - uint32 UpdateCharacterCorpse(uint32 dbid, uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, const CharacterCorpseEntry& corpse, const glm::vec4& position, uint32 guildid, bool rezzed = false); - uint32 UpdateCharacterCorpseConsent(uint32 charid, uint32 guildid); - uint32 GetFirstCorpseID(uint32 char_id); - uint32 GetCharacterCorpseCount(uint32 char_id); - uint32 GetCharacterCorpseID(uint32 char_id, uint8 corpse); - uint32 GetCharacterCorpseItemAt(uint32 corpse_id, uint16 slot_id); - uint32 GetPlayerCorpseTimeLeft(uint8 corpse, uint8 type); - void SendCharacterCorpseToNonInstance(uint32 corpse_db_id); + bool BuryAllCharacterCorpses(uint32 character_id); + bool BuryCharacterCorpse(uint32 corpse_id); + int64 CountCharacterCorpses(uint32 character_id); + int64 CountCharacterCorpsesByZoneID(uint32 character_id, uint32 zone_id); + bool DeleteCharacterCorpse(uint32 corpse_id); + bool DeleteItemOffCharacterCorpse(uint32 corpse_id, uint32 slot_id, uint32 item_id); + uint32 GetCharacterBuriedCorpseCount(uint32 character_id); + int64 GetCharacterCorpseCount(uint32 character_id); + uint32 GetCharacterCorpseDecayTimer(uint32 corpse_id); + uint32 GetCharacterCorpseID(uint32 character_id, uint8 corpse_limit); + uint32 GetCharacterCorpseItemAt(uint32 corpse_id, uint16 slot_id); + bool GetDecayTimes(npcDecayTimes_Struct* npc_decay_times); + uint32 GetFirstCorpseID(uint32 character_id); + Corpse* LoadCharacterCorpse(uint32 corpse_id); + bool LoadCharacterCorpseData(uint32 corpse_id, CharacterCorpseEntry &corpse); + bool LoadCharacterCorpses(uint32 zone_id, uint16 instance_id); + void MarkCorpseAsResurrected(uint32 corpse_id); + uint32 SaveCharacterCorpse(uint32 character_id, const std::string& name, uint32 zone_id, uint16 instance_id, const CharacterCorpseEntry& c, const glm::vec4& position, uint32 guild_consent_id); + uint32 SendCharacterCorpseToGraveyard(uint32 corpse_id, uint32 zone_id, uint16 instance_id, glm::vec4& position); + void SendCharacterCorpseToNonInstance(uint32 corpse_id); + Corpse* SummonBuriedCharacterCorpses(uint32 character_id, uint32 zone_id, uint16 instance_id, const glm::vec4& position); + bool SummonAllCharacterCorpses(uint32 character_id, uint32 zone_id, uint16 instance_id, const glm::vec4& position); + bool UnburyCharacterCorpse(uint32 corpse_id, uint32 zone_id, uint16 instance_id, const glm::vec4& position); + uint32 UpdateCharacterCorpse(uint32 corpse_id, uint32 character_id, const std::string& name, uint32 zone_id, uint16 instance_id, const CharacterCorpseEntry& c, const glm::vec4& position, uint32 guild_consent_id, bool is_resurrected = false); + uint32 UpdateCharacterCorpseConsent(uint32 character_id, uint32 guild_consent_id); /* Faction */ bool GetNPCFactionList(uint32 npcfaction_id, int32* faction_id, int32* value, uint8* temp, int32* primary_faction = 0);