[Fix] Fixes for corpses not properly saving some item instance data correctly. (#3123)

* Convert ZoneDb::LoadCharacterCorpseData to use a cleaner api that has a better layout.

* Update corpse save methods to use a new cleaner api.

* Add item to corpse will use a few new fields that don't yet save.

* Fix for some issues moving data to corpses.

* Make CreateItem more explicit to avoid overlooking places it's used and add more arguments.

* DB changes

* Revert of the changes to the database.CreateItem api change.

* Missed one.

* Fixes for mr Krab

* Small formatting

---------

Co-authored-by: KimLS <KimLS@peqtgc.com>
Co-authored-by: Akkadius <akkadius1@gmail.com>
This commit is contained in:
Alex 2023-03-22 23:16:52 -07:00 committed by GitHub
parent dc45e0d280
commit 5a6314e1a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 491 additions and 452 deletions

View File

@ -5522,7 +5522,11 @@ struct ServerLootItem_Struct {
uint32 aug_4; // uint32 aug_4;
uint32 aug_5; // uint32 aug_5;
uint32 aug_6; // uint32 aug_5;
uint8 attuned;
bool attuned;
std::string custom_data;
uint32 ornamenticon;
uint32 ornamentidfile;
uint32 ornament_hero_model;
uint16 trivial_min_level;
uint16 trivial_max_level;
uint16 npc_min_level;

View File

@ -203,12 +203,12 @@ namespace EQ
void dumpBankItems();
void dumpSharedBankItems();
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, std::string value);
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, int value);
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, float value);
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, bool value);
std::string GetCustomItemData(int16 slot_id, std::string identifier);
static const int GetItemStatValue(uint32 item_id, std::string identifier);
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, const std::string& value);
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, int value);
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, float value);
void SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, bool value);
std::string GetCustomItemData(int16 slot_id, const std::string& identifier);
static const int GetItemStatValue(uint32 item_id, const std::string& identifier);
protected:
///////////////////////////////
// Protected Methods

View File

@ -840,7 +840,20 @@ std::string EQ::ItemInstance::GetCustomDataString() const {
return ret_val;
}
std::string EQ::ItemInstance::GetCustomData(std::string identifier) {
void EQ::ItemInstance::SetCustomDataString(const std::string& str)
{
auto components = Strings::Split(str, "^");
auto value_count = components.size() / 2;
for (auto i = 0; i < value_count; i++) {
auto identifier = components[i * 2];
auto value = components[(i * 2) + 1];
SetCustomData(identifier, value);
}
}
std::string EQ::ItemInstance::GetCustomData(const std::string& identifier) {
std::map<std::string, std::string>::const_iterator iter = m_custom_data.find(identifier);
if (iter != m_custom_data.end()) {
return iter->second;
@ -849,33 +862,33 @@ std::string EQ::ItemInstance::GetCustomData(std::string identifier) {
return "";
}
void EQ::ItemInstance::SetCustomData(std::string identifier, std::string value) {
void EQ::ItemInstance::SetCustomData(const std::string& identifier, const std::string& value) {
DeleteCustomData(identifier);
m_custom_data[identifier] = value;
}
void EQ::ItemInstance::SetCustomData(std::string identifier, int value) {
void EQ::ItemInstance::SetCustomData(const std::string& identifier, int value) {
DeleteCustomData(identifier);
std::stringstream ss;
ss << value;
m_custom_data[identifier] = ss.str();
}
void EQ::ItemInstance::SetCustomData(std::string identifier, float value) {
void EQ::ItemInstance::SetCustomData(const std::string& identifier, float value) {
DeleteCustomData(identifier);
std::stringstream ss;
ss << value;
m_custom_data[identifier] = ss.str();
}
void EQ::ItemInstance::SetCustomData(std::string identifier, bool value) {
void EQ::ItemInstance::SetCustomData(const std::string& identifier, bool value) {
DeleteCustomData(identifier);
std::stringstream ss;
ss << value;
m_custom_data[identifier] = ss.str();
}
void EQ::ItemInstance::DeleteCustomData(std::string identifier) {
void EQ::ItemInstance::DeleteCustomData(const std::string& identifier) {
auto iter = m_custom_data.find(identifier);
if (iter != m_custom_data.end()) {
m_custom_data.erase(iter);

View File

@ -175,12 +175,13 @@ namespace EQ
void SetAttuned(bool flag) { m_attuned = flag; }
std::string GetCustomDataString() const;
std::string GetCustomData(std::string identifier);
void SetCustomData(std::string identifier, std::string value);
void SetCustomData(std::string identifier, int value);
void SetCustomData(std::string identifier, float value);
void SetCustomData(std::string identifier, bool value);
void DeleteCustomData(std::string identifier);
std::string GetCustomData(const std::string &identifier);
void SetCustomDataString(const std::string& str);
void SetCustomData(const std::string &identifier, const std::string& value);
void SetCustomData(const std::string &identifier, int value);
void SetCustomData(const std::string &identifier, float value);
void SetCustomData(const std::string &identifier, bool value);
void DeleteCustomData(const std::string& identifier);
// Allows treatment of this object as though it were a pointer to m_item
operator bool() const { return (m_item != nullptr); }

View File

@ -548,27 +548,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, EQ::InventoryProfile *inv, bool is
if (inst && row[9]) {
std::string data_str(row[9]);
std::string idAsString;
std::string value;
bool use_id = true;
for (int i = 0; i < data_str.length(); ++i) {
if (data_str[i] == '^') {
if (!use_id) {
inst->SetCustomData(idAsString, value);
idAsString.clear();
value.clear();
}
use_id = !use_id;
continue;
}
const char v = data_str[i];
if (use_id)
idAsString.push_back(v);
else
value.push_back(v);
}
inst->SetCustomDataString(data_str);
}
// theoretically inst can be nullptr ... this would be very bad ...
@ -679,28 +659,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, EQ::InventoryProfile *inv)
if (row[11]) {
std::string data_str(row[11]);
std::string idAsString;
std::string value;
bool use_id = true;
for (int i = 0; i < data_str.length(); ++i) {
if (data_str[i] == '^') {
if (!use_id) {
inst->SetCustomData(idAsString, value);
idAsString.clear();
value.clear();
}
use_id = !use_id;
continue;
}
const char v = data_str[i];
if (use_id)
idAsString.push_back(v);
else
value.push_back(v);
}
inst->SetCustomDataString(data_str);
}
inst->SetOrnamentIcon(ornament_icon);
@ -825,28 +784,7 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, EQ::InventoryPr
if (row[11]) {
std::string data_str(row[11]);
std::string idAsString;
std::string value;
bool use_id = true;
for (int i = 0; i < data_str.length(); ++i) {
if (data_str[i] == '^') {
if (!use_id) {
inst->SetCustomData(idAsString, value);
idAsString.clear();
value.clear();
}
use_id = !use_id;
continue;
}
const char v = data_str[i];
if (use_id)
idAsString.push_back(v);
else
value.push_back(v);
}
inst->SetCustomDataString(data_str);
}
inst->SetOrnamentIcon(ornament_icon);
@ -1544,7 +1482,11 @@ EQ::ItemInstance* SharedDatabase::CreateItem(
uint32 aug4,
uint32 aug5,
uint32 aug6,
bool attuned
bool attuned,
const std::string& custom_data,
uint32 ornamenticon,
uint32 ornamentidfile,
uint32 ornament_hero_model
) {
EQ::ItemInstance* inst = nullptr;
@ -1565,6 +1507,10 @@ EQ::ItemInstance* SharedDatabase::CreateItem(
inst->PutAugment(this, 4, aug5);
inst->PutAugment(this, 5, aug6);
inst->SetAttuned(attuned);
inst->SetCustomDataString(custom_data);
inst->SetOrnamentIcon(ornamenticon);
inst->SetOrnamentationIDFile(ornamentidfile);
inst->SetOrnamentHeroModel(ornament_hero_model);
}
return inst;
@ -1581,7 +1527,11 @@ EQ::ItemInstance* SharedDatabase::CreateItem(
uint32 aug4,
uint32 aug5,
uint32 aug6,
bool attuned
bool attuned,
const std::string& custom_data,
uint32 ornamenticon,
uint32 ornamentidfile,
uint32 ornament_hero_model
) {
EQ::ItemInstance* inst = nullptr;
if (item) {
@ -1600,6 +1550,10 @@ EQ::ItemInstance* SharedDatabase::CreateItem(
inst->PutAugment(this, 4, aug5);
inst->PutAugment(this, 5, aug6);
inst->SetAttuned(attuned);
inst->SetCustomDataString(custom_data);
inst->SetOrnamentIcon(ornamenticon);
inst->SetOrnamentationIDFile(ornamentidfile);
inst->SetOrnamentHeroModel(ornament_hero_model);
}
return inst;

View File

@ -126,7 +126,11 @@ public:
uint32 aug4 = 0,
uint32 aug5 = 0,
uint32 aug6 = 0,
bool attuned = 0
bool attuned = false,
const std::string& custom_data = "",
uint32 ornamenticon = 0,
uint32 ornamentidfile = 0,
uint32 ornament_hero_model = 0
);
EQ::ItemInstance *CreateItem(
const EQ::ItemData *item,
@ -137,7 +141,11 @@ public:
uint32 aug4 = 0,
uint32 aug5 = 0,
uint32 aug6 = 0,
bool attuned = 0
bool attuned = false,
const std::string &custom_data = "",
uint32 ornamenticon = 0,
uint32 ornamentidfile = 0,
uint32 ornament_hero_model = 0
);
EQ::ItemInstance *CreateBaseItem(const EQ::ItemData *item, int16 charges = 0);

View File

@ -42,7 +42,7 @@
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
*/
#define CURRENT_BINARY_DATABASE_VERSION 9225
#define CURRENT_BINARY_DATABASE_VERSION 9226
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9038

View File

@ -479,6 +479,7 @@
9223|2023_03_04_npc_scale_global_base_heroic_strikethrough.sql|SHOW COLUMNS FROM `npc_scale_global_base` LIKE 'heroic_strikethrough'|empty|
9224|2023_03_08_npc_scale_global_base_avoidance.sql|SHOW COLUMNS FROM `npc_scale_global_base` LIKE 'hp_regen_per_second'|empty|
9225|2023_01_21_bots_raid_members.sql|SHOW COLUMNS FROM `raid_members` LIKE 'bot_id'|empty|
9226|2023_03_17_corpse_fields.sql|SHOW COLUMNS FROM `character_corpse_items` LIKE 'custom_data'|empty|
# Upgrade conditions:
# This won't be needed after this system is implemented, but it is used database that are not

View File

@ -0,0 +1,5 @@
ALTER TABLE `character_corpse_items`
ADD COLUMN `custom_data` TEXT NULL AFTER `attuned`,
ADD COLUMN `ornamenticon` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `custom_data`,
ADD COLUMN `ornamentidfile` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `ornamenticon`,
ADD COLUMN `ornament_hero_model` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `ornamentidfile`;

View File

@ -946,28 +946,7 @@ bool WorldDatabase::GetCharSelInventory(uint32 account_id, char *name, EQ::Inven
if (row[11]) {
std::string data_str(row[11]);
std::string idAsString;
std::string value;
bool use_id = true;
for (int i = 0; i < data_str.length(); ++i) {
if (data_str[i] == '^') {
if (!use_id) {
inst->SetCustomData(idAsString, value);
idAsString.clear();
value.clear();
}
use_id = !use_id;
continue;
}
char v = data_str[i];
if (use_id)
idAsString.push_back(v);
else
value.push_back(v);
}
inst->SetCustomDataString(data_str);
}
inst->SetOrnamentIcon(ornament_icon);

View File

@ -1101,28 +1101,7 @@ bool BotDatabase::LoadItems(const uint32 bot_id, EQ::InventoryProfile& inventory
if (row[5]) {
std::string data_str(row[5]);
std::string idAsString;
std::string value;
bool use_id = true;
for (int i = 0; i < data_str.length(); ++i) {
if (data_str[i] == '^') {
if (!use_id) {
item_inst->SetCustomData(idAsString, value);
idAsString.clear();
value.clear();
}
use_id = !use_id;
continue;
}
char v = data_str[i];
if (use_id)
idAsString.push_back(v);
else
value.push_back(v);
}
item_inst->SetCustomDataString(data_str);
}
item_inst->SetOrnamentIcon((uint32)Strings::ToUnsignedInt(row[6]));

View File

@ -11050,7 +11050,11 @@ void Client::SummonBaggedItems(uint32 bag_item_id, const std::vector<ServerLootI
item.aug_4,
item.aug_5,
item.aug_6,
item.attuned
item.attuned,
item.custom_data,
item.ornamenticon,
item.ornamentidfile,
item.ornament_hero_model
);
if (summoned_bag_item)
{

View File

@ -75,76 +75,85 @@ void Corpse::SendLootReqErrorPacket(Client* client, LootResponse response) {
}
Corpse* Corpse::LoadCharacterCorpseEntity(uint32 in_dbid, uint32 in_charid, std::string in_charname, const glm::vec4& position, std::string time_of_death, bool rezzed, bool was_at_graveyard, uint32 guild_consent_id) {
uint32 item_count = database.GetCharacterCorpseItemCount(in_dbid);
auto buffer =
new char[sizeof(PlayerCorpse_Struct) + (item_count * sizeof(player_lootitem::ServerLootItem_Struct))];
PlayerCorpse_Struct *pcs = (PlayerCorpse_Struct*)buffer;
database.LoadCharacterCorpseData(in_dbid, pcs);
CharacterCorpseEntry ce;
if (!database.LoadCharacterCorpseData(in_dbid, ce)) {
LogDebug("Unable to create a corpse entity for [{}] [{}] [{}]", in_dbid, in_charid, in_charname);
return nullptr;
}
/* Load Items */
ItemList itemlist;
ServerLootItem_Struct* tmp = nullptr;
for (unsigned int i = 0; i < pcs->itemcount; i++) {
tmp = new ServerLootItem_Struct;
memcpy(tmp, &pcs->items[i], sizeof(player_lootitem::ServerLootItem_Struct));
for (auto &item: ce.items) {
auto tmp = new ServerLootItem_Struct;
tmp->equip_slot = item.equip_slot;
tmp->item_id = item.item_id;
tmp->charges = item.charges;
tmp->lootslot = item.lootslot;
tmp->aug_1 = item.aug_1;
tmp->aug_2 = item.aug_2;
tmp->aug_3 = item.aug_3;
tmp->aug_4 = item.aug_4;
tmp->aug_5 = item.aug_5;
tmp->aug_6 = item.aug_6;
tmp->attuned = item.attuned;
itemlist.push_back(tmp);
}
/* Create Corpse Entity */
auto pc = new Corpse(in_dbid, // uint32 in_dbid
in_charid, // uint32 in_charid
in_charname.c_str(), // char* in_charname
&itemlist, // ItemList* in_itemlist
pcs->copper, // uint32 in_copper
pcs->silver, // uint32 in_silver
pcs->gold, // uint32 in_gold
pcs->plat, // uint32 in_plat
position,
pcs->size, // float in_size
pcs->gender, // uint8 in_gender
pcs->race, // uint16 in_race
pcs->class_, // uint8 in_class
pcs->deity, // uint8 in_deity
pcs->level, // uint8 in_level
pcs->texture, // uint8 in_texture
pcs->helmtexture, // uint8 in_helmtexture
pcs->exp, // uint32 in_rezexp
was_at_graveyard // bool wasAtGraveyard
);
auto pc = new Corpse(
in_dbid, // uint32 in_dbid
in_charid, // uint32 in_charid
in_charname.c_str(), // char* in_charname
&itemlist, // ItemList* in_itemlist
ce.copper, // uint32 in_copper
ce.silver, // uint32 in_silver
ce.gold, // uint32 in_gold
ce.plat, // uint32 in_plat
position,
ce.size, // float in_size
ce.gender, // uint8 in_gender
ce.race, // uint16 in_race
ce.class_, // uint8 in_class
ce.deity, // uint8 in_deity
ce.level, // uint8 in_level
ce.texture, // uint8 in_texture
ce.helmtexture, // uint8 in_helmtexture
ce.exp, // uint32 in_rezexp
was_at_graveyard // bool wasAtGraveyard
);
if (pcs->locked)
if (ce.locked)
pc->Lock();
/* Load Item Tints */
pc->item_tint.Head.Color = pcs->item_tint.Head.Color;
pc->item_tint.Chest.Color = pcs->item_tint.Chest.Color;
pc->item_tint.Arms.Color = pcs->item_tint.Arms.Color;
pc->item_tint.Wrist.Color = pcs->item_tint.Wrist.Color;
pc->item_tint.Hands.Color = pcs->item_tint.Hands.Color;
pc->item_tint.Legs.Color = pcs->item_tint.Legs.Color;
pc->item_tint.Feet.Color = pcs->item_tint.Feet.Color;
pc->item_tint.Primary.Color = pcs->item_tint.Primary.Color;
pc->item_tint.Secondary.Color = pcs->item_tint.Secondary.Color;
pc->item_tint.Head.Color = ce.item_tint.Head.Color;
pc->item_tint.Chest.Color = ce.item_tint.Chest.Color;
pc->item_tint.Arms.Color = ce.item_tint.Arms.Color;
pc->item_tint.Wrist.Color = ce.item_tint.Wrist.Color;
pc->item_tint.Hands.Color = ce.item_tint.Hands.Color;
pc->item_tint.Legs.Color = ce.item_tint.Legs.Color;
pc->item_tint.Feet.Color = ce.item_tint.Feet.Color;
pc->item_tint.Primary.Color = ce.item_tint.Primary.Color;
pc->item_tint.Secondary.Color = ce.item_tint.Secondary.Color;
/* 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->haircolor = ce.haircolor;
pc->beardcolor = ce.beardcolor;
pc->eyecolor1 = ce.eyecolor1;
pc->eyecolor2 = ce.eyecolor2;
pc->hairstyle = ce.hairstyle;
pc->luclinface = ce.face;
pc->beard = ce.beard;
pc->drakkin_heritage = ce.drakkin_heritage;
pc->drakkin_tattoo = ce.drakkin_tattoo;
pc->drakkin_details = ce.drakkin_details;
pc->IsRezzed(rezzed);
pc->become_npc = false;
pc->become_npc = false;
pc->consented_guild_id = guild_consent_id;
pc->UpdateEquipmentLight(); // itemlist populated above..need to determine actual values
safe_delete_array(pcs);
return pc;
}
@ -509,8 +518,13 @@ void Corpse::MoveItemToCorpse(Client *client, EQ::ItemInstance *inst, int16 equi
inst->GetAugmentItemID(3),
inst->GetAugmentItemID(4),
inst->GetAugmentItemID(5),
inst->IsAttuned()
);
inst->IsAttuned(),
inst->GetCustomDataString(),
inst->GetOrnamentationIcon(),
inst->GetOrnamentationIDFile(),
inst->GetOrnamentHeroModel()
);
removedList.push_back(equipSlot);
while (true) {
@ -532,8 +546,13 @@ void Corpse::MoveItemToCorpse(Client *client, EQ::ItemInstance *inst, int16 equi
bag_inst->GetAugmentItemID(3),
bag_inst->GetAugmentItemID(4),
bag_inst->GetAugmentItemID(5),
bag_inst->IsAttuned()
);
bag_inst->IsAttuned(),
bag_inst->GetCustomDataString(),
bag_inst->GetOrnamentationIcon(),
bag_inst->GetOrnamentationIDFile(),
bag_inst->GetOrnamentHeroModel()
);
removedList.push_back(real_bag_slot);
client->DeleteItemInInventory(real_bag_slot, 0, true, false);
}
@ -677,63 +696,72 @@ void Corpse::CalcCorpseName() {
}
bool Corpse::Save() {
if (!is_player_corpse)
if (!is_player_corpse) {
return true;
if (!is_corpse_changed)
}
if (!is_corpse_changed) {
return true;
}
uint32 tmp = CountItems();
uint32 tmpsize = sizeof(PlayerCorpse_Struct) + (tmp * sizeof(player_lootitem::ServerLootItem_Struct));
CharacterCorpseEntry ce;
PlayerCorpse_Struct* dbpc = (PlayerCorpse_Struct*) new uchar[tmpsize];
memset(dbpc, 0, tmpsize);
dbpc->itemcount = tmp;
dbpc->size = size;
dbpc->locked = is_locked;
dbpc->copper = copper;
dbpc->silver = silver;
dbpc->gold = gold;
dbpc->plat = platinum;
dbpc->race = race;
dbpc->class_ = class_;
dbpc->gender = gender;
dbpc->deity = deity;
dbpc->level = level;
dbpc->texture = texture;
dbpc->helmtexture = helmtexture;
dbpc->exp = rez_experience;
ce.size = size;
ce.locked = is_locked;
ce.copper = copper;
ce.silver = silver;
ce.gold = gold;
ce.plat = platinum;
ce.race = race;
ce.class_ = class_;
ce.gender = gender;
ce.deity = deity;
ce.level = level;
ce.texture = texture;
ce.helmtexture = helmtexture;
ce.exp = rez_experience;
ce.item_tint = item_tint;
ce.haircolor = haircolor;
ce.beardcolor = beardcolor;
ce.eyecolor2 = eyecolor1;
ce.hairstyle = hairstyle;
ce.face = luclinface;
ce.beard = beard;
ce.drakkin_heritage = drakkin_heritage;
ce.drakkin_tattoo = drakkin_tattoo;
ce.drakkin_details = drakkin_details;
memcpy(&dbpc->item_tint.Slot, &item_tint.Slot, sizeof(dbpc->item_tint));
dbpc->haircolor = haircolor;
dbpc->beardcolor = beardcolor;
dbpc->eyecolor2 = eyecolor1;
dbpc->hairstyle = hairstyle;
dbpc->face = luclinface;
dbpc->beard = beard;
dbpc->drakkin_heritage = drakkin_heritage;
dbpc->drakkin_tattoo = drakkin_tattoo;
dbpc->drakkin_details = drakkin_details;
for (auto &item: itemlist) {
CharacterCorpseItemEntry e;
uint32 x = 0;
ItemList::iterator cur, end;
cur = itemlist.begin();
end = itemlist.end();
for (; cur != end; ++cur) {
ServerLootItem_Struct* item = *cur;
memcpy((char*)&dbpc->items[x++], (char*)item, sizeof(player_lootitem::ServerLootItem_Struct));
e.item_id = item->item_id;
e.equip_slot = item->equip_slot;
e.charges = item->charges;
e.lootslot = item->lootslot;
e.aug_1 = item->aug_1;
e.aug_2 = item->aug_2;
e.aug_3 = item->aug_3;
e.aug_4 = item->aug_4;
e.aug_5 = item->aug_5;
e.aug_6 = item->aug_6;
e.attuned = item->attuned;
e.custom_data = item->custom_data;
e.ornamenticon = item->ornamenticon;
e.ornamentidfile = item->ornamentidfile;
e.ornament_hero_model = item->ornament_hero_model;
ce.items.push_back(std::move(e));
}
/* Create New Corpse*/
if (corpse_db_id == 0) {
corpse_db_id = database.SaveCharacterCorpse(char_id, corpse_name, zone->GetZoneID(), zone->GetInstanceID(), dbpc, m_Position, consented_guild_id);
corpse_db_id = database.SaveCharacterCorpse(char_id, corpse_name, zone->GetZoneID(), zone->GetInstanceID(), ce, m_Position, consented_guild_id);
}
/* Update Corpse Data */
else{
corpse_db_id = database.UpdateCharacterCorpse(corpse_db_id, char_id, corpse_name, zone->GetZoneID(), zone->GetInstanceID(), dbpc, m_Position, consented_guild_id, IsRezzed());
corpse_db_id = database.UpdateCharacterCorpse(corpse_db_id, char_id, corpse_name, zone->GetZoneID(), zone->GetInstanceID(), ce, m_Position, consented_guild_id, IsRezzed());
}
safe_delete_array(dbpc);
return true;
}
@ -784,7 +812,21 @@ uint32 Corpse::CountItems() {
return itemlist.size();
}
void Corpse::AddItem(uint32 itemnum, uint16 charges, int16 slot, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned) {
void Corpse::AddItem(uint32 itemnum,
uint16 charges,
int16 slot,
uint32 aug1,
uint32 aug2,
uint32 aug3,
uint32 aug4,
uint32 aug5,
uint32 aug6,
bool attuned,
const std::string& custom_data,
uint32 ornamenticon,
uint32 ornamentidfile,
uint32 ornament_hero_model) {
if (!database.GetItem(itemnum))
return;
@ -792,17 +834,21 @@ void Corpse::AddItem(uint32 itemnum, uint16 charges, int16 slot, uint32 aug1, ui
auto item = new ServerLootItem_Struct;
memset(item, 0, sizeof(ServerLootItem_Struct));
item->item_id = itemnum;
item->charges = charges;
item->equip_slot = slot;
item->aug_1=aug1;
item->aug_2=aug2;
item->aug_3=aug3;
item->aug_4=aug4;
item->aug_5=aug5;
item->aug_6=aug6;
item->attuned=attuned;
item->aug_1 = aug1;
item->aug_2 = aug2;
item->aug_3 = aug3;
item->aug_4 = aug4;
item->aug_5 = aug5;
item->aug_6 = aug6;
item->attuned = attuned;
item->custom_data = custom_data;
item->ornamenticon = ornamenticon;
item->ornamentidfile = ornamentidfile;
item->ornament_hero_model = ornament_hero_model;
itemlist.push_back(item);
UpdateEquipmentLight();
@ -1291,7 +1337,11 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
item_data->aug_4,
item_data->aug_5,
item_data->aug_6,
item_data->attuned
item_data->attuned,
item_data->custom_data,
item_data->ornamenticon,
item_data->ornamentidfile,
item_data->ornament_hero_model
);
if (!inst)
continue;
@ -1418,7 +1468,9 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app)
if (item_data) {
inst = database.CreateItem(item, item_data ? item_data->charges : 0, item_data->aug_1,
item_data->aug_2, item_data->aug_3, item_data->aug_4,
item_data->aug_5, item_data->aug_6, item_data->attuned);
item_data->aug_5, item_data->aug_6, item_data->attuned,
item_data->custom_data, item_data->ornamenticon,
item_data->ornamentidfile, item_data->ornament_hero_model);
}
else {
inst = database.CreateItem(item);

View File

@ -100,7 +100,20 @@ class Corpse : public Mob {
void RemoveItem(uint16 lootslot);
void RemoveItem(ServerLootItem_Struct* item_data);
void RemoveItemByID(uint32 item_id, int quantity = 1);
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 aug6 = 0, uint8 attuned = 0);
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 aug6 = 0,
bool attuned = false,
const std::string &custom_data = std::string(),
uint32 ornamenticon = 0,
uint32 ornamentidfile = 0,
uint32 ornament_hero_model = 0);
/* Corpse: Coin */
void SetCash(uint32 in_copper, uint32 in_silver, uint32 in_gold, uint32 in_platinum);

View File

@ -1387,7 +1387,11 @@ void Client::PutLootInInventory(int16 slot_id, const EQ::ItemInstance &inst, Ser
bag_item_data[index]->aug_4,
bag_item_data[index]->aug_5,
bag_item_data[index]->aug_6,
bag_item_data[index]->attuned
bag_item_data[index]->attuned,
bag_item_data[index]->custom_data,
bag_item_data[index]->ornamenticon,
bag_item_data[index]->ornamentidfile,
bag_item_data[index]->ornament_hero_model
);
// Dump bag contents to cursor in the event that owning bag is not the first cursor item
@ -3958,7 +3962,7 @@ bool Client::InterrogateInventory_error(int16 head, int16 index, const EQ::ItemI
return false;
}
void EQ::InventoryProfile::SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, std::string value) {
void EQ::InventoryProfile::SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, const std::string &value) {
EQ::ItemInstance *inst = GetItem(slot_id);
if(inst) {
inst->SetCustomData(identifier, value);
@ -3966,7 +3970,7 @@ void EQ::InventoryProfile::SetCustomItemData(uint32 character_id, int16 slot_id,
}
}
void EQ::InventoryProfile::SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, int value) {
void EQ::InventoryProfile::SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, int value) {
EQ::ItemInstance *inst = GetItem(slot_id);
if(inst) {
inst->SetCustomData(identifier, value);
@ -3974,7 +3978,7 @@ void EQ::InventoryProfile::SetCustomItemData(uint32 character_id, int16 slot_id,
}
}
void EQ::InventoryProfile::SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, float value) {
void EQ::InventoryProfile::SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, float value) {
EQ::ItemInstance *inst = GetItem(slot_id);
if(inst) {
inst->SetCustomData(identifier, value);
@ -3982,7 +3986,7 @@ void EQ::InventoryProfile::SetCustomItemData(uint32 character_id, int16 slot_id,
}
}
void EQ::InventoryProfile::SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, bool value) {
void EQ::InventoryProfile::SetCustomItemData(uint32 character_id, int16 slot_id, const std::string &identifier, bool value) {
EQ::ItemInstance *inst = GetItem(slot_id);
if(inst) {
inst->SetCustomData(identifier, value);
@ -3990,7 +3994,7 @@ void EQ::InventoryProfile::SetCustomItemData(uint32 character_id, int16 slot_id,
}
}
std::string EQ::InventoryProfile::GetCustomItemData(int16 slot_id, std::string identifier) {
std::string EQ::InventoryProfile::GetCustomItemData(int16 slot_id, const std::string &identifier) {
EQ::ItemInstance *inst = GetItem(slot_id);
if(inst) {
return inst->GetCustomData(identifier);
@ -3998,7 +4002,7 @@ std::string EQ::InventoryProfile::GetCustomItemData(int16 slot_id, std::string i
return "";
}
const int EQ::InventoryProfile::GetItemStatValue(uint32 item_id, std::string identifier) {
const int EQ::InventoryProfile::GetItemStatValue(uint32 item_id, const std::string &identifier) {
if (identifier.empty()) {
return 0;
}

View File

@ -179,32 +179,32 @@ std::string Lua_ItemInst::GetCustomDataString() {
return self->GetCustomDataString();
}
void Lua_ItemInst::SetCustomData(std::string identifier, std::string value) {
void Lua_ItemInst::SetCustomData(const std::string &identifier, const std::string& value) {
Lua_Safe_Call_Void();
self->SetCustomData(identifier, value);
}
void Lua_ItemInst::SetCustomData(std::string identifier, int value) {
void Lua_ItemInst::SetCustomData(const std::string& identifier, int value) {
Lua_Safe_Call_Void();
self->SetCustomData(identifier, value);
}
void Lua_ItemInst::SetCustomData(std::string identifier, float value) {
void Lua_ItemInst::SetCustomData(const std::string& identifier, float value) {
Lua_Safe_Call_Void();
self->SetCustomData(identifier, value);
}
void Lua_ItemInst::SetCustomData(std::string identifier, bool value) {
void Lua_ItemInst::SetCustomData(const std::string& identifier, bool value) {
Lua_Safe_Call_Void();
self->SetCustomData(identifier, value);
}
std::string Lua_ItemInst::GetCustomData(std::string identifier) {
std::string Lua_ItemInst::GetCustomData(const std::string& identifier) {
Lua_Safe_Call_String();
return self->GetCustomData(identifier);
}
void Lua_ItemInst::DeleteCustomData(std::string identifier) {
void Lua_ItemInst::DeleteCustomData(const std::string& identifier) {
Lua_Safe_Call_Void();
self->DeleteCustomData(identifier);
}
@ -296,13 +296,13 @@ luabind::scope lua_register_iteminst() {
.def("Clone", (Lua_ItemInst(Lua_ItemInst::*)(void))&Lua_ItemInst::Clone)
.def("ContainsAugmentByID", (bool(Lua_ItemInst::*)(uint32))&Lua_ItemInst::ContainsAugmentByID)
.def("CountAugmentByID", (int(Lua_ItemInst::*)(uint32))&Lua_ItemInst::CountAugmentByID)
.def("DeleteCustomData", (void(Lua_ItemInst::*)(std::string))&Lua_ItemInst::DeleteCustomData)
.def("DeleteCustomData", (void(Lua_ItemInst::*)(const std::string &))&Lua_ItemInst::DeleteCustomData)
.def("GetAugment", (Lua_ItemInst(Lua_ItemInst::*)(int))&Lua_ItemInst::GetAugment)
.def("GetAugmentItemID", (uint32(Lua_ItemInst::*)(int))&Lua_ItemInst::GetAugmentItemID)
.def("GetAugmentType", (int(Lua_ItemInst::*)(void))&Lua_ItemInst::GetAugmentType)
.def("GetCharges", (int(Lua_ItemInst::*)(void))&Lua_ItemInst::GetCharges)
.def("GetColor", (uint32(Lua_ItemInst::*)(void))&Lua_ItemInst::GetColor)
.def("GetCustomData", (std::string(Lua_ItemInst::*)(std::string))&Lua_ItemInst::GetCustomData)
.def("GetCustomData", (std::string(Lua_ItemInst::*)(const std::string &))&Lua_ItemInst::GetCustomData)
.def("GetCustomDataString", (std::string(Lua_ItemInst::*)(void))&Lua_ItemInst::GetCustomDataString)
.def("GetExp", (uint32(Lua_ItemInst::*)(void))&Lua_ItemInst::GetExp)
.def("GetID", (uint32(Lua_ItemInst::*)(void))&Lua_ItemInst::GetID)
@ -329,10 +329,10 @@ luabind::scope lua_register_iteminst() {
.def("RemoveTaskDeliveredItems", &Lua_ItemInst::RemoveTaskDeliveredItems)
.def("SetCharges", (void(Lua_ItemInst::*)(int))&Lua_ItemInst::SetCharges)
.def("SetColor", (void(Lua_ItemInst::*)(uint32))&Lua_ItemInst::SetColor)
.def("SetCustomData", (void(Lua_ItemInst::*)(std::string,bool))&Lua_ItemInst::SetCustomData)
.def("SetCustomData", (void(Lua_ItemInst::*)(std::string,float))&Lua_ItemInst::SetCustomData)
.def("SetCustomData", (void(Lua_ItemInst::*)(std::string,int))&Lua_ItemInst::SetCustomData)
.def("SetCustomData", (void(Lua_ItemInst::*)(std::string,std::string))&Lua_ItemInst::SetCustomData)
.def("SetCustomData", (void(Lua_ItemInst::*)(const std::string&,bool))&Lua_ItemInst::SetCustomData)
.def("SetCustomData", (void(Lua_ItemInst::*)(const std::string&,float))&Lua_ItemInst::SetCustomData)
.def("SetCustomData", (void(Lua_ItemInst::*)(const std::string&,int))&Lua_ItemInst::SetCustomData)
.def("SetCustomData", (void(Lua_ItemInst::*)(const std::string&,const std::string&))&Lua_ItemInst::SetCustomData)
.def("SetExp", (void(Lua_ItemInst::*)(uint32))&Lua_ItemInst::SetExp)
.def("SetInstNoDrop", (void(Lua_ItemInst::*)(bool))&Lua_ItemInst::SetInstNoDrop)
.def("SetPrice", (void(Lua_ItemInst::*)(uint32))&Lua_ItemInst::SetPrice)

View File

@ -63,12 +63,12 @@ public:
bool IsInstNoDrop();
void SetInstNoDrop(bool flag);
std::string GetCustomDataString();
void SetCustomData(std::string identifier, std::string value);
void SetCustomData(std::string identifier, int value);
void SetCustomData(std::string identifier, float value);
void SetCustomData(std::string identifier, bool value);
std::string GetCustomData(std::string identifier);
void DeleteCustomData(std::string identifier);
void SetCustomData(const std::string &identifier, const std::string &value);
void SetCustomData(const std::string &identifier, int value);
void SetCustomData(const std::string &identifier, float value);
void SetCustomData(const std::string &identifier, bool value);
std::string GetCustomData(const std::string& identifier);
void DeleteCustomData(const std::string& identifier);
void SetScaling(bool v);
void SetScale(double scale_factor);
uint32 GetExp();

View File

@ -3606,7 +3606,17 @@ void QuestManager::UpdateZoneHeader(std::string type, std::string value) {
EQ::ItemInstance *QuestManager::CreateItem(uint32 item_id, int16 charges, uint32 augment_one, uint32 augment_two, uint32 augment_three, uint32 augment_four, uint32 augment_five, uint32 augment_six, bool attuned) const {
if (database.GetItem(item_id)) {
return database.CreateItem(item_id, charges, augment_one, augment_two, augment_three, augment_four, augment_five, augment_six, attuned);
return database.CreateItem(
item_id,
charges,
augment_one,
augment_two,
augment_three,
augment_four,
augment_five,
augment_six,
attuned
);
}
return nullptr;
}

View File

@ -3780,7 +3780,7 @@ uint32 ZoneDatabase::GetCharacterCorpseDecayTimer(uint32 corpse_db_id){
return 0;
}
uint32 ZoneDatabase::UpdateCharacterCorpse(uint32 db_id, uint32 char_id, const char* char_name, uint32 zone_id, uint16 instance_id, PlayerCorpse_Struct* dbpc, const glm::vec4& position, uint32 guild_id, bool is_rezzed) {
uint32 ZoneDatabase::UpdateCharacterCorpse(uint32 db_id, uint32 char_id, const char* char_name, uint32 zone_id, uint16 instance_id, const CharacterCorpseEntry& corpse, const glm::vec4& position, uint32 guild_id, bool is_rezzed) {
std::string query = StringFormat("UPDATE `character_corpses` "
"SET `charname` = '%s', `zone_id` = %u, `instance_id` = %u, `charid` = %d, "
"`x` = %1.1f,`y` = %1.1f,`z` = %1.1f, `heading` = %1.1f, `guild_consent_id` = %u, "
@ -3796,15 +3796,15 @@ uint32 ZoneDatabase::UpdateCharacterCorpse(uint32 db_id, uint32 char_id, const c
"WHERE `id` = %u",
Strings::Escape(char_name).c_str(), zone_id, instance_id, char_id,
position.x, position.y, position.z, position.w, guild_id,
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.Head.Color, dbpc->item_tint.Chest.Color, dbpc->item_tint.Arms.Color,
dbpc->item_tint.Wrist.Color, dbpc->item_tint.Hands.Color, dbpc->item_tint.Legs.Color,
dbpc->item_tint.Feet.Color, dbpc->item_tint.Primary.Color, dbpc->item_tint.Secondary.Color,
corpse.locked, corpse.exp, corpse.size, corpse.level, corpse.race,
corpse.gender, corpse.class_, corpse.deity, corpse.texture,
corpse.helmtexture, corpse.copper, corpse.silver, corpse.gold,
corpse.plat, corpse.haircolor, corpse.beardcolor, corpse.eyecolor1,
corpse.eyecolor2, corpse.hairstyle, corpse.face, corpse.beard,
corpse.drakkin_heritage, corpse.drakkin_tattoo, corpse.drakkin_details,
corpse.item_tint.Head.Color, corpse.item_tint.Chest.Color, corpse.item_tint.Arms.Color,
corpse.item_tint.Wrist.Color, corpse.item_tint.Hands.Color, corpse.item_tint.Legs.Color,
corpse.item_tint.Feet.Color, corpse.item_tint.Primary.Color, corpse.item_tint.Secondary.Color,
db_id);
auto results = QueryDatabase(query);
@ -3823,7 +3823,7 @@ void ZoneDatabase::MarkCorpseAsRezzed(uint32 db_id) {
auto results = QueryDatabase(query);
}
uint32 ZoneDatabase::SaveCharacterCorpse(uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, PlayerCorpse_Struct* dbpc, const glm::vec4& position, uint32 guildid) {
uint32 ZoneDatabase::SaveCharacterCorpse(uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, const CharacterCorpseEntry& corpse, const glm::vec4& position, uint32 guildid) {
/* Dump Basic Corpse Data */
std::string query = StringFormat(
"INSERT INTO `character_corpses` "
@ -3880,39 +3880,39 @@ uint32 ZoneDatabase::SaveCharacterCorpse(uint32 charid, const char* charname, ui
position.z,
position.w,
guildid,
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.Head.Color,
dbpc->item_tint.Chest.Color,
dbpc->item_tint.Arms.Color,
dbpc->item_tint.Wrist.Color,
dbpc->item_tint.Hands.Color,
dbpc->item_tint.Legs.Color,
dbpc->item_tint.Feet.Color,
dbpc->item_tint.Primary.Color,
dbpc->item_tint.Secondary.Color
corpse.locked,
corpse.exp,
corpse.size,
corpse.level,
corpse.race,
corpse.gender,
corpse.class_,
corpse.deity,
corpse.texture,
corpse.helmtexture,
corpse.copper,
corpse.silver,
corpse.gold,
corpse.plat,
corpse.haircolor,
corpse.beardcolor,
corpse.eyecolor1,
corpse.eyecolor2,
corpse.hairstyle,
corpse.face,
corpse.beard,
corpse.drakkin_heritage,
corpse.drakkin_tattoo,
corpse.drakkin_details,
corpse.item_tint.Head.Color,
corpse.item_tint.Chest.Color,
corpse.item_tint.Arms.Color,
corpse.item_tint.Wrist.Color,
corpse.item_tint.Hands.Color,
corpse.item_tint.Legs.Color,
corpse.item_tint.Feet.Color,
corpse.item_tint.Primary.Color,
corpse.item_tint.Secondary.Color
);
auto results = QueryDatabase(query);
uint32 last_insert_id = results.LastInsertedID();
@ -3920,41 +3920,51 @@ uint32 ZoneDatabase::SaveCharacterCorpse(uint32 charid, const char* charname, ui
std::string corpse_items_query;
/* Dump Items from Inventory */
uint8 first_entry = 0;
for (unsigned int i = 0; i < dbpc->itemcount; i++) {
for(auto &item : corpse.items)
{
if (first_entry != 1){
corpse_items_query = StringFormat("REPLACE INTO `character_corpse_items` \n"
" (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, aug_6, attuned) \n"
" VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n",
" (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, aug_6, attuned, custom_data, ornamenticon, ornamentidfile, ornament_hero_model) \n"
" VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, '%s', %u, %u, %u) \n",
last_insert_id,
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,
dbpc->items[i].aug_6,
dbpc->items[i].attuned
item.equip_slot,
item.item_id,
item.charges,
item.aug_1,
item.aug_2,
item.aug_3,
item.aug_4,
item.aug_5,
item.aug_6,
item.attuned,
item.custom_data.c_str(),
item.ornamenticon,
item.ornamentidfile,
item.ornament_hero_model
);
first_entry = 1;
}
else{
corpse_items_query = corpse_items_query + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n",
corpse_items_query = corpse_items_query + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, '%s', %u, %u, %u) \n",
last_insert_id,
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,
dbpc->items[i].aug_6,
dbpc->items[i].attuned
item.equip_slot,
item.item_id,
item.charges,
item.aug_1,
item.aug_2,
item.aug_3,
item.aug_4,
item.aug_5,
item.aug_6,
item.attuned,
item.custom_data.c_str(),
item.ornamenticon,
item.ornamentidfile,
item.ornament_hero_model
);
}
}
if (!corpse_items_query.empty())
QueryDatabase(corpse_items_query);
@ -3993,18 +4003,6 @@ uint32 ZoneDatabase::GetCharacterCorpseID(uint32 char_id, uint8 corpse) {
return 0;
}
uint32 ZoneDatabase::GetCharacterCorpseItemCount(uint32 corpse_id){
std::string query = StringFormat("SELECT COUNT(*) FROM character_corpse_items WHERE `corpse_id` = %u",
corpse_id
);
auto results = QueryDatabase(query);
auto& row = results.begin();
if (results.Success() && results.RowsAffected() != 0){
return Strings::ToInt(row[0]);
}
return 0;
}
uint32 ZoneDatabase::GetCharacterCorpseItemAt(uint32 corpse_id, uint16 slotid) {
Corpse* tmp = LoadCharacterCorpse(corpse_id);
uint32 itemid = 0;
@ -4016,7 +4014,7 @@ uint32 ZoneDatabase::GetCharacterCorpseItemAt(uint32 corpse_id, uint16 slotid) {
return itemid;
}
bool ZoneDatabase::LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct* pcs){
bool ZoneDatabase::LoadCharacterCorpseData(uint32 corpse_id, CharacterCorpseEntry& corpse){
std::string query = StringFormat(
"SELECT \n"
"is_locked, \n"
@ -4060,39 +4058,39 @@ bool ZoneDatabase::LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct
auto results = QueryDatabase(query);
uint16 i = 0;
for (auto& row = results.begin(); row != results.end(); ++row) {
pcs->locked = Strings::ToInt(row[i++]); // is_locked,
pcs->exp = Strings::ToUnsignedInt(row[i++]); // exp,
pcs->size = Strings::ToInt(row[i++]); // size,
pcs->level = Strings::ToInt(row[i++]); // `level`,
pcs->race = Strings::ToInt(row[i++]); // race,
pcs->gender = Strings::ToInt(row[i++]); // gender,
pcs->class_ = Strings::ToInt(row[i++]); // class,
pcs->deity = Strings::ToInt(row[i++]); // deity,
pcs->texture = Strings::ToInt(row[i++]); // texture,
pcs->helmtexture = Strings::ToInt(row[i++]); // helm_texture,
pcs->copper = Strings::ToUnsignedInt(row[i++]); // copper,
pcs->silver = Strings::ToUnsignedInt(row[i++]); // silver,
pcs->gold = Strings::ToUnsignedInt(row[i++]); // gold,
pcs->plat = Strings::ToUnsignedInt(row[i++]); // platinum,
pcs->haircolor = Strings::ToInt(row[i++]); // hair_color,
pcs->beardcolor = Strings::ToInt(row[i++]); // beard_color,
pcs->eyecolor1 = Strings::ToInt(row[i++]); // eye_color_1,
pcs->eyecolor2 = Strings::ToInt(row[i++]); // eye_color_2,
pcs->hairstyle = Strings::ToInt(row[i++]); // hair_style,
pcs->face = Strings::ToInt(row[i++]); // face,
pcs->beard = Strings::ToInt(row[i++]); // beard,
pcs->drakkin_heritage = Strings::ToUnsignedInt(row[i++]); // drakkin_heritage,
pcs->drakkin_tattoo = Strings::ToUnsignedInt(row[i++]); // drakkin_tattoo,
pcs->drakkin_details = Strings::ToUnsignedInt(row[i++]); // drakkin_details,
pcs->item_tint.Head.Color = Strings::ToUnsignedInt(row[i++]); // wc_1,
pcs->item_tint.Chest.Color = Strings::ToUnsignedInt(row[i++]); // wc_2,
pcs->item_tint.Arms.Color = Strings::ToUnsignedInt(row[i++]); // wc_3,
pcs->item_tint.Wrist.Color = Strings::ToUnsignedInt(row[i++]); // wc_4,
pcs->item_tint.Hands.Color = Strings::ToUnsignedInt(row[i++]); // wc_5,
pcs->item_tint.Legs.Color = Strings::ToUnsignedInt(row[i++]); // wc_6,
pcs->item_tint.Feet.Color = Strings::ToUnsignedInt(row[i++]); // wc_7,
pcs->item_tint.Primary.Color = Strings::ToUnsignedInt(row[i++]); // wc_8,
pcs->item_tint.Secondary.Color = Strings::ToUnsignedInt(row[i++]); // wc_9
corpse.locked = Strings::ToInt(row[i++]); // is_locked,
corpse.exp = Strings::ToUnsignedInt(row[i++]); // exp,
corpse.size = Strings::ToInt(row[i++]); // size,
corpse.level = Strings::ToInt(row[i++]); // `level`,
corpse.race = Strings::ToInt(row[i++]); // race,
corpse.gender = Strings::ToInt(row[i++]); // gender,
corpse.class_ = Strings::ToInt(row[i++]); // class,
corpse.deity = Strings::ToInt(row[i++]); // deity,
corpse.texture = Strings::ToInt(row[i++]); // texture,
corpse.helmtexture = Strings::ToInt(row[i++]); // helm_texture,
corpse.copper = Strings::ToUnsignedInt(row[i++]); // copper,
corpse.silver = Strings::ToUnsignedInt(row[i++]); // silver,
corpse.gold = Strings::ToUnsignedInt(row[i++]); // gold,
corpse.plat = Strings::ToUnsignedInt(row[i++]); // platinum,
corpse.haircolor = Strings::ToInt(row[i++]); // hair_color,
corpse.beardcolor = Strings::ToInt(row[i++]); // beard_color,
corpse.eyecolor1 = Strings::ToInt(row[i++]); // eye_color_1,
corpse.eyecolor2 = Strings::ToInt(row[i++]); // eye_color_2,
corpse.hairstyle = Strings::ToInt(row[i++]); // hair_style,
corpse.face = Strings::ToInt(row[i++]); // face,
corpse.beard = Strings::ToInt(row[i++]); // beard,
corpse.drakkin_heritage = Strings::ToUnsignedInt(row[i++]); // drakkin_heritage,
corpse.drakkin_tattoo = Strings::ToUnsignedInt(row[i++]); // drakkin_tattoo,
corpse.drakkin_details = Strings::ToUnsignedInt(row[i++]); // drakkin_details,
corpse.item_tint.Head.Color = Strings::ToUnsignedInt(row[i++]); // wc_1,
corpse.item_tint.Chest.Color = Strings::ToUnsignedInt(row[i++]); // wc_2,
corpse.item_tint.Arms.Color = Strings::ToUnsignedInt(row[i++]); // wc_3,
corpse.item_tint.Wrist.Color = Strings::ToUnsignedInt(row[i++]); // wc_4,
corpse.item_tint.Hands.Color = Strings::ToUnsignedInt(row[i++]); // wc_5,
corpse.item_tint.Legs.Color = Strings::ToUnsignedInt(row[i++]); // wc_6,
corpse.item_tint.Feet.Color = Strings::ToUnsignedInt(row[i++]); // wc_7,
corpse.item_tint.Primary.Color = Strings::ToUnsignedInt(row[i++]); // wc_8,
corpse.item_tint.Secondary.Color = Strings::ToUnsignedInt(row[i++]); // wc_9
}
query = StringFormat(
"SELECT \n"
@ -4105,7 +4103,11 @@ bool ZoneDatabase::LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct
"aug_4, \n"
"aug_5, \n"
"aug_6, \n"
"attuned \n"
"attuned, \n"
"custom_data, \n"
"ornamenticon, \n"
"ornamentidfile, \n"
"ornament_hero_model \n"
"FROM \n"
"character_corpse_items \n"
"WHERE `corpse_id` = %u\n"
@ -4115,20 +4117,32 @@ bool ZoneDatabase::LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct
results = QueryDatabase(query);
i = 0;
pcs->itemcount = results.RowCount();
uint16 r = 0;
for (auto& row = results.begin(); row != results.end(); ++row) {
memset(&pcs->items[i], 0, sizeof (player_lootitem::ServerLootItem_Struct));
pcs->items[i].equip_slot = Strings::ToInt(row[r++]); // equip_slot,
pcs->items[i].item_id = Strings::ToUnsignedInt(row[r++]); // item_id,
pcs->items[i].charges = Strings::ToInt(row[r++]); // charges,
pcs->items[i].aug_1 = Strings::ToInt(row[r++]); // aug_1,
pcs->items[i].aug_2 = Strings::ToInt(row[r++]); // aug_2,
pcs->items[i].aug_3 = Strings::ToInt(row[r++]); // aug_3,
pcs->items[i].aug_4 = Strings::ToInt(row[r++]); // aug_4,
pcs->items[i].aug_5 = Strings::ToInt(row[r++]); // aug_5,
pcs->items[i].aug_6 = Strings::ToInt(row[r++]); // aug_6,
pcs->items[i].attuned = Strings::ToInt(row[r++]); // attuned,
CharacterCorpseItemEntry item;
item.equip_slot = Strings::ToInt(row[r++]); // equip_slot,
item.item_id = Strings::ToUnsignedInt(row[r++]); // item_id,
item.charges = Strings::ToInt(row[r++]); // charges,
item.aug_1 = Strings::ToInt(row[r++]); // aug_1,
item.aug_2 = Strings::ToInt(row[r++]); // aug_2,
item.aug_3 = Strings::ToInt(row[r++]); // aug_3,
item.aug_4 = Strings::ToInt(row[r++]); // aug_4,
item.aug_5 = Strings::ToInt(row[r++]); // aug_5,
item.aug_6 = Strings::ToInt(row[r++]); // aug_6,
item.attuned = Strings::ToInt(row[r++]) > 0 ? true : false; // attuned,
if (row[r]) {
item.custom_data = row[r++];
}
else {
r++;
}
item.ornamenticon = Strings::ToUnsignedInt(row[r++]);
item.ornamentidfile = Strings::ToUnsignedInt(row[r++]);
item.ornament_hero_model = Strings::ToUnsignedInt(row[r++]);
corpse.items.push_back(std::move(item));
r = 0;
i++;
}

View File

@ -285,6 +285,55 @@ struct ClientMercEntry {
uint32 npcid;
};
struct CharacterCorpseItemEntry
{
uint32 item_id;
int16 equip_slot;
uint16 charges;
uint16 lootslot;
uint32 aug_1;
uint32 aug_2;
uint32 aug_3;
uint32 aug_4;
uint32 aug_5;
uint32 aug_6;
bool attuned;
std::string custom_data;
uint32 ornamenticon;
uint32 ornamentidfile;
uint32 ornament_hero_model;
};
struct CharacterCorpseEntry
{
bool locked;
uint32 exp;
float size;
uint8 level;
uint32 race;
uint8 gender;
uint8 class_;
uint8 deity;
uint8 texture;
uint8 helmtexture;
uint32 copper;
uint32 silver;
uint32 gold;
uint32 plat;
EQ::TintProfile item_tint;
uint8 haircolor;
uint8 beardcolor;
uint8 eyecolor1;
uint8 eyecolor2;
uint8 hairstyle;
uint8 face;
uint8 beard;
uint32 drakkin_heritage;
uint32 drakkin_tattoo;
uint32 drakkin_details;
std::vector<CharacterCorpseItemEntry> items;
};
namespace BeastlordPetData {
struct PetStruct {
uint16 race_id = WOLF;
@ -429,8 +478,7 @@ public:
/* Corpses */
bool DeleteItemOffCharacterCorpse(uint32 db_id, uint32 equip_slot, uint32 item_id);
uint32 GetCharacterCorpseItemCount(uint32 corpse_id);
bool LoadCharacterCorpseData(uint32 corpse_id, PlayerCorpse_Struct* pcs);
bool LoadCharacterCorpseData(uint32 corpse_id, CharacterCorpseEntry &corpse);
Corpse* LoadCharacterCorpse(uint32 player_corpse_id);
Corpse* SummonBuriedCharacterCorpses(uint32 char_id, uint32 dest_zoneid, uint16 dest_instanceid, const glm::vec4& position);
void MarkCorpseAsRezzed(uint32 dbid);
@ -446,8 +494,8 @@ public:
uint32 GetCharacterCorpseDecayTimer(uint32 corpse_db_id);
uint32 GetCharacterBuriedCorpseCount(uint32 char_id);
uint32 SendCharacterCorpseToGraveyard(uint32 dbid, uint32 zoneid, uint16 instanceid, const glm::vec4& position);
uint32 SaveCharacterCorpse(uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, PlayerCorpse_Struct* dbpc, const glm::vec4& position, uint32 guildid);
uint32 UpdateCharacterCorpse(uint32 dbid, uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, PlayerCorpse_Struct* dbpc, const glm::vec4& position, uint32 guildid, bool rezzed = false);
uint32 SaveCharacterCorpse(uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, const CharacterCorpseEntry& corpse, const glm::vec4& position, uint32 guildid);
uint32 UpdateCharacterCorpse(uint32 dbid, uint32 charid, const char* charname, uint32 zoneid, uint16 instanceid, const CharacterCorpseEntry& corpse, const glm::vec4& position, uint32 guildid, bool rezzed = false);
uint32 UpdateCharacterCorpseConsent(uint32 charid, uint32 guildid);
uint32 GetFirstCorpseID(uint32 char_id);
uint32 GetCharacterCorpseCount(uint32 char_id);

View File

@ -155,56 +155,6 @@ struct NPCType
bool keeps_sold_items;
};
namespace player_lootitem {
struct ServerLootItem_Struct {
uint32 item_id;
int16 equip_slot;
uint16 charges;
uint16 lootslot;
uint32 aug_1;
uint32 aug_2;
uint32 aug_3;
uint32 aug_4;
uint32 aug_5;
uint32 aug_6;
int8 attuned;
uint8 min_level; //
uint8 max_level; //
};
}
struct PlayerCorpse_Struct {
uint32 crc;
bool locked;
uint32 itemcount;
uint32 exp;
float size;
uint8 level;
uint32 race;
uint8 gender;
uint8 class_;
uint8 deity;
uint8 texture;
uint8 helmtexture;
uint32 copper;
uint32 silver;
uint32 gold;
uint32 plat;
EQ::TintProfile item_tint;
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::ServerLootItem_Struct items[0];
//std::list<player_lootitem::ServerLootItem_Struct*> items;
};
#pragma pack()
#endif