diff --git a/common/database.cpp b/common/database.cpp index 12ef93223..acc6175a6 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -48,6 +48,7 @@ #include "guilds.h" #include "string_util.h" #include "extprofile.h" + extern Client client; #ifdef _WINDOWS @@ -1349,7 +1350,6 @@ bool Database::CheckDatabaseConversions() { printf("Starting conversion...\n\n"); } - // Testing account = 11001 int char_iter_count = 0; rquery = StringFormat("SELECT `id` FROM `character_`"); results = QueryDatabase(rquery); @@ -2084,6 +2084,275 @@ bool Database::CheckDatabaseConversions() { #endif + DBPlayerCorpse_Struct_temp* dbpc; + classic_db_temp::DBPlayerCorpse_Struct_temp* dbpc_c; + uint32 in_datasize; + bool is_sof = false; + std::string c_type; + std::string scquery; + int8 first_entry = 0; + + rquery = StringFormat("SHOW COLUMNS FROM `character_corpses` LIKE 'data'"); + results = QueryDatabase(rquery); + if (results.RowCount() != 0){ + rquery = StringFormat("SELECT DISTINCT charid FROM character_corpses"); + results = QueryDatabase(rquery); + for (auto row = results.begin(); row != results.end(); ++row) { + squery = StringFormat("SELECT id, charname, data, time_of_death, is_rezzed FROM character_corpses WHERE `charid` = %i", atoi(row[0])); + auto results2 = QueryDatabase(squery); + for (auto row2 = results2.begin(); row2 != results2.end(); ++row2) { + in_datasize = results2.LengthOfColumn(2); + dbpc = (DBPlayerCorpse_Struct_temp*)row2[2]; + dbpc_c = (classic_db_temp::DBPlayerCorpse_Struct_temp*)row2[2]; + + if (dbpc == nullptr) + continue; + if (dbpc_c == nullptr) + continue; + + + /* SoF+ */ + uint32 esize1 = (sizeof(DBPlayerCorpse_Struct_temp)+(dbpc->itemcount * sizeof(player_lootitem_temp::ServerLootItem_Struct_temp))); + uint32 esize2 = (sizeof(classic_db_temp::DBPlayerCorpse_Struct_temp) + (dbpc_c->itemcount * sizeof(player_lootitem_temp::ServerLootItem_Struct_temp))); + + /* SoF */ + if (in_datasize == esize1) { + is_sof = true; + c_type = "SOF"; + } + /* Classic */ + if (in_datasize == esize2) { + is_sof = false; + c_type = "Legacy"; + } + if (in_datasize != esize2 && in_datasize != esize1) { + std::cout << "[Error] in Corpse Size - OLD SIZE: " << esize1 << " SOF SIZE: " << esize2 << " db_blob_datasize: " << in_datasize << std::endl; + is_sof = false; + c_type = "NULL"; + continue; + } + std::cout << "Corpse: OK [" << c_type << "]: " << "Corpse ID: " << atoi(row2[0]) << std::endl; + + if (is_sof){ + scquery = StringFormat("UPDATE `character_corpses` SET \n" + "`is_locked` = %d,\n" + "`exp` = %u,\n" + "`size` = %f,\n" + "`level` = %u,\n" + "`race` = %u,\n" + "`gender` = %u,\n" + "`class` = %u,\n" + "`deity` = %u,\n" + "`texture` = %u,\n" + "`helm_texture` = %u,\n" + "`copper` = %u,\n" + "`silver` = %u,\n" + "`gold` = %u,\n" + "`platinum` = %u,\n" + "`hair_color` = %u,\n" + "`beard_color` = %u,\n" + "`eye_color_1` = %u,\n" + "`eye_color_2` = %u,\n" + "`hair_style` = %u,\n" + "`face` = %u,\n" + "`beard` = %u,\n" + "`drakkin_heritage` = %u,\n" + "`drakkin_tattoo` = %u,\n" + "`drakkin_details` = %u,\n" + "`wc_1` = %u,\n" + "`wc_2` = %u,\n" + "`wc_3` = %u,\n" + "`wc_4` = %u,\n" + "`wc_5` = %u,\n" + "`wc_6` = %u,\n" + "`wc_7` = %u,\n" + "`wc_8` = %u,\n" + "`wc_9` = %u \n" + "WHERE `id` = %u \n", + dbpc->locked, + dbpc->exp, + dbpc->size, + dbpc->level, + dbpc->race, + dbpc->gender, + dbpc->class_, + dbpc->deity, + dbpc->texture, + dbpc->helmtexture, + dbpc->copper, + dbpc->silver, + dbpc->gold, + dbpc->plat, + dbpc->haircolor, + dbpc->beardcolor, + dbpc->eyecolor1, + dbpc->eyecolor2, + dbpc->hairstyle, + dbpc->face, + dbpc->beard, + dbpc->drakkin_heritage, + dbpc->drakkin_tattoo, + dbpc->drakkin_details, + dbpc->item_tint[0].color, + dbpc->item_tint[1].color, + dbpc->item_tint[2].color, + dbpc->item_tint[3].color, + dbpc->item_tint[4].color, + dbpc->item_tint[5].color, + dbpc->item_tint[6].color, + dbpc->item_tint[7].color, + dbpc->item_tint[8].color, + atoi(row2[0]) + ); + if (scquery != ""){ auto sc_results = QueryDatabase(scquery); ThrowDBError(sc_results.ErrorMessage(), "Corpse Convert: Base Data", scquery); } + + first_entry = 0; + scquery = ""; + /* Print Items */ + for (unsigned int i = 0; i < dbpc->itemcount; i++) { + if (first_entry != 1){ + scquery = StringFormat("REPLACE INTO `character_corpse_items` \n" + " (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, attuned) \n" + " VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, 0) \n", + atoi(row2[0]), + dbpc->items[i].equipSlot, + dbpc->items[i].item_id, + dbpc->items[i].charges, + dbpc->items[i].aug1, + dbpc->items[i].aug2, + dbpc->items[i].aug3, + dbpc->items[i].aug4, + dbpc->items[i].aug5 + ); + first_entry = 1; + } + else{ + scquery = scquery + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, 0) \n", + atoi(row2[0]), + dbpc->items[i].equipSlot, + dbpc->items[i].item_id, + dbpc->items[i].charges, + dbpc->items[i].aug1, + dbpc->items[i].aug2, + dbpc->items[i].aug3, + dbpc->items[i].aug4, + dbpc->items[i].aug5 + ); + } + } + if (scquery != ""){ auto sc_results = QueryDatabase(scquery); ThrowDBError(sc_results.ErrorMessage(), "Corpse Convert: SOF: Items", scquery); } + } + else{ + /* Classic Converter */ + scquery = StringFormat("UPDATE `character_corpses` SET \n" + "`is_locked` = %d,\n" + "`exp` = %u,\n" + "`size` = %f,\n" + "`level` = %u,\n" + "`race` = %u,\n" + "`gender` = %u,\n" + "`class` = %u,\n" + "`deity` = %u,\n" + "`texture` = %u,\n" + "`helm_texture` = %u,\n" + "`copper` = %u,\n" + "`silver` = %u,\n" + "`gold` = %u,\n" + "`platinum` = %u,\n" + "`hair_color` = %u,\n" + "`beard_color` = %u,\n" + "`eye_color_1` = %u,\n" + "`eye_color_2` = %u,\n" + "`hair_style` = %u,\n" + "`face` = %u,\n" + "`beard` = %u,\n" + "`wc_1` = %u,\n" + "`wc_2` = %u,\n" + "`wc_3` = %u,\n" + "`wc_4` = %u,\n" + "`wc_5` = %u,\n" + "`wc_6` = %u,\n" + "`wc_7` = %u,\n" + "`wc_8` = %u,\n" + "`wc_9` = %u \n" + "WHERE `id` = %u \n", + dbpc_c->locked, + dbpc_c->exp, + dbpc_c->size, + dbpc_c->level, + dbpc_c->race, + dbpc_c->gender, + dbpc_c->class_, + dbpc_c->deity, + dbpc_c->texture, + dbpc_c->helmtexture, + dbpc_c->copper, + dbpc_c->silver, + dbpc_c->gold, + dbpc_c->plat, + dbpc_c->haircolor, + dbpc_c->beardcolor, + dbpc_c->eyecolor1, + dbpc_c->eyecolor2, + dbpc_c->hairstyle, + dbpc_c->face, + dbpc_c->beard, + dbpc_c->item_tint[0].color, + dbpc_c->item_tint[1].color, + dbpc_c->item_tint[2].color, + dbpc_c->item_tint[3].color, + dbpc_c->item_tint[4].color, + dbpc_c->item_tint[5].color, + dbpc_c->item_tint[6].color, + dbpc_c->item_tint[7].color, + dbpc_c->item_tint[8].color, + atoi(row2[0]) + ); + if (scquery != ""){ auto sc_results = QueryDatabase(scquery); ThrowDBError(sc_results.ErrorMessage(), "Corpse Convert: Legacy :: Base Data", scquery); } + + first_entry = 0; + scquery = ""; + + /* Print Items */ + for (unsigned int i = 0; i < dbpc_c->itemcount; i++) { + if (first_entry != 1){ + scquery = StringFormat("REPLACE INTO `character_corpse_items` \n" + " (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, attuned) \n" + " VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, 0) \n", + atoi(row2[0]), + dbpc_c->items[i].equipSlot, + dbpc_c->items[i].item_id, + dbpc_c->items[i].charges, + dbpc_c->items[i].aug1, + dbpc_c->items[i].aug2, + dbpc_c->items[i].aug3, + dbpc_c->items[i].aug4, + dbpc_c->items[i].aug5 + ); + first_entry = 1; + } + else{ + scquery = scquery + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, 0) \n", + atoi(row2[0]), + dbpc_c->items[i].equipSlot, + dbpc_c->items[i].item_id, + dbpc_c->items[i].charges, + dbpc_c->items[i].aug1, + dbpc_c->items[i].aug2, + dbpc_c->items[i].aug3, + dbpc_c->items[i].aug4, + dbpc_c->items[i].aug5 + ); + } + } + if (scquery != ""){ auto sc_results = QueryDatabase(scquery); ThrowDBError(sc_results.ErrorMessage(), "Corpse Convert: Legacy : Items", scquery); } + } + } + } + QueryDatabase(StringFormat("ALTER TABLE `character_corpses` DROP COLUMN `data`")); + } + + /* Fetch Automatic Database Upgrade Script */ if (!std::ifstream("db_update.pl")){ std::cout << "Pulling down automatic database upgrade script...\n" << std::endl; @@ -2093,8 +2362,8 @@ bool Database::CheckDatabaseConversions() { system("wget -O db_update.pl https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/db_update.pl"); #endif } - /* Run Automatic Database Upgrade Script */ + /* Run Automatic Database Upgrade Script */ system("perl db_update.pl ran_from_world"); return true; @@ -3659,7 +3928,7 @@ bool Database::CheckInstanceExists(uint16 instance_id) void Database::BuryCorpsesInInstance(uint16 instance_id) { - std::string query = StringFormat("UPDATE player_corpses SET IsBurried=1, instanceid=0 WHERE instanceid=%u", instance_id); + std::string query = StringFormat("UPDATE character_corpses SET IsBurried=1, instanceid=0 WHERE instanceid=%u", instance_id); auto results = QueryDatabase(query); } diff --git a/common/database.h b/common/database.h index 9b388c84a..e089b22a9 100644 --- a/common/database.h +++ b/common/database.h @@ -93,6 +93,87 @@ struct ExtendedProfile_Struct; struct GuildMember_Struct; class PTimerList; +#pragma pack(1) + +namespace player_lootitem_temp +{ + struct ServerLootItem_Struct_temp { + uint32 item_id; + int16 equipSlot; + uint8 charges; + uint16 lootslot; + uint32 aug1; + uint32 aug2; + uint32 aug3; + uint32 aug4; + uint32 aug5; + }; +} + +struct DBPlayerCorpse_Struct_temp { + uint32 crc; + bool locked; + uint32 itemcount; + uint32 exp; + float size; + uint8 level; + uint8 race; + uint8 gender; + uint8 class_; + uint8 deity; + uint8 texture; + uint8 helmtexture; + uint32 copper; + uint32 silver; + uint32 gold; + uint32 plat; + Color_Struct item_tint[9]; + uint8 haircolor; + uint8 beardcolor; + uint8 eyecolor1; + uint8 eyecolor2; + uint8 hairstyle; + uint8 face; + uint8 beard; + uint32 drakkin_heritage; + uint32 drakkin_tattoo; + uint32 drakkin_details; + player_lootitem_temp::ServerLootItem_Struct_temp items[0]; +}; + +namespace classic_db_temp +{ + struct DBPlayerCorpse_Struct_temp { + uint32 crc; + bool locked; + uint32 itemcount; + uint32 exp; + float size; + uint8 level; + uint8 race; + uint8 gender; + uint8 class_; + uint8 deity; + uint8 texture; + uint8 helmtexture; + uint32 copper; + uint32 silver; + uint32 gold; + uint32 plat; + Color_Struct item_tint[9]; + uint8 haircolor; + uint8 beardcolor; + uint8 eyecolor1; + uint8 eyecolor2; + uint8 hairstyle; + uint8 face; + uint8 beard; + player_lootitem_temp::ServerLootItem_Struct_temp items[0]; + }; +} + +#pragma pack() + class Database : public DBcore { public: Database(); diff --git a/common/dbcore.cpp b/common/dbcore.cpp index fb038db2e..9e12f64aa 100644 --- a/common/dbcore.cpp +++ b/common/dbcore.cpp @@ -4,6 +4,7 @@ #include #endif +#include #include #include #include @@ -126,6 +127,16 @@ MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, boo MySQLRequestResult requestResult(res, (uint32)mysql_affected_rows(&mysql), rowCount, (uint32)mysql_field_count(&mysql), (uint32)mysql_insert_id(&mysql)); + /* Implement Logging at the Root*/ + if (requestResult.ErrorMessage() != ""){ + std::cout << "\n[MYSQL ERR] " << requestResult.ErrorMessage() << "\n\n" << query << "\n" << std::endl; + /* Write to log file */ + std::ofstream log("eqemu_query_error_log.txt", std::ios_base::app | std::ios_base::out); + log << "[MYSQL ERR] " << requestResult.ErrorMessage() << "\n" << query << "\n"; + log.close(); + } + + #if DEBUG_MYSQL_QUERIES >= 1 if (requestResult.Success()) diff --git a/common/shareddb.cpp b/common/shareddb.cpp index b0f29c74b..ae19d8e1f 100644 --- a/common/shareddb.cpp +++ b/common/shareddb.cpp @@ -1217,8 +1217,8 @@ ItemInst* SharedDatabase::CreateBaseItem(const Item_Struct* item, int16 charges) int32 SharedDatabase::DeleteStalePlayerCorpses() { if(RuleB(Zone, EnableShadowrest)) { - std::string query = StringFormat("UPDATE player_corpses SET IsBurried = 1 WHERE IsBurried = 0 AND " - "(UNIX_TIMESTAMP() - UNIX_TIMESTAMP(timeofdeath)) > %d AND NOT timeofdeath = 0", + std::string query = StringFormat("UPDATE character_corpses SET IsBurried = 1 WHERE IsBurried = 0 AND " + "(UNIX_TIMESTAMP() - UNIX_TIMESTAMP(time_of_death)) > %d AND NOT time_of_death = 0", (RuleI(Character, CorpseDecayTimeMS) / 1000)); auto results = QueryDatabase(query); if (!results.Success()) @@ -1227,8 +1227,8 @@ int32 SharedDatabase::DeleteStalePlayerCorpses() { return results.RowsAffected(); } - std::string query = StringFormat("DELETE FROM player_corpses WHERE (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(timeofdeath)) > %d " - "AND NOT timeofdeath = 0", (RuleI(Character, CorpseDecayTimeMS) / 1000)); + 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)); auto results = QueryDatabase(query); if (!results.Success()) return -1; @@ -1238,7 +1238,7 @@ int32 SharedDatabase::DeleteStalePlayerCorpses() { int32 SharedDatabase::DeleteStalePlayerBackups() { // 1209600 seconds = 2 weeks - const std::string query = "DELETE FROM player_corpses_backup WHERE (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(timeofdeath)) > 1209600"; + const std::string query = "DELETE FROM player_corpses_backup WHERE (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(time_of_death)) > 1209600"; auto results = QueryDatabase(query); if (!results.Success()) return -1; diff --git a/world/adventure.cpp b/world/adventure.cpp index 5f61aa5e9..ffb64779c 100644 --- a/world/adventure.cpp +++ b/world/adventure.cpp @@ -376,7 +376,7 @@ void Adventure::MoveCorpsesToGraveyard() std::list dbid_list; std::list charid_list; - std::string query = StringFormat("SELECT id, charid FROM player_corpses WHERE instanceid=%d", GetInstanceID()); + std::string query = StringFormat("SELECT id, charid FROM character_corpses WHERE instanceid=%d", GetInstanceID()); auto results = database.QueryDatabase(query); if(!results.Success()) LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::MoveCorpsesToGraveyard: %s (%s)", query.c_str(), results.ErrorMessage().c_str()); @@ -392,7 +392,7 @@ void Adventure::MoveCorpsesToGraveyard() float y = GetTemplate()->graveyard_y + MakeRandomFloat(-GetTemplate()->graveyard_radius, GetTemplate()->graveyard_radius); float z = GetTemplate()->graveyard_z; - query = StringFormat("UPDATE player_corpses " + query = StringFormat("UPDATE character_corpses " "SET zoneid = %d, instanceid = 0, " "x = %f, y = %f, z = %f WHERE instanceid = %d", GetTemplate()->graveyard_zone_id, diff --git a/zone/client.cpp b/zone/client.cpp index 9b10cb174..2c2b82aaa 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -4969,7 +4969,7 @@ void Client::SummonAndRezzAllCorpses() entity_list.RemoveAllCorpsesByCharID(CharacterID()); - int CorpseCount = database.SummonAllPlayerCorpses(CharacterID(), zone->GetZoneID(), zone->GetInstanceID(), + int CorpseCount = database.SummonAllCharacterCorpses(CharacterID(), zone->GetZoneID(), zone->GetInstanceID(), GetX(), GetY(), GetZ(), GetHeading()); if(CorpseCount <= 0) { @@ -5007,7 +5007,7 @@ void Client::SummonAllCorpses(float dest_x, float dest_y, float dest_z, float de entity_list.RemoveAllCorpsesByCharID(CharacterID()); - int CorpseCount = database.SummonAllPlayerCorpses(CharacterID(), zone->GetZoneID(), zone->GetInstanceID(), + int CorpseCount = database.SummonAllCharacterCorpses(CharacterID(), zone->GetZoneID(), zone->GetInstanceID(), dest_x, dest_y, dest_z, dest_heading); if(CorpseCount <= 0) { @@ -5051,7 +5051,7 @@ void Client::DepopPlayerCorpse(uint32 dbid) void Client::BuryPlayerCorpses() { - database.BuryAllPlayerCorpses(CharacterID()); + database.BuryAllCharacterCorpses(CharacterID()); } void Client::NotifyNewTitlesAvailable() diff --git a/zone/client.h b/zone/client.h index 3e54771ad..2f4ac0206 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1031,9 +1031,9 @@ void SetConsumption(int32 in_hunger, int32 in_thirst); void DepopAllCorpses(); void DepopPlayerCorpse(uint32 dbid); void BuryPlayerCorpses(); - uint32 GetCorpseCount() { return database.GetPlayerCorpseCount(CharacterID()); } - uint32 GetCorpseID(int corpse) { return database.GetPlayerCorpseID(CharacterID(), corpse); } - uint32 GetCorpseItemAt(int corpse_id, int slot_id) { return database.GetPlayerCorpseItemAt(corpse_id, slot_id); } + uint32 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(); void Doppelganger(uint16 spell_id, Mob *target, const char *name_override, int pet_count, int pet_duration); void NotifyNewTitlesAvailable(); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 238f324f2..000ed8fcc 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -4827,7 +4827,7 @@ void Client::Handle_OP_ConsiderCorpse(const EQApplicationPacket *app) else Message(0, "This corpse will decay in %i minutes and %i seconds.", min, sec); - Message(0, "This corpse %s be resurrected.", tcorpse->Rezzed() ? "cannot" : "can"); + Message(0, "This corpse %s be resurrected.", tcorpse->IsRezzed() ? "cannot" : "can"); /* hour = 0; @@ -6175,8 +6175,8 @@ void Client::Handle_OP_GMSearchCorpse(const EQApplicationPacket *app) char *escSearchString = new char[129]; database.DoEscapeString(escSearchString, gmscs->Name, strlen(gmscs->Name)); - std::string query = StringFormat("SELECT charname, zoneid, x, y, z, timeofdeath, rezzed, IsBurried " - "FROM player_corpses WheRE charname LIKE '%%%s%%' ORDER BY charname LIMIT %i", + std::string query = StringFormat("SELECT charname, zoneid, x, y, z, time_of_death, rezzed, IsBurried " + "FROM character_corpses WheRE charname LIKE '%%%s%%' ORDER BY charname LIMIT %i", escSearchString, maxResults); safe_delete_array(escSearchString); auto results = database.QueryDatabase(query); @@ -6193,7 +6193,7 @@ void Client::Handle_OP_GMSearchCorpse(const EQApplicationPacket *app) else Message(clientMessageYellow, "There are %i corpse(s) that match the search string '%s'.", results.RowCount(), gmscs->Name); - char charName[64], timeOfDeath[20]; + char charName[64], time_of_death[20]; std::string popupText = "", - charName, StaticGetZoneName(ZoneID), CorpseX, CorpseY, CorpseZ, timeOfDeath, + charName, StaticGetZoneName(ZoneID), CorpseX, CorpseY, CorpseZ, time_of_death, corpseRezzed ? "Yes" : "No", corpseBuried ? "Yes" : "No"); if (popupText.size() > 4000) { diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 13973df91..c4eb01f4a 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -2173,7 +2173,7 @@ void Client::HandleRespawnFromHover(uint32 Option) _log(SPELLS__REZ, "Found corpse. Marking corpse as rezzed."); - corpse->Rezzed(true); + corpse->IsRezzed(true); corpse->CompleteRezz(); } } diff --git a/zone/command.cpp b/zone/command.cpp index ce3d67fd6..27516d5a5 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -8456,7 +8456,7 @@ void command_setgraveyard(Client *c, const Seperator *sep) zoneid = database.GetZoneID(sep->arg[1]); if(zoneid > 0) { - graveyard_id = database.NewGraveyardRecord(zoneid, t->GetX(), t->GetY(), t->GetZ(), t->GetHeading()); + graveyard_id = database.CreateGraveyardRecord(zoneid, t->GetX(), t->GetY(), t->GetZ(), t->GetHeading()); if(graveyard_id > 0) { c->Message(0, "Successfuly added a new record for this graveyard!"); @@ -8519,7 +8519,7 @@ void command_summonburriedplayercorpse(Client *c, const Seperator *sep) return; } - Corpse* PlayerCorpse = database.SummonBurriedPlayerCorpse(t->CharacterID(), t->GetZoneID(), zone->GetInstanceID(), t->GetX(), t->GetY(), t->GetZ(), t->GetHeading()); + Corpse* PlayerCorpse = database.SummonBuriedCharacterCorpses(t->CharacterID(), t->GetZoneID(), zone->GetInstanceID(), t->GetX(), t->GetY(), t->GetZ(), t->GetHeading()); if(!PlayerCorpse) c->Message(0, "Your target doesn't have any burried corpses."); @@ -8538,7 +8538,7 @@ void command_getplayerburriedcorpsecount(Client *c, const Seperator *sep) return; } - uint32 CorpseCount = database.GetPlayerBurriedCorpseCount(t->CharacterID()); + uint32 CorpseCount = database.GetCharacterBuriedCorpseCount(t->CharacterID()); if(CorpseCount > 0) c->Message(0, "Your target has a total of %u burried corpses.", CorpseCount); diff --git a/zone/corpse.cpp b/zone/corpse.cpp index 8df695a84..886d32aac 100644 --- a/zone/corpse.cpp +++ b/zone/corpse.cpp @@ -63,131 +63,40 @@ void Corpse::SendLootReqErrorPacket(Client* client, uint8 response) { safe_delete(outapp); } -Corpse* Corpse::LoadFromDBData(uint32 in_dbid, uint32 in_charid, char* in_charname, uchar* in_data, uint32 in_datasize, float in_x, float in_y, float in_z, float in_heading, char* timeofdeath, bool rezzed, bool wasAtGraveyard) { - if (in_datasize < sizeof(classic_db::DBPlayerCorpse_Struct)) { - LogFile->write(EQEMuLog::Error, "Corpse::LoadFromDBData: Corrupt data: in_datasize < sizeof(DBPlayerCorpse_Struct)"); - return 0; - } - classic_db::DBPlayerCorpse_Struct* dbpc = (classic_db::DBPlayerCorpse_Struct*) in_data; - bool isSoF = true; - - uint32 esize1 = (sizeof(DBPlayerCorpse_Struct) + (dbpc->itemcount * sizeof(player_lootitem::ServerLootItem_Struct))); - uint32 esize2 = (sizeof(classic_db::DBPlayerCorpse_Struct) + (dbpc->itemcount * sizeof(player_lootitem::ServerLootItem_Struct))); - if (in_datasize != esize1) { - LogFile->write(EQEMuLog::Error, "Corpse::LoadFromDBData: Corrupt data: in_datasize (%i) != expected size (%i) Continuing on...", in_datasize, esize1); - if (in_datasize != esize2) { - LogFile->write(EQEMuLog::Error, "Corpse::LoadFromDBData: Corrupt data: in_datasize (%i) != expected size (%i) Your corpse is done broke, sir.", in_datasize, esize2); - return 0; - } - else - { - isSoF = false; - } +Corpse* Corpse::LoadFromDBData(uint32 in_dbid, uint32 in_charid, char* in_charname, PlayerCorpse_Struct* pcs, float in_x, float in_y, float in_z, float in_heading, char* time_of_death, bool rezzed, bool was_at_graveyard) { + /* Load Items */ + ItemList itemlist; + ServerLootItem_Struct* tmp = 0; + for (unsigned int i = 0; i < pcs->itemcount; i++) { + tmp = new ServerLootItem_Struct; + memcpy(tmp, &pcs->items[i], sizeof(player_lootitem::ServerLootItem_Struct)); + tmp->equipSlot = CorpseToServerSlot(tmp->equipSlot); + itemlist.push_back(tmp); } - if(isSoF) - { - DBPlayerCorpse_Struct* dbpcs = (DBPlayerCorpse_Struct*) in_data; - if (dbpcs->crc != CRC32::Generate(&((uchar*) dbpcs)[4], in_datasize - 4)) { - LogFile->write(EQEMuLog::Error, "Corpse::LoadFromDBData: Corrupt data: crc failure"); - return 0; - } - ItemList itemlist; - ServerLootItem_Struct* tmp = 0; - for (unsigned int i=0; i < dbpcs->itemcount; i++) { - tmp = new ServerLootItem_Struct; - memcpy(tmp, &dbpcs->items[i], sizeof(player_lootitem::ServerLootItem_Struct)); - tmp->equipSlot = CorpseToServerSlot(tmp->equipSlot); // temp hack until corpse blobs are removed - itemlist.push_back(tmp); - } + /* Create Corpse Entity */ + Corpse* pc = new Corpse(in_dbid, in_charid, in_charname, &itemlist, pcs->copper, pcs->silver, pcs->gold, pcs->plat, in_x, in_y, in_z, in_heading, pcs->size, pcs->gender, pcs->race, pcs->class_, pcs->deity, pcs->level, pcs->texture, pcs->helmtexture, pcs->exp, was_at_graveyard); + if (pcs->locked) + pc->Lock(); - // Little hack to account for the fact the race in the corpse struct is a uint8 and Froglok/Drakkin race number > 255 - // and to maintain backwards compatability with existing corpses in the database. - uint16 RealRace; + /* Load Item Tints */ + memcpy(pc->item_tint, pcs->item_tint, sizeof(pc->item_tint)); + + /* Load Physical Appearance */ + pc->haircolor = pcs->haircolor; + pc->beardcolor = pcs->beardcolor; + pc->eyecolor1 = pcs->eyecolor1; + pc->eyecolor2 = pcs->eyecolor2; + pc->hairstyle = pcs->hairstyle; + pc->luclinface = pcs->face; + pc->beard = pcs->beard; + pc->drakkin_heritage = pcs->drakkin_heritage; + pc->drakkin_tattoo = pcs->drakkin_tattoo; + pc->drakkin_details = pcs->drakkin_details; + pc->IsRezzed(rezzed); + pc->become_npc = false; - switch(dbpcs->race) { - case 254: - RealRace = DRAKKIN; - break; - case 255: - RealRace = FROGLOK; - break; - default: - RealRace = dbpc->race; - } - - Corpse* pc = new Corpse(in_dbid, in_charid, in_charname, &itemlist, dbpcs->copper, dbpcs->silver, dbpcs->gold, dbpcs->plat, in_x, in_y, in_z, in_heading, dbpcs->size, dbpcs->gender, RealRace, dbpcs->class_, dbpcs->deity, dbpcs->level, dbpcs->texture, dbpcs->helmtexture, dbpcs->exp, wasAtGraveyard); - if (dbpcs->locked) - pc->Lock(); - - // load tints - memcpy(pc->item_tint, dbpcs->item_tint, sizeof(pc->item_tint)); - // appearance - pc->haircolor = dbpcs->haircolor; - pc->beardcolor = dbpcs->beardcolor; - pc->eyecolor1 = dbpcs->eyecolor1; - pc->eyecolor2 = dbpcs->eyecolor2; - pc->hairstyle = dbpcs->hairstyle; - pc->luclinface = dbpcs->face; - pc->beard = dbpcs->beard; - pc->drakkin_heritage = dbpcs->drakkin_heritage; - pc->drakkin_tattoo = dbpcs->drakkin_tattoo; - pc->drakkin_details = dbpcs->drakkin_details; - pc->Rezzed(rezzed); - pc->become_npc = false; - return pc; - } - else - { - if (dbpc->crc != CRC32::Generate(&((uchar*) dbpc)[4], in_datasize - 4)) { - LogFile->write(EQEMuLog::Error, "Corpse::LoadFromDBData: Corrupt data: crc failure"); - return 0; - } - ItemList itemlist; - ServerLootItem_Struct* tmp = 0; - for (unsigned int i=0; i < dbpc->itemcount; i++) { - tmp = new ServerLootItem_Struct; - memcpy(tmp, &dbpc->items[i], sizeof(player_lootitem::ServerLootItem_Struct)); - tmp->equipSlot = CorpseToServerSlot(tmp->equipSlot); // temp hack until corpse blobs are removed - itemlist.push_back(tmp); - } - - // Little hack to account for the fact the race in the corpse struct is a uint8 and Froglok/Drakkin race number > 255 - // and to maintain backwards compatability with existing corpses in the database. - uint16 RealRace; - - switch(dbpc->race) { - case 254: - RealRace = DRAKKIN; - break; - case 255: - RealRace = FROGLOK; - break; - default: - RealRace = dbpc->race; - } - - Corpse* pc = new Corpse(in_dbid, in_charid, in_charname, &itemlist, dbpc->copper, dbpc->silver, dbpc->gold, dbpc->plat, in_x, in_y, in_z, in_heading, dbpc->size, dbpc->gender, RealRace, dbpc->class_, dbpc->deity, dbpc->level, dbpc->texture, dbpc->helmtexture,dbpc->exp, wasAtGraveyard); - if (dbpc->locked) - pc->Lock(); - - // load tints - memcpy(pc->item_tint, dbpc->item_tint, sizeof(pc->item_tint)); - // appearance - pc->haircolor = dbpc->haircolor; - pc->beardcolor = dbpc->beardcolor; - pc->eyecolor1 = dbpc->eyecolor1; - pc->eyecolor2 = dbpc->eyecolor2; - pc->hairstyle = dbpc->hairstyle; - pc->luclinface = dbpc->face; - pc->beard = dbpc->beard; - pc->drakkin_heritage = 0; - pc->drakkin_tattoo = 0; - pc->drakkin_details = 0; - pc->Rezzed(rezzed); - pc->become_npc = false; - return pc; - } + return pc; } // To be used on NPC death and ZoneStateLoad @@ -222,7 +131,7 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP npctype_id = in_npctypeid; SetPKItem(0); charid = 0; - dbid = 0; + corpse_db_id = 0; p_depop = false; strcpy(orgname, in_npc->GetName()); strcpy(name, in_npc->GetName()); @@ -331,7 +240,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) pLocked = false; BeingLootedBy = 0xFFFFFFFF; charid = client->CharacterID(); - dbid = 0; + corpse_db_id = 0; p_depop = false; copper = 0; silver = 0; @@ -435,14 +344,14 @@ Corpse::Corpse(Client* client, int32 in_rezexp) client->CalcBonuses(); // will only affect offline profile viewing of dead characters..unneeded overhead client->Save(); - Rezzed(false); + IsRezzed(false); Save(); database.TransactionCommit(); return; } //end "not leaving naked corpses" - Rezzed(false); + IsRezzed(false); Save(); } @@ -503,7 +412,7 @@ Corpse::Corpse(uint32 in_dbid, uint32 in_charid, char* in_charname, ItemList* in p_PlayerCorpse = true; pLocked = false; BeingLootedBy = 0xFFFFFFFF; - dbid = in_dbid; + corpse_db_id = in_dbid; p_depop = false; charid = in_charid; itemlist = *in_itemlist; @@ -522,7 +431,7 @@ Corpse::Corpse(uint32 in_dbid, uint32 in_charid, char* in_charname, ItemList* in } Corpse::~Corpse() { - if (p_PlayerCorpse && !(p_depop && dbid == 0)) { + if (p_PlayerCorpse && !(p_depop && corpse_db_id == 0)) { Save(); } ItemList::iterator cur,end; @@ -557,8 +466,8 @@ bool Corpse::Save() { return true; uint32 tmp = this->CountItems(); - uint32 tmpsize = sizeof(DBPlayerCorpse_Struct) + (tmp * sizeof(player_lootitem::ServerLootItem_Struct)); - DBPlayerCorpse_Struct* dbpc = (DBPlayerCorpse_Struct*) new uchar[tmpsize]; + uint32 tmpsize = sizeof(PlayerCorpse_Struct)+(tmp * sizeof(player_lootitem::ServerLootItem_Struct)); + PlayerCorpse_Struct* dbpc = (PlayerCorpse_Struct*) new uchar[tmpsize]; memset(dbpc, 0, tmpsize); dbpc->itemcount = tmp; dbpc->size = this->size; @@ -567,23 +476,7 @@ bool Corpse::Save() { dbpc->silver = this->silver; dbpc->gold = this->gold; dbpc->plat = this->platinum; - - // Little hack to account for the fact the race in the corpse struct is a uint8 and Froglok/Drakkin race number > 255 - // and to maintain backwards compatability with existing corpses in the database. - uint16 CorpseRace; - - switch(race) { - case DRAKKIN: - CorpseRace = 254; - break; - case FROGLOK: - CorpseRace = 255; - break; - default: - CorpseRace = race; - } - - dbpc->race = CorpseRace; + dbpc->race = this->race; dbpc->class_ = class_; dbpc->gender = gender; dbpc->deity = deity; @@ -604,45 +497,37 @@ bool Corpse::Save() { dbpc->drakkin_details = drakkin_details; uint32 x = 0; - ItemList::iterator cur,end; + ItemList::iterator cur, end; cur = itemlist.begin(); end = itemlist.end(); - for(; cur != end; ++cur) { + for (; cur != end; ++cur) { ServerLootItem_Struct* item = *cur; item->equipSlot = ServerToCorpseSlot(item->equipSlot); // temp hack until corpse blobs are removed - memcpy((char*) &dbpc->items[x++], (char*) item, sizeof(player_lootitem::ServerLootItem_Struct)); + memcpy((char*)&dbpc->items[x++], (char*)item, sizeof(player_lootitem::ServerLootItem_Struct)); } - dbpc->crc = CRC32::Generate(&((uchar*) dbpc)[4], tmpsize - 4); + if (corpse_db_id == 0) { + corpse_db_id = database.SaveCharacterCorpse(charid, orgname, zone->GetZoneID(), zone->GetInstanceID(), dbpc, x_pos, y_pos, z_pos, heading); + } + else{ + corpse_db_id = database.UpdateCharacterCorpse(corpse_db_id, charid, orgname, zone->GetZoneID(), zone->GetInstanceID(), dbpc, x_pos, y_pos, z_pos, heading, IsRezzed()); + } - if (dbid == 0) - { - dbid = database.CreatePlayerCorpse(charid, orgname, zone->GetZoneID(), zone->GetInstanceID(), (uchar*) dbpc, tmpsize, x_pos, y_pos, z_pos, heading); - if(RuleB(Zone, UsePlayerCorpseBackups) == true) - database.CreatePlayerCorpseBackup(dbid, charid, orgname, zone->GetZoneID(), zone->GetInstanceID(), (uchar*) dbpc, tmpsize, x_pos, y_pos, z_pos, heading); - } - else - dbid = database.UpdatePlayerCorpse(dbid, charid, orgname, zone->GetZoneID(), zone->GetInstanceID(), (uchar*) dbpc, tmpsize, x_pos, y_pos, z_pos, heading,Rezzed()); - safe_delete_array(dbpc); - if (dbid == 0) { - std::cout << "Error: Failed to save player corpse '" << this->GetName() << "'" << std::endl; - return false; - } return true; } void Corpse::Delete() { - if (IsPlayerCorpse() && dbid != 0) - database.DeletePlayerCorpse(dbid); - dbid = 0; - + if (IsPlayerCorpse() && corpse_db_id != 0) + database.DeleteCharacterCorpse(corpse_db_id); + + corpse_db_id = 0; p_depop = true; } void Corpse::Bury() { - if (IsPlayerCorpse() && dbid != 0) - database.BuryPlayerCorpse(dbid); - dbid = 0; + if (IsPlayerCorpse() && corpse_db_id != 0) + database.BuryCharacterCorpse(corpse_db_id); + corpse_db_id = 0; p_depop = true; } @@ -677,8 +562,7 @@ void Corpse::AddItem(uint32 itemnum, uint16 charges, int16 slot, uint32 aug1, ui itemlist.push_back(item); } -ServerLootItem_Struct* Corpse::GetItem(uint16 lootslot, ServerLootItem_Struct** bag_item_data) -{ +ServerLootItem_Struct* Corpse::GetItem(uint16 lootslot, ServerLootItem_Struct** bag_item_data) { ServerLootItem_Struct *sitem = 0, *sitem2; // find the item @@ -726,9 +610,7 @@ uint32 Corpse::GetWornItem(int16 equipSlot) const { return 0; } -void Corpse::RemoveItem(uint16 lootslot) -{ - +void Corpse::RemoveItem(uint16 lootslot) { if (lootslot == 0xFFFF) return; @@ -745,10 +627,8 @@ void Corpse::RemoveItem(uint16 lootslot) } } -void Corpse::RemoveItem(ServerLootItem_Struct* item_data) -{ - uint8 material; - +void Corpse::RemoveItem(ServerLootItem_Struct* item_data){ + uint8 material; ItemList::iterator cur,end; cur = itemlist.begin(); end = itemlist.end(); @@ -808,18 +688,18 @@ bool Corpse::Process() { if(zone->HasGraveyard()) { Save(); p_depop = true; - database.GraveyardPlayerCorpse(dbid, zone->graveyard_zoneid(), + database.SendCharacterCorpseToGraveyard(corpse_db_id, zone->graveyard_zoneid(), (zone->GetZoneID() == zone->graveyard_zoneid()) ? zone->GetInstanceID() : 0, zone->graveyard_x(), zone->graveyard_y(), zone->graveyard_z(), zone->graveyard_heading()); corpse_graveyard_timer.Disable(); ServerPacket* pack = new ServerPacket(ServerOP_SpawnPlayerCorpse, sizeof(SpawnPlayerCorpse_Struct)); SpawnPlayerCorpse_Struct* spc = (SpawnPlayerCorpse_Struct*)pack->pBuffer; - spc->player_corpse_id = dbid; + spc->player_corpse_id = corpse_db_id; spc->zone_id = zone->graveyard_zoneid(); worldserver.SendPacket(pack); safe_delete(pack); LogFile->write(EQEMuLog::Debug, "Moved %s player corpse to the designated graveyard in zone %s.", this->GetName(), database.GetZoneName(zone->graveyard_zoneid())); - dbid = 0; + corpse_db_id = 0; } corpse_graveyard_timer.Disable(); @@ -835,10 +715,10 @@ bool Corpse::Process() { if(!RuleB(Zone, EnableShadowrest)) Delete(); else { - if(database.BuryPlayerCorpse(dbid)) { + if(database.BuryCharacterCorpse(corpse_db_id)) { Save(); p_depop = true; - dbid = 0; + corpse_db_id = 0; LogFile->write(EQEMuLog::Debug, "Tagged %s player corpse has burried.", this->GetName()); } else @@ -895,7 +775,7 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a return; } - if(IsPlayerCorpse() && dbid == 0) { + if(IsPlayerCorpse() && corpse_db_id == 0) { // SendLootReqErrorPacket(client, 0); client->Message(13, "Warning: Corpse's dbid = 0! Corpse will not survive zone shutdown!"); std::cout << "Error: PlayerCorpse::MakeLootRequestPackets: dbid = 0!" << std::endl; @@ -1458,534 +1338,6 @@ void Corpse::Spawn() { safe_delete(app); } -bool ZoneDatabase::DeleteGraveyard(uint32 zone_id, uint32 graveyard_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = new char[256]; - uint32 query_length = 0; - uint32 affected_rows = 0; - - query_length = sprintf(query,"UPDATE zone SET graveyard_id=0 WHERE zoneidnumber=%u AND version=0", zone_id); - - if (!RunQuery(query, query_length, errbuf, 0, &affected_rows)) { - safe_delete_array(query); - std::cerr << "Error1 in DeleteGraveyard query " << errbuf << std::endl; - return false; - } - - if (affected_rows == 0) { - std::cerr << "Error2 in DeleteGraveyard query: affected_rows = 0" << std::endl; - return false; - } - - query_length = sprintf(query,"DELETE FROM graveyard WHERE id=%u", graveyard_id); - - if (!RunQuery(query, query_length, errbuf, 0, &affected_rows)) { - safe_delete_array(query); - std::cerr << "Error3 in DeleteGraveyard query " << errbuf << std::endl; - return false; - } - safe_delete_array(query); - - if (affected_rows == 0) { - std::cerr << "Error4 in DeleteGraveyard query: affected_rows = 0" << std::endl; - return false; - } - - return true; -} -uint32 ZoneDatabase::AddGraveyardIDToZone(uint32 zone_id, uint32 graveyard_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = new char[256]; - char* end = query; - uint32 affected_rows = 0; - - end += sprintf(end,"UPDATE zone SET graveyard_id=%u WHERE zoneidnumber=%u AND version=0", graveyard_id, zone_id); - - if (!RunQuery(query, (uint32) (end - query), errbuf, 0, &affected_rows)) { - safe_delete_array(query); - std::cerr << "Error1 in AddGraveyardIDToZone query " << errbuf << std::endl; - return 0; - } - safe_delete_array(query); - - if (affected_rows == 0) { - std::cerr << "Error2 in AddGraveyardIDToZone query: affected_rows = 0" << std::endl; - return 0; - } - - return zone_id; -} -uint32 ZoneDatabase::NewGraveyardRecord(uint32 graveyard_zoneid, float graveyard_x, float graveyard_y, float graveyard_z, float graveyard_heading) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = new char[256]; - char* end = query; - uint32 affected_rows = 0; - uint32 new_graveyard_id = 0; - - end += sprintf(end,"INSERT INTO graveyard SET zone_id=%u, x=%1.1f, y=%1.1f, z=%1.1f, heading=%1.1f", graveyard_zoneid, graveyard_x, graveyard_y, graveyard_z, graveyard_heading); - - if (!RunQuery(query, (uint32) (end - query), errbuf, 0, &affected_rows, &new_graveyard_id)) { - safe_delete_array(query); - std::cerr << "Error1 in NewGraveyardRecord query " << errbuf << std::endl; - return 0; - } - safe_delete_array(query); - - if (affected_rows == 0) { - std::cerr << "Error2 in NewGraveyardRecord query: affected_rows = 0" << std::endl; - return 0; - } - - if(new_graveyard_id <= 0) { - std::cerr << "Error3 in NewGraveyardRecord query: new_graveyard_id <= 0" << std::endl; - return 0; - } - - return new_graveyard_id; -} -uint32 ZoneDatabase::GraveyardPlayerCorpse(uint32 dbid, uint32 zoneid, uint16 instanceid, float x, float y, float z, float heading) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = new char[256]; - char* end = query; - uint32 affected_rows = 0; - - // We probably don't want a graveyard located in an instance. - end += sprintf(end,"Update player_corpses SET zoneid=%u, instanceid=0, x=%1.1f, y=%1.1f, z=%1.1f, heading=%1.1f, WasAtGraveyard=1 WHERE id=%d", zoneid, x, y, z, heading, dbid); - - if (!RunQuery(query, (uint32) (end - query), errbuf, 0, &affected_rows)) { - safe_delete_array(query); - std::cerr << "Error1 in GraveyardPlayerCorpse query " << errbuf << std::endl; - return 0; - } - safe_delete_array(query); - - if (affected_rows == 0) { - std::cerr << "Error2 in GraveyardPlayerCorpse query: affected_rows = 0" << std::endl; - return 0; - } - return dbid; -} -uint32 ZoneDatabase::UpdatePlayerCorpse(uint32 dbid, uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, uchar* data, uint32 datasize, float x, float y, float z, float heading, bool rezzed) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = new char[256+(datasize*2)]; - char* end = query; - uint32 affected_rows = 0; - - end += sprintf(end, "Update player_corpses SET data="); - *end++ = '\''; - end += DoEscapeString(end, (char*)data, datasize); - *end++ = '\''; - end += sprintf(end,", charname='%s', zoneid=%u, instanceid=%u, charid=%d, x=%1.1f, y=%1.1f, z=%1.1f, heading=%1.1f WHERE id=%d", charname, zoneid, instanceid, charid, x, y, z, heading, dbid); - - if (!RunQuery(query, (uint32) (end - query), errbuf, 0, &affected_rows)) { - safe_delete_array(query); - std::cerr << "Error1 in UpdatePlayerCorpse query " << errbuf << std::endl; - return 0; - } - safe_delete_array(query); - - if (affected_rows == 0) { - std::cerr << "Error2 in UpdatePlayerCorpse query: affected_rows = 0" << std::endl; - return 0; - } - if(rezzed){ - if (!RunQuery(query, MakeAnyLenString(&query, "update player_corpses set rezzed = 1 WHERE id=%d",dbid), errbuf)) { - std::cerr << "Error in UpdatePlayerCorpse/Rezzed query: " << errbuf << std::endl; - } - safe_delete_array(query); - } - return dbid; -} - -void ZoneDatabase::MarkCorpseAsRezzed(uint32 dbid) -{ - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = 0; - - if(!database.RunQuery(query,MakeAnyLenString(&query, "UPDATE player_corpses SET rezzed = 1 WHERE id = %i", dbid), errbuf)) - { - LogFile->write(EQEMuLog::Error, "MarkCorpseAsRezzed failed: %s, %s", query, errbuf); - } - safe_delete_array(query); -} - -uint32 ZoneDatabase::CreatePlayerCorpse(uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, uchar* data, uint32 datasize, float x, float y, float z, float heading) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = new char[256+(datasize*2)]; - char* end = query; - //MYSQL_RES *result; - //MYSQL_ROW row; - uint32 affected_rows = 0; - uint32 last_insert_id = 0; - - end += sprintf(end, "Insert into player_corpses SET data="); - *end++ = '\''; - end += DoEscapeString(end, (char*)data, datasize); - *end++ = '\''; - end += sprintf(end,", charname='%s', zoneid=%u, instanceid=%u, charid=%d, x=%1.1f, y=%1.1f, z=%1.1f, heading=%1.1f, timeofdeath=Now(), IsBurried=0", charname, zoneid, instanceid, charid, x, y, z, heading); - - if (!RunQuery(query, (uint32) (end - query), errbuf, 0, &affected_rows, &last_insert_id)) { - safe_delete_array(query); - std::cerr << "Error1 in CreatePlayerCorpse query " << errbuf << std::endl; - return 0; - } - safe_delete_array(query); - - if (affected_rows == 0) { - std::cerr << "Error2 in CreatePlayerCorpse query: affected_rows = 0" << std::endl; - return 0; - } - - if (last_insert_id == 0) { - std::cerr << "Error3 in CreatePlayerCorpse query: last_insert_id = 0" << std::endl; - return 0; - } - - return last_insert_id; -} - -bool ZoneDatabase::CreatePlayerCorpseBackup(uint32 dbid, uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, uchar* data, uint32 datasize, float x, float y, float z, float heading) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = new char[256+(datasize*2)]; - char* end = query; - uint32 affected_rows = 0; - uint32 last_insert_id = 0; - bool result = false; - DBPlayerCorpse_Struct* dbpcs = (DBPlayerCorpse_Struct*) data; - - if (dbid != 0) { - if(RuleB(Character, LeaveCorpses) == true && dbpcs->level >= RuleI(Character, DeathItemLossLevel)){ - end += sprintf(end, "Insert into player_corpses_backup SET data="); - *end++ = '\''; - end += DoEscapeString(end, (char*)data, datasize); - *end++ = '\''; - end += sprintf(end,", charname='%s', zoneid=%u, instanceid=%u, charid=%d, x=%1.1f, y=%1.1f, z=%1.1f, heading=%1.1f, timeofdeath=Now(), IsBurried=0, id=%u", charname, zoneid, instanceid, charid, x, y, z, heading, dbid); - - if (RunQuery(query, (uint32) (end - query), errbuf, 0, &affected_rows)) { - if (affected_rows == 1) - result = true; - else - std::cerr << "Error in CreatePlayerCorpseBackup query: affected_rows != 1" << std::endl; - } - else - std::cerr << "Error in CreatePlayerCorpseBackup query " << errbuf << std::endl; - } - safe_delete_array(query); - } - else { - std::cerr << "Error in CreatePlayerCorpseBackup: dbid = 0" << std::endl; - } - return result; -} - -uint32 ZoneDatabase::GetPlayerBurriedCorpseCount(uint32 char_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - uint32 CorpseCount = 0; - - if (RunQuery(query, MakeAnyLenString(&query, "select count(*) from player_corpses where charid = '%u' and IsBurried = 1", char_id), errbuf, &result)) { - row = mysql_fetch_row(result); - CorpseCount = atoi(row[0]); - mysql_free_result(result); - } - else { - std::cerr << "Error in GetPlayerBurriedCorpseCount query '" << query << "' " << errbuf << std::endl; - } - - safe_delete_array(query); - - return CorpseCount; -} - -uint32 ZoneDatabase::GetPlayerCorpseCount(uint32 char_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - uint32 CorpseCount = 0; - - if (RunQuery(query, MakeAnyLenString(&query, "select count(*) from player_corpses where charid = '%u'", char_id), errbuf, &result)) { - row = mysql_fetch_row(result); - CorpseCount = atoi(row[0]); - mysql_free_result(result); - } - else { - std::cerr << "Error in GetPlayerCorpseCount query '" << query << "' " << errbuf << std::endl; - } - - safe_delete_array(query); - - return CorpseCount; -} - -uint32 ZoneDatabase::GetPlayerCorpseID(uint32 char_id, uint8 corpse) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - uint32 id = 0; - - if (RunQuery(query, MakeAnyLenString(&query, "select id from player_corpses where charid = '%u'", char_id), errbuf, &result)) { - for (int i=0; iGetWornItem(slotid); - tmp->DepopCorpse(); - } - return itemid; -} - -Corpse* ZoneDatabase::SummonBurriedPlayerCorpse(uint32 char_id, uint32 dest_zoneid, uint16 dest_instanceid, float dest_x, float dest_y, float dest_z, float dest_heading) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - Corpse* NewCorpse = 0; - unsigned long* lengths; - - if (RunQuery(query, MakeAnyLenString(&query, "SELECT id, charname, data, timeofdeath, rezzed FROM player_corpses WHERE charid='%u' AND IsBurried=1 ORDER BY timeofdeath LIMIT 1", char_id), errbuf, &result)) { - row = mysql_fetch_row(result); - lengths = mysql_fetch_lengths(result); - if(row) { - NewCorpse = Corpse::LoadFromDBData(atoi(row[0]), char_id, row[1], (uchar*) row[2], lengths[2], dest_x, dest_y, dest_z, dest_heading, row[3],atoi(row[4])==1, false); - if(NewCorpse) { - entity_list.AddCorpse(NewCorpse); - NewCorpse->SetDecayTimer(RuleI(Character, CorpseDecayTimeMS)); - NewCorpse->Spawn(); - if(!UnburyPlayerCorpse(NewCorpse->GetDBID(), dest_zoneid, dest_instanceid, dest_x, dest_y, dest_z, dest_heading)) - LogFile->write(EQEMuLog::Error, "Unable to unbury a summoned player corpse for character id %u.", char_id); - } - else - LogFile->write(EQEMuLog::Error, "Unable to construct a player corpse from a burried player corpse for character id %u.", char_id); - } - - mysql_free_result(result); - } - else { - std::cerr << "Error in SummonBurriedPlayerCorpse query '" << query << "' " << errbuf << std::endl; - } - - safe_delete_array(query); - - return NewCorpse; -} - -bool ZoneDatabase::SummonAllPlayerCorpses(uint32 char_id, uint32 dest_zoneid, uint16 dest_instanceid, - float dest_x, float dest_y, float dest_z, float dest_heading) -{ - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - Corpse* NewCorpse = 0; - int CorpseCount = 0; - unsigned long* lengths; - - if(!RunQuery(query, MakeAnyLenString(&query, "UPDATE player_corpses SET zoneid = %i, instanceid = %i, x = %f, y = %f, z = %f, " - "heading = %f, IsBurried = 0, WasAtGraveyard = 0 WHERE charid = %i", - dest_zoneid, dest_instanceid, dest_x, dest_y, dest_z, dest_heading, char_id), errbuf)) - LogFile->write(EQEMuLog::Error, "Error moving corpses, Query = %s, Error = %s\n", query, errbuf); - - safe_delete_array(query); - - if (RunQuery(query, MakeAnyLenString(&query, "SELECT id, charname, data, timeofdeath, rezzed FROM player_corpses WHERE charid='%u'" - "ORDER BY timeofdeath", char_id), errbuf, &result)) - { - while((row = mysql_fetch_row(result))) - { - lengths = mysql_fetch_lengths(result); - NewCorpse = Corpse::LoadFromDBData(atoi(row[0]), char_id, row[1], (uchar*) row[2], lengths[2], dest_x, dest_y, - dest_z, dest_heading, row[3],atoi(row[4])==1, false); - if(NewCorpse) { - entity_list.AddCorpse(NewCorpse); - NewCorpse->SetDecayTimer(RuleI(Character, CorpseDecayTimeMS)); - NewCorpse->Spawn(); - ++CorpseCount; - } - else - LogFile->write(EQEMuLog::Error, "Unable to construct a player corpse for character id %u.", char_id); - } - - mysql_free_result(result); - } - else - LogFile->write(EQEMuLog::Error, "Error in SummonAllPlayerCorpses Query = %s, Error = %s\n", query, errbuf); - - safe_delete_array(query); - - return (CorpseCount > 0); -} - -bool ZoneDatabase::UnburyPlayerCorpse(uint32 dbid, uint32 new_zoneid, uint16 new_instanceid, float new_x, float new_y, float new_z, float new_heading) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char* query = new char[256]; - char* end = query; - uint32 affected_rows = 0; - bool Result = false; - - end += sprintf(end, "UPDATE player_corpses SET IsBurried=0, zoneid=%u, instanceid=%u, x=%f, y=%f, z=%f, heading=%f, timeofdeath=Now(), WasAtGraveyard=0 WHERE id=%u", new_zoneid, new_instanceid, new_x, new_y, new_z, new_heading, dbid); - - if (RunQuery(query, (uint32) (end - query), errbuf, 0, &affected_rows)) { - if (affected_rows == 1) - Result = true; - else - std::cerr << "Error2 in UnburyPlayerCorpse query: affected_rows NOT EQUAL to 1, as expected." << std::endl; - } - else - std::cerr << "Error1 in UnburyPlayerCorpse query " << errbuf << std::endl; - - safe_delete_array(query); - - return Result; -} - -Corpse* ZoneDatabase::LoadPlayerCorpse(uint32 player_corpse_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - Corpse* NewCorpse = 0; - unsigned long* lengths; - - if (RunQuery(query, MakeAnyLenString(&query, "SELECT id, charid, charname, x, y, z, heading, data, timeofdeath, rezzed, WasAtGraveyard FROM player_corpses WHERE id='%u'", player_corpse_id), errbuf, &result)) { - row = mysql_fetch_row(result); - lengths = mysql_fetch_lengths(result); - if(row && lengths) - { - NewCorpse = Corpse::LoadFromDBData(atoi(row[0]), atoi(row[1]), row[2], (uchar*) row[7], lengths[7], atof(row[3]), atoi(row[4]), atoi(row[5]), atoi(row[6]), row[8],atoi(row[9])==1, atoi(row[10])); - entity_list.AddCorpse(NewCorpse); - } - mysql_free_result(result); - } - else { - std::cerr << "Error in LoadPlayerCorpse query '" << query << "' " << errbuf << std::endl; - std::cerr << "Note that if your missing the 'rezzed' field you can add it with:\nALTER TABLE `player_corpses` ADD `rezzed` TINYINT UNSIGNED DEFAULT \"0\";\n"; - } - - safe_delete_array(query); - - return NewCorpse; -} - -bool ZoneDatabase::LoadPlayerCorpses(uint32 iZoneID, uint16 iInstanceID) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - uint32 query_length = 0; - - unsigned long* lengths; - - if(!RuleB(Zone, EnableShadowrest)) - query_length = MakeAnyLenString(&query, "SELECT id, charid, charname, x, y, z, heading, data, timeofdeath, rezzed, WasAtGraveyard FROM player_corpses WHERE zoneid='%u' AND instanceid='%u'", iZoneID, iInstanceID); - else - query_length = MakeAnyLenString(&query, "SELECT id, charid, charname, x, y, z, heading, data, timeofdeath, rezzed, 0 FROM player_corpses WHERE zoneid='%u' AND instanceid='%u' AND IsBurried=0", iZoneID, iInstanceID); - - if (RunQuery(query, query_length, errbuf, &result)) { - safe_delete_array(query); - while ((row = mysql_fetch_row(result))) { - lengths = mysql_fetch_lengths(result); - entity_list.AddCorpse(Corpse::LoadFromDBData(atoi(row[0]), atoi(row[1]), row[2], (uchar*) row[7], lengths[7], atof(row[3]), atoi(row[4]), atoi(row[5]), atoi(row[6]), row[8],atoi(row[9])==1, atoi(row[10]))); - } - mysql_free_result(result); - } - else { - std::cerr << "Error in LoadPlayerCorpses query '" << query << "' " << errbuf << std::endl; - std::cerr << "Note that if your missing the 'rezzed' field you can add it with:\nALTER TABLE `player_corpses` ADD `rezzed` TINYINT UNSIGNED DEFAULT \"0\";\n"; - safe_delete_array(query); - return false; - } - - return true; -} - -uint32 ZoneDatabase::GetFirstCorpseID(uint32 char_id) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - uint32 CorpseID = 0; - - MakeAnyLenString(&query, "SELECT id FROM player_corpses WHERE charid='%u' AND IsBurried=0 ORDER BY timeofdeath LIMIT 1", char_id); - if (RunQuery(query, strlen(query), errbuf, &result)) { - if (mysql_num_rows(result)!= 0){ - row = mysql_fetch_row(result); - CorpseID = atoi(row[0]); - mysql_free_result(result); - } - } - else { - std::cerr << "Error in GetFirstCorpseID query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); - return 0; - } - - safe_delete_array(query); - return CorpseID; -} - -bool ZoneDatabase::BuryPlayerCorpse(uint32 dbid) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - - if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE player_corpses SET IsBurried = 1 WHERE id=%d", dbid), errbuf)) { - std::cerr << "Error in BuryPlayerCorpse query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); - return false; - } - - safe_delete_array(query); - return true; -} - -bool ZoneDatabase::BuryAllPlayerCorpses(uint32 charid) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - - if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE player_corpses SET IsBurried = 1 WHERE charid=%d", charid), errbuf)) { - std::cerr << "Error in BuryPlayerCorpse query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); - return false; - } - - safe_delete_array(query); - return true; -} - -bool ZoneDatabase::DeletePlayerCorpse(uint32 dbid) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - - if (!RunQuery(query, MakeAnyLenString(&query, "Delete from player_corpses where id=%d", dbid), errbuf)) { - std::cerr << "Error in DeletePlayerCorpse query '" << query << "' " << errbuf << std::endl; - safe_delete_array(query); - return false; - } - - safe_delete_array(query); - return true; -} - -// these functions operate with a material slot, which is from 0 to 8 uint32 Corpse::GetEquipment(uint8 material_slot) const { int invslot; @@ -2039,7 +1391,7 @@ void Corpse::LoadPlayerCorpseDecayTime(uint32 dbid){ char *query = 0; MYSQL_RES *result; MYSQL_ROW row; - if (database.RunQuery(query, MakeAnyLenString(&query, "SELECT (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(timeofdeath)) FROM player_corpses WHERE id=%d and not timeofdeath=0", dbid), errbuf, &result)) { + if (database.RunQuery(query, MakeAnyLenString(&query, "SELECT (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(time_of_death)) FROM character_corpses WHERE id=%d and not time_of_death=0", dbid), errbuf, &result)) { safe_delete_array(query); while ((row = mysql_fetch_row(result))) { if(atoi(row[0]) > 0 && RuleI(Character, CorpseDecayTimeMS) > (atoi(row[0]) * 1000)) { @@ -2177,28 +1529,4 @@ int16 Corpse::CorpseToServerSlot(int16 corpse_slot) return corpse_slot; } */ -} - -/* -void Corpse::CastRezz(uint16 spellid, Mob* Caster){ - if(Rezzed()){ - if(Caster && Caster->IsClient()) - Caster->Message(13,"This character has already been resurrected."); - return; - } - - APPLAYER* outapp = new APPLAYER(OP_RezzRequest, sizeof(Resurrect_Struct)); - Resurrect_Struct* rezz = (Resurrect_Struct*) outapp->pBuffer; - memcpy(rezz->your_name,this->orgname,30); - memcpy(rezz->corpse_name,this->name,30); - memcpy(rezz->rezzer_name,Caster->GetName(),30); - memcpy(rezz->zone,zone->GetShortName(),15); - rezz->spellid = spellid; - rezz->x = this->x_pos; - rezz->y = this->y_pos; - rezz->z = (float)this->z_pos; - worldserver.RezzPlayer(outapp, rezzexp, OP_RezzRequest); - //DumpPacket(outapp); - safe_delete(outapp); -} -*/ +} \ No newline at end of file diff --git a/zone/corpse.h b/zone/corpse.h index 2d1eecc98..8b1269c1b 100644 --- a/zone/corpse.h +++ b/zone/corpse.h @@ -30,8 +30,8 @@ class Corpse : public Mob { public: static void SendEndLootErrorPacket(Client* client); - static void SendLootReqErrorPacket(Client* client, uint8 response = 2); - static Corpse* LoadFromDBData(uint32 in_corpseid, uint32 in_charid, char* in_charname, uchar* in_data, uint32 in_datasize, float in_x, float in_y, float in_z, float in_heading, char* timeofdeath, bool rezzed = false, bool wasAtGraveyard = false); + static void SendLootReqErrorPacket(Client* client, uint8 response = 2); + static Corpse* LoadFromDBData(uint32 in_corpseid, uint32 in_charid, char* in_charname, PlayerCorpse_Struct* pcs, float in_x, float in_y, float in_z, float in_heading, char* time_of_death, bool rezzed = false, bool wasAtGraveyard = false); Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NPCType** in_npctypedata, uint32 in_decaytime = 600000); Corpse(Client* client, int32 in_rezexp); @@ -39,51 +39,51 @@ public: ~Corpse(); //abstract virtual function implementations requird by base abstract class - virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, SkillUseTypes attack_skill) { return true; } - virtual void Damage(Mob* from, int32 damage, uint16 spell_id, SkillUseTypes attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false) { return; } - virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false, bool IsStrikethrough = true, bool IsFromSpell = false, - ExtraAttackOptions *opts = nullptr) { return false; } - virtual bool HasRaid() { return false; } - virtual bool HasGroup() { return false; } - virtual Raid* GetRaid() { return 0; } - virtual Group* GetGroup() { return 0; } + virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, SkillUseTypes attack_skill) { return true; } + virtual void Damage(Mob* from, int32 damage, uint16 spell_id, SkillUseTypes attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false) { return; } + virtual bool Attack(Mob* other, int Hand = MainPrimary, bool FromRiposte = false, + bool IsStrikethrough = true, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) { return false; } + virtual bool HasRaid() { return false; } + virtual bool HasGroup() { return false; } + virtual Raid* GetRaid() { return 0; } + virtual Group* GetGroup() { return 0; } - void LoadPlayerCorpseDecayTime(uint32 dbid); + void LoadPlayerCorpseDecayTime(uint32 dbid); - bool IsCorpse() const { return true; } - bool IsPlayerCorpse() const { return p_PlayerCorpse; } - bool IsNPCCorpse() const { return !p_PlayerCorpse; } - bool IsBecomeNPCCorpse() const { return become_npc; } - bool Process(); - bool Save(); - uint32 GetCharID() { return charid; } - uint32 SetCharID(uint32 iCharID) { if (IsPlayerCorpse()) { return (charid=iCharID); } return 0xFFFFFFFF; }; - uint32 GetDecayTime() { if (!corpse_decay_timer.Enabled()) return 0xFFFFFFFF; else return corpse_decay_timer.GetRemainingTime(); } - uint32 GetResTime() { if (!corpse_res_timer.Enabled()) return 0; else return corpse_res_timer.GetRemainingTime(); } - void CalcCorpseName(); + bool IsCorpse() const { return true; } + bool IsPlayerCorpse() const { return p_PlayerCorpse; } + bool IsNPCCorpse() const { return !p_PlayerCorpse; } + bool IsBecomeNPCCorpse() const { return become_npc; } + bool Process(); + bool Save(); + uint32 GetCharID() { return charid; } + uint32 SetCharID(uint32 iCharID) { if (IsPlayerCorpse()) { return (charid = iCharID); } return 0xFFFFFFFF; }; + uint32 GetDecayTime() { if (!corpse_decay_timer.Enabled()) return 0xFFFFFFFF; else return corpse_decay_timer.GetRemainingTime(); } + uint32 GetResTime() { if (!corpse_res_timer.Enabled()) return 0; else return corpse_res_timer.GetRemainingTime(); } + void CalcCorpseName(); inline void Lock() { pLocked = true; } inline void UnLock() { pLocked = false; } inline bool IsLocked() { return pLocked; } inline void ResetLooter() { BeingLootedBy = 0xFFFFFFFF; } inline bool IsBeingLooted() { return (BeingLootedBy != 0xFFFFFFFF); } - inline uint32 GetDBID() { return dbid; } + inline uint32 GetDBID() { return corpse_db_id; } inline char* GetOwnerName() { return orgname;} - void SetDecayTimer(uint32 decaytime); - bool IsEmpty() const; - void AddItem(uint32 itemnum, uint16 charges, int16 slot = 0, uint32 aug1=0, uint32 aug2=0, uint32 aug3=0, uint32 aug4=0, uint32 aug5=0); - uint32 GetWornItem(int16 equipSlot) const; - ServerLootItem_Struct* GetItem(uint16 lootslot, ServerLootItem_Struct** bag_item_data = 0); - void RemoveItem(uint16 lootslot); - void RemoveItem(ServerLootItem_Struct* item_data); - void SetCash(uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_platinum); - void RemoveCash(); - void QueryLoot(Client* to); - uint32 CountItems(); - void Delete(); - void Bury(); - virtual void Depop(); - virtual void DepopCorpse(); + void SetDecayTimer(uint32 decaytime); + bool IsEmpty() const; + void AddItem(uint32 itemnum, uint16 charges, int16 slot = 0, uint32 aug1=0, uint32 aug2=0, uint32 aug3=0, uint32 aug4=0, uint32 aug5=0); + uint32 GetWornItem(int16 equipSlot) const; + ServerLootItem_Struct* GetItem(uint16 lootslot, ServerLootItem_Struct** bag_item_data = 0); + void RemoveItem(uint16 lootslot); + void RemoveItem(ServerLootItem_Struct* item_data); + void SetCash(uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_platinum); + void RemoveCash(); + void QueryLoot(Client* to); + uint32 CountItems(); + void Delete(); + void Bury(); + virtual void Depop(); + virtual void DepopCorpse(); uint32 GetCopper() { return copper; } uint32 GetSilver() { return silver; } @@ -99,17 +99,17 @@ public: void CompleteRezz(); void SetPKItem(int32 id) { pkitem = id; } int32 GetPKItem() { return pkitem; } - bool CanMobLoot(int charid); - void AllowMobLoot(Mob *them, uint8 slot); - void AddLooter(Mob *who); - bool Rezzed() { return rez; } - void Rezzed(bool in_rez) { rez = in_rez; } + bool CanMobLoot(int charid); + void AllowMobLoot(Mob *them, uint8 slot); + void AddLooter(Mob *who); + bool IsRezzed() { return rez; } + void IsRezzed(bool in_rez) { rez = in_rez; } void Spawn(); char orgname[64]; - uint32 GetEquipment(uint8 material_slot) const; // returns item id - uint32 GetEquipmentColor(uint8 material_slot) const; - inline int GetRezzExp() { return rezzexp; } + uint32 GetEquipment(uint8 material_slot) const; // returns item id + uint32 GetEquipmentColor(uint8 material_slot) const; + inline int GetRezzExp() { return rezzexp; } // these are a temporary work-around until corpse inventory is removed from the database blob static int16 ServerToCorpseSlot(int16 server_slot); // encode @@ -122,7 +122,7 @@ private: bool p_PlayerCorpse; bool pIsChanged; bool pLocked; int32 pkitem; - uint32 dbid; + uint32 corpse_db_id; uint32 charid; ItemList itemlist; uint32 copper; diff --git a/zone/doors.cpp b/zone/doors.cpp index 5ff7eae26..4af1d3eae 100644 --- a/zone/doors.cpp +++ b/zone/doors.cpp @@ -50,7 +50,7 @@ Doors::Doors(const Door* door) incline = door->incline; opentype = door->opentype; guild_id = door->guild_id; - lockpick = door->lockpick; + lockpick = door->lock_pick; keyitem = door->keyitem; nokeyring = door->nokeyring; trigger_door = door->trigger_door; @@ -678,7 +678,7 @@ bool ZoneDatabase::LoadDoors(int32 iDoorCount, Door *into, const char *zone_name into[rowIndex].heading = (float)atof(row[7]); into[rowIndex].opentype = atoi(row[8]); into[rowIndex].guild_id = atoi(row[9]); - into[rowIndex].lockpick = atoi(row[10]); + into[rowIndex].lock_pick = atoi(row[10]); into[rowIndex].keyitem = atoi(row[11]); into[rowIndex].nokeyring = atoi(row[12]); into[rowIndex].trigger_door = atoi(row[13]); diff --git a/zone/entity.cpp b/zone/entity.cpp index ed5b99219..122e24582 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -1678,7 +1678,7 @@ int EntityList::RezzAllCorpsesByCharID(uint32 charid) while (it != corpse_list.end()) { if (it->second->GetCharID() == charid) { RezzExp += it->second->GetRezzExp(); - it->second->Rezzed(true); + it->second->IsRezzed(true); it->second->CompleteRezz(); } ++it; diff --git a/zone/lua_corpse.cpp b/zone/lua_corpse.cpp index 6498458ae..beada7e9a 100644 --- a/zone/lua_corpse.cpp +++ b/zone/lua_corpse.cpp @@ -44,7 +44,7 @@ uint32 Lua_Corpse::GetDBID() { bool Lua_Corpse::IsRezzed() { Lua_Safe_Call_Bool(); - return self->Rezzed(); + return self->IsRezzed(); } const char* Lua_Corpse::GetOwnerName() { diff --git a/zone/merc.cpp b/zone/merc.cpp index 94d129b14..2ecd0849e 100644 --- a/zone/merc.cpp +++ b/zone/merc.cpp @@ -4338,7 +4338,7 @@ Corpse* Merc::GetGroupMemberCorpse() { if(g->members[i] && g->members[i]->IsClient()) { corpse = entity_list.GetCorpseByOwnerWithinRange(g->members[i]->CastToClient(), this, RuleI(Mercs, ResurrectRadius)); - if(corpse && !corpse->Rezzed()) { + if(corpse && !corpse->IsRezzed()) { return corpse; } } @@ -6367,4 +6367,4 @@ uint32 Merc::CalcUpkeepCost(uint32 templateID , uint8 level, uint8 currency_type } return cost; -} \ No newline at end of file +} diff --git a/zone/perl_player_corpse.cpp b/zone/perl_player_corpse.cpp index 366299ea2..af5c79f16 100644 --- a/zone/perl_player_corpse.cpp +++ b/zone/perl_player_corpse.cpp @@ -780,7 +780,7 @@ XS(XS_Corpse_IsRezzed) if(THIS == nullptr) Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - RETVAL = THIS->Rezzed(); + RETVAL = THIS->IsRezzed(); ST(0) = boolSV(RETVAL); sv_2mortal(ST(0)); } diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index dc9d6d8f6..e014c01cd 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -1744,7 +1744,7 @@ bool QuestManager::summonburriedplayercorpse(uint32 char_id, float dest_x, float bool Result = false; if(char_id > 0) { - Corpse* PlayerCorpse = database.SummonBurriedPlayerCorpse(char_id, zone->GetZoneID(), zone->GetInstanceID(), dest_x, dest_y, dest_z, dest_heading); + Corpse* PlayerCorpse = database.SummonBuriedCharacterCorpses(char_id, zone->GetZoneID(), zone->GetInstanceID(), dest_x, dest_y, dest_z, dest_heading); if(PlayerCorpse) { Result = true; } @@ -1767,7 +1767,7 @@ uint32 QuestManager::getplayerburriedcorpsecount(uint32 char_id) { uint32 Result = 0; if(char_id > 0) { - Result = database.GetPlayerBurriedCorpseCount(char_id); + Result = database.GetCharacterBuriedCorpseCount(char_id); } return Result; } @@ -1781,7 +1781,7 @@ bool QuestManager::buryplayercorpse(uint32 char_id) uint32 PlayerCorpse = database.GetFirstCorpseID(char_id); if(PlayerCorpse > 0) { - database.BuryPlayerCorpse(PlayerCorpse); + database.BuryCharacterCorpse(PlayerCorpse); Corpse* corpse = entity_list.GetCorpseByDBID(PlayerCorpse); if(corpse) { diff --git a/zone/spells.cpp b/zone/spells.cpp index 06c28adaa..69ded563c 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -3806,9 +3806,9 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob* spelltar, bool reflect, bool use_r void Corpse::CastRezz(uint16 spellid, Mob* Caster) { - _log(SPELLS__REZ, "Corpse::CastRezz spellid %i, Rezzed() is %i, rezzexp is %i", spellid,Rezzed(),rezzexp); + _log(SPELLS__REZ, "Corpse::CastRezz spellid %i, Rezzed() is %i, rezzexp is %i", spellid,IsRezzed(),rezzexp); - if(Rezzed()){ + if(IsRezzed()){ if(Caster && Caster->IsClient()) Caster->Message(13,"This character has already been resurrected."); @@ -3838,7 +3838,7 @@ void Corpse::CastRezz(uint16 spellid, Mob* Caster) rezz->unknown020 = 0x00000000; rezz->unknown088 = 0x00000000; // We send this to world, because it needs to go to the player who may not be in this zone. - worldserver.RezzPlayer(outapp, rezzexp, dbid, OP_RezzRequest); + worldserver.RezzPlayer(outapp, rezzexp, corpse_db_id, OP_RezzRequest); _pkt(SPELLS__REZ, outapp); safe_delete(outapp); } diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index eb717f89a..bae01e70f 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -704,7 +704,7 @@ void WorldServer::Process() { _log(SPELLS__REZ, "Found corpse. Marking corpse as rezzed."); // I don't know why Rezzed is not set to true in CompleteRezz(). - corpse->Rezzed(true); + corpse->IsRezzed(true); corpse->CompleteRezz(); } } @@ -1382,7 +1382,7 @@ void WorldServer::Process() { case ServerOP_SpawnPlayerCorpse: { SpawnPlayerCorpse_Struct* s = (SpawnPlayerCorpse_Struct*)pack->pBuffer; - Corpse* NewCorpse = database.LoadPlayerCorpse(s->player_corpse_id); + Corpse* NewCorpse = database.LoadCharacterCorpse(s->player_corpse_id); if(NewCorpse) NewCorpse->Spawn(); else diff --git a/zone/zone.cpp b/zone/zone.cpp index 521684a0d..ecf10bcb5 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -917,7 +917,7 @@ bool Zone::Init(bool iStaticZone) { } LogFile->write(EQEMuLog::Status, "Loading player corpses..."); - if (!database.LoadPlayerCorpses(zoneid, instanceid)) { + if (!database.LoadCharacterCorpses(zoneid, instanceid)) { LogFile->write(EQEMuLog::Error, "Loading player corpses failed."); return false; } diff --git a/zone/zonedb.cpp b/zone/zonedb.cpp index 3599a3ff0..671d109ec 100644 --- a/zone/zonedb.cpp +++ b/zone/zonedb.cpp @@ -7,6 +7,7 @@ #include "../common/rulesys.h" #include "../common/rdtsc.h" #include "zone.h" +#include "corpse.h" #include "client.h" #include "merc.h" #include "groups.h" @@ -3328,3 +3329,723 @@ bool ZoneDatabase::GetFactionIdsForNPC(uint32 nfl_id, std::listlocked, + dbpc->exp, + dbpc->size, + dbpc->level, + dbpc->race, + dbpc->gender, + dbpc->class_, + dbpc->deity, + dbpc->texture, + dbpc->helmtexture, + dbpc->copper, + dbpc->silver, + dbpc->gold, + dbpc->plat, + dbpc->haircolor, + dbpc->beardcolor, + dbpc->eyecolor1, + dbpc->eyecolor2, + dbpc->hairstyle, + dbpc->face, + dbpc->beard, + dbpc->drakkin_heritage, + dbpc->drakkin_tattoo, + dbpc->drakkin_details, + dbpc->item_tint[0].color, + dbpc->item_tint[1].color, + dbpc->item_tint[2].color, + dbpc->item_tint[3].color, + dbpc->item_tint[4].color, + dbpc->item_tint[5].color, + dbpc->item_tint[6].color, + dbpc->item_tint[7].color, + dbpc->item_tint[8].color, + db_id + ); + auto results = QueryDatabase(query); + + query = StringFormat("DELETE FROM `character_corpse_items` WHERE `corpse_id` = %u"); + results = QueryDatabase(query); + + /* Dump Items from Inventory */ + uint8 first_entry = 0; + for (unsigned int i = 0; i < dbpc->itemcount; i++) { + if (first_entry != 1){ + 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, attuned) \n" + " VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, 0) \n", + db_id, + dbpc->items[i].equip_slot, + dbpc->items[i].item_id, + dbpc->items[i].charges, + dbpc->items[i].aug_1, + dbpc->items[i].aug_2, + dbpc->items[i].aug_3, + dbpc->items[i].aug_4, + dbpc->items[i].aug_5 + ); + first_entry = 1; + } + else{ + query = query + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, 0) \n", + db_id, + dbpc->items[i].equip_slot, + dbpc->items[i].item_id, + dbpc->items[i].charges, + dbpc->items[i].aug_1, + dbpc->items[i].aug_2, + dbpc->items[i].aug_3, + dbpc->items[i].aug_4, + dbpc->items[i].aug_5 + ); + } + } + results = QueryDatabase(query); + + return db_id; +} + +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, PlayerCorpse_Struct* dbpc, float x, float y, float z, float heading) { + /* Dump Basic Corpse Data */ + std::string query = StringFormat("INSERT INTO `character_corpses` SET \n" + "`charname` = '%s',\n" + "`zone_id` = %u,\n" + "`instance_id` = %u,\n" + "`charid` = %d,\n" + "`x` = %1.1f,\n" + "`y` = %1.1f,\n" + "`z` = %1.1f,\n" + "`heading` = %1.1f,\n" + "`time_of_death` = NOW(),\n" + "`is_buried` = 0," + "`is_locked` = %d,\n" + "`exp` = %u,\n" + "`size` = %f,\n" + "`level` = %u,\n" + "`race` = %u,\n" + "`gender` = %u,\n" + "`class` = %u,\n" + "`deity` = %u,\n" + "`texture` = %u,\n" + "`helm_texture` = %u,\n" + "`copper` = %u,\n" + "`silver` = %u,\n" + "`gold` = %u,\n" + "`platinum` = %u,\n" + "`hair_color` = %u,\n" + "`beard_color` = %u,\n" + "`eye_color_1` = %u,\n" + "`eye_color_2` = %u,\n" + "`hair_style` = %u,\n" + "`face` = %u,\n" + "`beard` = %u,\n" + "`drakkin_heritage` = %u,\n" + "`drakkin_tattoo` = %u,\n" + "`drakkin_details` = %u,\n" + "`wc_1` = %u,\n" + "`wc_2` = %u,\n" + "`wc_3` = %u,\n" + "`wc_4` = %u,\n" + "`wc_5` = %u,\n" + "`wc_6` = %u,\n" + "`wc_7` = %u,\n" + "`wc_8` = %u,\n" + "`wc_9` = %u \n", + EscapeString(charname).c_str(), + zoneid, + instanceid, + charid, + x, + y, + z, + heading, + dbpc->locked, + dbpc->exp, + dbpc->size, + dbpc->level, + dbpc->race, + dbpc->gender, + dbpc->class_, + dbpc->deity, + dbpc->texture, + dbpc->helmtexture, + dbpc->copper, + dbpc->silver, + dbpc->gold, + dbpc->plat, + dbpc->haircolor, + dbpc->beardcolor, + dbpc->eyecolor1, + dbpc->eyecolor2, + dbpc->hairstyle, + dbpc->face, + dbpc->beard, + dbpc->drakkin_heritage, + dbpc->drakkin_tattoo, + dbpc->drakkin_details, + dbpc->item_tint[0].color, + dbpc->item_tint[1].color, + dbpc->item_tint[2].color, + dbpc->item_tint[3].color, + dbpc->item_tint[4].color, + dbpc->item_tint[5].color, + dbpc->item_tint[6].color, + dbpc->item_tint[7].color, + dbpc->item_tint[8].color + ); + auto results = QueryDatabase(query); + uint32 last_insert_id = results.LastInsertedID(); + + /* Dump Items from Inventory */ + uint8 first_entry = 0; + for (unsigned int i = 0; i < dbpc->itemcount; i++) { + if (first_entry != 1){ + 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, attuned) \n" + " VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, 0) \n", + last_insert_id, + dbpc->items[i].equip_slot, + dbpc->items[i].item_id, + dbpc->items[i].charges, + dbpc->items[i].aug_1, + dbpc->items[i].aug_2, + dbpc->items[i].aug_3, + dbpc->items[i].aug_4, + dbpc->items[i].aug_5 + ); + first_entry = 1; + } + else{ + query = query + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, 0) \n", + last_insert_id, + dbpc->items[i].equip_slot, + dbpc->items[i].item_id, + dbpc->items[i].charges, + dbpc->items[i].aug_1, + dbpc->items[i].aug_2, + dbpc->items[i].aug_3, + dbpc->items[i].aug_4, + dbpc->items[i].aug_5 + ); + } + } + auto sc_results = QueryDatabase(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 atoi(row[0]); + } + return 0; +} + +uint32 ZoneDatabase::GetCharacterCorpseCount(uint32 char_id) { + std::string query = StringFormat("SELECT COUNT(*) FROM `character_corpses` WHERE `charid` = '%u'", char_id); + auto results = QueryDatabase(query); + + for (auto row = results.begin(); row != results.end(); ++row) { + return atoi(row[0]); + } + return 0; +} + +uint32 ZoneDatabase::GetCharacterCorpseID(uint32 char_id, uint8 corpse) { + 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) { + for (int i = 0; i < corpse; i++) { + return atoi(row[0]); + } + } + return 0; +} + +uint32 ZoneDatabase::GetCharacterCorpseItemAt(uint32 corpse_id, uint16 slotid) { + Corpse* tmp = LoadCharacterCorpse(corpse_id); + uint32 itemid = 0; + + if (tmp) { + itemid = tmp->GetWornItem(slotid); + tmp->DepopCorpse(); + } + return itemid; +} + +bool ZoneDatabase::LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct* pcs){ + std::string query = StringFormat( + "SELECT \n" + "id, \n" + "charid, \n" + "charname, \n" + "zone_id, \n" + "instance_id, \n" + "x, \n" + "y, \n" + "z, \n" + "heading, \n" + "`data`, \n" + "time_of_death, \n" + "is_rezzed, \n" + "is_buried, \n" + "was_at_graveyard, \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 + ); + auto results = QueryDatabase(query); + uint16 i = 0; + for (auto row = results.begin(); row != results.end(); ++row) { + pcs->locked = atoi(row[i]); i++; // is_locked, + pcs->exp = atoi(row[i]); i++; // exp, + pcs->size = atoi(row[i]); i++; // size, + pcs->level = atoi(row[i]); i++; // `level`, + pcs->race = atoi(row[i]); i++; // race, + pcs->gender = atoi(row[i]); i++; // gender, + pcs->class_ = atoi(row[i]); i++; // class, + pcs->deity = atoi(row[i]); i++; // deity, + pcs->texture = atoi(row[i]); i++; // texture, + pcs->helmtexture = atoi(row[i]); i++; // helm_texture, + pcs->copper = atoi(row[i]); i++; // copper, + pcs->silver = atoi(row[i]); i++; // silver, + pcs->gold = atoi(row[i]); i++; // gold, + pcs->plat = atoi(row[i]); i++; // platinum, + pcs->haircolor = atoi(row[i]); i++; // hair_color, + pcs->beardcolor = atoi(row[i]); i++; // beard_color, + pcs->eyecolor1 = atoi(row[i]); i++; // eye_color_1, + pcs->eyecolor2 = atoi(row[i]); i++; // eye_color_2, + pcs->hairstyle = atoi(row[i]); i++; // hair_style, + pcs->face = atoi(row[i]); i++; // face, + pcs->beard = atoi(row[i]); i++; // beard, + pcs->drakkin_heritage = atoi(row[i]); i++; // drakkin_heritage, + pcs->drakkin_tattoo = atoi(row[i]); i++; // drakkin_tattoo, + pcs->drakkin_details = atoi(row[i]); i++; // drakkin_details, + pcs->item_tint[0].color = atoi(row[i]); i++; // wc_1, + pcs->item_tint[1].color = atoi(row[i]); i++; // wc_2, + pcs->item_tint[2].color = atoi(row[i]); i++; // wc_3, + pcs->item_tint[3].color = atoi(row[i]); i++; // wc_4, + pcs->item_tint[4].color = atoi(row[i]); i++; // wc_5, + pcs->item_tint[5].color = atoi(row[i]); i++; // wc_6, + pcs->item_tint[6].color = atoi(row[i]); i++; // wc_7, + pcs->item_tint[7].color = atoi(row[i]); i++; // wc_8, + pcs->item_tint[8].color = atoi(row[i]); 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" + "attuned \n" + "FROM \n" + "character_corpse_items \n" + "WHERE `corpse_id` = %u\n" + "ORDER BY `equip_slot`", + corpse_id + ); + results = QueryDatabase(query); + i = 0; + uint16 r = 0; + for (auto row = results.begin(); row != results.end(); ++row) { + pcs->items[i].equip_slot = atoi(row[r]); r++; // equip_slot, + pcs->items[i].item_id = atoi(row[r]); r++; // item_id, + pcs->items[i].charges = atoi(row[r]); r++; // charges, + pcs->items[i].aug_1 = atoi(row[r]); r++; // aug_1, + pcs->items[i].aug_2 = atoi(row[r]); r++; // aug_2, + pcs->items[i].aug_3 = atoi(row[r]); r++; // aug_3, + pcs->items[i].aug_4 = atoi(row[r]); r++; // aug_4, + pcs->items[i].aug_5 = atoi(row[r]); r++; // aug_5, + r = 0; + i++; + } + pcs->itemcount = i; + return true; +} + +Corpse* ZoneDatabase::SummonBuriedCharacterCorpses(uint32 char_id, uint32 dest_zone_id, uint16 dest_instance_id, float dest_x, float dest_y, float dest_z, float dest_heading) { + Corpse* NewCorpse = 0; + std::string query = StringFormat( + "SELECT `id`, `charname`, `time_of_death`, `is_rezzed` FROM `character_corpses` WHERE `charid` = '%u' AND `is_buried` = 1 ORDER BY `time_of_death` LIMIT 1", + char_id + ); + auto results = QueryDatabase(query); + + for (auto row = results.begin(); row != results.end(); ++row) { + PlayerCorpse_Struct pcs; + database.LoadCharacterCorpseData(atoi(row[0]), &pcs); + NewCorpse = Corpse::LoadFromDBData(atoi(row[0]), char_id, row[1], &pcs, dest_x, dest_y, dest_z, dest_heading, row[2], atoi(row[3]) == 1, false); + if (NewCorpse) { + entity_list.AddCorpse(NewCorpse); + NewCorpse->SetDecayTimer(RuleI(Character, CorpseDecayTimeMS)); + NewCorpse->Spawn(); + if (!UnburyCharacterCorpse(NewCorpse->GetDBID(), dest_zone_id, dest_instance_id, dest_x, dest_y, dest_z, dest_heading)) + LogFile->write(EQEMuLog::Error, "Unable to unbury a summoned player corpse for character id %u.", char_id); + } + } + + return NewCorpse; +} + +bool ZoneDatabase::SummonAllCharacterCorpses(uint32 char_id, uint32 dest_zone_id, uint16 dest_instance_id, float dest_x, float dest_y, float dest_z, float dest_heading) { + Corpse* NewCorpse = 0; + int CorpseCount = 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, dest_x, dest_y, dest_z, dest_heading, char_id + ); + auto results = QueryDatabase(query); + + query = StringFormat( + "SELECT `id`, `charname`, `time_of_death`, `is_rezzed` FROM `character_corpses` WHERE `charid` = '%u'" + "ORDER BY time_of_death", + char_id + ); + results = QueryDatabase(query); + + for (auto row = results.begin(); row != results.end(); ++row) { + PlayerCorpse_Struct pcs; + database.LoadCharacterCorpseData(atoi(row[0]), &pcs); + NewCorpse = Corpse::LoadFromDBData(atoi(row[0]), + char_id, + row[1], + &pcs, + dest_x, + dest_y, + dest_z, + dest_heading, + row[2], + atoi(row[3]) == 1, false); + if (NewCorpse) { + entity_list.AddCorpse(NewCorpse); + NewCorpse->SetDecayTimer(RuleI(Character, CorpseDecayTimeMS)); + NewCorpse->Spawn(); + ++CorpseCount; + } + else{ + LogFile->write(EQEMuLog::Error, "Unable to construct a player corpse for character id %u.", char_id); + } + } + + return (CorpseCount > 0); +} + +bool ZoneDatabase::UnburyCharacterCorpse(uint32 db_id, uint32 new_zone_id, uint16 new_instance_id, float new_x, float new_y, float new_z, float new_heading) { + 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, new_x, new_y, new_z, new_heading, db_id + ); + auto results = QueryDatabase(query); + if (results.Success() && results.RowsAffected() != 0){ + return true; + } + 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` FROM `character_corpses` WHERE `id` = '%u' LIMIT 1", + player_corpse_id + ); + auto results = QueryDatabase(query); + for (auto row = results.begin(); row != results.end(); ++row) { + PlayerCorpse_Struct pcs; + database.LoadCharacterCorpseData(atoi(row[0]), &pcs); + NewCorpse = Corpse::LoadFromDBData( + atoi(row[0]), // id uint32 in_dbid + atoi(row[1]), // charid uint32 in_charid + row[2], // charname char* in_charname + &pcs, // PlayerCorpse_Struct* pcs + atof(row[3]), // x float in_x + atof(row[4]), // y float in_y + atof(row[5]), // z float in_z + atof(row[6]), // heading float in_heading + row[7], // time_of_death char* time_of_death + atoi(row[8]) == 1, // is_rezzed bool rezzed + atoi(row[9]) // was_at_graveyard bool was_at_graveyard + ); + entity_list.AddCorpse(NewCorpse); + } + return NewCorpse; +} + +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 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 FROM character_corpses WHERE zone_id='%u' AND instance_id='%u' AND is_buried=0", zone_id, instance_id); + + auto results = QueryDatabase(query); + for (auto row = results.begin(); row != results.end(); ++row) { + PlayerCorpse_Struct pcs; + database.LoadCharacterCorpseData(atoi(row[0]), &pcs); + entity_list.AddCorpse( + Corpse::LoadFromDBData( + atoi(row[0]), // id uint32 in_dbid + atoi(row[1]), // charid uint32 in_charid + row[2], // charname char* in_charname + &pcs, // PlayerCorpse_tSruct* pcs + atof(row[3]), // x float in_x + atof(row[4]), // y float in_y + atof(row[5]), // z float in_z + atof(row[6]), // heading float in_heading + row[7], // time_of_death char* time_of_death + atoi(row[8]) == 1, // is_rezzed bool rezzed + atoi(row[9]) + ) + ); + } + + 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 atoi(row[0]); + } + return 0; +} + +bool ZoneDatabase::BuryCharacterCorpse(uint32 db_id) { + std::string query = StringFormat("UPDATE `character_corpses` SET `is_buried` = 1 WHERE `id` = %d", db_id); + auto results = QueryDatabase(query); + if (results.Success() && results.RowsAffected() != 0){ + return true; + } + return false; +} + +bool ZoneDatabase::BuryAllCharacterCorpses(uint32 char_id) { + std::string query = StringFormat("UPDATE `character_corpses` SET `is_buried` = 1 WHERE `charid` = %d", char_id); + auto results = QueryDatabase(query); + if (results.Success() && results.RowsAffected() != 0){ + return true; + } + return false; +} + +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; +} diff --git a/zone/zonedb.h b/zone/zonedb.h index db796e481..982d4e2c7 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -214,7 +214,7 @@ public: ZoneDatabase(const char* host, const char* user, const char* passwd, const char* database,uint32 port); virtual ~ZoneDatabase(); - /* Objects and World Containers */ + /* Objects and World Containers */ void LoadWorldContainer(uint32 parentid, ItemInst* container); void SaveWorldContainer(uint32 zone_id, uint32 parent_id, const ItemInst* container); void DeleteWorldContainer(uint32 parent_id,uint32 zone_id); @@ -223,23 +223,24 @@ public: void DeleteObject(uint32 id); Ground_Spawns* LoadGroundSpawns(uint32 zone_id, int16 version, Ground_Spawns* gs); - /* Traders */ + /* Traders */ void SaveTraderItem(uint32 char_id,uint32 itemid,uint32 uniqueid, int32 charges,uint32 itemcost,uint8 slot); void UpdateTraderItemCharges(int char_id, uint32 ItemInstID, int32 charges); - void UpdateTraderItemPrice(int CharID, uint32 ItemID, uint32 Charges, uint32 NewPrice); - ItemInst* LoadSingleTraderItem(uint32 char_id, int uniqueid); + void UpdateTraderItemPrice(int CharID, uint32 ItemID, uint32 Charges, uint32 NewPrice); void DeleteTraderItem(uint32 char_id); void DeleteTraderItem(uint32 char_id,uint16 slot_id); + + ItemInst* LoadSingleTraderItem(uint32 char_id, int uniqueid); Trader_Struct* LoadTraderItem(uint32 char_id); TraderCharges_Struct* LoadTraderItemWithCharges(uint32 char_id); - /* Buyer/Barter */ + /* Buyer/Barter */ void AddBuyLine(uint32 CharID, uint32 BuySlot, uint32 ItemID, const char *ItemName, uint32 Quantity, uint32 Price); void RemoveBuyLine(uint32 CharID, uint32 BuySlot); void DeleteBuyLines(uint32 CharID); void UpdateBuyLine(uint32 CharID, uint32 BuySlot, uint32 Quantity); - /* General Character Related Stuff */ + /* General Character Related Stuff */ bool SetServerFilters(char* name, ServerSideFilters_Struct *ssfs); uint32 GetServerFilters(char* name, ServerSideFilters_Struct *ssfs); @@ -249,7 +250,7 @@ public: void SavePetInfo(Client *c); void RemoveTempFactions(Client *c); - /* Character Data Loaders */ + /* Character Data Loaders */ bool LoadCharacterFactionValues(uint32 character_id, faction_map & val_list); bool LoadCharacterSpellBook(uint32 character_id, PlayerProfile_Struct* pp); bool LoadCharacterMemmedSpells(uint32 character_id, PlayerProfile_Struct* pp); @@ -265,14 +266,14 @@ public: bool LoadCharacterPotions(uint32 character_id, PlayerProfile_Struct* pp); bool LoadCharacterLeadershipAA(uint32 character_id, PlayerProfile_Struct* pp); - /* Character Data Saves */ + /* Character Data Saves */ bool SaveCharacterBindPoint(uint32 character_id, uint32 zone_id, uint32 instance_id, float x, float y, float z, float heading, uint8 is_home); bool SaveCharacterCurrency(uint32 character_id, PlayerProfile_Struct* pp); bool SaveCharacterData(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp, ExtendedProfile_Struct* m_epp); bool SaveCharacterAA(uint32 character_id, uint32 aa_id, uint32 current_level); bool SaveCharacterSpell(uint32 character_id, uint32 spell_id, uint32 slot_id); bool SaveCharacterMemorizedSpell(uint32 character_id, uint32 spell_id, uint32 slot_id); - bool SaveCharacterMaterialColor(uint32 character_id, uint32 slot_id, uint32 color); + bool SaveCharacterMaterialColor(uint32 character_id, uint32 slot_id, uint32 color); bool SaveCharacterSkill(uint32 character_id, uint32 skill_id, uint32 value); bool SaveCharacterLanguage(uint32 character_id, uint32 lang_id, uint32 value); bool SaveCharacterDisc(uint32 character_id, uint32 slot_id, uint32 disc_id); @@ -281,120 +282,122 @@ public: bool SaveCharacterPotionBelt(uint32 character_id, uint8 potion_id, uint32 item_id, uint32 icon); bool SaveCharacterLeadershipAA(uint32 character_id, PlayerProfile_Struct* pp); - /* Character Data Deletes */ + /* Character Data Deletes */ bool DeleteCharacterSpell(uint32 character_id, uint32 spell_id, uint32 slot_id); bool DeleteCharacterMemorizedSpell(uint32 character_id, uint32 spell_id, uint32 slot_id); - bool DeleteCharacterDisc(uint32 character_id, uint32 slot_id); + bool DeleteCharacterDisc(uint32 character_id, uint32 slot_id); bool DeleteCharacterBandolier(uint32 character_id, uint32 band_id); bool DeleteCharacterLeadershipAAs(uint32 character_id); bool DeleteCharacterAAs(uint32 character_id); bool DeleteCharacterDye(uint32 character_id); - /* Character Inventory */ + /* Character Inventory */ bool NoRentExpired(const char* name); - /* Corpses */ - bool GetDecayTimes(npcDecayTimes_Struct* npcCorpseDecayTimes); - uint32 CreatePlayerCorpse(uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, uchar* data, uint32 datasize, float x, float y, float z, float heading); - bool CreatePlayerCorpseBackup(uint32 dbid, uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, uchar* data, uint32 datasize, float x, float y, float z, float heading); - uint32 UpdatePlayerCorpse(uint32 dbid, uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, uchar* data, uint32 datasize, float x, float y, float z, float heading, bool rezzed = false); - void MarkCorpseAsRezzed(uint32 dbid); - bool BuryPlayerCorpse(uint32 dbid); - bool BuryAllPlayerCorpses(uint32 charid); - bool DeletePlayerCorpse(uint32 dbid); - uint32 GetPlayerBurriedCorpseCount(uint32 char_id); - Corpse* SummonBurriedPlayerCorpse(uint32 char_id, uint32 dest_zoneid, uint16 dest_instanceid, float dest_x, float dest_y, float dest_z, float dest_heading); - bool SummonAllPlayerCorpses(uint32 char_id, uint32 dest_zoneid, uint16 dest_instanceid, float dest_x, float dest_y, float dest_z, float dest_heading); - bool SummonAllGraveyardCorpses(uint32 cur_zoneid, uint32 dest_zoneid, uint16 dest_instanceid, float dest_x, float dest_y, float dest_z, float dest_heading); - Corpse* LoadPlayerCorpse(uint32 player_corpse_id); - bool UnburyPlayerCorpse(uint32 dbid, uint32 new_zoneid, uint16 dest_instanceid, float new_x, float new_y, float new_z, float new_heading); - bool LoadPlayerCorpses(uint32 iZoneID, uint16 iInstanceID); - uint32 GraveyardPlayerCorpse(uint32 dbid, uint32 zoneid, uint16 instanceid, float x, float y, float z, float heading); - uint32 NewGraveyardRecord(uint32 graveyard_zoneid, float graveyard_x, float graveyard_y, float graveyard_z, float graveyard_heading); - uint32 AddGraveyardIDToZone(uint32 zone_id, uint32 graveyard_id); - bool DeleteGraveyard(uint32 zone_id, uint32 graveyard_id); - uint32 GetFirstCorpseID(uint32 char_id); - uint32 GetPlayerCorpseCount(uint32 char_id); - uint32 GetPlayerCorpseID(uint32 char_id, uint8 corpse); - uint32 GetPlayerCorpseItemAt(uint32 corpse_id, uint16 slotid); - uint32 GetPlayerCorpseTimeLeft(uint8 corpse, uint8 type); + /* Corpses */ + + bool LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct* pcs); + Corpse* LoadCharacterCorpse(uint32 player_corpse_id); + Corpse* SummonBuriedCharacterCorpses(uint32 char_id, uint32 dest_zoneid, uint16 dest_instanceid, float dest_x, float dest_y, float dest_z, float dest_heading); + 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, float dest_x, float dest_y, float dest_z, float dest_heading); + bool SummonAllGraveyardCorpses(uint32 cur_zoneid, uint32 dest_zoneid, uint16 dest_instanceid, float dest_x, float dest_y, float dest_z, float dest_heading); + bool UnburyCharacterCorpse(uint32 dbid, uint32 new_zoneid, uint16 dest_instanceid, float new_x, float new_y, float new_z, float new_heading); + bool LoadCharacterCorpses(uint32 iZoneID, uint16 iInstanceID); + bool DeleteGraveyard(uint32 zone_id, uint32 graveyard_id); + uint32 GetCharacterBuriedCorpseCount(uint32 char_id); + uint32 SendCharacterCorpseToGraveyard(uint32 dbid, uint32 zoneid, uint16 instanceid, float x, float y, float z, float heading); + uint32 CreateGraveyardRecord(uint32 graveyard_zoneid, float graveyard_x, float graveyard_y, float graveyard_z, float graveyard_heading); + uint32 AddGraveyardIDToZone(uint32 zone_id, uint32 graveyard_id); + uint32 SaveCharacterCorpse(uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, PlayerCorpse_Struct* dbpc, float x, float y, float z, float heading); + uint32 UpdateCharacterCorpse(uint32 dbid, uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, PlayerCorpse_Struct* dbpc, float x, float y, float z, float heading, bool rezzed = false); + uint32 GetFirstCorpseID(uint32 char_id); + uint32 GetCharacterCorpseCount(uint32 char_id); + uint32 GetCharacterCorpseID(uint32 char_id, uint8 corpse); + uint32 GetCharacterCorpseItemAt(uint32 corpse_id, uint16 slotid); + uint32 GetPlayerCorpseTimeLeft(uint8 corpse, uint8 type); - /* Faction */ - bool GetNPCFactionList(uint32 npcfaction_id, int32* faction_id, int32* value, uint8* temp, int32* primary_faction = 0); - bool GetFactionData(FactionMods* fd, uint32 class_mod, uint32 race_mod, uint32 deity_mod, int32 faction_id); //needed for factions Dec, 16 2001 - bool GetFactionName(int32 faction_id, char* name, uint32 buflen); // needed for factions Dec, 16 2001 - bool GetFactionIdsForNPC(uint32 nfl_id, std::list *faction_list, int32* primary_faction = 0); // improve faction handling - bool SetCharacterFactionLevel(uint32 char_id, int32 faction_id, int32 value, uint8 temp, faction_map &val_list); // needed for factions Dec, 16 2001 - bool LoadFactionData(); + /* Faction */ + bool GetNPCFactionList(uint32 npcfaction_id, int32* faction_id, int32* value, uint8* temp, int32* primary_faction = 0); + bool GetFactionData(FactionMods* fd, uint32 class_mod, uint32 race_mod, uint32 deity_mod, int32 faction_id); //needed for factions Dec, 16 2001 + bool GetFactionName(int32 faction_id, char* name, uint32 buflen); // needed for factions Dec, 16 2001 + bool GetFactionIdsForNPC(uint32 nfl_id, std::list *faction_list, int32* primary_faction = 0); // improve faction handling + bool SetCharacterFactionLevel(uint32 char_id, int32 faction_id, int32 value, uint8 temp, faction_map &val_list); // needed for factions Dec, 16 2001 + bool LoadFactionData(); - /* AAs */ - bool LoadAAEffects(); - bool LoadAAEffects2(); - bool LoadSwarmSpells(); - SendAA_Struct* GetAASkillVars(uint32 skill_id); - uint8 GetTotalAALevels(uint32 skill_id); - uint32 GetSizeAA(); - uint32 CountAAs(); - void LoadAAs(SendAA_Struct **load); - uint32 CountAAEffects(); - void FillAAEffects(SendAA_Struct* aa_struct); + /* AAs */ + bool LoadAAEffects(); + bool LoadAAEffects2(); + bool LoadSwarmSpells(); + SendAA_Struct*GetAASkillVars(uint32 skill_id); + uint8 GetTotalAALevels(uint32 skill_id); + uint32 GetSizeAA(); + uint32 CountAAs(); + void LoadAAs(SendAA_Struct **load); + uint32 CountAAEffects(); + void FillAAEffects(SendAA_Struct* aa_struct); - /* Zone related */ - bool GetZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct *data, bool &can_bind, bool &can_combat, bool &can_levitate, bool &can_castoutdoor, bool &is_city, bool &is_hotzone, bool &allow_mercs, uint8 &zone_type, int &ruleset, char **map_filename); - bool SaveZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct* zd); - bool LoadStaticZonePoints(LinkedList* zone_point_list,const char* zonename, uint32 version); - bool UpdateZoneSafeCoords(const char* zonename, float x, float y, float z); - uint8 GetUseCFGSafeCoords(); - int getZoneShutDownDelay(uint32 zoneID, uint32 version); + /* Zone related */ + bool GetZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct *data, bool &can_bind, bool &can_combat, bool &can_levitate, bool &can_castoutdoor, bool &is_city, bool &is_hotzone, bool &allow_mercs, uint8 &zone_type, int &ruleset, char **map_filename); + bool SaveZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct* zd); + bool LoadStaticZonePoints(LinkedList* zone_point_list,const char* zonename, uint32 version); + bool UpdateZoneSafeCoords(const char* zonename, float x, float y, float z); + uint8 GetUseCFGSafeCoords(); + int getZoneShutDownDelay(uint32 zoneID, uint32 version); - /* Spawns and Spawn Points */ - bool LoadSpawnGroups(const char* zone_name, uint16 version, SpawnGroupList* spawn_group_list); - bool LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList* spawn_group_list); - bool PopulateZoneSpawnList(uint32 zoneid, LinkedList &spawn2_list, int16 version, uint32 repopdelay = 0); - Spawn2* LoadSpawn2(LinkedList &spawn2_list, uint32 spawn2id, uint32 timeleft); - bool CreateSpawn2(Client *c, uint32 spawngroup, const char* zone, float heading, float x, float y, float z, uint32 respawn, uint32 variance, uint16 condition, int16 cond_value); - void UpdateSpawn2Timeleft(uint32 id, uint16 instance_id,uint32 timeleft); - uint32 GetSpawnTimeLeft(uint32 id, uint16 instance_id); - void UpdateSpawn2Status(uint32 id, uint8 new_status); + /* Spawns and Spawn Points */ + bool LoadSpawnGroups(const char* zone_name, uint16 version, SpawnGroupList* spawn_group_list); + bool LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList* spawn_group_list); + bool PopulateZoneSpawnList(uint32 zoneid, LinkedList &spawn2_list, int16 version, uint32 repopdelay = 0); + Spawn2* LoadSpawn2(LinkedList &spawn2_list, uint32 spawn2id, uint32 timeleft); + bool CreateSpawn2(Client *c, uint32 spawngroup, const char* zone, float heading, float x, float y, float z, uint32 respawn, uint32 variance, uint16 condition, int16 cond_value); + void UpdateSpawn2Timeleft(uint32 id, uint16 instance_id,uint32 timeleft); + uint32 GetSpawnTimeLeft(uint32 id, uint16 instance_id); + void UpdateSpawn2Status(uint32 id, uint8 new_status); - /* Grids/Paths */ - uint32 GetFreeGrid(uint16 zoneid); - void DeleteGrid(Client *c, uint32 sg2, uint32 grid_num, bool grid_too,uint16 zoneid); - void DeleteWaypoint(Client *c, uint32 grid_num, uint32 wp_num,uint16 zoneid); -// uint32 AddWP(Client *c, uint32 sg2, uint16 grid_num, uint8 wp_num, float xpos, float ypos, float zpos, uint32 pause, float xpos1, float ypos1, float zpos1, int type1, int type2,uint16 zoneid); - void AddWP(Client *c, uint32 gridid, uint32 wpnum, float xpos, float ypos, float zpos, uint32 pause, uint16 zoneid, float heading); - uint32 AddWPForSpawn(Client *c, uint32 spawn2id, float xpos, float ypos, float zpos, uint32 pause, int type1, int type2, uint16 zoneid, float heading); - void ModifyGrid(Client *c, bool remove, uint32 id, uint8 type = 0, uint8 type2 = 0,uint16 zoneid = 0); - void ModifyWP(Client *c, uint32 grid_id, uint32 wp_num, float xpos, float ypos, float zpos, uint32 script=0,uint16 zoneid =0); - uint8 GetGridType(uint32 grid,uint32 zoneid); - uint8 GetGridType2(uint32 grid, uint16 zoneid); - bool GetWaypoints(uint32 grid, uint16 zoneid, uint32 num, wplist* wp); - void AssignGrid(Client *client, float x, float y, uint32 id); - int GetHighestGrid(uint32 zoneid); - int GetHighestWaypoint(uint32 zoneid, uint32 gridid); + /* Grids/Paths */ + uint32 GetFreeGrid(uint16 zoneid); + void DeleteGrid(Client *c, uint32 sg2, uint32 grid_num, bool grid_too, uint16 zoneid); + void DeleteWaypoint(Client *c, uint32 grid_num, uint32 wp_num, uint16 zoneid); + void AddWP(Client *c, uint32 gridid, uint32 wpnum, float xpos, float ypos, float zpos, uint32 pause, uint16 zoneid, float heading); + uint32 AddWPForSpawn(Client *c, uint32 spawn2id, float xpos, float ypos, float zpos, uint32 pause, int type1, int type2, uint16 zoneid, float heading); + void ModifyGrid(Client *c, bool remove, uint32 id, uint8 type = 0, uint8 type2 = 0, uint16 zoneid = 0); + void ModifyWP(Client *c, uint32 grid_id, uint32 wp_num, float xpos, float ypos, float zpos, uint32 script = 0, uint16 zoneid = 0); + uint8 GetGridType(uint32 grid, uint32 zoneid); + uint8 GetGridType2(uint32 grid, uint16 zoneid); + bool GetWaypoints(uint32 grid, uint16 zoneid, uint32 num, wplist* wp); + void AssignGrid(Client *client, float x, float y, uint32 id); + int GetHighestGrid(uint32 zoneid); + int GetHighestWaypoint(uint32 zoneid, uint32 gridid); - /* NPCs */ - const NPCType* GetNPCType(uint32 id); - uint32 NPCSpawnDB(uint8 command, const char* zone, uint32 zone_version, Client *c, NPC* spawn = 0, uint32 extra = 0); // 0 = Create 1 = Add; 2 = Update; 3 = Remove; 4 = Delete - uint32 CreateNewNPCCommand(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 extra); - uint32 AddNewNPCSpawnGroupCommand(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 respawnTime); - uint32 DeleteSpawnLeaveInNPCTypeTable(const char* zone, Client *client, NPC* spawn); - uint32 DeleteSpawnRemoveFromNPCTypeTable(const char* zone, uint32 zone_version, Client *client, NPC* spawn); - uint32 AddSpawnFromSpawnGroup(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 spawnGroupID); - uint32 AddNPCTypes(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 spawnGroupID); - uint32 UpdateNPCTypeAppearance(Client *client, NPC* spawn); - bool SetSpecialAttkFlag(uint8 id, const char* flag); - bool GetPetEntry(const char *pet_type, PetRecord *into); - bool GetPoweredPetEntry(const char *pet_type, int16 petpower, PetRecord *into); - bool GetBasePetItems(int32 equipmentset, uint32 *items); - void AddLootTableToNPC(NPC* npc,uint32 loottable_id, ItemList* itemlist, uint32* copper, uint32* silver, uint32* gold, uint32* plat); - void AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* itemlist, uint8 droplimit, uint8 mindrop); - uint32 GetMaxNPCSpellsID(); - uint32 GetMaxNPCSpellsEffectsID(); - DBnpcspells_Struct* GetNPCSpells(uint32 iDBSpellsID); - DBnpcspellseffects_Struct* GetNPCSpellsEffects(uint32 iDBSpellsEffectsID); + /* NPCs */ + + uint32 NPCSpawnDB(uint8 command, const char* zone, uint32 zone_version, Client *c, NPC* spawn = 0, uint32 extra = 0); // 0 = Create 1 = Add; 2 = Update; 3 = Remove; 4 = Delete + uint32 CreateNewNPCCommand(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 extra); + uint32 AddNewNPCSpawnGroupCommand(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 respawnTime); + uint32 DeleteSpawnLeaveInNPCTypeTable(const char* zone, Client *client, NPC* spawn); + uint32 DeleteSpawnRemoveFromNPCTypeTable(const char* zone, uint32 zone_version, Client *client, NPC* spawn); + uint32 AddSpawnFromSpawnGroup(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 spawnGroupID); + uint32 AddNPCTypes(const char* zone, uint32 zone_version, Client *client, NPC* spawn, uint32 spawnGroupID); + uint32 UpdateNPCTypeAppearance(Client *client, NPC* spawn); + bool SetSpecialAttkFlag(uint8 id, const char* flag); + bool GetPetEntry(const char *pet_type, PetRecord *into); + bool GetPoweredPetEntry(const char *pet_type, int16 petpower, PetRecord *into); + bool GetBasePetItems(int32 equipmentset, uint32 *items); + void AddLootTableToNPC(NPC* npc, uint32 loottable_id, ItemList* itemlist, uint32* copper, uint32* silver, uint32* gold, uint32* plat); + void AddLootDropToNPC(NPC* npc, uint32 lootdrop_id, ItemList* itemlist, uint8 droplimit, uint8 mindrop); + uint32 GetMaxNPCSpellsID(); + uint32 GetMaxNPCSpellsEffectsID(); - /* Mercs */ + DBnpcspells_Struct* GetNPCSpells(uint32 iDBSpellsID); + DBnpcspellseffects_Struct* GetNPCSpellsEffects(uint32 iDBSpellsEffectsID); + const NPCType* GetNPCType(uint32 id); + + /* Mercs */ const NPCType* GetMercType(uint32 id, uint16 raceid, uint32 clientlevel); void LoadMercEquipment(Merc *merc); void SaveMercBuffs(Merc *merc); @@ -403,10 +406,8 @@ public: bool LoadCurrentMerc(Client *c); bool SaveMerc(Merc *merc); bool DeleteMerc(uint32 merc_id); - //void LoadMercTypesForMercMerchant(NPC *merchant); - //void LoadMercsForMercMerchant(NPC *merchant); - /* Petitions */ + /* Petitions */ void UpdateBug(BugStruct* bug); void UpdateBug(PetitionBug_Struct* bug); void DeletePetitionFromDB(Petition* wpet); @@ -414,23 +415,23 @@ public: void InsertPetitionToDB(Petition* wpet); void RefreshPetitionsFromDB(); - /* Merchants */ + /* Merchants */ void SaveMerchantTemp(uint32 npcid, uint32 slot, uint32 item, uint32 charges); void DeleteMerchantTemp(uint32 npcid, uint32 slot); - /* Tradeskills */ + /* Tradeskills */ bool GetTradeRecipe(const ItemInst* container, uint8 c_type, uint32 some_id, uint32 char_id, DBTradeskillRecipe_Struct *spec); bool GetTradeRecipe(uint32 recipe_id, uint8 c_type, uint32 some_id, uint32 char_id, DBTradeskillRecipe_Struct *spec); uint32 GetZoneForage(uint32 ZoneID, uint8 skill); /* for foraging */ uint32 GetZoneFishing(uint32 ZoneID, uint8 skill, uint32 &npc_id, uint8 &npc_chance); void UpdateRecipeMadecount(uint32 recipe_id, uint32 char_id, uint32 madecount); - bool EnableRecipe(uint32 recipe_id); - bool DisableRecipe(uint32 recipe_id); + bool EnableRecipe(uint32 recipe_id); + bool DisableRecipe(uint32 recipe_id); - /* Tribute */ + /* Tribute */ bool LoadTributes(); - /* Doors */ + /* Doors */ bool DoorIsOpen(uint8 door_id,const char* zone_name); void SetDoorPlace(uint8 value,uint8 door_id,const char* zone_name); bool LoadDoors(int32 iDoorCount, Door *into, const char *zone_name, int16 version); @@ -441,34 +442,34 @@ public: int32 GetDoorsCount(uint32* oMaxID, const char *zone_name, int16 version); int32 GetDoorsCountPlusOne(const char *zone_name, int16 version); int32 GetDoorsDBCountPlusOne(const char *zone_name, int16 version); - void InsertDoor(uint32 did, uint16 ddoorid, const char* ddoor_name, float dxpos, float dypos, float dzpos, float dheading, uint8 dopentype, uint16 dguildid, uint32 dlockpick, uint32 dkeyitem, uint8 ddoor_param, uint8 dinvert, int dincline, uint16 dsize); + void InsertDoor(uint32 did, uint16 ddoorid, const char* ddoor_name, float dxpos, float dypos, float dzpos, float dheading, uint8 dopentype, uint16 dguildid, uint32 dlockpick, uint32 dkeyitem, uint8 ddoor_param, uint8 dinvert, int dincline, uint16 dsize); - /* Blocked Spells */ + /* Blocked Spells */ int32 GetBlockedSpellsCount(uint32 zoneid); bool LoadBlockedSpells(int32 blockedSpellsCount, ZoneSpellsBlocked* into, uint32 zoneid); - /* Traps */ + /* Traps */ bool LoadTraps(const char* zonename, int16 version); char* GetTrapMessage(uint32 trap_id); - /* Time */ + /* Time */ uint32 GetZoneTZ(uint32 zoneid, uint32 version); bool SetZoneTZ(uint32 zoneid, uint32 version, uint32 tz); - /* Group */ + /* Group */ void RefreshGroupFromDB(Client *c); uint8 GroupCount(uint32 groupid); - /* Raid */ + /* Raid */ uint8 RaidGroupCount(uint32 raidid, uint32 groupid); - /* Instancing */ + /* Instancing */ void ListAllInstances(Client* c, uint32 charid); - /* QGlobals */ + /* QGlobals */ void QGlobalPurge(); - /* Alternate Currency */ + /* Alternate Currency */ void LoadAltCurrencyValues(uint32 char_id, std::map ¤cy); void UpdateAltCurrencyValue(uint32 char_id, uint32 currency_id, uint32 value); diff --git a/zone/zonedump.h b/zone/zonedump.h index fc9b7b152..b2ae96319 100644 --- a/zone/zonedump.h +++ b/zone/zonedump.h @@ -35,11 +35,9 @@ spawn2 mediumblob, npcs mediumblob, npc_loot mediumblob, gmspawntype mediumblob, struct NPCType { char name[64]; - char lastname[70]; - + char lastname[70]; int32 cur_hp; - int32 max_hp; - + int32 max_hp; float size; float runspeed; uint8 gender; @@ -91,7 +89,7 @@ struct NPCType uint32 min_dmg; uint32 max_dmg; int16 attack_count; - char special_abilities[512]; + char special_abilities[512]; uint16 d_meele_texture1; uint16 d_meele_texture2; char ammo_idfile[30]; @@ -130,38 +128,28 @@ struct NPCType uint8 probability; }; -/* -Below are the blob structures for saving player corpses to the database --Quagmire - -create table player_corpses (id int(11) unsigned not null auto_increment primary key, charid int(11) unsigned not null, -charname varchar(30) not null, zonename varchar(16)not null, x float not null, y float not null, z float not null, -heading float not null, data blob not null, time timestamp(14), index zonename (zonename)); -*/ - -namespace player_lootitem -{ +namespace player_lootitem { struct ServerLootItem_Struct { - uint32 item_id; - int16 equipSlot; - uint8 charges; - uint16 lootslot; - uint32 aug1; - uint32 aug2; - uint32 aug3; - uint32 aug4; - uint32 aug5; + uint32 item_id; + int16 equip_slot; + uint8 charges; + uint16 lootslot; + uint32 aug_1; + uint32 aug_2; + uint32 aug_3; + uint32 aug_4; + uint32 aug_5; }; } -struct DBPlayerCorpse_Struct { +struct PlayerCorpse_Struct { uint32 crc; bool locked; uint32 itemcount; uint32 exp; float size; uint8 level; - uint8 race; + uint32 race; uint8 gender; uint8 class_; uint8 deity; @@ -185,37 +173,6 @@ struct DBPlayerCorpse_Struct { player_lootitem::ServerLootItem_Struct items[0]; }; -namespace classic_db -{ - struct DBPlayerCorpse_Struct { - uint32 crc; - bool locked; - uint32 itemcount; - uint32 exp; - float size; - uint8 level; - uint8 race; - uint8 gender; - uint8 class_; - uint8 deity; - uint8 texture; - uint8 helmtexture; - uint32 copper; - uint32 silver; - uint32 gold; - uint32 plat; - Color_Struct item_tint[9]; - uint8 haircolor; - uint8 beardcolor; - uint8 eyecolor1; - uint8 eyecolor2; - uint8 hairstyle; - uint8 face; - uint8 beard; - player_lootitem::ServerLootItem_Struct items[0]; - }; -} - struct Door { uint32 db_id; uint8 door_id; @@ -228,7 +185,7 @@ struct Door { int incline; uint8 opentype; uint32 guild_id; - uint16 lockpick; + uint16 lock_pick; uint32 keyitem; uint8 nokeyring; uint8 trigger_door;
NameZoneXYZDate" "RezzedBuried
 " @@ -6208,13 +6208,13 @@ void Client::Handle_OP_GMSearchCorpse(const EQApplicationPacket *app) float CorpseY = atof(row[3]); float CorpseZ = atof(row[4]); - strn0cpy(timeOfDeath, row[5], sizeof(timeOfDeath)); + strn0cpy(time_of_death, row[5], sizeof(time_of_death)); bool corpseRezzed = atoi(row[6]); bool corpseBuried = atoi(row[7]); popupText += StringFormat("
%s%s%8.0f%8.0f%8.0f%s%s%s