mirror of
https://github.com/azerothcore/mod-ale
synced 2025-11-29 15:38:17 +08:00
Eluna fix crash on InterruptSpell. Make item use and item gossip hooks to be able to return false to stop spell casting.
This commit is contained in:
54
HookMgr.cpp
54
HookMgr.cpp
@@ -398,13 +398,36 @@ bool Eluna::OnQuestAccept(Player* pPlayer, Item* pItem, Quest const* pQuest)
|
||||
|
||||
bool Eluna::OnUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets)
|
||||
{
|
||||
return OnItemGossip(pPlayer, pItem, targets) || OnItemUse(pPlayer, pItem, targets);
|
||||
// pPlayer->SendEquipError((InventoryResult)83, pItem, NULL);
|
||||
// return true;
|
||||
ObjectGuid guid = pItem->GET_GUID();
|
||||
bool castSpell = true;
|
||||
|
||||
if (!OnItemGossip(pPlayer, pItem, targets))
|
||||
castSpell = false;
|
||||
|
||||
pItem = pPlayer->GetItemByGuid(guid);
|
||||
if (pItem && OnItemUse(pPlayer, pItem, targets))
|
||||
pItem = pPlayer->GetItemByGuid(guid);
|
||||
else
|
||||
castSpell = false;
|
||||
|
||||
if (pItem && castSpell)
|
||||
return true;
|
||||
|
||||
// Send equip error that shows no message
|
||||
// This is a hack fix to stop spell casting visual bug when a spell is not cast on use
|
||||
WorldPacket data(SMSG_INVENTORY_CHANGE_FAILURE, 18);
|
||||
data << uint8(83);
|
||||
data << ObjectGuid(guid);
|
||||
data << ObjectGuid(0);
|
||||
data << uint8(0);
|
||||
pPlayer->GetSession()->SendPacket(&data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Eluna::OnItemUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets)
|
||||
{
|
||||
ENTRY_BEGIN(ItemEventBindings, pItem->GetEntry(), ITEM_EVENT_ON_USE, return false);
|
||||
bool result = true;
|
||||
ENTRY_BEGIN(ItemEventBindings, pItem->GetEntry(), ITEM_EVENT_ON_USE, return result);
|
||||
Push(L, pPlayer);
|
||||
Push(L, pItem);
|
||||
#ifdef MANGOS
|
||||
@@ -432,20 +455,33 @@ bool Eluna::OnItemUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targ
|
||||
else
|
||||
Push(L);
|
||||
#endif
|
||||
ENTRY_EXECUTE(0);
|
||||
ENTRY_EXECUTE(1);
|
||||
FOR_RETS(i)
|
||||
{
|
||||
if (lua_isnoneornil(L, i))
|
||||
continue;
|
||||
result = CHECKVAL<bool>(L, i, result);
|
||||
}
|
||||
ENDCALL();
|
||||
return true;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Eluna::OnItemGossip(Player* pPlayer, Item* pItem, SpellCastTargets const& /*targets*/)
|
||||
{
|
||||
ENTRY_BEGIN(ItemGossipBindings, pItem->GetEntry(), GOSSIP_EVENT_ON_HELLO, return false);
|
||||
bool result = true;
|
||||
ENTRY_BEGIN(ItemGossipBindings, pItem->GetEntry(), GOSSIP_EVENT_ON_HELLO, return result);
|
||||
pPlayer->PlayerTalkClass->ClearMenus();
|
||||
Push(L, pPlayer);
|
||||
Push(L, pItem);
|
||||
ENTRY_EXECUTE(0);
|
||||
ENTRY_EXECUTE(1);
|
||||
FOR_RETS(i)
|
||||
{
|
||||
if (lua_isnoneornil(L, i))
|
||||
continue;
|
||||
result = CHECKVAL<bool>(L, i, result);
|
||||
}
|
||||
ENDCALL();
|
||||
return true;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Eluna::OnExpire(Player* pPlayer, ItemTemplate const* pProto)
|
||||
|
||||
@@ -248,7 +248,7 @@ namespace HookMgr
|
||||
enum ItemEvents
|
||||
{
|
||||
ITEM_EVENT_ON_DUMMY_EFFECT = 1, // (event, caster, spellid, effindex, item)
|
||||
ITEM_EVENT_ON_USE = 2, // (event, player, item, target)
|
||||
ITEM_EVENT_ON_USE = 2, // (event, player, item, target) - Can return false to stop the spell casting
|
||||
ITEM_EVENT_ON_QUEST_ACCEPT = 3, // (event, player, item, quest)
|
||||
ITEM_EVENT_ON_EXPIRE = 4, // (event, player, itemid)
|
||||
ITEM_EVENT_ON_REMOVE = 5, // (event, player, item)
|
||||
@@ -261,7 +261,7 @@ namespace HookMgr
|
||||
// RegisterPlayerGossipEvent(menu_id, EventId, function)
|
||||
enum GossipEvents
|
||||
{
|
||||
GOSSIP_EVENT_ON_HELLO = 1, // (event, player, object) - Object is the Creature/GameObject/Item
|
||||
GOSSIP_EVENT_ON_HELLO = 1, // (event, player, object) - Object is the Creature/GameObject/Item. For item gossip can return false to stop spell casting.
|
||||
GOSSIP_EVENT_ON_SELECT = 2, // (event, player, object, sender, intid, code, menu_id) - Object is the Creature/GameObject/Item/Player, menu_id is only for player gossip
|
||||
GOSSIP_EVENT_COUNT
|
||||
};
|
||||
|
||||
@@ -338,8 +338,8 @@ ElunaRegister<Unit> UnitMethods[] =
|
||||
{ "PlayDirectSound", &LuaUnit::PlayDirectSound }, // :PlayDirectSound(soundId, player) - Unit plays soundID to player, or everyone around if no player
|
||||
{ "PlayDistanceSound", &LuaUnit::PlayDistanceSound }, // :PlayDistanceSound(soundId, player) - Unit plays soundID to player, or everyone around if no player. The sound fades the further you are
|
||||
{ "Kill", &LuaUnit::Kill }, // :Kill(target, durabilityLoss) - Unit kills the target. Durabilityloss is true by default
|
||||
{ "StopSpellCast", &LuaUnit::StopSpellCast }, // :StopSpellCast(spellId(optional)) - Stops the unit from casting a spell. If a spellId is defined, it will stop that unit from casting that spell
|
||||
{ "InterruptSpell", &LuaUnit::InterruptSpell }, // :InterruptSpell(spellType, delayed(optional)) - Interrupts the unit's spell by the spellType. If delayed is true it will skip if the spell is delayed.
|
||||
{ "StopSpellCast", &LuaUnit::StopSpellCast }, // :StopSpellCast([spellId]) - Stops the unit from casting a spell. If a spellId is defined, it will stop that unit from casting that spell
|
||||
{ "InterruptSpell", &LuaUnit::InterruptSpell }, // :InterruptSpell(spellType[, delayed]) - Interrupts the unit's spell by the spellType. If delayed is true it will skip if the spell is delayed.
|
||||
{ "SendChatMessageToPlayer", &LuaUnit::SendChatMessageToPlayer }, // :SendChatMessageToPlayer(type, lang, msg, target) - Unit sends a chat message to the given target player
|
||||
{ "Emote", &LuaUnit::Emote }, // :Emote(emote)
|
||||
{ "CountPctFromCurHealth", &LuaUnit::CountPctFromCurHealth }, // :CountPctFromCurHealth(int32 pct)
|
||||
|
||||
@@ -1478,7 +1478,10 @@ namespace LuaUnit
|
||||
case 3:
|
||||
spellType = CURRENT_AUTOREPEAT_SPELL;
|
||||
break;
|
||||
default:
|
||||
return luaL_argerror(L, 2, "valid CurrentSpellTypes expected");
|
||||
}
|
||||
|
||||
unit->InterruptSpell((CurrentSpellTypes)spellType, delayed);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user