player items now get stored when they die, items are removed from player. corpses show as lootable

This commit is contained in:
ElderShell 2026-05-01 15:47:56 -06:00
parent 18987fe43d
commit 70a5d07325

View file

@ -4467,7 +4467,7 @@ void Player::OfflineResurrect(ObjectGuid const& guid, CharacterDatabaseTransacti
Corpse* Player::CreateCorpse()
{
// prevent existence 2 corpse for player
SpawnCorpseBones();
SpawnCorpseBones(); // TODO: We'd love to allow for several corpses in the world per player but it might break things... [ElderShell]
uint32 _uf, _pb, _pb2, _cfb1, _cfb2;
@ -4499,7 +4499,7 @@ Corpse* Player::CreateCorpse()
corpse->SetUInt32Value(CORPSE_FIELD_BYTES_1, _cfb1);
corpse->SetUInt32Value(CORPSE_FIELD_BYTES_2, _cfb2);
uint32 flags = CORPSE_FLAG_UNK2;
uint32 flags = CORPSE_FLAG_UNK2 | CORPSE_FLAG_LOOTABLE;
if (HasPlayerFlag(PLAYER_FLAGS_HIDE_HELM))
flags |= CORPSE_FLAG_HIDE_HELM;
if (HasPlayerFlag(PLAYER_FLAGS_HIDE_CLOAK))
@ -4518,6 +4518,9 @@ Corpse* Player::CreateCorpse()
corpse->SetUInt32Value(CORPSE_FIELD_GUILD, GetGuildId());
corpse->lootRecipient = this;
corpse->SetUInt32Value(CORPSE_FIELD_DYNAMIC_FLAGS, CORPSE_DYNFLAG_LOOTABLE);
uint32 iDisplayID;
uint32 iIventoryType;
uint32 _cfi;
@ -4542,6 +4545,120 @@ Corpse* Player::CreateCorpse()
if (!GetMap()->IsBattlegroundOrArena())
corpse->SaveToDB();
uint64 playerGuid = GetGUID().GetCounter();
uint64 corpseGuid = corpse->GetGUID().GetCounter();
// Insert corpse
CharacterDatabase.DirectExecute(
"INSERT INTO lost_corpses "
"(player_guid, corpse_guid, map_id, zone_id, position_x, position_y, position_z, orientation, money) "
"VALUES ({}, {}, {}, {}, {}, {}, {}, {}, {})",
playerGuid,
corpseGuid,
GetMapId(),
GetZoneId(),
GetPositionX(),
GetPositionY(),
GetPositionZ(),
GetOrientation(),
GetMoney()
);
QueryResult result = CharacterDatabase.Query(
"SELECT lost_corpse_id "
"FROM lost_corpses "
"WHERE player_guid = {} "
"ORDER BY lost_corpse_id DESC "
"LIMIT 1",
playerGuid);
if (!result)
return corpse;
Field* fields = result->Fetch();
uint32 lostCorpseId = fields[0].Get<uint32>();
auto insertItem = [&](Item* item)
{
if (!item)
return;
CharacterDatabase.Execute(
"INSERT INTO lost_corpse_items "
"(lost_corpse_id, item_entry, count, randomPropertyId, durability, enchantments, looted) "
"VALUES ({}, {}, {}, {}, {}, '{}', 0)",
lostCorpseId,
item->GetEntry(),
item->GetCount(),
item->GetItemRandomPropertyId(),
item->GetUInt32Value(ITEM_FIELD_DURABILITY),
""
);
};
// EQUIPPED ITEMS
for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
{
if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
insertItem(item);
}
// INVENTORY + BAGS
for (uint8 slot = INVENTORY_SLOT_ITEM_START; slot < INVENTORY_SLOT_ITEM_END; ++slot)
{
if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
insertItem(item);
}
// BAGS
for (uint8 bag = INVENTORY_SLOT_BAG_START; bag < INVENTORY_SLOT_BAG_END; ++bag)
{
if (Bag* b = GetBagByPos(bag))
{
for (uint32 slot = 0; slot < b->GetBagSize(); ++slot)
{
if (Item* item = b->GetItemByPos(slot))
insertItem(item);
}
}
}
// Remove items and bags from player
for (uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; ++i)
{
if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
{
RemoveItem(INVENTORY_SLOT_BAG_0, i, true);
}
}
for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
{
if (Bag* bag = GetBagByPos(i))
{
for (uint32 slot = 0; slot < bag->GetBagSize(); ++slot)
{
if (Item* item = bag->GetItemByPos(slot))
{
bag->RemoveItem(slot, true);
}
}
}
}
CharacterDatabase.Execute(
"DELETE ii FROM item_instance ii "
"JOIN character_inventory ci ON ci.item = ii.guid "
"WHERE ci.guid = {}",
GetGUID().GetCounter());
CharacterDatabase.Execute(
"DELETE FROM character_inventory "
"WHERE guid = {}",
GetGUID().GetCounter());
SetMoney(0);
return corpse;
}