mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-09 22:20:24 +00:00
[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:
+162
-110
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user