diff --git a/HookMgr.cpp b/HookMgr.cpp index 0d9e65d..cfe9bd1 100644 --- a/HookMgr.cpp +++ b/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(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(L, i, result); + } ENDCALL(); - return true; + return result; } bool Eluna::OnExpire(Player* pPlayer, ItemTemplate const* pProto) diff --git a/HookMgr.h b/HookMgr.h index de91deb..d930d86 100644 --- a/HookMgr.h +++ b/HookMgr.h @@ -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 }; diff --git a/LuaEngine.h b/LuaEngine.h index 325e248..1902d96 100644 --- a/LuaEngine.h +++ b/LuaEngine.h @@ -189,7 +189,7 @@ struct EventMgr Object* obj; // Object to push }; - EventMgr(Eluna& _E) : E(_E) + EventMgr(Eluna& _E): E(_E) { } diff --git a/LuaFunctions.cpp b/LuaFunctions.cpp index 9901fbc..b46e6e5 100644 --- a/LuaFunctions.cpp +++ b/LuaFunctions.cpp @@ -338,8 +338,8 @@ ElunaRegister 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) diff --git a/UnitMethods.h b/UnitMethods.h index e41fde1..1f96d22 100644 --- a/UnitMethods.h +++ b/UnitMethods.h @@ -853,8 +853,8 @@ namespace LuaUnit /* int GetVehicle(lua_State* L, Unit* unit) { - Eluna::Push(L, unit->GetVehicle()); - return 1; + Eluna::Push(L, unit->GetVehicle()); + return 1; } */ @@ -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; }