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)
|
bool Eluna::OnUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targets)
|
||||||
{
|
{
|
||||||
return OnItemGossip(pPlayer, pItem, targets) || OnItemUse(pPlayer, pItem, targets);
|
ObjectGuid guid = pItem->GET_GUID();
|
||||||
// pPlayer->SendEquipError((InventoryResult)83, pItem, NULL);
|
bool castSpell = true;
|
||||||
// return 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)
|
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, pPlayer);
|
||||||
Push(L, pItem);
|
Push(L, pItem);
|
||||||
#ifdef MANGOS
|
#ifdef MANGOS
|
||||||
@@ -432,20 +455,33 @@ bool Eluna::OnItemUse(Player* pPlayer, Item* pItem, SpellCastTargets const& targ
|
|||||||
else
|
else
|
||||||
Push(L);
|
Push(L);
|
||||||
#endif
|
#endif
|
||||||
ENTRY_EXECUTE(0);
|
ENTRY_EXECUTE(1);
|
||||||
|
FOR_RETS(i)
|
||||||
|
{
|
||||||
|
if (lua_isnoneornil(L, i))
|
||||||
|
continue;
|
||||||
|
result = CHECKVAL<bool>(L, i, result);
|
||||||
|
}
|
||||||
ENDCALL();
|
ENDCALL();
|
||||||
return true;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Eluna::OnItemGossip(Player* pPlayer, Item* pItem, SpellCastTargets const& /*targets*/)
|
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();
|
pPlayer->PlayerTalkClass->ClearMenus();
|
||||||
Push(L, pPlayer);
|
Push(L, pPlayer);
|
||||||
Push(L, pItem);
|
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();
|
ENDCALL();
|
||||||
return true;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Eluna::OnExpire(Player* pPlayer, ItemTemplate const* pProto)
|
bool Eluna::OnExpire(Player* pPlayer, ItemTemplate const* pProto)
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ namespace HookMgr
|
|||||||
enum ItemEvents
|
enum ItemEvents
|
||||||
{
|
{
|
||||||
ITEM_EVENT_ON_DUMMY_EFFECT = 1, // (event, caster, spellid, effindex, item)
|
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_QUEST_ACCEPT = 3, // (event, player, item, quest)
|
||||||
ITEM_EVENT_ON_EXPIRE = 4, // (event, player, itemid)
|
ITEM_EVENT_ON_EXPIRE = 4, // (event, player, itemid)
|
||||||
ITEM_EVENT_ON_REMOVE = 5, // (event, player, item)
|
ITEM_EVENT_ON_REMOVE = 5, // (event, player, item)
|
||||||
@@ -261,7 +261,7 @@ namespace HookMgr
|
|||||||
// RegisterPlayerGossipEvent(menu_id, EventId, function)
|
// RegisterPlayerGossipEvent(menu_id, EventId, function)
|
||||||
enum GossipEvents
|
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_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
|
GOSSIP_EVENT_COUNT
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ struct EventMgr
|
|||||||
Object* obj; // Object to push
|
Object* obj; // Object to push
|
||||||
};
|
};
|
||||||
|
|
||||||
EventMgr(Eluna& _E) : E(_E)
|
EventMgr(Eluna& _E): E(_E)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -338,8 +338,8 @@ ElunaRegister<Unit> UnitMethods[] =
|
|||||||
{ "PlayDirectSound", &LuaUnit::PlayDirectSound }, // :PlayDirectSound(soundId, player) - Unit plays soundID to player, or everyone around if no player
|
{ "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
|
{ "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
|
{ "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
|
{ "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(optional)) - Interrupts the unit's spell by the spellType. If delayed is true it will skip if the spell is delayed.
|
{ "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
|
{ "SendChatMessageToPlayer", &LuaUnit::SendChatMessageToPlayer }, // :SendChatMessageToPlayer(type, lang, msg, target) - Unit sends a chat message to the given target player
|
||||||
{ "Emote", &LuaUnit::Emote }, // :Emote(emote)
|
{ "Emote", &LuaUnit::Emote }, // :Emote(emote)
|
||||||
{ "CountPctFromCurHealth", &LuaUnit::CountPctFromCurHealth }, // :CountPctFromCurHealth(int32 pct)
|
{ "CountPctFromCurHealth", &LuaUnit::CountPctFromCurHealth }, // :CountPctFromCurHealth(int32 pct)
|
||||||
|
|||||||
@@ -853,8 +853,8 @@ namespace LuaUnit
|
|||||||
/*
|
/*
|
||||||
int GetVehicle(lua_State* L, Unit* unit)
|
int GetVehicle(lua_State* L, Unit* unit)
|
||||||
{
|
{
|
||||||
Eluna::Push(L, unit->GetVehicle());
|
Eluna::Push(L, unit->GetVehicle());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -1478,7 +1478,10 @@ namespace LuaUnit
|
|||||||
case 3:
|
case 3:
|
||||||
spellType = CURRENT_AUTOREPEAT_SPELL;
|
spellType = CURRENT_AUTOREPEAT_SPELL;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
return luaL_argerror(L, 2, "valid CurrentSpellTypes expected");
|
||||||
}
|
}
|
||||||
|
|
||||||
unit->InterruptSpell((CurrentSpellTypes)spellType, delayed);
|
unit->InterruptSpell((CurrentSpellTypes)spellType, delayed);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user