added a corpse summon spell... well copying contents of corpses, close enough.

This commit is contained in:
ElderShell 2026-05-04 01:07:18 -06:00
parent a0b945afcd
commit be47269ede
2 changed files with 141 additions and 0 deletions

View file

@ -0,0 +1,139 @@
#include "ScriptMgr.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
#include "Player.h"
#include "ObjectMgr.h"
#include "DatabaseEnv.h"
enum CustomSpells
{
SPELL_RECOVER_CORPSE_ITEMS = 90001
};
// SPELL_RECOVER_CORPSE_ITEMS, ID 90001
class spell_custom_recover_corpse_items : public SpellScript
{
PrepareSpellScript(spell_custom_recover_corpse_items);
void HandleAfterCast()
{
sLog->outMessage("spells", LOG_LEVEL_INFO, "AfterCast triggered for spell %u by %s", GetSpellInfo()->Id, GetCaster()->GetName().c_str());
if (GetSpellInfo()->Id != SPELL_RECOVER_CORPSE_ITEMS)
return;
Player* target = GetCaster()->ToPlayer();
if (!target)
return;
uint64 playerGuid = target->GetGUID().GetCounter();
// Get latest active corpse
QueryResult corpseResult = CharacterDatabase.Query(
"SELECT lost_corpse_id, money, money_collected "
"FROM lost_corpses "
"WHERE player_guid = {} AND active = 1 "
"ORDER BY created_at DESC LIMIT 1",
playerGuid);
if (!corpseResult)
return;
uint64 corpseId = (*corpseResult)[0].Get<uint64>();
uint32 money = (*corpseResult)[1].Get<uint32>();
bool moneyCollected = (*corpseResult)[2].Get<uint8>();
if (!moneyCollected)
{
bool modMoney = target->ModifyMoney(money);
if (!modMoney)
{
return;
}
CharacterDatabase.DirectExecute(
"UPDATE lost_corpses SET money_collected = 1 "
"WHERE lost_corpse_id = {}",
corpseId
);
}
// Get unlooted items
QueryResult itemsResult = CharacterDatabase.Query(
"SELECT id, item_entry, count, durability "
"FROM lost_corpse_items "
"WHERE lost_corpse_id = {} AND looted = 0",
corpseId);
if (!itemsResult)
return;
do
{
Field* fields = itemsResult->Fetch();
uint64 rowId = fields[0].Get<uint64>();
uint32 itemId = fields[1].Get<uint32>();
uint32 count = fields[2].Get<uint32>();
uint32 dur = fields[3].Get<uint32>();
ItemPosCountVec dest;
InventoryResult msg = target->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, count);
// Inventory full, stop immediately
if (msg != EQUIP_ERR_OK)
break;
Item* item = target->StoreNewItem(dest, itemId, true);
if (item)
{
if (ItemTemplate const* proto = item->GetTemplate())
{
uint32 maxDur = proto->MaxDurability;
if (maxDur > 0)
{
item->SetUInt32Value(ITEM_FIELD_DURABILITY, dur);
item->SetUInt32Value(ITEM_FIELD_MAXDURABILITY, maxDur);
}
}
// Mark as looted only if successfully given
CharacterDatabase.DirectExecute(
"UPDATE lost_corpse_items SET looted = 1 WHERE id = {}",
rowId);
}
} while (itemsResult->NextRow());
// Check that all items were looted
QueryResult remaining = CharacterDatabase.Query(
"SELECT COUNT(*) FROM lost_corpse_items "
"WHERE lost_corpse_id = {} AND looted = 0",
corpseId
);
if (remaining)
{
uint32 count = remaining->Fetch()[0].Get<uint32>();
if (count == 0)
{
CharacterDatabase.Execute(
"UPDATE lost_corpses SET active = 0 WHERE lost_corpse_id = {}",
corpseId
);
}
}
}
void Register() override
{
AfterCast += SpellCastFn(spell_custom_recover_corpse_items::HandleAfterCast);
}
};
void AddSC_custom_spell_scripts()
{
RegisterSpellScript(spell_custom_recover_corpse_items);
}

View file

@ -29,6 +29,7 @@ void AddSC_warlock_spell_scripts();
void AddSC_warrior_spell_scripts();
void AddSC_quest_spell_scripts();
void AddSC_item_spell_scripts();
void AddSC_custom_spell_scripts();
// The name of this function should match:
// void Add${NameOfDirectory}Scripts()
@ -47,4 +48,5 @@ void AddSpellsScripts()
AddSC_warrior_spell_scripts();
AddSC_quest_spell_scripts();
AddSC_item_spell_scripts();
AddSC_custom_spell_scripts();
}