Moved zonedatabase functions out of corpse.cpp

Conversion portion mostly complete
Some header readability cleanup
Some function renaming
Struct renaming
Many variable renaming
MySQL error log for all of QueryDatabase
Corpse table renaming
Corpse table field renaming
Most corpse database functions redone
This commit is contained in:
Akkadius 2014-11-22 17:55:48 -06:00
parent 79a70271d5
commit 111fb84041
24 changed files with 1380 additions and 1012 deletions

View File

@ -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);
}

View File

@ -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();

View File

@ -4,6 +4,7 @@
#include <winsock2.h>
#endif
#include <fstream>
#include <iostream>
#include <errmsg.h>
#include <mysqld_error.h>
@ -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())

View File

@ -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;

View File

@ -376,7 +376,7 @@ void Adventure::MoveCorpsesToGraveyard()
std::list<uint32> dbid_list;
std::list<uint32> 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,

View File

@ -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()

View File

@ -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();

View File

@ -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 = "<table><tr><td>Name</td><td>Zone</td><td>X</td><td>Y</td><td>Z</td><td>Date</td><td>"
"Rezzed</td><td>Buried</td></tr><tr><td>&nbsp</td><td></td><td></td><td></td><td></td><td>"
@ -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("<tr><td>%s</td><td>%s</td><td>%8.0f</td><td>%8.0f</td><td>%8.0f</td><td>%s</td><td>%s</td><td>%s</td></tr>",
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) {

View File

@ -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();
}
}

View File

@ -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);

View File

@ -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; i<corpse;i++) {
row = mysql_fetch_row(result);
id = (uint32)atoi(row[0]);
}
mysql_free_result(result);
}
else {
std::cerr << "Error in GetPlayerCorpseID query '" << query << "' " << errbuf << std::endl;
}
safe_delete_array(query);
return id;
}
uint32 ZoneDatabase::GetPlayerCorpseItemAt(uint32 corpse_id, uint16 slotid) {
Corpse* tmp = LoadPlayerCorpse(corpse_id);
uint32 itemid = 0;
if (tmp) {
itemid = tmp->GetWornItem(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);
}
*/
}

View File

@ -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;

View File

@ -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]);

View File

@ -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;

View File

@ -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() {

View File

@ -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;
}
}

View File

@ -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));
}

View File

@ -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)
{

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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::list<struct NPCFactio
}
return true;
}
/*
Corpse Queries
*/
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 zone_idnumber=%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 zone_idnumber=%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::CreateGraveyardRecord(uint32 graveyard_zone_id, 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_zone_id, 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::SendCharacterCorpseToGraveyard(uint32 dbid, uint32 zone_id, uint16 instance_id, 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 character_corpses SET zone_id=%u, instance_id=0, x=%1.1f, y=%1.1f, z=%1.1f, heading=%1.1f, was_at_graveyard=1 WHERE id=%d", zone_id, 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::UpdateCharacterCorpse(uint32 db_id, uint32 char_id, const char* char_name, uint32 zone_id, uint16 instance_id, PlayerCorpse_Struct* dbpc, float x, float y, float z, float heading, bool is_rezzed) {
std::string query = StringFormat("UPDATE `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"
"`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",
EscapeString(char_name).c_str(),
zone_id,
instance_id,
char_id,
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,
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;
}

View File

@ -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<struct NPCFaction*> *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<struct NPCFaction*> *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<ZonePoint*>* 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<ZonePoint*>* 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*> &spawn2_list, int16 version, uint32 repopdelay = 0);
Spawn2* LoadSpawn2(LinkedList<Spawn2*> &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*> &spawn2_list, int16 version, uint32 repopdelay = 0);
Spawn2* LoadSpawn2(LinkedList<Spawn2*> &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<uint32, uint32> &currency);
void UpdateAltCurrencyValue(uint32 char_id, uint32 currency_id, uint32 value);

View File

@ -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;