diff options
Diffstat (limited to 'src/game/AI/SmartScripts/SmartScript.cpp')
-rw-r--r-- | src/game/AI/SmartScripts/SmartScript.cpp | 5985 |
1 files changed, 3010 insertions, 2975 deletions
diff --git a/src/game/AI/SmartScripts/SmartScript.cpp b/src/game/AI/SmartScripts/SmartScript.cpp index c665b26102..7951d39de9 100644 --- a/src/game/AI/SmartScripts/SmartScript.cpp +++ b/src/game/AI/SmartScripts/SmartScript.cpp @@ -1,8 +1,8 @@ /* - * Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license: http://github.com/azerothcore/azerothcore-wotlk/LICENSE-GPL2 - * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - */ +* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license: http://github.com/azerothcore/azerothcore-wotlk/LICENSE-GPL2 +* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> +* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> +*/ #include "Chat.h" #include "Cell.h" @@ -29,23 +29,23 @@ class TrinityStringTextBuilder { - public: - TrinityStringTextBuilder(WorldObject* obj, ChatMsg msgtype, int32 id, uint32 language, WorldObject* target) - : _source(obj), _msgType(msgtype), _textId(id), _language(language), _target(target) - { - } +public: + TrinityStringTextBuilder(WorldObject* obj, ChatMsg msgtype, int32 id, uint32 language, WorldObject* target) + : _source(obj), _msgType(msgtype), _textId(id), _language(language), _target(target) + { + } - size_t operator()(WorldPacket* data, LocaleConstant locale) const - { - std::string text = sObjectMgr->GetTrinityString(_textId, locale); - return ChatHandler::BuildChatPacket(*data, _msgType, Language(_language), _source, _target, text, 0, "", locale); - } + size_t operator()(WorldPacket* data, LocaleConstant locale) const + { + std::string text = sObjectMgr->GetTrinityString(_textId, locale); + return ChatHandler::BuildChatPacket(*data, _msgType, Language(_language), _source, _target, text, 0, "", locale); + } - WorldObject* _source; - ChatMsg _msgType; - int32 _textId; - uint32 _language; - WorldObject* _target; + WorldObject* _source; + ChatMsg _msgType; + int32 _textId; + uint32 _language; + WorldObject* _target; }; SmartScript::SmartScript() @@ -144,2659 +144,2691 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (unit) mLastInvoker = unit->GetGUID(); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) if (Unit* tempInvoker = GetLastInvoker()) sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: Invoker: %s (guidlow: %u)", tempInvoker->GetName().c_str(), tempInvoker->GetGUIDLow()); #endif switch (e.GetActionType()) { - case SMART_ACTION_TALK: + case SMART_ACTION_TALK: + { + ObjectList* targets = GetTargets(e, unit); + Creature* talker = e.target.type == 0 ? me : NULL; // xinef: tc retardness fix + Unit* talkTarget = NULL; + if (targets) { - ObjectList* targets = GetTargets(e, unit); - Creature* talker = e.target.type == 0 ? me : NULL; // xinef: tc retardness fix - Unit* talkTarget = NULL; - if (targets) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsCreature((*itr)) && !(*itr)->ToCreature()->IsPet()) // Prevented sending text to pets. { - if (IsCreature((*itr)) && !(*itr)->ToCreature()->IsPet()) // Prevented sending text to pets. + if (e.action.talk.useTalkTarget) { - if (e.action.talk.useTalkTarget) - { - talker = me; - talkTarget = (*itr)->ToCreature(); - } - else - talker = (*itr)->ToCreature(); - break; - } - else if (IsPlayer((*itr))) - { - talker = me; // xinef: added - talkTarget = (*itr)->ToPlayer(); - break; + talker = me; + talkTarget = (*itr)->ToCreature(); } + else + talker = (*itr)->ToCreature(); + break; + } + else if (IsPlayer((*itr))) + { + talker = me; // xinef: added + talkTarget = (*itr)->ToPlayer(); + break; } - - delete targets; } - if (!talkTarget) - talkTarget = GetLastInvoker(); + delete targets; + } - if (!talker) - break; + if (!talkTarget) + talkTarget = GetLastInvoker(); + + if (!talker) + break; - mTalkerEntry = talker->GetEntry(); - mLastTextID = e.action.talk.textGroupID; - mTextTimer = e.action.talk.duration; - mUseTextTimer = true; - sCreatureTextMgr->SendChat(talker, uint8(e.action.talk.textGroupID), talkTarget); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_TALK: talker: %s (GuidLow: %u), textId: %u", talker->GetName().c_str(), talker->GetGUIDLow(), mLastTextID); + mTalkerEntry = talker->GetEntry(); + mLastTextID = e.action.talk.textGroupID; + mTextTimer = e.action.talk.duration; + mUseTextTimer = true; + sCreatureTextMgr->SendChat(talker, uint8(e.action.talk.textGroupID), talkTarget); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_TALK: talker: %s (GuidLow: %u), textId: %u", talker->GetName().c_str(), talker->GetGUIDLow(), mLastTextID); #endif - break; } - case SMART_ACTION_SIMPLE_TALK: + break; + } + case SMART_ACTION_SIMPLE_TALK: + { + ObjectList* targets = GetTargets(e, unit); + if (targets) { - ObjectList* targets = GetTargets(e, unit); - if (targets) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsCreature(*itr)) + sCreatureTextMgr->SendChat((*itr)->ToCreature(), uint8(e.action.talk.textGroupID), IsPlayer(GetLastInvoker()) ? GetLastInvoker() : 0); + else if (IsPlayer(*itr) && me) { - if (IsCreature(*itr)) - sCreatureTextMgr->SendChat((*itr)->ToCreature(), uint8(e.action.talk.textGroupID), IsPlayer(GetLastInvoker())? GetLastInvoker() : 0); - else if (IsPlayer(*itr) && me) - { - Unit* templastInvoker = GetLastInvoker(); - sCreatureTextMgr->SendChat(me, uint8(e.action.talk.textGroupID), IsPlayer(templastInvoker) ? templastInvoker : 0, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, TEAM_NEUTRAL, false, (*itr)->ToPlayer()); - } -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SIMPLE_TALK: talker: %s (GuidLow: %u), textGroupId: %u", - (*itr)->GetName().c_str(), (*itr)->GetGUIDLow(), uint8(e.action.talk.textGroupID)); -#endif } - - delete targets; + Unit* templastInvoker = GetLastInvoker(); + sCreatureTextMgr->SendChat(me, uint8(e.action.talk.textGroupID), IsPlayer(templastInvoker) ? templastInvoker : 0, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, TEAM_NEUTRAL, false, (*itr)->ToPlayer()); + } +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SIMPLE_TALK: talker: %s (GuidLow: %u), textGroupId: %u", + (*itr)->GetName().c_str(), (*itr)->GetGUIDLow(), uint8(e.action.talk.textGroupID)); +#endif } - break; + + delete targets; } - case SMART_ACTION_PLAY_EMOTE: + break; + } + case SMART_ACTION_PLAY_EMOTE: + { + ObjectList* targets = GetTargets(e, unit); + if (targets) { - ObjectList* targets = GetTargets(e, unit); - if (targets) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsUnit(*itr)) { - if (IsUnit(*itr)) - { - (*itr)->ToUnit()->HandleEmoteCommand(e.action.emote.emote); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_PLAY_EMOTE: target: %s (GuidLow: %u), emote: %u", - (*itr)->GetName().c_str(), (*itr)->GetGUIDLow(), e.action.emote.emote); -#endif } + (*itr)->ToUnit()->HandleEmoteCommand(e.action.emote.emote); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_PLAY_EMOTE: target: %s (GuidLow: %u), emote: %u", + (*itr)->GetName().c_str(), (*itr)->GetGUIDLow(), e.action.emote.emote); +#endif } - - delete targets; } - break; + + delete targets; } - case SMART_ACTION_SOUND: + break; + } + case SMART_ACTION_SOUND: + { + ObjectList* targets = GetTargets(e, unit); + if (targets) { - ObjectList* targets = GetTargets(e, unit); - if (targets) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsUnit(*itr)) { - if (IsUnit(*itr)) - { - (*itr)->SendPlaySound(e.action.sound.sound, e.action.sound.onlySelf > 0); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SOUND: target: %s (GuidLow: %u), sound: %u, onlyself: %u", - (*itr)->GetName().c_str(), (*itr)->GetGUIDLow(), e.action.sound.sound); -#endif } + (*itr)->SendPlaySound(e.action.sound.sound, e.action.sound.onlySelf > 0); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SOUND: target: %s (GuidLow: %u), sound: %u, onlyself: %u", + (*itr)->GetName().c_str(), (*itr)->GetGUIDLow(), e.action.sound.sound); +#endif } - - delete targets; } - break; + + delete targets; } - case SMART_ACTION_SET_FACTION: + break; + } + case SMART_ACTION_SET_FACTION: + { + ObjectList* targets = GetTargets(e, unit); + if (targets) { - ObjectList* targets = GetTargets(e, unit); - if (targets) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsCreature(*itr)) { - if (IsCreature(*itr)) + if (e.action.faction.factionID) { - if (e.action.faction.factionID) - { - (*itr)->ToCreature()->setFaction(e.action.faction.factionID); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SET_FACTION: Creature entry %u, GuidLow %u set faction to %u", - (*itr)->GetEntry(), (*itr)->GetGUIDLow(), e.action.faction.factionID); -#endif } - else + (*itr)->ToCreature()->setFaction(e.action.faction.factionID); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SET_FACTION: Creature entry %u, GuidLow %u set faction to %u", + (*itr)->GetEntry(), (*itr)->GetGUIDLow(), e.action.faction.factionID); +#endif + } + else + { + if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate((*itr)->ToCreature()->GetEntry())) { - if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate((*itr)->ToCreature()->GetEntry())) + if ((*itr)->ToCreature()->getFaction() != ci->faction) { - if ((*itr)->ToCreature()->getFaction() != ci->faction) - { - (*itr)->ToCreature()->setFaction(ci->faction); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SET_FACTION: Creature entry %u, GuidLow %u set faction to %u", - (*itr)->GetEntry(), (*itr)->GetGUIDLow(), ci->faction); -#endif } + (*itr)->ToCreature()->setFaction(ci->faction); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SET_FACTION: Creature entry %u, GuidLow %u set faction to %u", + (*itr)->GetEntry(), (*itr)->GetGUIDLow(), ci->faction); +#endif } } } } - - delete targets; } - break; + + delete targets; } - case SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL: + break; + } + case SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) + break; + + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; + if (!IsCreature(*itr)) + continue; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (e.action.morphOrMount.creature || e.action.morphOrMount.model) { - if (!IsCreature(*itr)) - continue; - - if (e.action.morphOrMount.creature || e.action.morphOrMount.model) + //set model based on entry from creature_template + if (e.action.morphOrMount.creature) { - //set model based on entry from creature_template - if (e.action.morphOrMount.creature) - { - if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(e.action.morphOrMount.creature)) - { - uint32 displayId = ObjectMgr::ChooseDisplayId(ci); - (*itr)->ToCreature()->SetDisplayId(displayId); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL: Creature entry %u, GuidLow %u set displayid to %u", - (*itr)->GetEntry(), (*itr)->GetGUIDLow(), displayId); -#endif } - } - //if no param1, then use value from param2 (modelId) - else + if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(e.action.morphOrMount.creature)) { - (*itr)->ToCreature()->SetDisplayId(e.action.morphOrMount.model); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS + uint32 displayId = ObjectMgr::ChooseDisplayId(ci); + (*itr)->ToCreature()->SetDisplayId(displayId); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL: Creature entry %u, GuidLow %u set displayid to %u", - (*itr)->GetEntry(), (*itr)->GetGUIDLow(), e.action.morphOrMount.model); -#endif } + (*itr)->GetEntry(), (*itr)->GetGUIDLow(), displayId); +#endif + } } + //if no param1, then use value from param2 (modelId) else { - (*itr)->ToCreature()->DeMorph(); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL: Creature entry %u, GuidLow %u demorphs.", - (*itr)->GetEntry(), (*itr)->GetGUIDLow()); -#endif } + (*itr)->ToCreature()->SetDisplayId(e.action.morphOrMount.model); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL: Creature entry %u, GuidLow %u set displayid to %u", + (*itr)->GetEntry(), (*itr)->GetGUIDLow(), e.action.morphOrMount.model); +#endif + } } + else + { + (*itr)->ToCreature()->DeMorph(); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL: Creature entry %u, GuidLow %u demorphs.", + (*itr)->GetEntry(), (*itr)->GetGUIDLow()); +#endif + } + } - delete targets; + delete targets; + break; + } + case SMART_ACTION_FAIL_QUEST: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_FAIL_QUEST: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (IsPlayer(*itr)) { - if (IsPlayer(*itr)) - { - (*itr)->ToPlayer()->FailQuest(e.action.quest.quest); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_FAIL_QUEST: Player guidLow %u fails quest %u", - (*itr)->GetGUIDLow(), e.action.quest.quest); -#endif } + (*itr)->ToPlayer()->FailQuest(e.action.quest.quest); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_FAIL_QUEST: Player guidLow %u fails quest %u", + (*itr)->GetGUIDLow(), e.action.quest.quest); +#endif } + } - delete targets; + delete targets; + break; + } + case SMART_ACTION_ADD_QUEST: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_ADD_QUEST: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (IsPlayer(*itr)) { - if (IsPlayer(*itr)) + if (Quest const* q = sObjectMgr->GetQuestTemplate(e.action.quest.quest)) { - if (Quest const* q = sObjectMgr->GetQuestTemplate(e.action.quest.quest)) - { - (*itr)->ToPlayer()->AddQuestAndCheckCompletion(q, NULL); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_ADD_QUEST: Player guidLow %u add quest %u", - (*itr)->GetGUIDLow(), e.action.quest.quest); -#endif } + (*itr)->ToPlayer()->AddQuestAndCheckCompletion(q, NULL); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_ADD_QUEST: Player guidLow %u add quest %u", + (*itr)->GetGUIDLow(), e.action.quest.quest); +#endif } } + } - delete targets; + delete targets; + break; + } + case SMART_ACTION_SET_REACT_STATE: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_SET_REACT_STATE: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - { - if (!IsCreature(*itr)) - continue; + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (!IsCreature(*itr)) + continue; - (*itr)->ToCreature()->SetReactState(ReactStates(e.action.react.state)); - } + (*itr)->ToCreature()->SetReactState(ReactStates(e.action.react.state)); + } - delete targets; + delete targets; + break; + } + case SMART_ACTION_RANDOM_EMOTE: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_RANDOM_EMOTE: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - uint32 emotes[SMART_ACTION_PARAM_COUNT]; - emotes[0] = e.action.randomEmote.emote1; - emotes[1] = e.action.randomEmote.emote2; - emotes[2] = e.action.randomEmote.emote3; - emotes[3] = e.action.randomEmote.emote4; - emotes[4] = e.action.randomEmote.emote5; - emotes[5] = e.action.randomEmote.emote6; - uint32 temp[SMART_ACTION_PARAM_COUNT]; - uint32 count = 0; - for (uint8 i = 0; i < SMART_ACTION_PARAM_COUNT; i++) + uint32 emotes[SMART_ACTION_PARAM_COUNT]; + emotes[0] = e.action.randomEmote.emote1; + emotes[1] = e.action.randomEmote.emote2; + emotes[2] = e.action.randomEmote.emote3; + emotes[3] = e.action.randomEmote.emote4; + emotes[4] = e.action.randomEmote.emote5; + emotes[5] = e.action.randomEmote.emote6; + uint32 temp[SMART_ACTION_PARAM_COUNT]; + uint32 count = 0; + for (uint8 i = 0; i < SMART_ACTION_PARAM_COUNT; i++) + { + if (emotes[i]) { - if (emotes[i]) - { - temp[count] = emotes[i]; - ++count; - } + temp[count] = emotes[i]; + ++count; } + } - if (count == 0) - { - delete targets; - break; - } + if (count == 0) + { + delete targets; + break; + } - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (IsUnit(*itr)) { - if (IsUnit(*itr)) - { - uint32 emote = temp[urand(0, count - 1)]; - (*itr)->ToUnit()->HandleEmoteCommand(emote); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_RANDOM_EMOTE: Creature guidLow %u handle random emote %u", - (*itr)->GetGUIDLow(), emote); -#endif } + uint32 emote = temp[urand(0, count - 1)]; + (*itr)->ToUnit()->HandleEmoteCommand(emote); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_RANDOM_EMOTE: Creature guidLow %u handle random emote %u", + (*itr)->GetGUIDLow(), emote); +#endif } + } - delete targets; + delete targets; + break; + } + case SMART_ACTION_THREAT_ALL_PCT: + { + if (!me) break; - } - case SMART_ACTION_THREAT_ALL_PCT: - { - if (!me) - break; - ThreatContainer::StorageType threatList = me->getThreatManager().getThreatList(); - for (ThreatContainer::StorageType::const_iterator i = threatList.begin(); i != threatList.end(); ++i) + ThreatContainer::StorageType threatList = me->getThreatManager().getThreatList(); + for (ThreatContainer::StorageType::const_iterator i = threatList.begin(); i != threatList.end(); ++i) + { + if (Unit* target = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid())) { - if (Unit* target = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid())) - { - me->getThreatManager().modifyThreatPercent(target, e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_THREAT_ALL_PCT: Creature guidLow %u modify threat for unit %u, value %i", - me->GetGUIDLow(), target->GetGUIDLow(), e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC); -#endif } + me->getThreatManager().modifyThreatPercent(target, e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_THREAT_ALL_PCT: Creature guidLow %u modify threat for unit %u, value %i", + me->GetGUIDLow(), target->GetGUIDLow(), e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC); +#endif } - break; } - case SMART_ACTION_THREAT_SINGLE_PCT: - { - if (!me) - break; + break; + } + case SMART_ACTION_THREAT_SINGLE_PCT: + { + if (!me) + break; - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; + ObjectList* targets = GetTargets(e, unit); + if (!targets) + break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (IsUnit(*itr)) { - if (IsUnit(*itr)) - { - me->getThreatManager().modifyThreatPercent((*itr)->ToUnit(), e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_THREAT_SINGLE_PCT: Creature guidLow %u modify threat for unit %u, value %i", - me->GetGUIDLow(), (*itr)->GetGUIDLow(), e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC); -#endif } + me->getThreatManager().modifyThreatPercent((*itr)->ToUnit(), e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_THREAT_SINGLE_PCT: Creature guidLow %u modify threat for unit %u, value %i", + me->GetGUIDLow(), (*itr)->GetGUIDLow(), e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC); +#endif } + } - delete targets; + delete targets; + break; + } + case SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + // Special handling for vehicles + if (IsUnit(*itr)) { - // Special handling for vehicles - if (IsUnit(*itr)) - { - if (Vehicle* vehicle = (*itr)->ToUnit()->GetVehicleKit()) - for (SeatMap::iterator it = vehicle->Seats.begin(); it != vehicle->Seats.end(); ++it) - if (Player* player = ObjectAccessor::GetPlayer(*(*itr), it->second.Passenger.Guid)) - player->AreaExploredOrEventHappens(e.action.quest.quest); + if (Vehicle* vehicle = (*itr)->ToUnit()->GetVehicleKit()) + for (SeatMap::iterator it = vehicle->Seats.begin(); it != vehicle->Seats.end(); ++it) + if (Player* player = ObjectAccessor::GetPlayer(*(*itr), it->second.Passenger.Guid)) + player->AreaExploredOrEventHappens(e.action.quest.quest); - if (Player* player = (*itr)->ToUnit()->GetCharmerOrOwnerPlayerOrPlayerItself()) - { - player->GroupEventHappens(e.action.quest.quest, me); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS: Player guidLow %u credited quest %u", - (*itr)->GetGUIDLow(), e.action.quest.quest); -#endif } + if (Player* player = (*itr)->ToUnit()->GetCharmerOrOwnerPlayerOrPlayerItself()) + { + player->GroupEventHappens(e.action.quest.quest, me); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS: Player guidLow %u credited quest %u", + (*itr)->GetGUIDLow(), e.action.quest.quest); +#endif } } + } - delete targets; + delete targets; + break; + } + case SMART_ACTION_CAST: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_CAST: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - Unit* caster = me; - // Areatrigger Cast! - if (e.GetScriptType() == SMART_SCRIPT_TYPE_AREATRIGGER) - caster = unit->SummonTrigger(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetOrientation(), 5000); + Unit* caster = me; + // Areatrigger Cast! + if (e.GetScriptType() == SMART_SCRIPT_TYPE_AREATRIGGER) + caster = unit->SummonTrigger(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetOrientation(), 5000); - if (e.action.cast.targetsLimit > 0 && targets->size() > e.action.cast.targetsLimit) - Trinity::Containers::RandomResizeList(*targets, e.action.cast.targetsLimit); + if (e.action.cast.targetsLimit > 0 && targets->size() > e.action.cast.targetsLimit) + Trinity::Containers::RandomResizeList(*targets, e.action.cast.targetsLimit); - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (go) { - if (go) - { - // Xinef: may be NULL! - go->CastSpell((*itr)->ToUnit(), e.action.cast.spell); - } + // Xinef: may be NULL! + go->CastSpell((*itr)->ToUnit(), e.action.cast.spell); + } - if (!IsUnit(*itr)) - continue; + if (!IsUnit(*itr)) + continue; - if (caster && caster != me) // Areatrigger cast - { - caster->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED)); - } - else if (me && (!(e.action.cast.flags & SMARTCAST_AURA_NOT_PRESENT) || !(*itr)->ToUnit()->HasAura(e.action.cast.spell))) - { - if (e.action.cast.flags & SMARTCAST_INTERRUPT_PREVIOUS) - me->InterruptNonMeleeSpells(false); + if (caster && caster != me) // Areatrigger cast + { + caster->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED)); + } + else if (me && (!(e.action.cast.flags & SMARTCAST_AURA_NOT_PRESENT) || !(*itr)->ToUnit()->HasAura(e.action.cast.spell))) + { + if (e.action.cast.flags & SMARTCAST_INTERRUPT_PREVIOUS) + me->InterruptNonMeleeSpells(false); - // Xinef: flag usable only if caster has max dist set - if ((e.action.cast.flags & SMARTCAST_COMBAT_MOVE) && GetCasterMaxDist() > 0.0f && me->GetMaxPower(GetCasterPowerType()) > 0) + // Xinef: flag usable only if caster has max dist set + if ((e.action.cast.flags & SMARTCAST_COMBAT_MOVE) && GetCasterMaxDist() > 0.0f && me->GetMaxPower(GetCasterPowerType()) > 0) + { + // Xinef: check mana case only and operate movement accordingly, LoS and range is checked in targetet movement generator + if (me->GetPowerPct(GetCasterPowerType()) < 15.0f) { - // Xinef: check mana case only and operate movement accordingly, LoS and range is checked in targetet movement generator - if (me->GetPowerPct(GetCasterPowerType()) < 15.0f) - { - SetCasterActualDist(0); - CAST_AI(SmartAI, me->AI())->SetForcedCombatMove(0); - } - else if (GetCasterActualDist() == 0.0f && me->GetPowerPct(GetCasterPowerType()) > 30.0f) - { - RestoreCasterMaxDist(); - CAST_AI(SmartAI, me->AI())->SetForcedCombatMove(GetCasterActualDist()); - } + SetCasterActualDist(0); + CAST_AI(SmartAI, me->AI())->SetForcedCombatMove(0); + } + else if (GetCasterActualDist() == 0.0f && me->GetPowerPct(GetCasterPowerType()) > 30.0f) + { + RestoreCasterMaxDist(); + CAST_AI(SmartAI, me->AI())->SetForcedCombatMove(GetCasterActualDist()); } - - me->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED)); } + + me->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED)); } + } - delete targets; + delete targets; + break; + } + case SMART_ACTION_INVOKER_CAST: + { + Unit* tempLastInvoker = GetLastInvoker(unit); // xinef: can be used for area triggers cast + if (!tempLastInvoker) break; - } - case SMART_ACTION_INVOKER_CAST: - { - Unit* tempLastInvoker = GetLastInvoker(unit); // xinef: can be used for area triggers cast - if (!tempLastInvoker) - break; - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; + ObjectList* targets = GetTargets(e, unit); + if (!targets) + break; - if (e.action.cast.targetsLimit > 0 && targets->size() > e.action.cast.targetsLimit) - Trinity::Containers::RandomResizeList(*targets, e.action.cast.targetsLimit); + if (e.action.cast.targetsLimit > 0 && targets->size() > e.action.cast.targetsLimit) + Trinity::Containers::RandomResizeList(*targets, e.action.cast.targetsLimit); - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - { - if (!IsUnit(*itr)) - continue; + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (!IsUnit(*itr)) + continue; - if (!(e.action.cast.flags & SMARTCAST_AURA_NOT_PRESENT) || !(*itr)->ToUnit()->HasAura(e.action.cast.spell)) - { - if (e.action.cast.flags & SMARTCAST_INTERRUPT_PREVIOUS) - tempLastInvoker->InterruptNonMeleeSpells(false); + if (!(e.action.cast.flags & SMARTCAST_AURA_NOT_PRESENT) || !(*itr)->ToUnit()->HasAura(e.action.cast.spell)) + { + if (e.action.cast.flags & SMARTCAST_INTERRUPT_PREVIOUS) + tempLastInvoker->InterruptNonMeleeSpells(false); - tempLastInvoker->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED)); - } + tempLastInvoker->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED)); } + } - delete targets; + delete targets; + break; + } + case SMART_ACTION_ADD_AURA: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_ADD_AURA: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (IsUnit(*itr)) { - if (IsUnit(*itr)) - { - (*itr)->ToUnit()->AddAura(e.action.cast.spell, (*itr)->ToUnit()); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_ADD_AURA: Adding aura %u to unit %u", - e.action.cast.spell, (*itr)->GetGUIDLow()); -#endif } + (*itr)->ToUnit()->AddAura(e.action.cast.spell, (*itr)->ToUnit()); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_ADD_AURA: Adding aura %u to unit %u", + e.action.cast.spell, (*itr)->GetGUIDLow()); +#endif } + } - delete targets; + delete targets; + break; + } + case SMART_ACTION_ACTIVATE_GOBJECT: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_ACTIVATE_GOBJECT: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (IsGameObject(*itr)) { - if (IsGameObject(*itr)) - { - // Activate - // xinef: wtf is this shit? - (*itr)->ToGameObject()->SetLootState(GO_READY); - (*itr)->ToGameObject()->UseDoorOrButton(0, e.action.activateObject.alternative ? true : false, unit); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_ACTIVATE_GOBJECT. Gameobject %u (entry: %u) activated", - (*itr)->GetGUIDLow(), (*itr)->GetEntry()); -#endif } + // Activate + // xinef: wtf is this shit? + (*itr)->ToGameObject()->SetLootState(GO_READY); + (*itr)->ToGameObject()->UseDoorOrButton(0, e.action.activateObject.alternative ? true : false, unit); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_ACTIVATE_GOBJECT. Gameobject %u (entry: %u) activated", + (*itr)->GetGUIDLow(), (*itr)->GetEntry()); +#endif } + } - delete targets; + delete targets; + break; + } + case SMART_ACTION_RESET_GOBJECT: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_RESET_GOBJECT: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (IsGameObject(*itr)) { - if (IsGameObject(*itr)) - { - (*itr)->ToGameObject()->ResetDoorOrButton(); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_RESET_GOBJECT. Gameobject %u (entry: %u) reset", - (*itr)->GetGUIDLow(), (*itr)->GetEntry()); -#endif } + (*itr)->ToGameObject()->ResetDoorOrButton(); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_RESET_GOBJECT. Gameobject %u (entry: %u) reset", + (*itr)->GetGUIDLow(), (*itr)->GetEntry()); +#endif } + } - delete targets; + delete targets; + break; + } + case SMART_ACTION_SET_EMOTE_STATE: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_SET_EMOTE_STATE: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (IsUnit(*itr)) { - if (IsUnit(*itr)) - { - (*itr)->ToUnit()->SetUInt32Value(UNIT_NPC_EMOTESTATE, e.action.emote.emote); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SET_EMOTE_STATE. Unit %u set emotestate to %u", - (*itr)->GetGUIDLow(), e.action.emote.emote); -#endif } + (*itr)->ToUnit()->SetUInt32Value(UNIT_NPC_EMOTESTATE, e.action.emote.emote); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SET_EMOTE_STATE. Unit %u set emotestate to %u", + (*itr)->GetGUIDLow(), e.action.emote.emote); +#endif } + } - delete targets; + delete targets; + break; + } + case SMART_ACTION_SET_UNIT_FLAG: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_SET_UNIT_FLAG: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (IsUnit(*itr)) { - if (IsUnit(*itr)) + if (!e.action.unitFlag.type) { - if (!e.action.unitFlag.type) - { - (*itr)->ToUnit()->SetFlag(UNIT_FIELD_FLAGS, e.action.unitFlag.flag); - //TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SET_UNIT_FLAG. Unit %u added flag %u to UNIT_FIELD_FLAGS", - //(*itr)->GetGUIDLow(), e.action.unitFlag.flag); - } - else - { - (*itr)->ToUnit()->SetFlag(UNIT_FIELD_FLAGS_2, e.action.unitFlag.flag); - //TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SET_UNIT_FLAG. Unit %u added flag %u to UNIT_FIELD_FLAGS_2", - //(*itr)->GetGUIDLow(), e.action.unitFlag.flag); - } + (*itr)->ToUnit()->SetFlag(UNIT_FIELD_FLAGS, e.action.unitFlag.flag); + //TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SET_UNIT_FLAG. Unit %u added flag %u to UNIT_FIELD_FLAGS", + //(*itr)->GetGUIDLow(), e.action.unitFlag.flag); + } + else + { + (*itr)->ToUnit()->SetFlag(UNIT_FIELD_FLAGS_2, e.action.unitFlag.flag); + //TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SET_UNIT_FLAG. Unit %u added flag %u to UNIT_FIELD_FLAGS_2", + //(*itr)->GetGUIDLow(), e.action.unitFlag.flag); } } + } - delete targets; + delete targets; + break; + } + case SMART_ACTION_REMOVE_UNIT_FLAG: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_REMOVE_UNIT_FLAG: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (IsUnit(*itr)) { - if (IsUnit(*itr)) + if (!e.action.unitFlag.type) { - if (!e.action.unitFlag.type) - { - (*itr)->ToUnit()->RemoveFlag(UNIT_FIELD_FLAGS, e.action.unitFlag.flag); - //TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_REMOVE_UNIT_FLAG. Unit %u removed flag %u to UNIT_FIELD_FLAGS", - //(*itr)->GetGUIDLow(), e.action.unitFlag.flag); - } - else - { - (*itr)->ToUnit()->RemoveFlag(UNIT_FIELD_FLAGS_2, e.action.unitFlag.flag); - //TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_REMOVE_UNIT_FLAG. Unit %u removed flag %u to UNIT_FIELD_FLAGS_2", - //(*itr)->GetGUIDLow(), e.action.unitFlag.flag); - } + (*itr)->ToUnit()->RemoveFlag(UNIT_FIELD_FLAGS, e.action.unitFlag.flag); + //TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_REMOVE_UNIT_FLAG. Unit %u removed flag %u to UNIT_FIELD_FLAGS", + //(*itr)->GetGUIDLow(), e.action.unitFlag.flag); + } + else + { + (*itr)->ToUnit()->RemoveFlag(UNIT_FIELD_FLAGS_2, e.action.unitFlag.flag); + //TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_REMOVE_UNIT_FLAG. Unit %u removed flag %u to UNIT_FIELD_FLAGS_2", + //(*itr)->GetGUIDLow(), e.action.unitFlag.flag); } } - - delete targets; - break; } - case SMART_ACTION_AUTO_ATTACK: - { - if (!IsSmart()) - break; - CAST_AI(SmartAI, me->AI())->SetAutoAttack(e.action.autoAttack.attack); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_AUTO_ATTACK: Creature: %u bool on = %u", - me->GetGUIDLow(), e.action.autoAttack.attack); -#endif break; - } - case SMART_ACTION_ALLOW_COMBAT_MOVEMENT: - { - if (!IsSmart()) - break; + delete targets; + break; + } + case SMART_ACTION_AUTO_ATTACK: + { + if (!IsSmart()) + break; - // Xinef: Fix Combat Movement - bool move = e.action.combatMove.move; - if (move && GetMaxCombatDist() && e.GetEventType() == SMART_EVENT_MANA_PCT) - { - SetActualCombatDist(0); - CAST_AI(SmartAI, me->AI())->SetForcedCombatMove(0); - } - else - CAST_AI(SmartAI, me->AI())->SetCombatMove(move); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_ALLOW_COMBAT_MOVEMENT: Creature %u bool on = %u", - me->GetGUIDLow(), e.action.combatMove.move); -#endif break; - } - case SMART_ACTION_SET_EVENT_PHASE: - { - if (!GetBaseObject()) - break; + CAST_AI(SmartAI, me->AI())->SetAutoAttack(e.action.autoAttack.attack); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_AUTO_ATTACK: Creature: %u bool on = %u", + me->GetGUIDLow(), e.action.autoAttack.attack); +#endif + break; + } + case SMART_ACTION_ALLOW_COMBAT_MOVEMENT: + { + if (!IsSmart()) + break; - SetPhase(e.action.setEventPhase.phase); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SET_EVENT_PHASE: Creature %u set event phase %u", - GetBaseObject()->GetGUIDLow(), e.action.setEventPhase.phase); -#endif break; - } - case SMART_ACTION_INC_EVENT_PHASE: + // Xinef: Fix Combat Movement + bool move = e.action.combatMove.move; + if (move && GetMaxCombatDist() && e.GetEventType() == SMART_EVENT_MANA_PCT) { - if (!GetBaseObject()) - break; - - IncPhase(e.action.incEventPhase.inc); - DecPhase(e.action.incEventPhase.dec); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_INC_EVENT_PHASE: Creature %u inc event phase by %u, " - "decrease by %u", GetBaseObject()->GetGUIDLow(), e.action.incEventPhase.inc, e.action.incEventPhase.dec); -#endif break; + SetActualCombatDist(0); + CAST_AI(SmartAI, me->AI())->SetForcedCombatMove(0); } - case SMART_ACTION_EVADE: - { - if (!GetBaseObject()) - break; - - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsCreature((*itr))) - if ((*itr)->ToCreature()->IsAIEnabled) - (*itr)->ToCreature()->AI()->EnterEvadeMode(); - - delete targets; + else + CAST_AI(SmartAI, me->AI())->SetCombatMove(move); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_ALLOW_COMBAT_MOVEMENT: Creature %u bool on = %u", + me->GetGUIDLow(), e.action.combatMove.move); +#endif + break; + } + case SMART_ACTION_SET_EVENT_PHASE: + { + if (!GetBaseObject()) break; - } - case SMART_ACTION_FLEE_FOR_ASSIST: - { - // Xinef: do not allow to flee without control (stun, fear etc) - if (!me || me->HasUnitState(UNIT_STATE_LOST_CONTROL) || me->GetSpeed(MOVE_RUN) < 0.1f) - break; - me->DoFleeToGetAssistance(); - if (e.action.flee.withEmote) - { - TrinityStringTextBuilder builder(me, CHAT_MSG_MONSTER_EMOTE, LANG_FLEE, LANG_UNIVERSAL, NULL); - sCreatureTextMgr->SendChatPacket(me, builder, CHAT_MSG_MONSTER_EMOTE); - } -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_FLEE_FOR_ASSIST: Creature %u DoFleeToGetAssistance", me->GetGUIDLow()); + SetPhase(e.action.setEventPhase.phase); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SET_EVENT_PHASE: Creature %u set event phase %u", + GetBaseObject()->GetGUIDLow(), e.action.setEventPhase.phase); #endif + break; + } + case SMART_ACTION_INC_EVENT_PHASE: + { + if (!GetBaseObject()) break; - } - case SMART_ACTION_COMBAT_STOP: - { - if (!me) - break; - me->CombatStop(true); + IncPhase(e.action.incEventPhase.inc); + DecPhase(e.action.incEventPhase.dec); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_INC_EVENT_PHASE: Creature %u inc event phase by %u, " + "decrease by %u", GetBaseObject()->GetGUIDLow(), e.action.incEventPhase.inc, e.action.incEventPhase.dec); +#endif + break; + } + case SMART_ACTION_EVADE: + { + if (!GetBaseObject()) break; - } - case SMART_ACTION_CALL_GROUPEVENTHAPPENS: - { - if (!GetBaseObject()) - break; - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - { - if (IsUnit((*itr))) - { - if (Player* player = (*itr)->ToUnit()->GetCharmerOrOwnerPlayerOrPlayerItself()) - player->GroupEventHappens(e.action.quest.quest, GetBaseObject()); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_CALL_GROUPEVENTHAPPENS: Player %u, group credit for quest %u", - (*itr)->GetGUIDLow(), e.action.quest.quest); -#endif } - } - - delete targets; + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_REMOVEAURASFROMSPELL: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - { - if (!IsUnit((*itr))) - continue; - - if (e.action.removeAura.spell) - { - if (e.action.removeAura.charges) - { - if (Aura* aur = (*itr)->ToUnit()->GetAura(e.action.removeAura.spell)) - aur->ModCharges(-static_cast<int32>(e.action.removeAura.charges), AURA_REMOVE_BY_EXPIRE); - } - else - (*itr)->ToUnit()->RemoveAurasDueToSpell(e.action.removeAura.spell); - } - else - (*itr)->ToUnit()->RemoveAllAuras(); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_REMOVEAURASFROMSPELL: Unit %u, spell %u", - (*itr)->GetGUIDLow(), e.action.removeAura.spell); -#endif } + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsCreature((*itr))) + if ((*itr)->ToCreature()->IsAIEnabled) + (*itr)->ToCreature()->AI()->EnterEvadeMode(); - delete targets; + delete targets; + break; + } + case SMART_ACTION_FLEE_FOR_ASSIST: + { + // Xinef: do not allow to flee without control (stun, fear etc) + if (!me || me->HasUnitState(UNIT_STATE_LOST_CONTROL) || me->GetSpeed(MOVE_RUN) < 0.1f) break; - } - case SMART_ACTION_FOLLOW: - { - if (!IsSmart()) - break; - ObjectList* targets = GetTargets(e, unit); - if (!targets) - { - CAST_AI(SmartAI, me->AI())->StopFollow(false); - break; - } + me->DoFleeToGetAssistance(); + if (e.action.flee.withEmote) + { + TrinityStringTextBuilder builder(me, CHAT_MSG_MONSTER_EMOTE, LANG_FLEE, LANG_UNIVERSAL, NULL); + sCreatureTextMgr->SendChatPacket(me, builder, CHAT_MSG_MONSTER_EMOTE); + } +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_FLEE_FOR_ASSIST: Creature %u DoFleeToGetAssistance", me->GetGUIDLow()); +#endif + break; + } + case SMART_ACTION_COMBAT_STOP: + { + if (!me) + break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - { - if (IsUnit((*itr))) - { - float angle = e.action.follow.angle > 6 ? (e.action.follow.angle * M_PI / 180.0f) : e.action.follow.angle; - CAST_AI(SmartAI, me->AI())->SetFollow((*itr)->ToUnit(), float(int32(e.action.follow.dist))+0.1f, angle, e.action.follow.credit, e.action.follow.entry, e.action.follow.creditType, e.action.follow.aliveState); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_FOLLOW: Creature %u following target %u", - me->GetGUIDLow(), (*itr)->GetGUIDLow()); -#endif break; - } - } + me->CombatStop(true); + break; + } + case SMART_ACTION_CALL_GROUPEVENTHAPPENS: + { + if (!GetBaseObject()) + break; - delete targets; + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_RANDOM_PHASE: - { - if (!GetBaseObject()) - break; - uint32 phases[SMART_ACTION_PARAM_COUNT]; - phases[0] = e.action.randomPhase.phase1; - phases[1] = e.action.randomPhase.phase2; - phases[2] = e.action.randomPhase.phase3; - phases[3] = e.action.randomPhase.phase4; - phases[4] = e.action.randomPhase.phase5; - phases[5] = e.action.randomPhase.phase6; - uint32 temp[SMART_ACTION_PARAM_COUNT]; - uint32 count = 0; - for (uint8 i = 0; i < SMART_ACTION_PARAM_COUNT; i++) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (IsUnit((*itr))) { - if (phases[i] > 0) - { - temp[count] = phases[i]; - ++count; - } + if (Player* player = (*itr)->ToUnit()->GetCharmerOrOwnerPlayerOrPlayerItself()) + player->GroupEventHappens(e.action.quest.quest, GetBaseObject()); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_CALL_GROUPEVENTHAPPENS: Player %u, group credit for quest %u", + (*itr)->GetGUIDLow(), e.action.quest.quest); +#endif } + } - if (count == 0) - break; + delete targets; + break; + } + case SMART_ACTION_REMOVEAURASFROMSPELL: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) + break; - uint32 phase = temp[urand(0, count - 1)]; - SetPhase(phase); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_RANDOM_PHASE: Creature %u sets event phase to %u", - GetBaseObject()->GetGUIDLow(), phase); -#endif break; - } - case SMART_ACTION_RANDOM_PHASE_RANGE: + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { - if (!GetBaseObject()) - break; + if (!IsUnit((*itr))) + continue; - uint32 phase = urand(e.action.randomPhaseRange.phaseMin, e.action.randomPhaseRange.phaseMax); - SetPhase(phase); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_RANDOM_PHASE_RANGE: Creature %u sets event phase to %u", - GetBaseObject()->GetGUIDLow(), phase); -#endif break; - } - case SMART_ACTION_CALL_KILLEDMONSTER: - { - if (trigger && IsPlayer(unit)) + if (e.action.removeAura.spell) { - unit->ToPlayer()->RewardPlayerAndGroupAtEvent(e.action.killedMonster.creature, unit); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_CALL_KILLEDMONSTER: (trigger == true) Player %u, Killcredit: %u", - unit->GetGUIDLow(), e.action.killedMonster.creature); -#endif } - else if (e.target.type == SMART_TARGET_NONE || e.target.type == SMART_TARGET_SELF) // Loot recipient and his group members - { - if (!me) - break; - - if (Player* player = me->GetLootRecipient()) + if (e.action.removeAura.charges) { - player->RewardPlayerAndGroupAtEvent(e.action.killedMonster.creature, player); - //TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_CALL_KILLEDMONSTER: Player %u, Killcredit: %u", - // player->GetGUIDLow(), e.action.killedMonster.creature); + if (Aura* aur = (*itr)->ToUnit()->GetAura(e.action.removeAura.spell)) + aur->ModCharges(-static_cast<int32>(e.action.removeAura.charges), AURA_REMOVE_BY_EXPIRE); } + else + (*itr)->ToUnit()->RemoveAurasDueToSpell(e.action.removeAura.spell); } - else // Specific target type - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - { - if (!IsUnit(*itr)) - continue; + else + (*itr)->ToUnit()->RemoveAllAuras(); - Player* player = (*itr)->ToUnit()->GetCharmerOrOwnerPlayerOrPlayerItself(); - if (!player) - continue; +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_REMOVEAURASFROMSPELL: Unit %u, spell %u", + (*itr)->GetGUIDLow(), e.action.removeAura.spell); +#endif + } - player->RewardPlayerAndGroupAtEvent(e.action.killedMonster.creature, player); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_CALL_KILLEDMONSTER: Player %u, Killcredit: %u", - (*itr)->GetGUIDLow(), e.action.killedMonster.creature); -#endif } + delete targets; + break; + } + case SMART_ACTION_FOLLOW: + { + if (!IsSmart()) + break; - delete targets; - } + ObjectList* targets = GetTargets(e, unit); + if (!targets) + { + CAST_AI(SmartAI, me->AI())->StopFollow(false); break; } - case SMART_ACTION_SET_INST_DATA: - { - WorldObject* obj = GetBaseObject(); - if (!obj) - obj = unit; - if (!obj) - break; - - InstanceScript* instance = obj->GetInstanceScript(); - if (!instance) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (IsUnit((*itr))) { - sLog->outErrorDb("SmartScript: Event %u attempt to set instance data without instance script. EntryOrGuid %d", e.GetEventType(), e.entryOrGuid); + float angle = e.action.follow.angle > 6 ? (e.action.follow.angle * M_PI / 180.0f) : e.action.follow.angle; + CAST_AI(SmartAI, me->AI())->SetFollow((*itr)->ToUnit(), float(int32(e.action.follow.dist)) + 0.1f, angle, e.action.follow.credit, e.action.follow.entry, e.action.follow.creditType, e.action.follow.aliveState); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_FOLLOW: Creature %u following target %u", + me->GetGUIDLow(), (*itr)->GetGUIDLow()); +#endif break; } - - instance->SetData(e.action.setInstanceData.field, e.action.setInstanceData.data); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_SET_INST_DATA: Field: %u, data: %u", - e.action.setInstanceData.field, e.action.setInstanceData.data); -#endif break; } - case SMART_ACTION_SET_INST_DATA64: - { - WorldObject* obj = GetBaseObject(); - if (!obj) - obj = unit; - if (!obj) - break; + delete targets; + break; + } + case SMART_ACTION_RANDOM_PHASE: + { + if (!GetBaseObject()) + break; - InstanceScript* instance = obj->GetInstanceScript(); - if (!instance) + uint32 phases[SMART_ACTION_PARAM_COUNT]; + phases[0] = e.action.randomPhase.phase1; + phases[1] = e.action.randomPhase.phase2; + phases[2] = e.action.randomPhase.phase3; + phases[3] = e.action.randomPhase.phase4; + phases[4] = e.action.randomPhase.phase5; + phases[5] = e.action.randomPhase.phase6; + uint32 temp[SMART_ACTION_PARAM_COUNT]; + uint32 count = 0; + for (uint8 i = 0; i < SMART_ACTION_PARAM_COUNT; i++) + { + if (phases[i] > 0) { - sLog->outErrorDb("SmartScript: Event %u attempt to set instance data without instance script. EntryOrGuid %d", e.GetEventType(), e.entryOrGuid); - break; + temp[count] = phases[i]; + ++count; } + } - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; + if (count == 0) + break; - instance->SetData64(e.action.setInstanceData64.field, targets->front()->GetGUID()); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_SET_INST_DATA64: Field: %u, data: "UI64FMTD, - e.action.setInstanceData64.field, targets->front()->GetGUID()); + uint32 phase = temp[urand(0, count - 1)]; + SetPhase(phase); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_RANDOM_PHASE: Creature %u sets event phase to %u", + GetBaseObject()->GetGUIDLow(), phase); #endif - delete targets; + break; + } + case SMART_ACTION_RANDOM_PHASE_RANGE: + { + if (!GetBaseObject()) break; + + uint32 phase = urand(e.action.randomPhaseRange.phaseMin, e.action.randomPhaseRange.phaseMax); + SetPhase(phase); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_RANDOM_PHASE_RANGE: Creature %u sets event phase to %u", + GetBaseObject()->GetGUIDLow(), phase); +#endif + break; + } + case SMART_ACTION_CALL_KILLEDMONSTER: + { + if (trigger && IsPlayer(unit)) + { + unit->ToPlayer()->RewardPlayerAndGroupAtEvent(e.action.killedMonster.creature, unit); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_CALL_KILLEDMONSTER: (trigger == true) Player %u, Killcredit: %u", + unit->GetGUIDLow(), e.action.killedMonster.creature); +#endif } - case SMART_ACTION_UPDATE_TEMPLATE: + else if (e.target.type == SMART_TARGET_NONE || e.target.type == SMART_TARGET_SELF) // Loot recipient and his group members { - ObjectList* targets = GetTargets(e, unit); - if (!targets) + if (!me) break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsCreature(*itr)) - (*itr)->ToCreature()->UpdateEntry(e.action.updateTemplate.creature, NULL, !e.action.updateTemplate.doNotChangeLevel); - - delete targets; - break; - } - case SMART_ACTION_DIE: - { - if (me && !me->isDead()) + if (Player* player = me->GetLootRecipient()) { - Unit::Kill(me, me); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_DIE: Creature %u", me->GetGUIDLow()); -#endif + player->RewardPlayerAndGroupAtEvent(e.action.killedMonster.creature, player); + //TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_CALL_KILLEDMONSTER: Player %u, Killcredit: %u", + // player->GetGUIDLow(), e.action.killedMonster.creature); } - break; } - case SMART_ACTION_SET_IN_COMBAT_WITH_ZONE: + else // Specific target type { ObjectList* targets = GetTargets(e, unit); if (!targets) break; for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsCreature(*itr)) - (*itr)->ToCreature()->SetInCombatWithZone(); + { + if (!IsUnit(*itr)) + continue; + + Player* player = (*itr)->ToUnit()->GetCharmerOrOwnerPlayerOrPlayerItself(); + if (!player) + continue; + + player->RewardPlayerAndGroupAtEvent(e.action.killedMonster.creature, player); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_CALL_KILLEDMONSTER: Player %u, Killcredit: %u", + (*itr)->GetGUIDLow(), e.action.killedMonster.creature); +#endif + } delete targets; - break; } - case SMART_ACTION_CALL_FOR_HELP: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; + break; + } + case SMART_ACTION_SET_INST_DATA: + { + WorldObject* obj = GetBaseObject(); + if (!obj) + obj = unit; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsCreature(*itr)) - { - (*itr)->ToCreature()->CallForHelp((float)e.action.callHelp.range); - if (e.action.callHelp.withEmote) - { - TrinityStringTextBuilder builder(*itr, CHAT_MSG_MONSTER_EMOTE, LANG_CALL_FOR_HELP, LANG_UNIVERSAL, NULL); - sCreatureTextMgr->SendChatPacket(*itr, builder, CHAT_MSG_MONSTER_EMOTE); - } - } + if (!obj) + break; - delete targets; + InstanceScript* instance = obj->GetInstanceScript(); + if (!instance) + { + sLog->outErrorDb("SmartScript: Event %u attempt to set instance data without instance script. EntryOrGuid %d", e.GetEventType(), e.entryOrGuid); break; } - case SMART_ACTION_SET_SHEATH: + + instance->SetData(e.action.setInstanceData.field, e.action.setInstanceData.data); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_SET_INST_DATA: Field: %u, data: %u", + e.action.setInstanceData.field, e.action.setInstanceData.data); +#endif + break; + } + case SMART_ACTION_SET_INST_DATA64: + { + WorldObject* obj = GetBaseObject(); + if (!obj) + obj = unit; + + if (!obj) + break; + + InstanceScript* instance = obj->GetInstanceScript(); + if (!instance) { - if (me) - { - me->SetSheath(SheathState(e.action.setSheath.sheath)); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_SET_SHEATH: Creature %u, State: %u", - me->GetGUIDLow(), e.action.setSheath.sheath); -#endif } + sLog->outErrorDb("SmartScript: Event %u attempt to set instance data without instance script. EntryOrGuid %d", e.GetEventType(), e.entryOrGuid); break; } - case SMART_ACTION_FORCE_DESPAWN: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - { - if (IsCreature(*itr)) - (*itr)->ToCreature()->DespawnOrUnsummon(e.action.forceDespawn.delay + 1); - else if (IsGameObject(*itr)) - (*itr)->ToGameObject()->Delete(); - } + ObjectList* targets = GetTargets(e, unit); + if (!targets) + break; - delete targets; + instance->SetData64(e.action.setInstanceData64.field, targets->front()->GetGUID()); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_SET_INST_DATA64: Field: %u, data: %u", + e.action.setInstanceData64.field, targets->front()->GetGUID()); +#endif + delete targets; + break; + } + case SMART_ACTION_UPDATE_TEMPLATE: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_SET_INGAME_PHASE_MASK: + + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsCreature(*itr)) + (*itr)->ToCreature()->UpdateEntry(e.action.updateTemplate.creature, NULL, !e.action.updateTemplate.doNotChangeLevel); + + delete targets; + break; + } + case SMART_ACTION_DIE: + { + if (me && !me->isDead()) { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; + Unit::Kill(me, me); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_DIE: Creature %u", me->GetGUIDLow()); +#endif + } + break; + } + case SMART_ACTION_SET_IN_COMBAT_WITH_ZONE: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) + break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - { - if (IsUnit(*itr)) - (*itr)->ToUnit()->SetPhaseMask(e.action.ingamePhaseMask.mask, true); - else if (IsGameObject(*itr)) - (*itr)->ToGameObject()->SetPhaseMask(e.action.ingamePhaseMask.mask, true); - } + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsCreature(*itr)) + (*itr)->ToCreature()->SetInCombatWithZone(); - delete targets; + delete targets; + break; + } + case SMART_ACTION_CALL_FOR_HELP: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_MOUNT_TO_ENTRY_OR_MODEL: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsCreature(*itr)) { - if (!IsUnit(*itr)) - continue; - - if (e.action.morphOrMount.creature || e.action.morphOrMount.model) + (*itr)->ToCreature()->CallForHelp((float)e.action.callHelp.range); + if (e.action.callHelp.withEmote) { - if (e.action.morphOrMount.creature > 0) - { - if (CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(e.action.morphOrMount.creature)) - (*itr)->ToUnit()->Mount(ObjectMgr::ChooseDisplayId(cInfo)); - } - else - (*itr)->ToUnit()->Mount(e.action.morphOrMount.model); + TrinityStringTextBuilder builder(*itr, CHAT_MSG_MONSTER_EMOTE, LANG_CALL_FOR_HELP, LANG_UNIVERSAL, NULL); + sCreatureTextMgr->SendChatPacket(*itr, builder, CHAT_MSG_MONSTER_EMOTE); } - else - (*itr)->ToUnit()->Dismount(); } - delete targets; + delete targets; + break; + } + case SMART_ACTION_SET_SHEATH: + { + if (me) + { + me->SetSheath(SheathState(e.action.setSheath.sheath)); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_SET_SHEATH: Creature %u, State: %u", + me->GetGUIDLow(), e.action.setSheath.sheath); +#endif + } + break; + } + case SMART_ACTION_FORCE_DESPAWN: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; + + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (IsCreature(*itr)) + (*itr)->ToCreature()->DespawnOrUnsummon(e.action.forceDespawn.delay + 1); + else if (IsGameObject(*itr)) + (*itr)->ToGameObject()->Delete(); } - case SMART_ACTION_SET_INVINCIBILITY_HP_LEVEL: + + delete targets; + break; + } + case SMART_ACTION_SET_INGAME_PHASE_MASK: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) + break; + + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; + if (IsUnit(*itr)) + (*itr)->ToUnit()->SetPhaseMask(e.action.ingamePhaseMask.mask, true); + else if (IsGameObject(*itr)) + (*itr)->ToGameObject()->SetPhaseMask(e.action.ingamePhaseMask.mask, true); + } - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + delete targets; + break; + } + case SMART_ACTION_MOUNT_TO_ENTRY_OR_MODEL: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) + break; + + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (!IsUnit(*itr)) + continue; + + if (e.action.morphOrMount.creature || e.action.morphOrMount.model) { - if (IsCreature(*itr)) + if (e.action.morphOrMount.creature > 0) { - SmartAI* ai = CAST_AI(SmartAI, (*itr)->ToCreature()->AI()); - if (!ai) - continue; - - if (e.action.invincHP.percent) - ai->SetInvincibilityHpLevel((*itr)->ToCreature()->CountPctFromMaxHealth(e.action.invincHP.percent)); - else - ai->SetInvincibilityHpLevel(e.action.invincHP.minHP); + if (CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(e.action.morphOrMount.creature)) + (*itr)->ToUnit()->Mount(ObjectMgr::ChooseDisplayId(cInfo)); } + else + (*itr)->ToUnit()->Mount(e.action.morphOrMount.model); } + else + (*itr)->ToUnit()->Dismount(); + } - delete targets; + delete targets; + break; + } + case SMART_ACTION_SET_INVINCIBILITY_HP_LEVEL: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_SET_DATA: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (IsCreature(*itr)) { - if (IsCreature(*itr)) - (*itr)->ToCreature()->AI()->SetData(e.action.setData.field, e.action.setData.data); - else if (IsGameObject(*itr)) - (*itr)->ToGameObject()->AI()->SetData(e.action.setData.field, e.action.setData.data); - } + SmartAI* ai = CAST_AI(SmartAI, (*itr)->ToCreature()->AI()); + if (!ai) + continue; - delete targets; - break; + if (e.action.invincHP.percent) + ai->SetInvincibilityHpLevel((*itr)->ToCreature()->CountPctFromMaxHealth(e.action.invincHP.percent)); + else + ai->SetInvincibilityHpLevel(e.action.invincHP.minHP); + } } - case SMART_ACTION_MOVE_FORWARD: - { - if (!me) - break; - float x, y, z; - me->GetClosePoint(x, y, z, me->GetObjectSize() / 3, (float)e.action.moveRandom.distance); - me->GetMotionMaster()->MovePoint(SMART_RANDOM_POINT, x, y, z); + delete targets; + break; + } + case SMART_ACTION_SET_DATA: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_RISE_UP: + + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { - if (!me) - break; + if (IsCreature(*itr)) + (*itr)->ToCreature()->AI()->SetData(e.action.setData.field, e.action.setData.data); + else if (IsGameObject(*itr)) + (*itr)->ToGameObject()->AI()->SetData(e.action.setData.field, e.action.setData.data); + } - me->GetMotionMaster()->MovePoint(SMART_RANDOM_POINT, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + (float)e.action.moveRandom.distance); + delete targets; + break; + } + case SMART_ACTION_MOVE_FORWARD: + { + if (!me) break; - } - case SMART_ACTION_SET_VISIBILITY: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsUnit(*itr)) - (*itr)->ToUnit()->SetVisible(e.action.visibility.state ? true : false); + float x, y, z; + me->GetClosePoint(x, y, z, me->GetObjectSize() / 3, (float)e.action.moveRandom.distance); + me->GetMotionMaster()->MovePoint(SMART_RANDOM_POINT, x, y, z); + break; + } + case SMART_ACTION_RISE_UP: + { + if (!me) + break; - delete targets; + me->GetMotionMaster()->MovePoint(SMART_RANDOM_POINT, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + (float)e.action.moveRandom.distance); + break; + } + case SMART_ACTION_SET_VISIBILITY: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_SET_ACTIVE: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - (*itr)->setActive(e.action.setActive.state ? true : false); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsUnit(*itr)) + (*itr)->ToUnit()->SetVisible(e.action.visibility.state ? true : false); - delete targets; + delete targets; + break; + } + case SMART_ACTION_SET_ACTIVE: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_ATTACK_START: - { - if (!me) - break; - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + (*itr)->setActive(e.action.setActive.state ? true : false); - // xinef: attack random target - if (Unit* target = Trinity::Containers::SelectRandomContainerElement(*targets)->ToUnit()) - me->AI()->AttackStart(target); - - delete targets; + delete targets; + break; + } + case SMART_ACTION_ATTACK_START: + { + if (!me) break; - } - case SMART_ACTION_SUMMON_CREATURE: - { - ObjectList* targets = GetTargets(e, unit); - WorldObject* summoner = GetBaseObject() ? GetBaseObject() : unit; - if (!summoner) - break; - - if (targets) - { - float x, y, z, o; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - { - (*itr)->GetPosition(x, y, z, o); - x += e.target.x; - y += e.target.y; - z += e.target.z; - o += e.target.o; - if (Creature* summon = summoner->SummonCreature(e.action.summonCreature.creature, x, y, z, o, (TempSummonType)e.action.summonCreature.type, e.action.summonCreature.duration)) - { - if (e.action.summonCreature.attackInvoker == 2) // pussywizard: proper attackInvoker implementation, but not spoiling tc shitness - summon->AI()->AttackStart(unit); - else if (e.action.summonCreature.attackInvoker) - summon->AI()->AttackStart((*itr)->ToUnit()); - else if (me && e.action.summonCreature.attackScriptOwner) - summon->AI()->AttackStart(me); - } - } - delete targets; - } + ObjectList* targets = GetTargets(e, unit); + if (!targets) + break; - if (e.GetTargetType() != SMART_TARGET_POSITION) - break; + // xinef: attack random target + if (Unit* target = Trinity::Containers::SelectRandomContainerElement(*targets)->ToUnit()) + me->AI()->AttackStart(target); - if (Creature* summon = summoner->SummonCreature(e.action.summonCreature.creature, e.target.x, e.target.y, e.target.z, e.target.o, (TempSummonType)e.action.summonCreature.type, e.action.summonCreature.duration)) - { - if (unit && e.action.summonCreature.attackInvoker) - summon->AI()->AttackStart(unit); - else if (me && e.action.summonCreature.attackScriptOwner) - summon->AI()->AttackStart(me); - } + delete targets; + break; + } + case SMART_ACTION_SUMMON_CREATURE: + { + ObjectList* targets = GetTargets(e, unit); + WorldObject* summoner = GetBaseObject() ? GetBaseObject() : unit; + if (!summoner) break; - } - case SMART_ACTION_SUMMON_GO: - { - if (!GetBaseObject()) - break; - ObjectList* targets = GetTargets(e, unit); - if (targets) + if (targets) + { + float x, y, z, o; + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { - float x, y, z, o; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + (*itr)->GetPosition(x, y, z, o); + x += e.target.x; + y += e.target.y; + z += e.target.z; + o += e.target.o; + if (Creature* summon = summoner->SummonCreature(e.action.summonCreature.creature, x, y, z, o, (TempSummonType)e.action.summonCreature.type, e.action.summonCreature.duration)) { - // xinef: allow gameobjects to summon gameobjects! - //if(!IsUnit((*itr))) - // continue; - - (*itr)->GetPosition(x, y, z, o); - x += e.target.x; - y += e.target.y; - z += e.target.z; - o += e.target.o; - if (!e.action.summonGO.targetsummon) - GetBaseObject()->SummonGameObject(e.action.summonGO.entry, x, y, z, o, 0, 0, 0, 0, e.action.summonGO.despawnTime); - else - (*itr)->SummonGameObject(e.action.summonGO.entry, GetBaseObject()->GetPositionX(), GetBaseObject()->GetPositionY(), GetBaseObject()->GetPositionZ(), GetBaseObject()->GetOrientation(), 0, 0, 0, 0, e.action.summonGO.despawnTime); + if (e.action.summonCreature.attackInvoker == 2) // pussywizard: proper attackInvoker implementation, but not spoiling tc shitness + summon->AI()->AttackStart(unit); + else if (e.action.summonCreature.attackInvoker) + summon->AI()->AttackStart((*itr)->ToUnit()); + else if (me && e.action.summonCreature.attackScriptOwner) + summon->AI()->AttackStart(me); } - - delete targets; } - if (e.GetTargetType() != SMART_TARGET_POSITION) - break; + delete targets; + } - GetBaseObject()->SummonGameObject(e.action.summonGO.entry, e.target.x, e.target.y, e.target.z, e.target.o, 0, 0, 0, 0, e.action.summonGO.despawnTime); + if (e.GetTargetType() != SMART_TARGET_POSITION) break; - } - case SMART_ACTION_KILL_UNIT: + + if (Creature* summon = summoner->SummonCreature(e.action.summonCreature.creature, e.target.x, e.target.y, e.target.z, e.target.o, (TempSummonType)e.action.summonCreature.type, e.action.summonCreature.duration)) { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; + if (unit && e.action.summonCreature.attackInvoker) + summon->AI()->AttackStart(unit); + else if (me && e.action.summonCreature.attackScriptOwner) + summon->AI()->AttackStart(me); + } + break; + } + case SMART_ACTION_SUMMON_GO: + { + if (!GetBaseObject()) + break; + ObjectList* targets = GetTargets(e, unit); + if (targets) + { + float x, y, z, o; for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { - if (!IsUnit(*itr)) - continue; - - Unit::Kill((*itr)->ToUnit(), (*itr)->ToUnit()); + // xinef: allow gameobjects to summon gameobjects! + //if(!IsUnit((*itr))) + // continue; + + (*itr)->GetPosition(x, y, z, o); + x += e.target.x; + y += e.target.y; + z += e.target.z; + o += e.target.o; + if (!e.action.summonGO.targetsummon) + GetBaseObject()->SummonGameObject(e.action.summonGO.entry, x, y, z, o, 0, 0, 0, 0, e.action.summonGO.despawnTime); + else + (*itr)->SummonGameObject(e.action.summonGO.entry, GetBaseObject()->GetPositionX(), GetBaseObject()->GetPositionY(), GetBaseObject()->GetPositionZ(), GetBaseObject()->GetOrientation(), 0, 0, 0, 0, e.action.summonGO.despawnTime); } delete targets; - break; } - case SMART_ACTION_INSTALL_AI_TEMPLATE: - { - InstallTemplate(e); + + if (e.GetTargetType() != SMART_TARGET_POSITION) break; - } - case SMART_ACTION_ADD_ITEM: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - { - if (!IsPlayer(*itr)) - continue; + GetBaseObject()->SummonGameObject(e.action.summonGO.entry, e.target.x, e.target.y, e.target.z, e.target.o, 0, 0, 0, 0, e.action.summonGO.despawnTime); + break; + } + case SMART_ACTION_KILL_UNIT: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) + break; - (*itr)->ToPlayer()->AddItem(e.action.item.entry, e.action.item.count); - } + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (!IsUnit(*itr)) + continue; - delete targets; - break; + Unit::Kill((*itr)->ToUnit(), (*itr)->ToUnit()); } - case SMART_ACTION_REMOVE_ITEM: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - { - if (!IsPlayer(*itr)) - continue; + delete targets; + break; + } + case SMART_ACTION_INSTALL_AI_TEMPLATE: + { + InstallTemplate(e); + break; + } + case SMART_ACTION_ADD_ITEM: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) + break; - (*itr)->ToPlayer()->DestroyItemCount(e.action.item.entry, e.action.item.count, true); - } + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (!IsPlayer(*itr)) + continue; - delete targets; - break; + (*itr)->ToPlayer()->AddItem(e.action.item.entry, e.action.item.count); } - case SMART_ACTION_STORE_TARGET_LIST: - { - ObjectList* targets = GetTargets(e, unit); - StoreTargetList(targets, e.action.storeTargets.id); + + delete targets; + break; + } + case SMART_ACTION_REMOVE_ITEM: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_TELEPORT: + + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; + if (!IsPlayer(*itr)) + continue; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - { - if (IsPlayer(*itr)) - (*itr)->ToPlayer()->TeleportTo(e.action.teleport.mapID, e.target.x, e.target.y, e.target.z, e.target.o); - else if (IsUnit(*itr)) - (*itr)->ToUnit()->NearTeleportTo(e.target.x, e.target.y, e.target.z, e.target.o); - } + (*itr)->ToPlayer()->DestroyItemCount(e.action.item.entry, e.action.item.count, true); + } - delete targets; + delete targets; + break; + } + case SMART_ACTION_STORE_TARGET_LIST: + { + ObjectList* targets = GetTargets(e, unit); + StoreTargetList(targets, e.action.storeTargets.id); + break; + } + case SMART_ACTION_TELEPORT: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_SET_FLY: + + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { - if (!IsSmart()) - break; + if (IsPlayer(*itr)) + (*itr)->ToPlayer()->TeleportTo(e.action.teleport.mapID, e.target.x, e.target.y, e.target.z, e.target.o); + else if (IsUnit(*itr)) + (*itr)->ToUnit()->NearTeleportTo(e.target.x, e.target.y, e.target.z, e.target.o); + } - CAST_AI(SmartAI, me->AI())->SetFly(e.action.setFly.fly); - // Xinef: Set speed if any - if (e.action.setFly.speed) - me->SetSpeed(MOVE_RUN, float(e.action.setFly.speed/100.0f), true); + delete targets; + break; + } + case SMART_ACTION_SET_FLY: + { + if (!IsSmart()) + break; + + CAST_AI(SmartAI, me->AI())->SetFly(e.action.setFly.fly); + // Xinef: Set speed if any + if (e.action.setFly.speed) + me->SetSpeed(MOVE_RUN, float(e.action.setFly.speed / 100.0f), true); - // Xinef: this wil be executed only if state is different - me->SetDisableGravity(e.action.setFly.disableGravity); + // Xinef: this wil be executed only if state is different + me->SetDisableGravity(e.action.setFly.disableGravity); + break; + } + case SMART_ACTION_SET_RUN: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_SET_RUN: + + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; + if (IsCreature(*itr)) + { + if (IsSmart((*itr)->ToCreature())) + CAST_AI(SmartAI, (*itr)->ToCreature()->AI())->SetRun(e.action.setRun.run); + else + (*itr)->ToCreature()->SetWalk(e.action.setRun.run ? false : true); // Xinef: reversed + } + } + delete targets; + break; + } + case SMART_ACTION_SET_SWIM: + { + if (!IsSmart()) + break; + + CAST_AI(SmartAI, me->AI())->SetSwim(e.action.setSwim.swim); + break; + } + case SMART_ACTION_SET_COUNTER: + { + if (ObjectList* targets = GetTargets(e, unit)) + { for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { if (IsCreature(*itr)) { - if (IsSmart((*itr)->ToCreature())) - CAST_AI(SmartAI, (*itr)->ToCreature()->AI())->SetRun(e.action.setRun.run); + if (SmartAI* ai = CAST_AI(SmartAI, (*itr)->ToCreature()->AI())) + ai->GetScript()->StoreCounter(e.action.setCounter.counterId, e.action.setCounter.value, e.action.setCounter.reset); + else + sLog->outError("SmartScript: Action target for SMART_ACTION_SET_COUNTER is not using SmartAI, skipping"); + } + else if (IsGameObject(*itr)) + { + if (SmartGameObjectAI* ai = CAST_AI(SmartGameObjectAI, (*itr)->ToGameObject()->AI())) + ai->GetScript()->StoreCounter(e.action.setCounter.counterId, e.action.setCounter.value, e.action.setCounter.reset); else - (*itr)->ToCreature()->SetWalk(e.action.setRun.run ? false : true); // Xinef: reversed + sLog->outError("SmartScript: Action target for SMART_ACTION_SET_COUNTER is not using SmartGameObjectAI, skipping"); } } delete targets; - break; } - case SMART_ACTION_SET_SWIM: - { - if (!IsSmart()) - break; + else + StoreCounter(e.action.setCounter.counterId, e.action.setCounter.value, e.action.setCounter.reset); - CAST_AI(SmartAI, me->AI())->SetSwim(e.action.setSwim.swim); + break; + } + case SMART_ACTION_WP_START: + { + if (!IsSmart()) break; - } - case SMART_ACTION_SET_COUNTER: - { - if (ObjectList* targets = GetTargets(e, unit)) - { - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - { - if (IsCreature(*itr)) - { - if (SmartAI* ai = CAST_AI(SmartAI, (*itr)->ToCreature()->AI())) - ai->GetScript()->StoreCounter(e.action.setCounter.counterId, e.action.setCounter.value, e.action.setCounter.reset); - else - sLog->outError("SmartScript: Action target for SMART_ACTION_SET_COUNTER is not using SmartAI, skipping"); - } - else if (IsGameObject(*itr)) - { - if (SmartGameObjectAI* ai = CAST_AI(SmartGameObjectAI, (*itr)->ToGameObject()->AI())) - ai->GetScript()->StoreCounter(e.action.setCounter.counterId, e.action.setCounter.value, e.action.setCounter.reset); - else - sLog->outError("SmartScript: Action target for SMART_ACTION_SET_COUNTER is not using SmartGameObjectAI, skipping"); - } - } - delete targets; - } - else - StoreCounter(e.action.setCounter.counterId, e.action.setCounter.value, e.action.setCounter.reset); + bool run = e.action.wpStart.run; + uint32 entry = e.action.wpStart.pathID; + bool repeat = e.action.wpStart.repeat; - break; - } - case SMART_ACTION_WP_START: + // Xinef: ensure that SMART_ESCORT_TARGETS contains at least one player reference + bool stored = false; + ObjectList* targets = GetTargets(e, unit); + if (targets) { - if (!IsSmart()) - break; - - bool run = e.action.wpStart.run; - uint32 entry = e.action.wpStart.pathID; - bool repeat = e.action.wpStart.repeat; - - // Xinef: ensure that SMART_ESCORT_TARGETS contains at least one player reference - bool stored = false; - ObjectList* targets = GetTargets(e, unit); - if (targets) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsPlayer(*itr)) { - if (IsPlayer(*itr)) - { - stored = true; - StoreTargetList(targets, SMART_ESCORT_TARGETS); - break; - } + stored = true; + StoreTargetList(targets, SMART_ESCORT_TARGETS); + break; } - if (!stored) - delete targets; } + if (!stored) + delete targets; + } - me->SetReactState((ReactStates)e.action.wpStart.reactState); - CAST_AI(SmartAI, me->AI())->StartPath(run, entry, repeat, unit); + me->SetReactState((ReactStates)e.action.wpStart.reactState); + CAST_AI(SmartAI, me->AI())->StartPath(run, entry, repeat, unit); - uint32 quest = e.action.wpStart.quest; - uint32 DespawnTime = e.action.wpStart.despawnTime; - CAST_AI(SmartAI, me->AI())->mEscortQuestID = quest; - CAST_AI(SmartAI, me->AI())->SetDespawnTime(DespawnTime); + uint32 quest = e.action.wpStart.quest; + uint32 DespawnTime = e.action.wpStart.despawnTime; + CAST_AI(SmartAI, me->AI())->mEscortQuestID = quest; + CAST_AI(SmartAI, me->AI())->SetDespawnTime(DespawnTime); + break; + } + case SMART_ACTION_WP_PAUSE: + { + if (!IsSmart()) break; - } - case SMART_ACTION_WP_PAUSE: - { - if (!IsSmart()) - break; - uint32 delay = e.action.wpPause.delay; - CAST_AI(SmartAI, me->AI())->PausePath(delay, e.GetEventType() == SMART_EVENT_WAYPOINT_REACHED ? false : true); + uint32 delay = e.action.wpPause.delay; + CAST_AI(SmartAI, me->AI())->PausePath(delay, e.GetEventType() == SMART_EVENT_WAYPOINT_REACHED ? false : true); + break; + } + case SMART_ACTION_WP_STOP: + { + if (!IsSmart()) break; - } - case SMART_ACTION_WP_STOP: - { - if (!IsSmart()) - break; - uint32 DespawnTime = e.action.wpStop.despawnTime; - uint32 quest = e.action.wpStop.quest; - bool fail = e.action.wpStop.fail; - CAST_AI(SmartAI, me->AI())->StopPath(DespawnTime, quest, fail); + uint32 DespawnTime = e.action.wpStop.despawnTime; + uint32 quest = e.action.wpStop.quest; + bool fail = e.action.wpStop.fail; + CAST_AI(SmartAI, me->AI())->StopPath(DespawnTime, quest, fail); + break; + } + case SMART_ACTION_WP_RESUME: + { + if (!IsSmart()) break; - } - case SMART_ACTION_WP_RESUME: - { - if (!IsSmart()) - break; - CAST_AI(SmartAI, me->AI())->SetWPPauseTimer(0); + CAST_AI(SmartAI, me->AI())->SetWPPauseTimer(0); + break; + } + case SMART_ACTION_SET_ORIENTATION: + { + if (!me) break; + + if (e.GetTargetType() == SMART_TARGET_SELF) + { + me->SetFacingTo((me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && me->GetTransGUID() ? me->GetTransportHomePosition() : me->GetHomePosition()).GetOrientation()); + if (e.action.orientation.quickChange) + me->SetOrientation((me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && me->GetTransGUID() ? me->GetTransportHomePosition() : me->GetHomePosition()).GetOrientation()); } - case SMART_ACTION_SET_ORIENTATION: + else if (e.GetTargetType() == SMART_TARGET_POSITION) { - if (!me) - break; - - if (e.GetTargetType() == SMART_TARGET_SELF) - { - me->SetFacingTo((me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && me->GetTransGUID() ? me->GetTransportHomePosition() : me->GetHomePosition()).GetOrientation()); - if (e.action.orientation.quickChange) - me->SetOrientation((me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && me->GetTransGUID() ? me->GetTransportHomePosition() : me->GetHomePosition()).GetOrientation()); - } - else if (e.GetTargetType() == SMART_TARGET_POSITION) + me->SetFacingTo(e.target.o); + if (e.action.orientation.quickChange) + me->SetOrientation(e.target.o); + } + else if (ObjectList* targets = GetTargets(e, unit)) + { + if (!targets->empty()) { - me->SetFacingTo(e.target.o); + me->SetFacingToObject(*targets->begin()); if (e.action.orientation.quickChange) - me->SetOrientation(e.target.o); + me->SetInFront(*targets->begin()); } - else if (ObjectList* targets = GetTargets(e, unit)) - { - if (!targets->empty()) - { - me->SetFacingToObject(*targets->begin()); - if (e.action.orientation.quickChange) - me->SetInFront(*targets->begin()); - } - delete targets; - } + delete targets; + } + break; + } + case SMART_ACTION_PLAYMOVIE: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_PLAYMOVIE: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - { - if (!IsPlayer(*itr)) - continue; + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (!IsPlayer(*itr)) + continue; - (*itr)->ToPlayer()->SendMovieStart(e.action.movie.entry); - } + (*itr)->ToPlayer()->SendMovieStart(e.action.movie.entry); + } - delete targets; + delete targets; + break; + } + case SMART_ACTION_MOVE_TO_POS: + { + if (!IsSmart()) break; - } - case SMART_ACTION_MOVE_TO_POS: - { - if (!IsSmart()) - break; - WorldObject* target = NULL; + WorldObject* target = NULL; - /*if (e.GetTargetType() == SMART_TARGET_CREATURE_RANGE || e.GetTargetType() == SMART_TARGET_CREATURE_GUID || - e.GetTargetType() == SMART_TARGET_CREATURE_DISTANCE || e.GetTargetType() == SMART_TARGET_GAMEOBJECT_RANGE || - e.GetTargetType() == SMART_TARGET_GAMEOBJECT_GUID || e.GetTargetType() == SMART_TARGET_GAMEOBJECT_DISTANCE || - e.GetTargetType() == SMART_TARGET_CLOSEST_CREATURE || e.GetTargetType() == SMART_TARGET_CLOSEST_GAMEOBJECT || - e.GetTargetType() == SMART_TARGET_OWNER_OR_SUMMONER || e.GetTargetType() == SMART_TARGET_ACTION_INVOKER || - e.GetTargetType() == SMART_TARGET_CLOSEST_ENEMY || e.GetTargetType() == SMART_TARGET_CLOSEST_FRIENDLY || - e.GetTargetType() == SMART_TARGET_SELF || e.GetTargetType() == SMART_TARGET_STORED) // Xinef: bieda i rozpierdol TC)*/ + /*if (e.GetTargetType() == SMART_TARGET_CREATURE_RANGE || e.GetTargetType() == SMART_TARGET_CREATURE_GUID || + e.GetTargetType() == SMART_TARGET_CREATURE_DISTANCE || e.GetTargetType() == SMART_TARGET_GAMEOBJECT_RANGE || + e.GetTargetType() == SMART_TARGET_GAMEOBJECT_GUID || e.GetTargetType() == SMART_TARGET_GAMEOBJECT_DISTANCE || + e.GetTargetType() == SMART_TARGET_CLOSEST_CREATURE || e.GetTargetType() == SMART_TARGET_CLOSEST_GAMEOBJECT || + e.GetTargetType() == SMART_TARGET_OWNER_OR_SUMMONER || e.GetTargetType() == SMART_TARGET_ACTION_INVOKER || + e.GetTargetType() == SMART_TARGET_CLOSEST_ENEMY || e.GetTargetType() == SMART_TARGET_CLOSEST_FRIENDLY || + e.GetTargetType() == SMART_TARGET_SELF || e.GetTargetType() == SMART_TARGET_STORED) // Xinef: bieda i rozpierdol TC)*/ + { + if (ObjectList* targets = GetTargets(e, unit)) { - if (ObjectList* targets = GetTargets(e, unit)) - { - // xinef: we want to move to random element - target = Trinity::Containers::SelectRandomContainerElement(*targets); - delete targets; - } + // xinef: we want to move to random element + target = Trinity::Containers::SelectRandomContainerElement(*targets); + delete targets; } + } - if (!target) - { - G3D::Vector3 dest(e.target.x, e.target.y, e.target.z); - if (e.action.MoveToPos.transport) - if (TransportBase* trans = me->GetDirectTransport()) - trans->CalculatePassengerPosition(dest.x, dest.y, dest.z); - - me->GetMotionMaster()->MovePoint(e.action.MoveToPos.pointId, dest.x, dest.y, dest.z, true, true, e.action.MoveToPos.controlled ? MOTION_SLOT_CONTROLLED : MOTION_SLOT_ACTIVE); - } - else // Xinef: we can use dest.x, dest.y, dest.z to make offset :) - me->GetMotionMaster()->MovePoint(e.action.MoveToPos.pointId, target->GetPositionX()+e.target.x, target->GetPositionY()+e.target.y, target->GetPositionZ()+e.target.z, true, true, e.action.MoveToPos.controlled ? MOTION_SLOT_CONTROLLED : MOTION_SLOT_ACTIVE); + if (!target) + { + G3D::Vector3 dest(e.target.x, e.target.y, e.target.z); + if (e.action.MoveToPos.transport) + if (TransportBase* trans = me->GetDirectTransport()) + trans->CalculatePassengerPosition(dest.x, dest.y, dest.z); - break; + me->GetMotionMaster()->MovePoint(e.action.MoveToPos.pointId, dest.x, dest.y, dest.z, true, true, e.action.MoveToPos.controlled ? MOTION_SLOT_CONTROLLED : MOTION_SLOT_ACTIVE); } - case SMART_ACTION_MOVE_TO_POS_TARGET: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - return; + else // Xinef: we can use dest.x, dest.y, dest.z to make offset :) + me->GetMotionMaster()->MovePoint(e.action.MoveToPos.pointId, target->GetPositionX() + e.target.x, target->GetPositionY() + e.target.y, target->GetPositionZ() + e.target.z, true, true, e.action.MoveToPos.controlled ? MOTION_SLOT_CONTROLLED : MOTION_SLOT_ACTIVE); - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + break; + } + case SMART_ACTION_MOVE_TO_POS_TARGET: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) + return; + + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (IsCreature(*itr)) { - if (IsCreature(*itr)) - { - Creature* target = (*itr)->ToCreature(); - target->GetMotionMaster()->MovePoint(e.action.MoveToPos.pointId, e.target.x, e.target.y , e.target.z, true, true, e.action.MoveToPos.controlled ? MOTION_SLOT_CONTROLLED : MOTION_SLOT_ACTIVE); - } + Creature* target = (*itr)->ToCreature(); + target->GetMotionMaster()->MovePoint(e.action.MoveToPos.pointId, e.target.x, e.target.y, e.target.z, true, true, e.action.MoveToPos.controlled ? MOTION_SLOT_CONTROLLED : MOTION_SLOT_ACTIVE); } + } - delete targets; + delete targets; + break; + } + case SMART_ACTION_RESPAWN_TARGET: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_RESPAWN_TARGET: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (IsCreature(*itr)) + (*itr)->ToCreature()->Respawn(e.action.RespawnTarget.goRespawnTime); + else if (IsGameObject(*itr)) { - if (IsCreature(*itr)) - (*itr)->ToCreature()->Respawn(e.action.RespawnTarget.goRespawnTime); - else if (IsGameObject(*itr)) - { - // Xinef: do not modify respawndelay of already spawned gameobjects QQ - if ((*itr)->ToGameObject()->isSpawnedByDefault()) - (*itr)->ToGameObject()->Respawn(); - else - (*itr)->ToGameObject()->SetRespawnTime(e.action.RespawnTarget.goRespawnTime); - } + // Xinef: do not modify respawndelay of already spawned gameobjects QQ + if ((*itr)->ToGameObject()->isSpawnedByDefault()) + (*itr)->ToGameObject()->Respawn(); + else + (*itr)->ToGameObject()->SetRespawnTime(e.action.RespawnTarget.goRespawnTime); } + } - delete targets; + delete targets; + break; + } + case SMART_ACTION_CLOSE_GOSSIP: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_CLOSE_GOSSIP: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsPlayer(*itr)) - (*itr)->ToPlayer()->PlayerTalkClass->SendCloseGossip(); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsPlayer(*itr)) + (*itr)->ToPlayer()->PlayerTalkClass->SendCloseGossip(); - delete targets; + delete targets; + break; + } + case SMART_ACTION_EQUIP: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_EQUIP: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (Creature* npc = (*itr)->ToCreature()) { - if (Creature* npc = (*itr)->ToCreature()) + uint32 slot[3]; + int8 equipId = (int8)e.action.equip.entry; + if (equipId) { - uint32 slot[3]; - int8 equipId = (int8)e.action.equip.entry; - if (equipId) + EquipmentInfo const* einfo = sObjectMgr->GetEquipmentInfo(npc->GetEntry(), equipId); + if (!einfo) { - EquipmentInfo const* einfo = sObjectMgr->GetEquipmentInfo(npc->GetEntry(), equipId); - if (!einfo) - { - sLog->outError("SmartScript: SMART_ACTION_EQUIP uses non-existent equipment info id %u for creature %u", equipId, npc->GetEntry()); - break; - } - npc->SetCurrentEquipmentId(equipId); - slot[0] = einfo->ItemEntry[0]; - slot[1] = einfo->ItemEntry[1]; - slot[2] = einfo->ItemEntry[2]; - } - else - { - slot[0] = e.action.equip.slot1; - slot[1] = e.action.equip.slot2; - slot[2] = e.action.equip.slot3; + sLog->outError("SmartScript: SMART_ACTION_EQUIP uses non-existent equipment info id %u for creature %u", equipId, npc->GetEntry()); + break; } - if (!e.action.equip.mask || (e.action.equip.mask & 1)) - npc->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, slot[0]); - if (!e.action.equip.mask || (e.action.equip.mask & 2)) - npc->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, slot[1]); - if (!e.action.equip.mask || (e.action.equip.mask & 4)) - npc->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, slot[2]); + npc->SetCurrentEquipmentId(equipId); + slot[0] = einfo->ItemEntry[0]; + slot[1] = einfo->ItemEntry[1]; + slot[2] = einfo->ItemEntry[2]; } + else + { + slot[0] = e.action.equip.slot1; + slot[1] = e.action.equip.slot2; + slot[2] = e.action.equip.slot3; + } + if (!e.action.equip.mask || (e.action.equip.mask & 1)) + npc->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, slot[0]); + if (!e.action.equip.mask || (e.action.equip.mask & 2)) + npc->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, slot[1]); + if (!e.action.equip.mask || (e.action.equip.mask & 4)) + npc->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, slot[2]); } + } - delete targets; + delete targets; + break; + } + case SMART_ACTION_CREATE_TIMED_EVENT: + { + SmartEvent ne = SmartEvent(); + ne.type = (SMART_EVENT)SMART_EVENT_UPDATE; + ne.event_chance = e.action.timeEvent.chance; + if (!ne.event_chance) ne.event_chance = 100; + + ne.minMaxRepeat.min = e.action.timeEvent.min; + ne.minMaxRepeat.max = e.action.timeEvent.max; + ne.minMaxRepeat.repeatMin = e.action.timeEvent.repeatMin; + ne.minMaxRepeat.repeatMax = e.action.timeEvent.repeatMax; + + ne.event_flags = 0; + if (!ne.minMaxRepeat.repeatMin && !ne.minMaxRepeat.repeatMax) + ne.event_flags |= SMART_EVENT_FLAG_NOT_REPEATABLE; + + SmartAction ac = SmartAction(); + ac.type = (SMART_ACTION)SMART_ACTION_TRIGGER_TIMED_EVENT; + ac.timeEvent.id = e.action.timeEvent.id; + + SmartScriptHolder ev = SmartScriptHolder(); + ev.event = ne; + ev.event_id = e.action.timeEvent.id; + ev.target = e.target; + ev.action = ac; + InitTimer(ev); + mStoredEvents.push_back(ev); + break; + } + case SMART_ACTION_TRIGGER_TIMED_EVENT: + ProcessEventsFor((SMART_EVENT)SMART_EVENT_TIMED_EVENT_TRIGGERED, NULL, e.action.timeEvent.id); + + // xinef: remove this event if not repeatable + if (e.event.event_flags & SMART_EVENT_FLAG_NOT_REPEATABLE) + mRemIDs.push_back(e.action.timeEvent.id); + break; + case SMART_ACTION_REMOVE_TIMED_EVENT: + mRemIDs.push_back(e.action.timeEvent.id); + break; + case SMART_ACTION_OVERRIDE_SCRIPT_BASE_OBJECT: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_CREATE_TIMED_EVENT: + + for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr) { - SmartEvent ne = SmartEvent(); - ne.type = (SMART_EVENT)SMART_EVENT_UPDATE; - ne.event_chance = e.action.timeEvent.chance; - if (!ne.event_chance) ne.event_chance = 100; + if (IsCreature(*itr)) + { + if (!meOrigGUID) + meOrigGUID = me ? me->GetGUID() : 0; + if (!goOrigGUID) + goOrigGUID = go ? go->GetGUID() : 0; + go = NULL; + me = (*itr)->ToCreature(); + break; + } + else if (IsGameObject(*itr)) + { + if (!meOrigGUID) + meOrigGUID = me ? me->GetGUID() : 0; + if (!goOrigGUID) + goOrigGUID = go ? go->GetGUID() : 0; + go = (*itr)->ToGameObject(); + me = NULL; + break; + } + } - ne.minMaxRepeat.min = e.action.timeEvent.min; - ne.minMaxRepeat.max = e.action.timeEvent.max; - ne.minMaxRepeat.repeatMin = e.action.timeEvent.repeatMin; - ne.minMaxRepeat.repeatMax = e.action.timeEvent.repeatMax; + delete targets; + break; + } + case SMART_ACTION_RESET_SCRIPT_BASE_OBJECT: + ResetBaseObject(); + break; + case SMART_ACTION_CALL_SCRIPT_RESET: + OnReset(); + break; + case SMART_ACTION_SET_RANGED_MOVEMENT: + { + if (!IsSmart()) + break; - ne.event_flags = 0; - if (!ne.minMaxRepeat.repeatMin && !ne.minMaxRepeat.repeatMax) - ne.event_flags |= SMART_EVENT_FLAG_NOT_REPEATABLE; + float attackDistance = float(e.action.setRangedMovement.distance); + float attackAngle = float(e.action.setRangedMovement.angle) / 180.0f * M_PI; - SmartAction ac = SmartAction(); - ac.type = (SMART_ACTION)SMART_ACTION_TRIGGER_TIMED_EVENT; - ac.timeEvent.id = e.action.timeEvent.id; + ObjectList* targets = GetTargets(e, unit); + if (targets) + { + for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (Creature* target = (*itr)->ToCreature()) + if (IsSmart(target) && target->GetVictim()) + if (CAST_AI(SmartAI, target->AI())->CanCombatMove()) + target->GetMotionMaster()->MoveChase(target->GetVictim(), attackDistance, attackAngle); - SmartScriptHolder ev = SmartScriptHolder(); - ev.event = ne; - ev.event_id = e.action.timeEvent.id; - ev.target = e.target; - ev.action = ac; - InitTimer(ev); - mStoredEvents.push_back(ev); + delete targets; + } + break; + } + case SMART_ACTION_CALL_TIMED_ACTIONLIST: + { + if (e.GetTargetType() == SMART_TARGET_NONE) + { + sLog->outErrorDb("SmartScript: Entry %d SourceType %u Event %u Action %u is using TARGET_NONE(0) for Script9 target. Please correct target_type in database.", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType()); break; } - case SMART_ACTION_TRIGGER_TIMED_EVENT: - ProcessEventsFor((SMART_EVENT)SMART_EVENT_TIMED_EVENT_TRIGGERED, NULL, e.action.timeEvent.id); - // xinef: remove this event if not repeatable - if (e.event.event_flags & SMART_EVENT_FLAG_NOT_REPEATABLE) - mRemIDs.push_back(e.action.timeEvent.id); - break; - case SMART_ACTION_REMOVE_TIMED_EVENT: - mRemIDs.push_back(e.action.timeEvent.id); - break; - case SMART_ACTION_OVERRIDE_SCRIPT_BASE_OBJECT: + if (ObjectList* targets = GetTargets(e, unit)) { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr) { - if (IsCreature(*itr)) + if (Creature* target = (*itr)->ToCreature()) { - if (!meOrigGUID) - meOrigGUID = me ? me->GetGUID() : 0; - if (!goOrigGUID) - goOrigGUID = go ? go->GetGUID() : 0; - go = NULL; - me = (*itr)->ToCreature(); - break; + if (IsSmart(target)) + CAST_AI(SmartAI, target->AI())->SetScript9(e, e.action.timedActionList.id, GetLastInvoker()); } - else if (IsGameObject(*itr)) + else if (GameObject* goTarget = (*itr)->ToGameObject()) { - if (!meOrigGUID) - meOrigGUID = me ? me->GetGUID() : 0; - if (!goOrigGUID) - goOrigGUID = go ? go->GetGUID() : 0; - go = (*itr)->ToGameObject(); - me = NULL; - break; + if (IsSmartGO(goTarget)) + CAST_AI(SmartGameObjectAI, goTarget->AI())->SetScript9(e, e.action.timedActionList.id, GetLastInvoker()); } } delete targets; - break; } - case SMART_ACTION_RESET_SCRIPT_BASE_OBJECT: - ResetBaseObject(); - break; - case SMART_ACTION_CALL_SCRIPT_RESET: - OnReset(); + break; + } + case SMART_ACTION_SET_NPC_FLAG: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - case SMART_ACTION_SET_RANGED_MOVEMENT: - { - if (!IsSmart()) - break; - - float attackDistance = float(e.action.setRangedMovement.distance); - float attackAngle = float(e.action.setRangedMovement.angle) / 180.0f * M_PI; - ObjectList* targets = GetTargets(e, unit); - if (targets) - { - for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (Creature* target = (*itr)->ToCreature()) - if (IsSmart(target) && target->GetVictim()) - if (CAST_AI(SmartAI, target->AI())->CanCombatMove()) - target->GetMotionMaster()->MoveChase(target->GetVictim(), attackDistance, attackAngle); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsCreature(*itr)) + (*itr)->ToUnit()->SetUInt32Value(UNIT_NPC_FLAGS, e.action.unitFlag.flag); - delete targets; - } + delete targets; + break; + } + case SMART_ACTION_ADD_NPC_FLAG: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_CALL_TIMED_ACTIONLIST: - { - if (e.GetTargetType() == SMART_TARGET_NONE) - { - sLog->outErrorDb("SmartScript: Entry %d SourceType %u Event %u Action %u is using TARGET_NONE(0) for Script9 target. Please correct target_type in database.", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType()); - break; - } - if (ObjectList* targets = GetTargets(e, unit)) - { - for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr) - { - if (Creature* target = (*itr)->ToCreature()) - { - if (IsSmart(target)) - CAST_AI(SmartAI, target->AI())->SetScript9(e, e.action.timedActionList.id, GetLastInvoker()); - } - else if (GameObject* goTarget = (*itr)->ToGameObject()) - { - if (IsSmartGO(goTarget)) - CAST_AI(SmartGameObjectAI, goTarget->AI())->SetScript9(e, e.action.timedActionList.id, GetLastInvoker()); - } - } + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsCreature(*itr)) + (*itr)->ToUnit()->SetFlag(UNIT_NPC_FLAGS, e.action.unitFlag.flag); - delete targets; - } + delete targets; + break; + } + case SMART_ACTION_REMOVE_NPC_FLAG: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_SET_NPC_FLAG: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsCreature(*itr)) - (*itr)->ToUnit()->SetUInt32Value(UNIT_NPC_FLAGS, e.action.unitFlag.flag); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsCreature(*itr)) + (*itr)->ToUnit()->RemoveFlag(UNIT_NPC_FLAGS, e.action.unitFlag.flag); - delete targets; + delete targets; + break; + } + case SMART_ACTION_CROSS_CAST: + { + ObjectList* casters = GetTargets(CreateEvent(SMART_EVENT_UPDATE_IC, 0, 0, 0, 0, 0, SMART_ACTION_NONE, 0, 0, 0, 0, 0, 0, (SMARTAI_TARGETS)e.action.crossCast.targetType, e.action.crossCast.targetParam1, e.action.crossCast.targetParam2, e.action.crossCast.targetParam3, 0), unit); + if (!casters) break; - } - case SMART_ACTION_ADD_NPC_FLAG: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsCreature(*itr)) - (*itr)->ToUnit()->SetFlag(UNIT_NPC_FLAGS, e.action.unitFlag.flag); - delete targets; - break; - } - case SMART_ACTION_REMOVE_NPC_FLAG: + ObjectList* targets = GetTargets(e, unit); + if (!targets) { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsCreature(*itr)) - (*itr)->ToUnit()->RemoveFlag(UNIT_NPC_FLAGS, e.action.unitFlag.flag); - - delete targets; + delete casters; // casters already validated, delete now break; } - case SMART_ACTION_CROSS_CAST: + + for (ObjectList::const_iterator itr = casters->begin(); itr != casters->end(); ++itr) { - ObjectList* casters = GetTargets(CreateEvent(SMART_EVENT_UPDATE_IC, 0, 0, 0, 0, 0, SMART_ACTION_NONE, 0, 0, 0, 0, 0, 0, (SMARTAI_TARGETS)e.action.crossCast.targetType, e.action.crossCast.targetParam1, e.action.crossCast.targetParam2, e.action.crossCast.targetParam3, 0), unit); - if (!casters) - break; + if (!IsUnit(*itr)) + continue; - ObjectList* targets = GetTargets(e, unit); - if (!targets) - { - delete casters; // casters already validated, delete now - break; - } + bool interruptedSpell = false; - for (ObjectList::const_iterator itr = casters->begin(); itr != casters->end(); ++itr) + for (ObjectList::const_iterator it = targets->begin(); it != targets->end(); ++it) { - if (!IsUnit(*itr)) + if (!IsUnit(*it)) continue; - bool interruptedSpell = false; - - for (ObjectList::const_iterator it = targets->begin(); it != targets->end(); ++it) + if (!(e.action.cast.flags & SMARTCAST_AURA_NOT_PRESENT) || !(*it)->ToUnit()->HasAura(e.action.cast.spell)) { - if (!IsUnit(*it)) - continue; - - if (!(e.action.cast.flags & SMARTCAST_AURA_NOT_PRESENT) || !(*it)->ToUnit()->HasAura(e.action.cast.spell)) + if (!interruptedSpell && e.action.cast.flags & SMARTCAST_INTERRUPT_PREVIOUS) { - if (!interruptedSpell && e.action.cast.flags & SMARTCAST_INTERRUPT_PREVIOUS) - { - (*itr)->ToUnit()->InterruptNonMeleeSpells(false); - interruptedSpell = true; - } - - (*itr)->ToUnit()->CastSpell((*it)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED)); + (*itr)->ToUnit()->InterruptNonMeleeSpells(false); + interruptedSpell = true; } - //else - // TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "Spell %u not casted because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (Guid: " UI64FMTD " Entry: %u Type: %u) already has the aura", e.action.cast.spell, (*it)->GetGUID(), (*it)->GetEntry(), uint32((*it)->GetTypeId())); + + (*itr)->ToUnit()->CastSpell((*it)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED)); } + //else + // TC_LOG_DEBUG(LOG_FILTER_DATABASE_AI, "Spell %u not casted because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (Guid: " UI64FMTD " Entry: %u Type: %u) already has the aura", e.action.cast.spell, (*it)->GetGUID(), (*it)->GetEntry(), uint32((*it)->GetTypeId())); } + } - delete targets; - delete casters; + delete targets; + delete casters; + break; + } + case SMART_ACTION_CALL_RANDOM_TIMED_ACTIONLIST: + { + uint32 actions[SMART_ACTION_PARAM_COUNT]; + actions[0] = e.action.randTimedActionList.entry1; + actions[1] = e.action.randTimedActionList.entry2; + actions[2] = e.action.randTimedActionList.entry3; + actions[3] = e.action.randTimedActionList.entry4; + actions[4] = e.action.randTimedActionList.entry5; + actions[5] = e.action.randTimedActionList.entry6; + uint32 temp[SMART_ACTION_PARAM_COUNT]; + uint32 count = 0; + for (uint8 i = 0; i < SMART_ACTION_PARAM_COUNT; i++) + { + if (actions[i] > 0) + { + temp[count] = actions[i]; + ++count; + } + } + + if (count == 0) + break; + + uint32 id = temp[urand(0, count - 1)]; + if (e.GetTargetType() == SMART_TARGET_NONE) + { + sLog->outErrorDb("SmartScript: Entry %d SourceType %u Event %u Action %u is using TARGET_NONE(0) for Script9 target. Please correct target_type in database.", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType()); break; } - case SMART_ACTION_CALL_RANDOM_TIMED_ACTIONLIST: + + ObjectList* targets = GetTargets(e, unit); + if (targets) { - uint32 actions[SMART_ACTION_PARAM_COUNT]; - actions[0] = e.action.randTimedActionList.entry1; - actions[1] = e.action.randTimedActionList.entry2; - actions[2] = e.action.randTimedActionList.entry3; - actions[3] = e.action.randTimedActionList.entry4; - actions[4] = e.action.randTimedActionList.entry5; - actions[5] = e.action.randTimedActionList.entry6; - uint32 temp[SMART_ACTION_PARAM_COUNT]; - uint32 count = 0; - for (uint8 i = 0; i < SMART_ACTION_PARAM_COUNT; i++) + for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr) { - if (actions[i] > 0) + if (Creature* target = (*itr)->ToCreature()) { - temp[count] = actions[i]; - ++count; + if (IsSmart(target)) + CAST_AI(SmartAI, target->AI())->SetScript9(e, id, GetLastInvoker()); } - } - - if (count == 0) - break; - - uint32 id = temp[urand(0, count - 1)]; - if (e.GetTargetType() == SMART_TARGET_NONE) - { - sLog->outErrorDb("SmartScript: Entry %d SourceType %u Event %u Action %u is using TARGET_NONE(0) for Script9 target. Please correct target_type in database.", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType()); - break; - } - - ObjectList* targets = GetTargets(e, unit); - if (targets) - { - for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr) + else if (GameObject* goTarget = (*itr)->ToGameObject()) { - if (Creature* target = (*itr)->ToCreature()) - { - if (IsSmart(target)) - CAST_AI(SmartAI, target->AI())->SetScript9(e, id, GetLastInvoker()); - } - else if (GameObject* goTarget = (*itr)->ToGameObject()) - { - if (IsSmartGO(goTarget)) - CAST_AI(SmartGameObjectAI, goTarget->AI())->SetScript9(e, id, GetLastInvoker()); - } + if (IsSmartGO(goTarget)) + CAST_AI(SmartGameObjectAI, goTarget->AI())->SetScript9(e, id, GetLastInvoker()); } - - delete targets; } - break; + + delete targets; } - case SMART_ACTION_CALL_RANDOM_RANGE_TIMED_ACTIONLIST: + break; + } + case SMART_ACTION_CALL_RANDOM_RANGE_TIMED_ACTIONLIST: + { + uint32 id = urand(e.action.randTimedActionList.entry1, e.action.randTimedActionList.entry2); + if (e.GetTargetType() == SMART_TARGET_NONE) { - uint32 id = urand(e.action.randTimedActionList.entry1, e.action.randTimedActionList.entry2); - if (e.GetTargetType() == SMART_TARGET_NONE) - { - sLog->outErrorDb("SmartScript: Entry %d SourceType %u Event %u Action %u is using TARGET_NONE(0) for Script9 target. Please correct target_type in database.", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType()); - break; - } + sLog->outErrorDb("SmartScript: Entry %d SourceType %u Event %u Action %u is using TARGET_NONE(0) for Script9 target. Please correct target_type in database.", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType()); + break; + } - ObjectList* targets = GetTargets(e, unit); - if (targets) + ObjectList* targets = GetTargets(e, unit); + if (targets) + { + for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr) { - for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (Creature* target = (*itr)->ToCreature()) { - if (Creature* target = (*itr)->ToCreature()) - { - if (IsSmart(target)) - CAST_AI(SmartAI, target->AI())->SetScript9(e, id, GetLastInvoker()); - } - else if (GameObject* goTarget = (*itr)->ToGameObject()) - { - if (IsSmartGO(goTarget)) - CAST_AI(SmartGameObjectAI, goTarget->AI())->SetScript9(e, id, GetLastInvoker()); - } + if (IsSmart(target)) + CAST_AI(SmartAI, target->AI())->SetScript9(e, id, GetLastInvoker()); + } + else if (GameObject* goTarget = (*itr)->ToGameObject()) + { + if (IsSmartGO(goTarget)) + CAST_AI(SmartGameObjectAI, goTarget->AI())->SetScript9(e, id, GetLastInvoker()); } - - delete targets; } - break; - } - case SMART_ACTION_ACTIVATE_TAXI: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsPlayer(*itr)) - (*itr)->ToPlayer()->ActivateTaxiPathTo(e.action.taxi.id); delete targets; - break; } - case SMART_ACTION_RANDOM_MOVE: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; + break; + } + case SMART_ACTION_ACTIVATE_TAXI: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) + break; - bool foundTarget = false; + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsPlayer(*itr)) + (*itr)->ToPlayer()->ActivateTaxiPathTo(e.action.taxi.id); - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - { - if (IsCreature((*itr))) - { - foundTarget = true; + delete targets; + break; + } + case SMART_ACTION_RANDOM_MOVE: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) + break; - if (e.action.moveRandom.distance) - (*itr)->ToCreature()->GetMotionMaster()->MoveRandom((float)e.action.moveRandom.distance); - else - (*itr)->ToCreature()->GetMotionMaster()->MoveIdle(); - } - } + bool foundTarget = false; - if (!foundTarget && me && IsCreature(me)) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + { + if (IsCreature((*itr))) { + foundTarget = true; + if (e.action.moveRandom.distance) - me->GetMotionMaster()->MoveRandom((float)e.action.moveRandom.distance); + (*itr)->ToCreature()->GetMotionMaster()->MoveRandom((float)e.action.moveRandom.distance); else - me->GetMotionMaster()->MoveIdle(); + (*itr)->ToCreature()->GetMotionMaster()->MoveIdle(); } - - delete targets; - break; } - case SMART_ACTION_SET_UNIT_FIELD_BYTES_1: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsUnit(*itr)) - (*itr)->ToUnit()->SetByteFlag(UNIT_FIELD_BYTES_1, e.action.setunitByte.type, e.action.setunitByte.byte1); - delete targets; - break; - } - case SMART_ACTION_REMOVE_UNIT_FIELD_BYTES_1: + if (!foundTarget && me && IsCreature(me)) { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsUnit(*itr)) - (*itr)->ToUnit()->RemoveByteFlag(UNIT_FIELD_BYTES_1, e.action.delunitByte.type, e.action.delunitByte.byte1); - - delete targets; - break; + if (e.action.moveRandom.distance) + me->GetMotionMaster()->MoveRandom((float)e.action.moveRandom.distance); + else + me->GetMotionMaster()->MoveIdle(); } - case SMART_ACTION_INTERRUPT_SPELL: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsUnit(*itr)) - (*itr)->ToUnit()->InterruptNonMeleeSpells(e.action.interruptSpellCasting.withDelayed, e.action.interruptSpellCasting.spell_id, e.action.interruptSpellCasting.withInstant); + delete targets; + break; + } + case SMART_ACTION_SET_UNIT_FIELD_BYTES_1: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) + break; + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsUnit(*itr)) + (*itr)->ToUnit()->SetByteFlag(UNIT_FIELD_BYTES_1, e.action.setunitByte.type, e.action.setunitByte.byte1); - delete targets; + delete targets; + break; + } + case SMART_ACTION_REMOVE_UNIT_FIELD_BYTES_1: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_SEND_GO_CUSTOM_ANIM: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsGameObject(*itr)) - (*itr)->ToGameObject()->SendCustomAnim(e.action.sendGoCustomAnim.anim); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsUnit(*itr)) + (*itr)->ToUnit()->RemoveByteFlag(UNIT_FIELD_BYTES_1, e.action.delunitByte.type, e.action.delunitByte.byte1); - delete targets; + delete targets; + break; + } + case SMART_ACTION_INTERRUPT_SPELL: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_SET_DYNAMIC_FLAG: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsUnit(*itr)) - (*itr)->ToUnit()->SetUInt32Value(UNIT_DYNAMIC_FLAGS, e.action.unitFlag.flag); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsUnit(*itr)) + (*itr)->ToUnit()->InterruptNonMeleeSpells(e.action.interruptSpellCasting.withDelayed, e.action.interruptSpellCasting.spell_id, e.action.interruptSpellCasting.withInstant); - delete targets; + delete targets; + break; + } + case SMART_ACTION_SEND_GO_CUSTOM_ANIM: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_ADD_DYNAMIC_FLAG: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsUnit(*itr)) - (*itr)->ToUnit()->SetFlag(UNIT_DYNAMIC_FLAGS, e.action.unitFlag.flag); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsGameObject(*itr)) + (*itr)->ToGameObject()->SendCustomAnim(e.action.sendGoCustomAnim.anim); - delete targets; + delete targets; + break; + } + case SMART_ACTION_SET_DYNAMIC_FLAG: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_REMOVE_DYNAMIC_FLAG: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsUnit(*itr)) - (*itr)->ToUnit()->RemoveFlag(UNIT_DYNAMIC_FLAGS, e.action.unitFlag.flag); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsUnit(*itr)) + (*itr)->ToUnit()->SetUInt32Value(UNIT_DYNAMIC_FLAGS, e.action.unitFlag.flag); - delete targets; + delete targets; + break; + } + case SMART_ACTION_ADD_DYNAMIC_FLAG: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_JUMP_TO_POS: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - // xinef: my implementation - if (e.action.jump.selfJump) - { - if (WorldObject* target = Trinity::Containers::SelectRandomContainerElement(*targets)) - if (me) - me->GetMotionMaster()->MoveJump(target->GetPositionX() + e.target.x, target->GetPositionY() + e.target.y, target->GetPositionZ() + e.target.z, (float)e.action.jump.speedxy, (float)e.action.jump.speedz); - } - else - { - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (WorldObject* obj = (*itr)) - { - if (Creature* creature = obj->ToCreature()) - creature->GetMotionMaster()->MoveJump(e.target.x, e.target.y, e.target.z, (float)e.action.jump.speedxy, (float)e.action.jump.speedz); - } - } + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsUnit(*itr)) + (*itr)->ToUnit()->SetFlag(UNIT_DYNAMIC_FLAGS, e.action.unitFlag.flag); - delete targets; + delete targets; + break; + } + case SMART_ACTION_REMOVE_DYNAMIC_FLAG: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_GO_SET_LOOT_STATE: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsGameObject(*itr)) - (*itr)->ToGameObject()->SetLootState((LootState)e.action.setGoLootState.state); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsUnit(*itr)) + (*itr)->ToUnit()->RemoveFlag(UNIT_DYNAMIC_FLAGS, e.action.unitFlag.flag); - delete targets; + delete targets; + break; + } + case SMART_ACTION_JUMP_TO_POS: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; + + // xinef: my implementation + if (e.action.jump.selfJump) + { + if (WorldObject* target = Trinity::Containers::SelectRandomContainerElement(*targets)) + if (me) + me->GetMotionMaster()->MoveJump(target->GetPositionX() + e.target.x, target->GetPositionY() + e.target.y, target->GetPositionZ() + e.target.z, (float)e.action.jump.speedxy, (float)e.action.jump.speedz); } - case SMART_ACTION_SEND_TARGET_TO_TARGET: + else { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - - ObjectList* storedTargets = GetTargetList(e.action.sendTargetToTarget.id); - if (!storedTargets) - { - delete targets; - break; - } - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - { - if (IsCreature(*itr)) + if (WorldObject* obj = (*itr)) { - if (SmartAI* ai = CAST_AI(SmartAI, (*itr)->ToCreature()->AI())) - ai->GetScript()->StoreTargetList(new ObjectList(*storedTargets), e.action.sendTargetToTarget.id); // store a copy of target list - else - sLog->outErrorDb("SmartScript: Action target for SMART_ACTION_SEND_TARGET_TO_TARGET is not using SmartAI, skipping"); - } - else if (IsGameObject(*itr)) - { - if (SmartGameObjectAI* ai = CAST_AI(SmartGameObjectAI, (*itr)->ToGameObject()->AI())) - ai->GetScript()->StoreTargetList(new ObjectList(*storedTargets), e.action.sendTargetToTarget.id); // store a copy of target list - else - sLog->outErrorDb("SmartScript: Action target for SMART_ACTION_SEND_TARGET_TO_TARGET is not using SmartGameObjectAI, skipping"); + if (Creature* creature = obj->ToCreature()) + creature->GetMotionMaster()->MoveJump(e.target.x, e.target.y, e.target.z, (float)e.action.jump.speedxy, (float)e.action.jump.speedz); } - } - - delete targets; - break; } - case SMART_ACTION_SEND_GOSSIP_MENU: - { - if (!GetBaseObject()) - break; -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SEND_GOSSIP_MENU: gossipMenuId %d, gossipNpcTextId %d", - e.action.sendGossipMenu.gossipMenuId, e.action.sendGossipMenu.gossipNpcTextId); -#endif - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; + delete targets; + break; + } + case SMART_ACTION_GO_SET_LOOT_STATE: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) + break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (Player* player = (*itr)->ToPlayer()) - { - if (e.action.sendGossipMenu.gossipMenuId) - player->PrepareGossipMenu(GetBaseObject(), e.action.sendGossipMenu.gossipMenuId, true); - else - player->PlayerTalkClass->ClearMenus(); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsGameObject(*itr)) + (*itr)->ToGameObject()->SetLootState((LootState)e.action.setGoLootState.state); - player->SEND_GOSSIP_MENU(e.action.sendGossipMenu.gossipNpcTextId, GetBaseObject()->GetGUID()); - } + delete targets; + break; + } + case SMART_ACTION_SEND_TARGET_TO_TARGET: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) + break; + ObjectList* storedTargets = GetTargetList(e.action.sendTargetToTarget.id); + if (!storedTargets) + { delete targets; break; } - case SMART_ACTION_SET_HOME_POS: + + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) { - ObjectList* targets = GetTargets(e, unit); - if (targets) + if (IsCreature(*itr)) { - float x, y, z, o; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsCreature(*itr)) - { - if (e.action.setHomePos.spawnPos) - { - (*itr)->ToCreature()->GetRespawnPosition(x, y, z, &o); - (*itr)->ToCreature()->SetHomePosition(x, y, z, o); - } - else - (*itr)->ToCreature()->SetHomePosition((*itr)->GetPositionX(), (*itr)->GetPositionY(), (*itr)->GetPositionZ(), (*itr)->GetOrientation()); - - } - delete targets; + if (SmartAI* ai = CAST_AI(SmartAI, (*itr)->ToCreature()->AI())) + ai->GetScript()->StoreTargetList(new ObjectList(*storedTargets), e.action.sendTargetToTarget.id); // store a copy of target list + else + sLog->outErrorDb("SmartScript: Action target for SMART_ACTION_SEND_TARGET_TO_TARGET is not using SmartAI, skipping"); } - else if (me && e.GetTargetType() == SMART_TARGET_POSITION) + else if (IsGameObject(*itr)) { - if (e.action.setHomePos.spawnPos) - { - float x, y, z, o; - me->GetRespawnPosition(x, y, z, &o); - me->SetHomePosition(x, y, z, o); - } + if (SmartGameObjectAI* ai = CAST_AI(SmartGameObjectAI, (*itr)->ToGameObject()->AI())) + ai->GetScript()->StoreTargetList(new ObjectList(*storedTargets), e.action.sendTargetToTarget.id); // store a copy of target list else - me->SetHomePosition(e.target.x, e.target.y, e.target.z, e.target.o); + sLog->outErrorDb("SmartScript: Action target for SMART_ACTION_SEND_TARGET_TO_TARGET is not using SmartGameObjectAI, skipping"); } - break; } - /*{ - ObjectList* movers = GetTargets(CreateEvent(SMART_EVENT_UPDATE_IC, 0, 0, 0, 0, 0, SMART_ACTION_NONE, 0, 0, 0, 0, 0, 0, (SMARTAI_TARGETS)e.action.sethome.targetType, e.action.sethome.targetParam1, e.action.sethome.targetParam2, e.action.sethome.targetParam3, 0), unit); - if (!movers) - break; - if (e.GetTargetType() == SMART_TARGET_POSITION) - { - for (ObjectList::const_iterator itr = movers->begin(); itr != movers->end(); ++itr) - if (IsCreature(*itr)) - (*itr)->ToCreature()->SetHomePosition(e.target.x, e.target.y, e.target.z, e.target.o); - } - else if (ObjectList* targets = GetTargets(e, unit)) + delete targets; + break; + } + case SMART_ACTION_SEND_GOSSIP_MENU: + { + if (!GetBaseObject()) + break; + +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SEND_GOSSIP_MENU: gossipMenuId %d, gossipNpcTextId %d", + e.action.sendGossipMenu.gossipMenuId, e.action.sendGossipMenu.gossipNpcTextId); +#endif + ObjectList* targets = GetTargets(e, unit); + if (!targets) + break; + + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (Player* player = (*itr)->ToPlayer()) { - if (WorldObject* target = targets->front()) - for (ObjectList::const_iterator itr = movers->begin(); itr != movers->end(); ++itr) - if (IsCreature(*itr)) - (*itr)->ToCreature()->SetHomePosition(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation()); + if (e.action.sendGossipMenu.gossipMenuId) + player->PrepareGossipMenu(GetBaseObject(), e.action.sendGossipMenu.gossipMenuId, true); + else + player->PlayerTalkClass->ClearMenus(); - delete targets; + player->SEND_GOSSIP_MENU(e.action.sendGossipMenu.gossipNpcTextId, GetBaseObject()->GetGUID()); } - delete movers; - break; - }*/ - case SMART_ACTION_SET_HEALTH_REGEN: + delete targets; + break; + } + case SMART_ACTION_SET_HOME_POS: + { + ObjectList* targets = GetTargets(e, unit); + if (targets) { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - + float x, y, z, o; for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) if (IsCreature(*itr)) - (*itr)->ToCreature()->SetRegeneratingHealth(e.action.setHealthRegen.regenHealth); + { + if (e.action.setHomePos.spawnPos) + { + (*itr)->ToCreature()->GetRespawnPosition(x, y, z, &o); + (*itr)->ToCreature()->SetHomePosition(x, y, z, o); + } + else + (*itr)->ToCreature()->SetHomePosition((*itr)->GetPositionX(), (*itr)->GetPositionY(), (*itr)->GetPositionZ(), (*itr)->GetOrientation()); + } delete targets; - break; } - case SMART_ACTION_SET_ROOT: + else if (me && e.GetTargetType() == SMART_TARGET_POSITION) { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; + if (e.action.setHomePos.spawnPos) + { + float x, y, z, o; + me->GetRespawnPosition(x, y, z, &o); + me->SetHomePosition(x, y, z, o); + } + else + me->SetHomePosition(e.target.x, e.target.y, e.target.z, e.target.o); + } + break; + } + /*{ + ObjectList* movers = GetTargets(CreateEvent(SMART_EVENT_UPDATE_IC, 0, 0, 0, 0, 0, SMART_ACTION_NONE, 0, 0, 0, 0, 0, 0, (SMARTAI_TARGETS)e.action.sethome.targetType, e.action.sethome.targetParam1, e.action.sethome.targetParam2, e.action.sethome.targetParam3, 0), unit); + if (!movers) + break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsCreature(*itr)) - (*itr)->ToCreature()->SetControlled(e.action.setRoot.root, UNIT_STATE_ROOT); + if (e.GetTargetType() == SMART_TARGET_POSITION) + { + for (ObjectList::const_iterator itr = movers->begin(); itr != movers->end(); ++itr) + if (IsCreature(*itr)) + (*itr)->ToCreature()->SetHomePosition(e.target.x, e.target.y, e.target.z, e.target.o); + } + else if (ObjectList* targets = GetTargets(e, unit)) + { + if (WorldObject* target = targets->front()) + for (ObjectList::const_iterator itr = movers->begin(); itr != movers->end(); ++itr) + if (IsCreature(*itr)) + (*itr)->ToCreature()->SetHomePosition(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation()); - delete targets; + delete targets; + } + + delete movers; + break; + }*/ + case SMART_ACTION_SET_HEALTH_REGEN: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_SET_GO_FLAG: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsGameObject(*itr)) - (*itr)->ToGameObject()->SetUInt32Value(GAMEOBJECT_FLAGS, e.action.goFlag.flag); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsCreature(*itr)) + (*itr)->ToCreature()->SetRegeneratingHealth(e.action.setHealthRegen.regenHealth); - delete targets; + delete targets; + break; + } + case SMART_ACTION_SET_ROOT: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_ADD_GO_FLAG: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsGameObject(*itr)) - (*itr)->ToGameObject()->SetFlag(GAMEOBJECT_FLAGS, e.action.goFlag.flag); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsCreature(*itr)) + (*itr)->ToCreature()->SetControlled(e.action.setRoot.root, UNIT_STATE_ROOT); - delete targets; + delete targets; + break; + } + case SMART_ACTION_SET_GO_FLAG: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_REMOVE_GO_FLAG: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsGameObject(*itr)) - (*itr)->ToGameObject()->RemoveFlag(GAMEOBJECT_FLAGS, e.action.goFlag.flag); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsGameObject(*itr)) + (*itr)->ToGameObject()->SetUInt32Value(GAMEOBJECT_FLAGS, e.action.goFlag.flag); - delete targets; + delete targets; + break; + } + case SMART_ACTION_ADD_GO_FLAG: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_SUMMON_CREATURE_GROUP: - { - std::list<TempSummon*> summonList; - GetBaseObject()->SummonCreatureGroup(e.action.creatureGroup.group, &summonList); - for (std::list<TempSummon*>::const_iterator itr = summonList.begin(); itr != summonList.end(); ++itr) - { - if (unit && e.action.creatureGroup.attackInvoker) - (*itr)->AI()->AttackStart(unit); - else if (me && e.action.creatureGroup.attackScriptOwner) - (*itr)->AI()->AttackStart(me); - } + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsGameObject(*itr)) + (*itr)->ToGameObject()->SetFlag(GAMEOBJECT_FLAGS, e.action.goFlag.flag); + delete targets; + break; + } + case SMART_ACTION_REMOVE_GO_FLAG: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_SET_POWER: - { - ObjectList* targets = GetTargets(e, unit); - if (targets) - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsUnit(*itr)) - (*itr)->ToUnit()->SetPower(Powers(e.action.power.powerType), e.action.power.newPower); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsGameObject(*itr)) + (*itr)->ToGameObject()->RemoveFlag(GAMEOBJECT_FLAGS, e.action.goFlag.flag); - delete targets; - break; - } - case SMART_ACTION_ADD_POWER: + delete targets; + break; + } + case SMART_ACTION_SUMMON_CREATURE_GROUP: + { + std::list<TempSummon*> summonList; + GetBaseObject()->SummonCreatureGroup(e.action.creatureGroup.group, &summonList); + + for (std::list<TempSummon*>::const_iterator itr = summonList.begin(); itr != summonList.end(); ++itr) { - ObjectList* targets = GetTargets(e, unit); + if (unit && e.action.creatureGroup.attackInvoker) + (*itr)->AI()->AttackStart(unit); + else if (me && e.action.creatureGroup.attackScriptOwner) + (*itr)->AI()->AttackStart(me); + } - if (targets) - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsUnit(*itr)) - (*itr)->ToUnit()->SetPower(Powers(e.action.power.powerType), (*itr)->ToUnit()->GetPower(Powers(e.action.power.powerType)) + e.action.power.newPower); + break; + } + case SMART_ACTION_SET_POWER: + { + ObjectList* targets = GetTargets(e, unit); - delete targets; - break; - } - case SMART_ACTION_REMOVE_POWER: - { - ObjectList* targets = GetTargets(e, unit); + if (targets) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsUnit(*itr)) + (*itr)->ToUnit()->SetPower(Powers(e.action.power.powerType), e.action.power.newPower); - if (targets) - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsUnit(*itr)) - (*itr)->ToUnit()->SetPower(Powers(e.action.power.powerType), (*itr)->ToUnit()->GetPower(Powers(e.action.power.powerType)) - e.action.power.newPower); + delete targets; + break; + } + case SMART_ACTION_ADD_POWER: + { + ObjectList* targets = GetTargets(e, unit); - delete targets; - break; - } - case SMART_ACTION_GAME_EVENT_STOP: + if (targets) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsUnit(*itr)) + (*itr)->ToUnit()->SetPower(Powers(e.action.power.powerType), (*itr)->ToUnit()->GetPower(Powers(e.action.power.powerType)) + e.action.power.newPower); + + delete targets; + break; + } + case SMART_ACTION_REMOVE_POWER: + { + ObjectList* targets = GetTargets(e, unit); + + if (targets) + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsUnit(*itr)) + (*itr)->ToUnit()->SetPower(Powers(e.action.power.powerType), (*itr)->ToUnit()->GetPower(Powers(e.action.power.powerType)) - e.action.power.newPower); + + delete targets; + break; + } + case SMART_ACTION_GAME_EVENT_STOP: + { + uint32 eventId = e.action.gameEventStop.id; + if (!sGameEventMgr->IsActiveEvent(eventId)) { - uint32 eventId = e.action.gameEventStop.id; - if (!sGameEventMgr->IsActiveEvent(eventId)) - { - sLog->outError("SmartScript::ProcessAction: At case SMART_ACTION_GAME_EVENT_STOP, inactive event (id: %u)", eventId); - break; - } - sGameEventMgr->StopEvent(eventId, true); + sLog->outError("SmartScript::ProcessAction: At case SMART_ACTION_GAME_EVENT_STOP, inactive event (id: %u)", eventId); break; } - case SMART_ACTION_GAME_EVENT_START: + sGameEventMgr->StopEvent(eventId, true); + break; + } + case SMART_ACTION_GAME_EVENT_START: + { + uint32 eventId = e.action.gameEventStart.id; + if (sGameEventMgr->IsActiveEvent(eventId)) { - uint32 eventId = e.action.gameEventStart.id; - if (sGameEventMgr->IsActiveEvent(eventId)) - { - sLog->outError("SmartScript::ProcessAction: At case SMART_ACTION_GAME_EVENT_START, already activated event (id: %u)", eventId); - break; - } - sGameEventMgr->StartEvent(eventId, true); + sLog->outError("SmartScript::ProcessAction: At case SMART_ACTION_GAME_EVENT_START, already activated event (id: %u)", eventId); break; } - case SMART_ACTION_START_CLOSEST_WAYPOINT: + sGameEventMgr->StartEvent(eventId, true); + break; + } + case SMART_ACTION_START_CLOSEST_WAYPOINT: + { + uint32 waypoints[SMART_ACTION_PARAM_COUNT]; + waypoints[0] = e.action.closestWaypointFromList.wp1; + waypoints[1] = e.action.closestWaypointFromList.wp2; + waypoints[2] = e.action.closestWaypointFromList.wp3; + waypoints[3] = e.action.closestWaypointFromList.wp4; + waypoints[4] = e.action.closestWaypointFromList.wp5; + waypoints[5] = e.action.closestWaypointFromList.wp6; + float distanceToClosest = std::numeric_limits<float>::max(); + WayPoint* closestWp = NULL; + + ObjectList* targets = GetTargets(e, unit); + if (targets) { - uint32 waypoints[SMART_ACTION_PARAM_COUNT]; - waypoints[0] = e.action.closestWaypointFromList.wp1; - waypoints[1] = e.action.closestWaypointFromList.wp2; - waypoints[2] = e.action.closestWaypointFromList.wp3; - waypoints[3] = e.action.closestWaypointFromList.wp4; - waypoints[4] = e.action.closestWaypointFromList.wp5; - waypoints[5] = e.action.closestWaypointFromList.wp6; - float distanceToClosest = std::numeric_limits<float>::max(); - WayPoint* closestWp = NULL; - - ObjectList* targets = GetTargets(e, unit); - if (targets) + for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr) { - for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (Creature* target = (*itr)->ToCreature()) { - if (Creature* target = (*itr)->ToCreature()) + if (IsSmart(target)) { - if (IsSmart(target)) + for (uint8 i = 0; i < SMART_ACTION_PARAM_COUNT; i++) { - for (uint8 i = 0; i < SMART_ACTION_PARAM_COUNT; i++) - { - if (!waypoints[i]) - continue; + if (!waypoints[i]) + continue; - WPPath* path = sSmartWaypointMgr->GetPath(waypoints[i]); + WPPath* path = sSmartWaypointMgr->GetPath(waypoints[i]); - if (!path || path->empty()) - continue; + if (!path || path->empty()) + continue; - WPPath::const_iterator itrWp = path->find(0); + WPPath::const_iterator itrWp = path->find(0); - if (itrWp != path->end()) + if (itrWp != path->end()) + { + if (WayPoint* wp = itrWp->second) { - if (WayPoint* wp = itrWp->second) - { - float distToThisPath = target->GetDistance(wp->x, wp->y, wp->z); + float distToThisPath = target->GetDistance(wp->x, wp->y, wp->z); - if (distToThisPath < distanceToClosest) - { - distanceToClosest = distToThisPath; - closestWp = wp; - } + if (distToThisPath < distanceToClosest) + { + distanceToClosest = distToThisPath; + closestWp = wp; } } } - - if (closestWp) - CAST_AI(SmartAI, target->AI())->StartPath(false, closestWp->id, true); } + + if (closestWp) + CAST_AI(SmartAI, target->AI())->StartPath(false, closestWp->id, true); } } - - delete targets; } - break; - } - case SMART_ACTION_SET_GO_STATE: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsGameObject(*itr)) - (*itr)->ToGameObject()->SetGoState((GOState)e.action.goState.state); delete targets; - break; } - case SMART_ACTION_EXIT_VEHICLE: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; + break; + } + case SMART_ACTION_SET_GO_STATE: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) + break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsUnit(*itr)) - (*itr)->ToUnit()->ExitVehicle(); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsGameObject(*itr)) + (*itr)->ToGameObject()->SetGoState((GOState)e.action.goState.state); - delete targets; + delete targets; + break; + } + case SMART_ACTION_EXIT_VEHICLE: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_SET_UNIT_MOVEMENT_FLAGS: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsUnit(*itr)) - { - (*itr)->ToUnit()->SetUnitMovementFlags(e.action.movementFlag.flag); - (*itr)->ToUnit()->SendMovementFlagUpdate(); - } + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsUnit(*itr)) + (*itr)->ToUnit()->ExitVehicle(); - delete targets; + delete targets; + break; + } + case SMART_ACTION_SET_UNIT_MOVEMENT_FLAGS: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_SET_COMBAT_DISTANCE: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsCreature(*itr)) - (*itr)->ToCreature()->m_CombatDistance = e.action.combatDistance.dist; + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsUnit(*itr)) + { + (*itr)->ToUnit()->SetUnitMovementFlags(e.action.movementFlag.flag); + (*itr)->ToUnit()->SendMovementFlagUpdate(); + } - delete targets; + delete targets; + break; + } + case SMART_ACTION_SET_COMBAT_DISTANCE: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_SET_CASTER_COMBAT_DIST: - { - if (e.action.casterDistance.reset) - RestoreCasterMaxDist(); - else - SetCasterActualDist(e.action.casterDistance.dist); - if (me->GetVictim() && me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE) - me->GetMotionMaster()->MoveChase(me->GetVictim(), GetCasterActualDist()); - break; - } - case SMART_ACTION_SET_SIGHT_DIST: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsCreature(*itr)) + (*itr)->ToCreature()->m_CombatDistance = e.action.combatDistance.dist; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsCreature(*itr)) - (*itr)->ToCreature()->m_SightDistance = e.action.sightDistance.dist; + delete targets; + break; + } + case SMART_ACTION_SET_CASTER_COMBAT_DIST: + { + if (e.action.casterDistance.reset) + RestoreCasterMaxDist(); + else + SetCasterActualDist(e.action.casterDistance.dist); - delete targets; + if (me->GetVictim() && me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE) + me->GetMotionMaster()->MoveChase(me->GetVictim(), GetCasterActualDist()); + break; + } + case SMART_ACTION_SET_SIGHT_DIST: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_FLEE: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsCreature(*itr)) - (*itr)->ToCreature()->GetMotionMaster()->MoveFleeing(me, e.action.flee.withEmote); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsCreature(*itr)) + (*itr)->ToCreature()->m_SightDistance = e.action.sightDistance.dist; - delete targets; + delete targets; + break; + } + case SMART_ACTION_FLEE: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_ADD_THREAT: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsUnit(*itr)) - me->AddThreat((*itr)->ToUnit(), (float)e.action.threatPCT.threatINC - (float)e.action.threatPCT.threatDEC); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsCreature(*itr)) + (*itr)->ToCreature()->GetMotionMaster()->MoveFleeing(me, e.action.flee.withEmote); - delete targets; + delete targets; + break; + } + case SMART_ACTION_ADD_THREAT: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_LOAD_EQUIPMENT: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsCreature(*itr)) - (*itr)->ToCreature()->LoadEquipment(e.action.loadEquipment.id, e.action.loadEquipment.force); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsUnit(*itr)) + me->AddThreat((*itr)->ToUnit(), (float)e.action.threatPCT.threatINC - (float)e.action.threatPCT.threatDEC); - delete targets; - break; - } - case SMART_ACTION_TRIGGER_RANDOM_TIMED_EVENT: - { - uint32 eventId = urand(e.action.randomTimedEvent.minId, e.action.randomTimedEvent.maxId); - ProcessEventsFor((SMART_EVENT)SMART_EVENT_TIMED_EVENT_TRIGGERED, NULL, eventId); + delete targets; + break; + } + case SMART_ACTION_LOAD_EQUIPMENT: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_SET_HOVER: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsUnit(*itr)) - (*itr)->ToUnit()->SetHover(e.action.setHover.state); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsCreature(*itr)) + (*itr)->ToCreature()->LoadEquipment(e.action.loadEquipment.id, e.action.loadEquipment.force); - delete targets; + delete targets; + break; + } + case SMART_ACTION_TRIGGER_RANDOM_TIMED_EVENT: + { + uint32 eventId = urand(e.action.randomTimedEvent.minId, e.action.randomTimedEvent.maxId); + ProcessEventsFor((SMART_EVENT)SMART_EVENT_TIMED_EVENT_TRIGGERED, NULL, eventId); + break; + } + case SMART_ACTION_SET_HOVER: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_ADD_IMMUNITY: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsUnit(*itr)) - (*itr)->ToUnit()->ApplySpellImmune(e.action.immunity.id, e.action.immunity.type, e.action.immunity.value, true); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsUnit(*itr)) + (*itr)->ToUnit()->SetHover(e.action.setHover.state); - delete targets; + delete targets; + break; + } + case SMART_ACTION_ADD_IMMUNITY: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_REMOVE_IMMUNITY: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsUnit(*itr)) - (*itr)->ToUnit()->ApplySpellImmune(e.action.immunity.id, e.action.immunity.type, e.action.immunity.value, false); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsUnit(*itr)) + (*itr)->ToUnit()->ApplySpellImmune(e.action.immunity.id, e.action.immunity.type, e.action.immunity.value, true); - delete targets; + delete targets; + break; + } + case SMART_ACTION_REMOVE_IMMUNITY: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_FALL: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsUnit(*itr)) - (*itr)->ToUnit()->GetMotionMaster()->MoveFall(); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsUnit(*itr)) + (*itr)->ToUnit()->ApplySpellImmune(e.action.immunity.id, e.action.immunity.type, e.action.immunity.value, false); - delete targets; - break; - } - case SMART_ACTION_SET_EVENT_FLAG_RESET: - { - SetPhaseReset(e.action.setActive.state); + delete targets; + break; + } + case SMART_ACTION_FALL: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_REMOVE_ALL_GAMEOBJECTS: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsUnit(*itr)) - (*itr)->ToUnit()->RemoveAllGameObjects(); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsUnit(*itr)) + (*itr)->ToUnit()->GetMotionMaster()->MoveFall(); - delete targets; + delete targets; + break; + } + case SMART_ACTION_SET_EVENT_FLAG_RESET: + { + SetPhaseReset(e.action.setActive.state); + break; + } + case SMART_ACTION_REMOVE_ALL_GAMEOBJECTS: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_STOP_MOTION: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsUnit(*itr)) - { - if (e.action.stopMotion.stopMovement) - (*itr)->ToUnit()->StopMoving(); - if (e.action.stopMotion.movementExpired) - (*itr)->ToUnit()->GetMotionMaster()->MovementExpired(); - } + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsUnit(*itr)) + (*itr)->ToUnit()->RemoveAllGameObjects(); - delete targets; + delete targets; + break; + } + case SMART_ACTION_STOP_MOTION: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_NO_ENVIRONMENT_UPDATE: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsUnit(*itr)) - (*itr)->ToUnit()->AddUnitState(UNIT_STATE_NO_ENVIRONMENT_UPD); + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsUnit(*itr)) + { + if (e.action.stopMotion.stopMovement) + (*itr)->ToUnit()->StopMoving(); + if (e.action.stopMotion.movementExpired) + (*itr)->ToUnit()->GetMotionMaster()->MovementExpired(); + } - delete targets; + delete targets; + break; + } + case SMART_ACTION_NO_ENVIRONMENT_UPDATE: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; - } - case SMART_ACTION_ZONE_UNDER_ATTACK: - { - ObjectList* targets = GetTargets(e, unit); - if (!targets) - break; - for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - if (IsUnit(*itr)) - if (Player* player = (*itr)->ToUnit()->GetCharmerOrOwnerPlayerOrPlayerItself()) - { - me->SendZoneUnderAttackMessage(player); - break; - } + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsUnit(*itr)) + (*itr)->ToUnit()->AddUnitState(UNIT_STATE_NO_ENVIRONMENT_UPD); - delete targets; - break; - } - case SMART_ACTION_LOAD_GRID: - { - if (me && me->FindMap()) - me->FindMap()->LoadGrid(e.target.x, e.target.y); - break; - } - default: - sLog->outErrorDb("SmartScript::ProcessAction: Entry %d SourceType %u, Event %u, Unhandled Action type %u", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); + delete targets; + break; + } + case SMART_ACTION_ZONE_UNDER_ATTACK: + { + ObjectList* targets = GetTargets(e, unit); + if (!targets) break; + + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + if (IsUnit(*itr)) + if (Player* player = (*itr)->ToUnit()->GetCharmerOrOwnerPlayerOrPlayerItself()) + { + me->SendZoneUnderAttackMessage(player); + break; + } + + delete targets; + break; + } + case SMART_ACTION_LOAD_GRID: + { + if (me && me->FindMap()) + me->FindMap()->LoadGrid(e.target.x, e.target.y); + break; + } + default: + sLog->outErrorDb("SmartScript::ProcessAction: Entry %d SourceType %u, Event %u, Unhandled Action type %u", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); + break; } if (e.link && e.link != e.event_id) @@ -2836,65 +2868,65 @@ void SmartScript::InstallTemplate(SmartScriptHolder const& e) mTemplate = (SMARTAI_TEMPLATE)e.action.installTtemplate.id; switch ((SMARTAI_TEMPLATE)e.action.installTtemplate.id) { - case SMARTAI_TEMPLATE_CASTER: - { - AddEvent(SMART_EVENT_UPDATE_IC, 0, 0, 0, e.action.installTtemplate.param2, e.action.installTtemplate.param3, SMART_ACTION_CAST, e.action.installTtemplate.param1, e.target.raw.param1, 0, 0, 0, 0, SMART_TARGET_VICTIM, 0, 0, 0, 1); - AddEvent(SMART_EVENT_RANGE, 0, e.action.installTtemplate.param4, 300, 0, 0, SMART_ACTION_ALLOW_COMBAT_MOVEMENT, 1, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 1); - AddEvent(SMART_EVENT_RANGE, 0, 0, e.action.installTtemplate.param4>10?e.action.installTtemplate.param4-10:0, 0, 0, SMART_ACTION_ALLOW_COMBAT_MOVEMENT, 0, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 1); - AddEvent(SMART_EVENT_MANA_PCT, 0, e.action.installTtemplate.param5-15>100?100:e.action.installTtemplate.param5+15, 100, 1000, 1000, SMART_ACTION_SET_EVENT_PHASE, 1, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0); - AddEvent(SMART_EVENT_MANA_PCT, 0, 0, e.action.installTtemplate.param5, 1000, 1000, SMART_ACTION_SET_EVENT_PHASE, 0, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0); - AddEvent(SMART_EVENT_MANA_PCT, 0, 0, e.action.installTtemplate.param5, 1000, 1000, SMART_ACTION_ALLOW_COMBAT_MOVEMENT, 1, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0); - break; - } - case SMARTAI_TEMPLATE_TURRET: - { - AddEvent(SMART_EVENT_UPDATE_IC, 0, 0, 0, e.action.installTtemplate.param2, e.action.installTtemplate.param3, SMART_ACTION_CAST, e.action.installTtemplate.param1, e.target.raw.param1, 0, 0, 0, 0, SMART_TARGET_VICTIM, 0, 0, 0, 0); - AddEvent(SMART_EVENT_JUST_CREATED, 0, 0, 0, 0, 0, SMART_ACTION_ALLOW_COMBAT_MOVEMENT, 0, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0); - break; - } - case SMARTAI_TEMPLATE_CAGED_NPC_PART: - { - if (!me) - return; - //store cage as id1 - AddEvent(SMART_EVENT_DATA_SET, 0, 0, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 1, 0, 0, 0, 0, 0, SMART_TARGET_CLOSEST_GAMEOBJECT, e.action.installTtemplate.param1, 10, 0, 0); + case SMARTAI_TEMPLATE_CASTER: + { + AddEvent(SMART_EVENT_UPDATE_IC, 0, 0, 0, e.action.installTtemplate.param2, e.action.installTtemplate.param3, SMART_ACTION_CAST, e.action.installTtemplate.param1, e.target.raw.param1, 0, 0, 0, 0, SMART_TARGET_VICTIM, 0, 0, 0, 1); + AddEvent(SMART_EVENT_RANGE, 0, e.action.installTtemplate.param4, 300, 0, 0, SMART_ACTION_ALLOW_COMBAT_MOVEMENT, 1, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 1); + AddEvent(SMART_EVENT_RANGE, 0, 0, e.action.installTtemplate.param4>10 ? e.action.installTtemplate.param4 - 10 : 0, 0, 0, SMART_ACTION_ALLOW_COMBAT_MOVEMENT, 0, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 1); + AddEvent(SMART_EVENT_MANA_PCT, 0, e.action.installTtemplate.param5 - 15>100 ? 100 : e.action.installTtemplate.param5 + 15, 100, 1000, 1000, SMART_ACTION_SET_EVENT_PHASE, 1, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0); + AddEvent(SMART_EVENT_MANA_PCT, 0, 0, e.action.installTtemplate.param5, 1000, 1000, SMART_ACTION_SET_EVENT_PHASE, 0, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0); + AddEvent(SMART_EVENT_MANA_PCT, 0, 0, e.action.installTtemplate.param5, 1000, 1000, SMART_ACTION_ALLOW_COMBAT_MOVEMENT, 1, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0); + break; + } + case SMARTAI_TEMPLATE_TURRET: + { + AddEvent(SMART_EVENT_UPDATE_IC, 0, 0, 0, e.action.installTtemplate.param2, e.action.installTtemplate.param3, SMART_ACTION_CAST, e.action.installTtemplate.param1, e.target.raw.param1, 0, 0, 0, 0, SMART_TARGET_VICTIM, 0, 0, 0, 0); + AddEvent(SMART_EVENT_JUST_CREATED, 0, 0, 0, 0, 0, SMART_ACTION_ALLOW_COMBAT_MOVEMENT, 0, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0); + break; + } + case SMARTAI_TEMPLATE_CAGED_NPC_PART: + { + if (!me) + return; + //store cage as id1 + AddEvent(SMART_EVENT_DATA_SET, 0, 0, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 1, 0, 0, 0, 0, 0, SMART_TARGET_CLOSEST_GAMEOBJECT, e.action.installTtemplate.param1, 10, 0, 0); - //reset(close) cage on hostage(me) respawn - AddEvent(SMART_EVENT_UPDATE, SMART_EVENT_FLAG_NOT_REPEATABLE, 0, 0, 0, 0, SMART_ACTION_RESET_GOBJECT, 0, 0, 0, 0, 0, 0, SMART_TARGET_GAMEOBJECT_DISTANCE, e.action.installTtemplate.param1, 5, 0, 0); + //reset(close) cage on hostage(me) respawn + AddEvent(SMART_EVENT_UPDATE, SMART_EVENT_FLAG_NOT_REPEATABLE, 0, 0, 0, 0, SMART_ACTION_RESET_GOBJECT, 0, 0, 0, 0, 0, 0, SMART_TARGET_GAMEOBJECT_DISTANCE, e.action.installTtemplate.param1, 5, 0, 0); - AddEvent(SMART_EVENT_DATA_SET, 0, 0, 0, 0, 0, SMART_ACTION_SET_RUN, e.action.installTtemplate.param3, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0); - AddEvent(SMART_EVENT_DATA_SET, 0, 0, 0, 0, 0, SMART_ACTION_SET_EVENT_PHASE, 1, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0); + AddEvent(SMART_EVENT_DATA_SET, 0, 0, 0, 0, 0, SMART_ACTION_SET_RUN, e.action.installTtemplate.param3, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0); + AddEvent(SMART_EVENT_DATA_SET, 0, 0, 0, 0, 0, SMART_ACTION_SET_EVENT_PHASE, 1, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0); - AddEvent(SMART_EVENT_UPDATE, SMART_EVENT_FLAG_NOT_REPEATABLE, 1000, 1000, 0, 0, SMART_ACTION_MOVE_FORWARD, e.action.installTtemplate.param4, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 1); - //phase 1: give quest credit on movepoint reached - AddEvent(SMART_EVENT_MOVEMENTINFORM, 0, POINT_MOTION_TYPE, SMART_RANDOM_POINT, 0, 0, SMART_ACTION_SET_DATA, 0, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 1, 0, 0, 1); - //phase 1: despawn after time on movepoint reached - AddEvent(SMART_EVENT_MOVEMENTINFORM, 0, POINT_MOTION_TYPE, SMART_RANDOM_POINT, 0, 0, SMART_ACTION_FORCE_DESPAWN, e.action.installTtemplate.param2, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 1); + AddEvent(SMART_EVENT_UPDATE, SMART_EVENT_FLAG_NOT_REPEATABLE, 1000, 1000, 0, 0, SMART_ACTION_MOVE_FORWARD, e.action.installTtemplate.param4, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 1); + //phase 1: give quest credit on movepoint reached + AddEvent(SMART_EVENT_MOVEMENTINFORM, 0, POINT_MOTION_TYPE, SMART_RANDOM_POINT, 0, 0, SMART_ACTION_SET_DATA, 0, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 1, 0, 0, 1); + //phase 1: despawn after time on movepoint reached + AddEvent(SMART_EVENT_MOVEMENTINFORM, 0, POINT_MOTION_TYPE, SMART_RANDOM_POINT, 0, 0, SMART_ACTION_FORCE_DESPAWN, e.action.installTtemplate.param2, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 1); - if (sCreatureTextMgr->TextExist(me->GetEntry(), (uint8)e.action.installTtemplate.param5)) - AddEvent(SMART_EVENT_MOVEMENTINFORM, 0, POINT_MOTION_TYPE, SMART_RANDOM_POINT, 0, 0, SMART_ACTION_TALK, e.action.installTtemplate.param5, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 1); - break; - } - case SMARTAI_TEMPLATE_CAGED_GO_PART: - { - if (!go) - return; - //store hostage as id1 - AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 1, 0, 0, 0, 0, 0, SMART_TARGET_CLOSEST_CREATURE, e.action.installTtemplate.param1, 10, 0, 0); - //store invoker as id2 - AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 2, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0); - //signal hostage - AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_SET_DATA, 0, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 1, 0, 0, 0); - //when hostage raeched end point, give credit to invoker - if (e.action.installTtemplate.param2) - AddEvent(SMART_EVENT_DATA_SET, 0, 0, 0, 0, 0, SMART_ACTION_CALL_KILLEDMONSTER, e.action.installTtemplate.param1, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 2, 0, 0, 0); - else - AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_CALL_KILLEDMONSTER, e.action.installTtemplate.param1, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 2, 0, 0, 0); - break; - } - case SMARTAI_TEMPLATE_BASIC: - default: + if (sCreatureTextMgr->TextExist(me->GetEntry(), (uint8)e.action.installTtemplate.param5)) + AddEvent(SMART_EVENT_MOVEMENTINFORM, 0, POINT_MOTION_TYPE, SMART_RANDOM_POINT, 0, 0, SMART_ACTION_TALK, e.action.installTtemplate.param5, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 1); + break; + } + case SMARTAI_TEMPLATE_CAGED_GO_PART: + { + if (!go) return; + //store hostage as id1 + AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 1, 0, 0, 0, 0, 0, SMART_TARGET_CLOSEST_CREATURE, e.action.installTtemplate.param1, 10, 0, 0); + //store invoker as id2 + AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 2, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0); + //signal hostage + AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_SET_DATA, 0, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 1, 0, 0, 0); + //when hostage raeched end point, give credit to invoker + if (e.action.installTtemplate.param2) + AddEvent(SMART_EVENT_DATA_SET, 0, 0, 0, 0, 0, SMART_ACTION_CALL_KILLEDMONSTER, e.action.installTtemplate.param1, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 2, 0, 0, 0); + else + AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_CALL_KILLEDMONSTER, e.action.installTtemplate.param1, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 2, 0, 0, 0); + break; + } + case SMARTAI_TEMPLATE_BASIC: + default: + return; } } @@ -2946,361 +2978,361 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /* ObjectList* l = new ObjectList(); switch (e.GetTargetType()) { - case SMART_TARGET_SELF: - if (baseObject) - l->push_back(baseObject); - break; - case SMART_TARGET_VICTIM: - if (me && me->GetVictim()) - l->push_back(me->GetVictim()); - break; - case SMART_TARGET_HOSTILE_SECOND_AGGRO: - if (me) - { - if (e.target.hostilRandom.powerType) - { - if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_TOPAGGRO, 1, PowerUsersSelector(me, Powers(e.target.hostilRandom.powerType-1), (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly))) - l->push_back(u); - } - else if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_TOPAGGRO, 1, (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly)) - l->push_back(u); - } - break; - case SMART_TARGET_HOSTILE_LAST_AGGRO: - if (me) - { - if (e.target.hostilRandom.powerType) - { - if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_BOTTOMAGGRO, 0, PowerUsersSelector(me, Powers(e.target.hostilRandom.powerType-1), (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly))) - l->push_back(u); - } - else if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_BOTTOMAGGRO, 0, (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly)) + case SMART_TARGET_SELF: + if (baseObject) + l->push_back(baseObject); + break; + case SMART_TARGET_VICTIM: + if (me && me->GetVictim()) + l->push_back(me->GetVictim()); + break; + case SMART_TARGET_HOSTILE_SECOND_AGGRO: + if (me) + { + if (e.target.hostilRandom.powerType) + { + if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_TOPAGGRO, 1, PowerUsersSelector(me, Powers(e.target.hostilRandom.powerType - 1), (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly))) l->push_back(u); } - break; - case SMART_TARGET_HOSTILE_RANDOM: - if (me) + else if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_TOPAGGRO, 1, (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly)) + l->push_back(u); + } + break; + case SMART_TARGET_HOSTILE_LAST_AGGRO: + if (me) + { + if (e.target.hostilRandom.powerType) { - if (e.target.hostilRandom.powerType) - { - if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, PowerUsersSelector(me, Powers(e.target.hostilRandom.powerType-1), (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly))) - l->push_back(u); - } - else if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly)) + if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_BOTTOMAGGRO, 0, PowerUsersSelector(me, Powers(e.target.hostilRandom.powerType - 1), (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly))) l->push_back(u); } - break; - case SMART_TARGET_HOSTILE_RANDOM_NOT_TOP: - if (me) + else if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_BOTTOMAGGRO, 0, (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly)) + l->push_back(u); + } + break; + case SMART_TARGET_HOSTILE_RANDOM: + if (me) + { + if (e.target.hostilRandom.powerType) { - if (e.target.hostilRandom.powerType) - { - if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 1, PowerUsersSelector(me, Powers(e.target.hostilRandom.powerType-1), (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly))) - l->push_back(u); - } - else if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 1, (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly)) + if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, PowerUsersSelector(me, Powers(e.target.hostilRandom.powerType - 1), (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly))) l->push_back(u); } - break; - case SMART_TARGET_FARTHEST: - if (me) + else if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly)) + l->push_back(u); + } + break; + case SMART_TARGET_HOSTILE_RANDOM_NOT_TOP: + if (me) + { + if (e.target.hostilRandom.powerType) { - if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_FARTHEST, 0, FarthestTargetSelector(me, e.target.farthest.maxDist, e.target.farthest.playerOnly, e.target.farthest.isInLos))) + if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 1, PowerUsersSelector(me, Powers(e.target.hostilRandom.powerType - 1), (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly))) l->push_back(u); } - break; - case SMART_TARGET_ACTION_INVOKER: - if (scriptTrigger) - l->push_back(scriptTrigger); - break; - case SMART_TARGET_ACTION_INVOKER_VEHICLE: - if (scriptTrigger && scriptTrigger->GetVehicle() && scriptTrigger->GetVehicle()->GetBase()) - l->push_back(scriptTrigger->GetVehicle()->GetBase()); - break; - case SMART_TARGET_INVOKER_PARTY: - if (scriptTrigger) - { - if (Player* player = scriptTrigger->ToPlayer()) + else if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 1, (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly)) + l->push_back(u); + } + break; + case SMART_TARGET_FARTHEST: + if (me) + { + if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_FARTHEST, 0, FarthestTargetSelector(me, e.target.farthest.maxDist, e.target.farthest.playerOnly, e.target.farthest.isInLos))) + l->push_back(u); + } + break; + case SMART_TARGET_ACTION_INVOKER: + if (scriptTrigger) + l->push_back(scriptTrigger); + break; + case SMART_TARGET_ACTION_INVOKER_VEHICLE: + if (scriptTrigger && scriptTrigger->GetVehicle() && scriptTrigger->GetVehicle()->GetBase()) + l->push_back(scriptTrigger->GetVehicle()->GetBase()); + break; + case SMART_TARGET_INVOKER_PARTY: + if (scriptTrigger) + { + if (Player* player = scriptTrigger->ToPlayer()) + { + if (Group* group = player->GetGroup()) { - if (Group* group = player->GetGroup()) - { - for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next()) - if (Player* member = groupRef->GetSource()) - if (member->IsInMap(player)) - l->push_back(member); - } - // We still add the player to the list if there is no group. If we do - // this even if there is a group (thus the else-check), it will add the - // same player to the list twice. We don't want that to happen. - else - l->push_back(scriptTrigger); + for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next()) + if (Player* member = groupRef->GetSource()) + if (member->IsInMap(player)) + l->push_back(member); } + // We still add the player to the list if there is no group. If we do + // this even if there is a group (thus the else-check), it will add the + // same player to the list twice. We don't want that to happen. + else + l->push_back(scriptTrigger); } - break; - case SMART_TARGET_CREATURE_RANGE: + } + break; + case SMART_TARGET_CREATURE_RANGE: + { + // will always return a valid pointer, even if empty list + ObjectList* units = GetWorldObjectsInDist((float)e.target.unitRange.maxDist); + for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr) { - // will always return a valid pointer, even if empty list - ObjectList* units = GetWorldObjectsInDist((float)e.target.unitRange.maxDist); - for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr) + if (!IsCreature(*itr)) + continue; + + if (me && me->GetGUID() == (*itr)->GetGUID()) + continue; + + // check alive state - 1 alive, 2 dead, 0 both + if (uint32 state = e.target.unitRange.livingState) { - if (!IsCreature(*itr)) + if ((*itr)->ToCreature()->IsAlive() && state == 2) continue; - - if (me && me->GetGUID() == (*itr)->GetGUID()) + if (!(*itr)->ToCreature()->IsAlive() && state == 1) continue; - - // check alive state - 1 alive, 2 dead, 0 both - if (uint32 state = e.target.unitRange.livingState) - { - if ((*itr)->ToCreature()->IsAlive() && state == 2) - continue; - if (!(*itr)->ToCreature()->IsAlive() && state == 1) - continue; - } - - if (((e.target.unitRange.creature && (*itr)->ToCreature()->GetEntry() == e.target.unitRange.creature) || !e.target.unitRange.creature) && baseObject->IsInRange(*itr, (float)e.target.unitRange.minDist, (float)e.target.unitRange.maxDist)) - l->push_back(*itr); } - delete units; - break; + if (((e.target.unitRange.creature && (*itr)->ToCreature()->GetEntry() == e.target.unitRange.creature) || !e.target.unitRange.creature) && baseObject->IsInRange(*itr, (float)e.target.unitRange.minDist, (float)e.target.unitRange.maxDist)) + l->push_back(*itr); } - case SMART_TARGET_CREATURE_DISTANCE: + + delete units; + break; + } + case SMART_TARGET_CREATURE_DISTANCE: + { + // will always return a valid pointer, even if empty list + ObjectList* units = GetWorldObjectsInDist((float)e.target.unitDistance.dist); + for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr) { - // will always return a valid pointer, even if empty list - ObjectList* units = GetWorldObjectsInDist((float)e.target.unitDistance.dist); - for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr) + if (!IsCreature(*itr)) + continue; + + if (me && me->GetGUID() == (*itr)->GetGUID()) + continue; + + // check alive state - 1 alive, 2 dead, 0 both + if (uint32 state = e.target.unitDistance.livingState) { - if (!IsCreature(*itr)) + if ((*itr)->ToCreature()->IsAlive() && state == 2) continue; - - if (me && me->GetGUID() == (*itr)->GetGUID()) + if (!(*itr)->ToCreature()->IsAlive() && state == 1) continue; - - // check alive state - 1 alive, 2 dead, 0 both - if (uint32 state = e.target.unitDistance.livingState) - { - if ((*itr)->ToCreature()->IsAlive() && state == 2) - continue; - if (!(*itr)->ToCreature()->IsAlive() && state == 1) - continue; - } - - if ((e.target.unitDistance.creature && (*itr)->ToCreature()->GetEntry() == e.target.unitDistance.creature) || !e.target.unitDistance.creature) - l->push_back(*itr); } - delete units; - break; + if ((e.target.unitDistance.creature && (*itr)->ToCreature()->GetEntry() == e.target.unitDistance.creature) || !e.target.unitDistance.creature) + l->push_back(*itr); } - case SMART_TARGET_GAMEOBJECT_DISTANCE: - { - // will always return a valid pointer, even if empty list - ObjectList* units = GetWorldObjectsInDist((float)e.target.goDistance.dist); - for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr) - { - if (!IsGameObject(*itr)) - continue; - if (go && go->GetGUID() == (*itr)->GetGUID()) - continue; + delete units; + break; + } + case SMART_TARGET_GAMEOBJECT_DISTANCE: + { + // will always return a valid pointer, even if empty list + ObjectList* units = GetWorldObjectsInDist((float)e.target.goDistance.dist); + for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr) + { + if (!IsGameObject(*itr)) + continue; - if ((e.target.goDistance.entry && (*itr)->ToGameObject()->GetEntry() == e.target.goDistance.entry) || !e.target.goDistance.entry) - l->push_back(*itr); - } + if (go && go->GetGUID() == (*itr)->GetGUID()) + continue; - delete units; - break; + if ((e.target.goDistance.entry && (*itr)->ToGameObject()->GetEntry() == e.target.goDistance.entry) || !e.target.goDistance.entry) + l->push_back(*itr); } - case SMART_TARGET_GAMEOBJECT_RANGE: + + delete units; + break; + } + case SMART_TARGET_GAMEOBJECT_RANGE: + { + // will always return a valid pointer, even if empty list + ObjectList* units = GetWorldObjectsInDist((float)e.target.goRange.maxDist); + for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr) { - // will always return a valid pointer, even if empty list - ObjectList* units = GetWorldObjectsInDist((float)e.target.goRange.maxDist); - for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr) - { - if (!IsGameObject(*itr)) - continue; + if (!IsGameObject(*itr)) + continue; - if (go && go->GetGUID() == (*itr)->GetGUID()) - continue; + if (go && go->GetGUID() == (*itr)->GetGUID()) + continue; - if (((e.target.goRange.entry && IsGameObject(*itr) && (*itr)->ToGameObject()->GetEntry() == e.target.goRange.entry) || !e.target.goRange.entry) && baseObject->IsInRange((*itr), (float)e.target.goRange.minDist, (float)e.target.goRange.maxDist)) - l->push_back(*itr); - } + if (((e.target.goRange.entry && IsGameObject(*itr) && (*itr)->ToGameObject()->GetEntry() == e.target.goRange.entry) || !e.target.goRange.entry) && baseObject->IsInRange((*itr), (float)e.target.goRange.minDist, (float)e.target.goRange.maxDist)) + l->push_back(*itr); + } - delete units; + delete units; + break; + } + case SMART_TARGET_CREATURE_GUID: + { + Creature* target = NULL; + if (!scriptTrigger && !baseObject) + { + sLog->outError("SMART_TARGET_CREATURE_GUID can not be used without invoker"); break; } - case SMART_TARGET_CREATURE_GUID: - { - Creature* target = NULL; - if (!scriptTrigger && !baseObject) - { - sLog->outError("SMART_TARGET_CREATURE_GUID can not be used without invoker"); - break; - } - // xinef: my addition - if (e.target.unitGUID.getFromHashMap) - { - if (target = ObjectAccessor::GetCreature(scriptTrigger ? *scriptTrigger : *GetBaseObject(), MAKE_NEW_GUID(e.target.unitGUID.dbGuid, e.target.unitGUID.entry, HIGHGUID_UNIT))) - l->push_back(target); - } - else - { - target = FindCreatureNear(scriptTrigger ? scriptTrigger : GetBaseObject(), e.target.unitGUID.dbGuid); - if (target && (!e.target.unitGUID.entry || target->GetEntry() == e.target.unitGUID.entry)) - l->push_back(target); - } - break; + // xinef: my addition + if (e.target.unitGUID.getFromHashMap) + { + if (target = ObjectAccessor::GetCreature(scriptTrigger ? *scriptTrigger : *GetBaseObject(), MAKE_NEW_GUID(e.target.unitGUID.dbGuid, e.target.unitGUID.entry, HIGHGUID_UNIT))) + l->push_back(target); } - case SMART_TARGET_GAMEOBJECT_GUID: + else { - GameObject* target = NULL; - if (!scriptTrigger && !GetBaseObject()) - { - sLog->outError("SMART_TARGET_GAMEOBJECT_GUID can not be used without invoker"); - break; - } - - // xinef: my addition - if (e.target.goGUID.getFromHashMap) - { - if (target = ObjectAccessor::GetGameObject(scriptTrigger ? *scriptTrigger : *GetBaseObject(), MAKE_NEW_GUID(e.target.goGUID.dbGuid, e.target.goGUID.entry, HIGHGUID_GAMEOBJECT))) - l->push_back(target); - } - else - { - target = FindGameObjectNear(scriptTrigger ? scriptTrigger : GetBaseObject(), e.target.goGUID.dbGuid); - if (target && (!e.target.goGUID.entry || target->GetEntry() == e.target.goGUID.entry)) - l->push_back(target); - } - break; + target = FindCreatureNear(scriptTrigger ? scriptTrigger : GetBaseObject(), e.target.unitGUID.dbGuid); + if (target && (!e.target.unitGUID.entry || target->GetEntry() == e.target.unitGUID.entry)) + l->push_back(target); } - case SMART_TARGET_PLAYER_RANGE: + break; + } + case SMART_TARGET_GAMEOBJECT_GUID: + { + GameObject* target = NULL; + if (!scriptTrigger && !GetBaseObject()) { - uint32 count = 0; - // will always return a valid pointer, even if empty list - ObjectList* units = GetWorldObjectsInDist((float)e.target.playerRange.maxDist); - if (!units->empty() && GetBaseObject()) - for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr) - if (IsPlayer(*itr) && GetBaseObject()->IsInRange(*itr, (float)e.target.playerRange.minDist, (float)e.target.playerRange.maxDist)) - { - l->push_back(*itr); - if (e.target.playerRange.maxCount && ++count >= e.target.playerRange.maxCount) - break; - } - - delete units; + sLog->outError("SMART_TARGET_GAMEOBJECT_GUID can not be used without invoker"); break; } - case SMART_TARGET_PLAYER_DISTANCE: + + // xinef: my addition + if (e.target.goGUID.getFromHashMap) { - // will always return a valid pointer, even if empty list - ObjectList* units = GetWorldObjectsInDist((float)e.target.playerDistance.dist); + if (target = ObjectAccessor::GetGameObject(scriptTrigger ? *scriptTrigger : *GetBaseObject(), MAKE_NEW_GUID(e.target.goGUID.dbGuid, e.target.goGUID.entry, HIGHGUID_GAMEOBJECT))) + l->push_back(target); + } + else + { + target = FindGameObjectNear(scriptTrigger ? scriptTrigger : GetBaseObject(), e.target.goGUID.dbGuid); + if (target && (!e.target.goGUID.entry || target->GetEntry() == e.target.goGUID.entry)) + l->push_back(target); + } + break; + } + case SMART_TARGET_PLAYER_RANGE: + { + uint32 count = 0; + // will always return a valid pointer, even if empty list + ObjectList* units = GetWorldObjectsInDist((float)e.target.playerRange.maxDist); + if (!units->empty() && GetBaseObject()) for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr) - if (IsPlayer(*itr)) + if (IsPlayer(*itr) && GetBaseObject()->IsInRange(*itr, (float)e.target.playerRange.minDist, (float)e.target.playerRange.maxDist)) + { l->push_back(*itr); + if (e.target.playerRange.maxCount && ++count >= e.target.playerRange.maxCount) + break; + } - delete units; - break; - } - case SMART_TARGET_STORED: + delete units; + break; + } + case SMART_TARGET_PLAYER_DISTANCE: + { + // will always return a valid pointer, even if empty list + ObjectList* units = GetWorldObjectsInDist((float)e.target.playerDistance.dist); + for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr) + if (IsPlayer(*itr)) + l->push_back(*itr); + + delete units; + break; + } + case SMART_TARGET_STORED: + { + ObjectListMap::iterator itr = mTargetStorage->find(e.target.stored.id); + if (itr != mTargetStorage->end()) { - ObjectListMap::iterator itr = mTargetStorage->find(e.target.stored.id); - if (itr != mTargetStorage->end()) - { - ObjectList* objectList = itr->second->GetObjectList(); - l->assign(objectList->begin(), objectList->end()); - } - - // xinef: return l, retardness... what if list is empty? will return empty list instead of null pointer - break; + ObjectList* objectList = itr->second->GetObjectList(); + l->assign(objectList->begin(), objectList->end()); } - case SMART_TARGET_CLOSEST_CREATURE: + + // xinef: return l, retardness... what if list is empty? will return empty list instead of null pointer + break; + } + case SMART_TARGET_CLOSEST_CREATURE: + { + Creature* target = GetClosestCreatureWithEntry(GetBaseObject(), e.target.closest.entry, (float)(e.target.closest.dist ? e.target.closest.dist : 100), !e.target.closest.dead); + if (target) + l->push_back(target); + break; + } + case SMART_TARGET_CLOSEST_GAMEOBJECT: + { + GameObject* target = GetClosestGameObjectWithEntry(GetBaseObject(), e.target.closest.entry, (float)(e.target.closest.dist ? e.target.closest.dist : 100)); + if (target) + l->push_back(target); + break; + } + case SMART_TARGET_CLOSEST_PLAYER: + { + if (WorldObject* obj = GetBaseObject()) { - Creature* target = GetClosestCreatureWithEntry(GetBaseObject(), e.target.closest.entry, (float)(e.target.closest.dist ? e.target.closest.dist : 100), !e.target.closest.dead); + Player* target = obj->SelectNearestPlayer((float)e.target.playerDistance.dist); if (target) l->push_back(target); - break; } - case SMART_TARGET_CLOSEST_GAMEOBJECT: + break; + } + case SMART_TARGET_OWNER_OR_SUMMONER: + { + if (me) { - GameObject* target = GetClosestGameObjectWithEntry(GetBaseObject(), e.target.closest.entry, (float)(e.target.closest.dist ? e.target.closest.dist : 100)); - if (target) - l->push_back(target); - break; + if (Unit* owner = ObjectAccessor::GetUnit(*me, me->GetCharmerOrOwnerGUID())) + l->push_back(owner); + // Xinef: dont add same unit twice + else if (me->IsSummon() && me->ToTempSummon()->GetSummoner()) + l->push_back(me->ToTempSummon()->GetSummoner()); } - case SMART_TARGET_CLOSEST_PLAYER: + else if (go) { - if (WorldObject* obj = GetBaseObject()) - { - Player* target = obj->SelectNearestPlayer((float)e.target.playerDistance.dist); - if (target) - l->push_back(target); - } - break; + if (Unit* owner = ObjectAccessor::GetUnit(*go, go->GetOwnerGUID())) + l->push_back(owner); } - case SMART_TARGET_OWNER_OR_SUMMONER: - { - if (me) - { - if (Unit* owner = ObjectAccessor::GetUnit(*me, me->GetCharmerOrOwnerGUID())) - l->push_back(owner); - // Xinef: dont add same unit twice - else if (me->IsSummon() && me->ToTempSummon()->GetSummoner()) - l->push_back(me->ToTempSummon()->GetSummoner()); - } - else if (go) - { - if (Unit* owner = ObjectAccessor::GetUnit(*go, go->GetOwnerGUID())) - l->push_back(owner); - } - // xinef: Get owner of owner - if (e.target.owner.useCharmerOrOwner && !l->empty()) - { - Unit* owner = l->front()->ToUnit(); - l->clear(); + // xinef: Get owner of owner + if (e.target.owner.useCharmerOrOwner && !l->empty()) + { + Unit* owner = l->front()->ToUnit(); + l->clear(); - if (Unit* base = ObjectAccessor::GetUnit(*owner, owner->GetCharmerOrOwnerGUID())) - l->push_back(base); - } - break; + if (Unit* base = ObjectAccessor::GetUnit(*owner, owner->GetCharmerOrOwnerGUID())) + l->push_back(base); } - case SMART_TARGET_THREAT_LIST: + break; + } + case SMART_TARGET_THREAT_LIST: + { + if (me) { - if (me) - { - ThreatContainer::StorageType threatList = me->getThreatManager().getThreatList(); - for (ThreatContainer::StorageType::const_iterator i = threatList.begin(); i != threatList.end(); ++i) - if (Unit* temp = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid())) - // Xinef: added distance check - if (e.target.hostilRandom.maxDist == 0 || me->IsWithinCombatRange(temp, (float)e.target.hostilRandom.maxDist)) - l->push_back(temp); - } - break; + ThreatContainer::StorageType threatList = me->getThreatManager().getThreatList(); + for (ThreatContainer::StorageType::const_iterator i = threatList.begin(); i != threatList.end(); ++i) + if (Unit* temp = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid())) + // Xinef: added distance check + if (e.target.hostilRandom.maxDist == 0 || me->IsWithinCombatRange(temp, (float)e.target.hostilRandom.maxDist)) + l->push_back(temp); } - case SMART_TARGET_CLOSEST_ENEMY: - { - if (me) - if (Unit* target = me->SelectNearestTarget(e.target.closestAttackable.maxDist, e.target.closestAttackable.playerOnly)) - l->push_back(target); + break; + } + case SMART_TARGET_CLOSEST_ENEMY: + { + if (me) + if (Unit* target = me->SelectNearestTarget(e.target.closestAttackable.maxDist, e.target.closestAttackable.playerOnly)) + l->push_back(target); - break; - } - case SMART_TARGET_CLOSEST_FRIENDLY: - { - if (me) - if (Unit* target = DoFindClosestFriendlyInRange(e.target.closestFriendly.maxDist, e.target.closestFriendly.playerOnly)) - l->push_back(target); + break; + } + case SMART_TARGET_CLOSEST_FRIENDLY: + { + if (me) + if (Unit* target = DoFindClosestFriendlyInRange(e.target.closestFriendly.maxDist, e.target.closestFriendly.playerOnly)) + l->push_back(target); - break; - } - case SMART_TARGET_NONE: - case SMART_TARGET_POSITION: - default: - break; + break; + } + case SMART_TARGET_NONE: + case SMART_TARGET_POSITION: + default: + break; } if (l->empty()) @@ -3335,550 +3367,550 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui switch (e.GetEventType()) { - case SMART_EVENT_LINK://special handling - ProcessAction(e, unit, var0, var1, bvar, spell, gob); - break; + case SMART_EVENT_LINK://special handling + ProcessAction(e, unit, var0, var1, bvar, spell, gob); + break; //called from Update tick - case SMART_EVENT_UPDATE: - ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); - break; - case SMART_EVENT_UPDATE_OOC: - if (me && me->IsInCombat()) - return; - ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); - break; - case SMART_EVENT_UPDATE_IC: - if (!me || !me->IsInCombat()) - return; - ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); - break; - case SMART_EVENT_HEALTH_PCT: - { - if (!me || !me->IsInCombat() || !me->GetMaxHealth()) - return; - uint32 perc = (uint32)me->GetHealthPct(); - if (perc > e.event.minMaxRepeat.max || perc < e.event.minMaxRepeat.min) - return; - ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); - break; - } - case SMART_EVENT_TARGET_HEALTH_PCT: - { - if (!me || !me->IsInCombat() || !me->GetVictim() || !me->GetVictim()->GetMaxHealth()) - return; - uint32 perc = (uint32)me->GetVictim()->GetHealthPct(); - if (perc > e.event.minMaxRepeat.max || perc < e.event.minMaxRepeat.min) - return; - ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax, me->GetVictim()); - break; - } - case SMART_EVENT_MANA_PCT: - { - if (!me || !me->IsInCombat() || !me->GetMaxPower(POWER_MANA)) - return; - uint32 perc = uint32(me->GetPowerPct(POWER_MANA)); - if (perc > e.event.minMaxRepeat.max || perc < e.event.minMaxRepeat.min) - return; - ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); - break; - } - case SMART_EVENT_TARGET_MANA_PCT: - { - if (!me || !me->IsInCombat() || !me->GetVictim() || !me->GetVictim()->GetMaxPower(POWER_MANA)) - return; - uint32 perc = uint32(me->GetVictim()->GetPowerPct(POWER_MANA)); - if (perc > e.event.minMaxRepeat.max || perc < e.event.minMaxRepeat.min) - return; + case SMART_EVENT_UPDATE: + ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); + break; + case SMART_EVENT_UPDATE_OOC: + if (me && me->IsInCombat()) + return; + ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); + break; + case SMART_EVENT_UPDATE_IC: + if (!me || !me->IsInCombat()) + return; + ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); + break; + case SMART_EVENT_HEALTH_PCT: + { + if (!me || !me->IsInCombat() || !me->GetMaxHealth()) + return; + uint32 perc = (uint32)me->GetHealthPct(); + if (perc > e.event.minMaxRepeat.max || perc < e.event.minMaxRepeat.min) + return; + ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); + break; + } + case SMART_EVENT_TARGET_HEALTH_PCT: + { + if (!me || !me->IsInCombat() || !me->GetVictim() || !me->GetVictim()->GetMaxHealth()) + return; + uint32 perc = (uint32)me->GetVictim()->GetHealthPct(); + if (perc > e.event.minMaxRepeat.max || perc < e.event.minMaxRepeat.min) + return; + ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax, me->GetVictim()); + break; + } + case SMART_EVENT_MANA_PCT: + { + if (!me || !me->IsInCombat() || !me->GetMaxPower(POWER_MANA)) + return; + uint32 perc = uint32(me->GetPowerPct(POWER_MANA)); + if (perc > e.event.minMaxRepeat.max || perc < e.event.minMaxRepeat.min) + return; + ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); + break; + } + case SMART_EVENT_TARGET_MANA_PCT: + { + if (!me || !me->IsInCombat() || !me->GetVictim() || !me->GetVictim()->GetMaxPower(POWER_MANA)) + return; + uint32 perc = uint32(me->GetVictim()->GetPowerPct(POWER_MANA)); + if (perc > e.event.minMaxRepeat.max || perc < e.event.minMaxRepeat.min) + return; + ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax, me->GetVictim()); + break; + } + case SMART_EVENT_RANGE: + { + if (!me || !me->IsInCombat() || !me->GetVictim()) + return; + + if (me->IsInRange(me->GetVictim(), (float)e.event.minMaxRepeat.min, (float)e.event.minMaxRepeat.max)) ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax, me->GetVictim()); - break; - } - case SMART_EVENT_RANGE: - { - if (!me || !me->IsInCombat() || !me->GetVictim()) - return; + else // xinef: make it predictable + RecalcTimer(e, 500, 500); + break; + } + case SMART_EVENT_VICTIM_CASTING: + { + if (!me || !me->IsInCombat()) + return; - if (me->IsInRange(me->GetVictim(), (float)e.event.minMaxRepeat.min, (float)e.event.minMaxRepeat.max)) - ProcessTimedAction(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax, me->GetVictim()); - else // xinef: make it predictable - RecalcTimer(e, 500, 500); - break; - } - case SMART_EVENT_VICTIM_CASTING: - { - if (!me || !me->IsInCombat()) - return; + Unit* victim = me->GetVictim(); - Unit* victim = me->GetVictim(); + if (!victim || !victim->IsNonMeleeSpellCast(false, false, true)) + return; - if (!victim || !victim->IsNonMeleeSpellCast(false, false, true)) - return; + if (e.event.targetCasting.spellId > 0) + if (Spell* currSpell = victim->GetCurrentSpell(CURRENT_GENERIC_SPELL)) + if (currSpell->m_spellInfo->Id != e.event.targetCasting.spellId) + return; - if (e.event.targetCasting.spellId > 0) - if (Spell* currSpell = victim->GetCurrentSpell(CURRENT_GENERIC_SPELL)) - if (currSpell->m_spellInfo->Id != e.event.targetCasting.spellId) - return; + ProcessTimedAction(e, e.event.targetCasting.repeatMin, e.event.targetCasting.repeatMax, me->GetVictim()); + break; + } + case SMART_EVENT_FRIENDLY_HEALTH: + { + if (!me || !me->IsInCombat()) + return; - ProcessTimedAction(e, e.event.targetCasting.repeatMin, e.event.targetCasting.repeatMax, me->GetVictim()); - break; - } - case SMART_EVENT_FRIENDLY_HEALTH: + Unit* target = DoSelectLowestHpFriendly((float)e.event.friendlyHealth.radius, e.event.friendlyHealth.hpDeficit); + if (!target || !target->IsInCombat()) { - if (!me || !me->IsInCombat()) - return; - - Unit* target = DoSelectLowestHpFriendly((float)e.event.friendlyHealth.radius, e.event.friendlyHealth.hpDeficit); - if (!target || !target->IsInCombat()) - { - // Xinef: if there are at least two same npcs, they will perform the same action immediately even if this is useless... - RecalcTimer(e, 1000, 3000); - return; - } - ProcessTimedAction(e, e.event.friendlyHealth.repeatMin, e.event.friendlyHealth.repeatMax, target); - break; + // Xinef: if there are at least two same npcs, they will perform the same action immediately even if this is useless... + RecalcTimer(e, 1000, 3000); + return; } - case SMART_EVENT_FRIENDLY_IS_CC: - { - if (!me || !me->IsInCombat()) - return; + ProcessTimedAction(e, e.event.friendlyHealth.repeatMin, e.event.friendlyHealth.repeatMax, target); + break; + } + case SMART_EVENT_FRIENDLY_IS_CC: + { + if (!me || !me->IsInCombat()) + return; - std::list<Creature*> pList; - DoFindFriendlyCC(pList, (float)e.event.friendlyCC.radius); - if (pList.empty()) - { - // Xinef: if there are at least two same npcs, they will perform the same action immediately even if this is useless... - RecalcTimer(e, 1000, 3000); - return; - } - ProcessTimedAction(e, e.event.friendlyCC.repeatMin, e.event.friendlyCC.repeatMax, Trinity::Containers::SelectRandomContainerElement(pList)); - break; - } - case SMART_EVENT_FRIENDLY_MISSING_BUFF: + std::list<Creature*> pList; + DoFindFriendlyCC(pList, (float)e.event.friendlyCC.radius); + if (pList.empty()) { - std::list<Creature*> pList; - DoFindFriendlyMissingBuff(pList, (float)e.event.missingBuff.radius, e.event.missingBuff.spell); + // Xinef: if there are at least two same npcs, they will perform the same action immediately even if this is useless... + RecalcTimer(e, 1000, 3000); + return; + } + ProcessTimedAction(e, e.event.friendlyCC.repeatMin, e.event.friendlyCC.repeatMax, Trinity::Containers::SelectRandomContainerElement(pList)); + break; + } + case SMART_EVENT_FRIENDLY_MISSING_BUFF: + { + std::list<Creature*> pList; + DoFindFriendlyMissingBuff(pList, (float)e.event.missingBuff.radius, e.event.missingBuff.spell); - if (pList.empty()) - return; + if (pList.empty()) + return; - ProcessTimedAction(e, e.event.missingBuff.repeatMin, e.event.missingBuff.repeatMax, Trinity::Containers::SelectRandomContainerElement(pList)); - break; - } - case SMART_EVENT_HAS_AURA: - { - if (!me) - return; - uint32 count = me->GetAuraCount(e.event.aura.spell); - if ((!e.event.aura.count && !count) || (e.event.aura.count && count >= e.event.aura.count)) - ProcessTimedAction(e, e.event.aura.repeatMin, e.event.aura.repeatMax); - break; - } - case SMART_EVENT_TARGET_BUFFED: - { - if (!me || !me->GetVictim()) - return; - uint32 count = me->GetVictim()->GetAuraCount(e.event.aura.spell); - if (count < e.event.aura.count) - return; + ProcessTimedAction(e, e.event.missingBuff.repeatMin, e.event.missingBuff.repeatMax, Trinity::Containers::SelectRandomContainerElement(pList)); + break; + } + case SMART_EVENT_HAS_AURA: + { + if (!me) + return; + uint32 count = me->GetAuraCount(e.event.aura.spell); + if ((!e.event.aura.count && !count) || (e.event.aura.count && count >= e.event.aura.count)) ProcessTimedAction(e, e.event.aura.repeatMin, e.event.aura.repeatMax); - break; - } - //no params - case SMART_EVENT_AGGRO: - case SMART_EVENT_DEATH: - case SMART_EVENT_EVADE: - case SMART_EVENT_REACHED_HOME: - case SMART_EVENT_CHARMED: - case SMART_EVENT_CHARMED_TARGET: - case SMART_EVENT_CORPSE_REMOVED: - case SMART_EVENT_AI_INIT: - case SMART_EVENT_TRANSPORT_ADDPLAYER: - case SMART_EVENT_TRANSPORT_REMOVE_PLAYER: - case SMART_EVENT_QUEST_ACCEPTED: - case SMART_EVENT_QUEST_OBJ_COPLETETION: - case SMART_EVENT_QUEST_COMPLETION: - case SMART_EVENT_QUEST_REWARDED: - case SMART_EVENT_QUEST_FAIL: - case SMART_EVENT_JUST_SUMMONED: - case SMART_EVENT_RESET: - case SMART_EVENT_JUST_CREATED: - case SMART_EVENT_FOLLOW_COMPLETED: - case SMART_EVENT_ON_SPELLCLICK: - ProcessAction(e, unit, var0, var1, bvar, spell, gob); - break; + break; + } + case SMART_EVENT_TARGET_BUFFED: + { + if (!me || !me->GetVictim()) + return; + uint32 count = me->GetVictim()->GetAuraCount(e.event.aura.spell); + if (count < e.event.aura.count) + return; + ProcessTimedAction(e, e.event.aura.repeatMin, e.event.aura.repeatMax); + break; + } + //no params + case SMART_EVENT_AGGRO: + case SMART_EVENT_DEATH: + case SMART_EVENT_EVADE: + case SMART_EVENT_REACHED_HOME: + case SMART_EVENT_CHARMED: + case SMART_EVENT_CHARMED_TARGET: + case SMART_EVENT_CORPSE_REMOVED: + case SMART_EVENT_AI_INIT: + case SMART_EVENT_TRANSPORT_ADDPLAYER: + case SMART_EVENT_TRANSPORT_REMOVE_PLAYER: + case SMART_EVENT_QUEST_ACCEPTED: + case SMART_EVENT_QUEST_OBJ_COPLETETION: + case SMART_EVENT_QUEST_COMPLETION: + case SMART_EVENT_QUEST_REWARDED: + case SMART_EVENT_QUEST_FAIL: + case SMART_EVENT_JUST_SUMMONED: + case SMART_EVENT_RESET: + case SMART_EVENT_JUST_CREATED: + case SMART_EVENT_FOLLOW_COMPLETED: + case SMART_EVENT_ON_SPELLCLICK: + ProcessAction(e, unit, var0, var1, bvar, spell, gob); + break; // Xinef: added no report use distinction for gameobjects - case SMART_EVENT_GOSSIP_HELLO: - if (e.event.gossipHello.noReportUse && var0) - return; - ProcessAction(e, unit, var0, var1, bvar, spell, gob); - break; - case SMART_EVENT_IS_BEHIND_TARGET: - { - if (!me) - return; + case SMART_EVENT_GOSSIP_HELLO: + if (e.event.gossipHello.noReportUse && var0) + return; + ProcessAction(e, unit, var0, var1, bvar, spell, gob); + break; + case SMART_EVENT_IS_BEHIND_TARGET: + { + if (!me) + return; - if (Unit* victim = me->GetVictim()) - { - if (!victim->HasInArc(static_cast<float>(M_PI), me)) - ProcessTimedAction(e, e.event.behindTarget.cooldownMin, e.event.behindTarget.cooldownMax, victim); - } - break; - } - case SMART_EVENT_RECEIVE_EMOTE: - if (e.event.emote.emote == var0) - { - ProcessAction(e, unit); - RecalcTimer(e, e.event.emote.cooldownMin, e.event.emote.cooldownMax); - } - break; - case SMART_EVENT_KILL: + if (Unit* victim = me->GetVictim()) { - if (!me || !unit) - return; - if (e.event.kill.playerOnly && unit->GetTypeId() != TYPEID_PLAYER) - return; - if (e.event.kill.creature && unit->GetEntry() != e.event.kill.creature) - return; - RecalcTimer(e, e.event.kill.cooldownMin, e.event.kill.cooldownMax); - ProcessAction(e, unit); - break; + if (!victim->HasInArc(static_cast<float>(M_PI), me)) + ProcessTimedAction(e, e.event.behindTarget.cooldownMin, e.event.behindTarget.cooldownMax, victim); } - case SMART_EVENT_SPELLHIT_TARGET: - case SMART_EVENT_SPELLHIT: + break; + } + case SMART_EVENT_RECEIVE_EMOTE: + if (e.event.emote.emote == var0) { - if (!spell) - return; - if ((!e.event.spellHit.spell || spell->Id == e.event.spellHit.spell) && - (!e.event.spellHit.school || (spell->SchoolMask & e.event.spellHit.school))) - { - RecalcTimer(e, e.event.spellHit.cooldownMin, e.event.spellHit.cooldownMax); - ProcessAction(e, unit, 0, 0, bvar, spell); - } - break; + ProcessAction(e, unit); + RecalcTimer(e, e.event.emote.cooldownMin, e.event.emote.cooldownMax); } - case SMART_EVENT_OOC_LOS: + break; + case SMART_EVENT_KILL: + { + if (!me || !unit) + return; + if (e.event.kill.playerOnly && unit->GetTypeId() != TYPEID_PLAYER) + return; + if (e.event.kill.creature && unit->GetEntry() != e.event.kill.creature) + return; + RecalcTimer(e, e.event.kill.cooldownMin, e.event.kill.cooldownMax); + ProcessAction(e, unit); + break; + } + case SMART_EVENT_SPELLHIT_TARGET: + case SMART_EVENT_SPELLHIT: + { + if (!spell) + return; + if ((!e.event.spellHit.spell || spell->Id == e.event.spellHit.spell) && + (!e.event.spellHit.school || (spell->SchoolMask & e.event.spellHit.school))) { - if (!me || me->IsInCombat()) - return; - //can trigger if closer than fMaxAllowedRange - float range = (float)e.event.los.maxDist; + RecalcTimer(e, e.event.spellHit.cooldownMin, e.event.spellHit.cooldownMax); + ProcessAction(e, unit, 0, 0, bvar, spell); + } + break; + } + case SMART_EVENT_OOC_LOS: + { + if (!me || me->IsInCombat()) + return; + //can trigger if closer than fMaxAllowedRange + float range = (float)e.event.los.maxDist; - //if range is ok and we are actually in LOS - if (me->IsWithinDistInMap(unit, range) && me->IsWithinLOSInMap(unit)) + //if range is ok and we are actually in LOS + if (me->IsWithinDistInMap(unit, range) && me->IsWithinLOSInMap(unit)) + { + //if friendly event&&who is not hostile OR hostile event&&who is hostile + if ((e.event.los.noHostile && !me->IsHostileTo(unit)) || + (!e.event.los.noHostile && me->IsHostileTo(unit))) { - //if friendly event&&who is not hostile OR hostile event&&who is hostile - if ((e.event.los.noHostile && !me->IsHostileTo(unit)) || - (!e.event.los.noHostile && me->IsHostileTo(unit))) - { - RecalcTimer(e, e.event.los.cooldownMin, e.event.los.cooldownMax); - ProcessAction(e, unit); - } + RecalcTimer(e, e.event.los.cooldownMin, e.event.los.cooldownMax); + ProcessAction(e, unit); } - break; } - case SMART_EVENT_IC_LOS: - { - if (!me || !me->IsInCombat()) - return; - //can trigger if closer than fMaxAllowedRange - float range = (float)e.event.los.maxDist; + break; + } + case SMART_EVENT_IC_LOS: + { + if (!me || !me->IsInCombat()) + return; + //can trigger if closer than fMaxAllowedRange + float range = (float)e.event.los.maxDist; - //if range is ok and we are actually in LOS - if (me->IsWithinDistInMap(unit, range) && me->IsWithinLOSInMap(unit)) + //if range is ok and we are actually in LOS + if (me->IsWithinDistInMap(unit, range) && me->IsWithinLOSInMap(unit)) + { + //if friendly event&&who is not hostile OR hostile event&&who is hostile + if ((e.event.los.noHostile && !me->IsHostileTo(unit)) || + (!e.event.los.noHostile && me->IsHostileTo(unit))) { - //if friendly event&&who is not hostile OR hostile event&&who is hostile - if ((e.event.los.noHostile && !me->IsHostileTo(unit)) || - (!e.event.los.noHostile && me->IsHostileTo(unit))) - { - RecalcTimer(e, e.event.los.cooldownMin, e.event.los.cooldownMax); - ProcessAction(e, unit); - } + RecalcTimer(e, e.event.los.cooldownMin, e.event.los.cooldownMax); + ProcessAction(e, unit); } - break; - } - case SMART_EVENT_RESPAWN: - { - if (!GetBaseObject()) - return; - if (e.event.respawn.type == SMART_SCRIPT_RESPAWN_CONDITION_MAP && GetBaseObject()->GetMapId() != e.event.respawn.map) - return; - if (e.event.respawn.type == SMART_SCRIPT_RESPAWN_CONDITION_AREA && GetBaseObject()->GetZoneId() != e.event.respawn.area) - return; - ProcessAction(e); - break; - } - case SMART_EVENT_SUMMONED_UNIT: - { - if (!IsCreature(unit)) - return; - if (e.event.summoned.creature && unit->GetEntry() != e.event.summoned.creature) - return; - RecalcTimer(e, e.event.summoned.cooldownMin, e.event.summoned.cooldownMax); - ProcessAction(e, unit); - break; - } - case SMART_EVENT_RECEIVE_HEAL: - case SMART_EVENT_DAMAGED: - case SMART_EVENT_DAMAGED_TARGET: - { - if (var0 > e.event.minMaxRepeat.max || var0 < e.event.minMaxRepeat.min) - return; - RecalcTimer(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); - ProcessAction(e, unit); - break; - } - case SMART_EVENT_MOVEMENTINFORM: - { - if ((e.event.movementInform.type && var0 != e.event.movementInform.type) || (e.event.movementInform.id && var1 != e.event.movementInform.id)) - return; - ProcessAction(e, unit, var0, var1); - break; - } - case SMART_EVENT_TRANSPORT_RELOCATE: - case SMART_EVENT_WAYPOINT_START: - { - if (e.event.waypoint.pathID && var0 != e.event.waypoint.pathID) - return; - ProcessAction(e, unit, var0); - break; - } - case SMART_EVENT_WAYPOINT_REACHED: - case SMART_EVENT_WAYPOINT_RESUMED: - case SMART_EVENT_WAYPOINT_PAUSED: - case SMART_EVENT_WAYPOINT_STOPPED: - case SMART_EVENT_WAYPOINT_ENDED: - { - if (!me || (e.event.waypoint.pointID && var0 != e.event.waypoint.pointID) || (e.event.waypoint.pathID && GetPathId() != e.event.waypoint.pathID)) - return; - ProcessAction(e, unit); - break; - } - case SMART_EVENT_SUMMON_DESPAWNED: - { - if (e.event.summoned.creature && e.event.summoned.creature != var0) - return; - RecalcTimer(e, e.event.summoned.cooldownMin, e.event.summoned.cooldownMax); - ProcessAction(e, unit, var0); - break; - } - case SMART_EVENT_INSTANCE_PLAYER_ENTER: - { - if (e.event.instancePlayerEnter.team && var0 != e.event.instancePlayerEnter.team) - return; - RecalcTimer(e, e.event.instancePlayerEnter.cooldownMin, e.event.instancePlayerEnter.cooldownMax); - ProcessAction(e, unit, var0); - break; - } - case SMART_EVENT_ACCEPTED_QUEST: - case SMART_EVENT_REWARD_QUEST: - { - if (e.event.quest.quest && var0 != e.event.quest.quest) - return; - ProcessAction(e, unit, var0); - break; - } - case SMART_EVENT_TRANSPORT_ADDCREATURE: - { - if (e.event.transportAddCreature.creature && var0 != e.event.transportAddCreature.creature) - return; - ProcessAction(e, unit, var0); - break; - } - case SMART_EVENT_AREATRIGGER_ONTRIGGER: - { - if (e.event.areatrigger.id && var0 != e.event.areatrigger.id) - return; - ProcessAction(e, unit, var0); - break; } - case SMART_EVENT_TEXT_OVER: - { - if (var0 != e.event.textOver.textGroupID || (e.event.textOver.creatureEntry && e.event.textOver.creatureEntry != var1)) - return; - ProcessAction(e, unit, var0); - break; - } - case SMART_EVENT_DATA_SET: - { - if (e.event.dataSet.id != var0 || e.event.dataSet.value != var1) - return; - RecalcTimer(e, e.event.dataSet.cooldownMin, e.event.dataSet.cooldownMax); - ProcessAction(e, unit, var0, var1); - break; - } - case SMART_EVENT_PASSENGER_REMOVED: - case SMART_EVENT_PASSENGER_BOARDED: - { - if (!unit) - return; - RecalcTimer(e, e.event.minMax.repeatMin, e.event.minMax.repeatMax); + break; + } + case SMART_EVENT_RESPAWN: + { + if (!GetBaseObject()) + return; + if (e.event.respawn.type == SMART_SCRIPT_RESPAWN_CONDITION_MAP && GetBaseObject()->GetMapId() != e.event.respawn.map) + return; + if (e.event.respawn.type == SMART_SCRIPT_RESPAWN_CONDITION_AREA && GetBaseObject()->GetZoneId() != e.event.respawn.area) + return; + ProcessAction(e); + break; + } + case SMART_EVENT_SUMMONED_UNIT: + { + if (!IsCreature(unit)) + return; + if (e.event.summoned.creature && unit->GetEntry() != e.event.summoned.creature) + return; + RecalcTimer(e, e.event.summoned.cooldownMin, e.event.summoned.cooldownMax); + ProcessAction(e, unit); + break; + } + case SMART_EVENT_RECEIVE_HEAL: + case SMART_EVENT_DAMAGED: + case SMART_EVENT_DAMAGED_TARGET: + { + if (var0 > e.event.minMaxRepeat.max || var0 < e.event.minMaxRepeat.min) + return; + RecalcTimer(e, e.event.minMaxRepeat.repeatMin, e.event.minMaxRepeat.repeatMax); + ProcessAction(e, unit); + break; + } + case SMART_EVENT_MOVEMENTINFORM: + { + if ((e.event.movementInform.type && var0 != e.event.movementInform.type) || (e.event.movementInform.id && var1 != e.event.movementInform.id)) + return; + ProcessAction(e, unit, var0, var1); + break; + } + case SMART_EVENT_TRANSPORT_RELOCATE: + case SMART_EVENT_WAYPOINT_START: + { + if (e.event.waypoint.pathID && var0 != e.event.waypoint.pathID) + return; + ProcessAction(e, unit, var0); + break; + } + case SMART_EVENT_WAYPOINT_REACHED: + case SMART_EVENT_WAYPOINT_RESUMED: + case SMART_EVENT_WAYPOINT_PAUSED: + case SMART_EVENT_WAYPOINT_STOPPED: + case SMART_EVENT_WAYPOINT_ENDED: + { + if (!me || (e.event.waypoint.pointID && var0 != e.event.waypoint.pointID) || (e.event.waypoint.pathID && GetPathId() != e.event.waypoint.pathID)) + return; + ProcessAction(e, unit); + break; + } + case SMART_EVENT_SUMMON_DESPAWNED: + { + if (e.event.summoned.creature && e.event.summoned.creature != var0) + return; + RecalcTimer(e, e.event.summoned.cooldownMin, e.event.summoned.cooldownMax); + ProcessAction(e, unit, var0); + break; + } + case SMART_EVENT_INSTANCE_PLAYER_ENTER: + { + if (e.event.instancePlayerEnter.team && var0 != e.event.instancePlayerEnter.team) + return; + RecalcTimer(e, e.event.instancePlayerEnter.cooldownMin, e.event.instancePlayerEnter.cooldownMax); + ProcessAction(e, unit, var0); + break; + } + case SMART_EVENT_ACCEPTED_QUEST: + case SMART_EVENT_REWARD_QUEST: + { + if (e.event.quest.quest && var0 != e.event.quest.quest) + return; + ProcessAction(e, unit, var0); + break; + } + case SMART_EVENT_TRANSPORT_ADDCREATURE: + { + if (e.event.transportAddCreature.creature && var0 != e.event.transportAddCreature.creature) + return; + ProcessAction(e, unit, var0); + break; + } + case SMART_EVENT_AREATRIGGER_ONTRIGGER: + { + if (e.event.areatrigger.id && var0 != e.event.areatrigger.id) + return; + ProcessAction(e, unit, var0); + break; + } + case SMART_EVENT_TEXT_OVER: + { + if (var0 != e.event.textOver.textGroupID || (e.event.textOver.creatureEntry && e.event.textOver.creatureEntry != var1)) + return; + ProcessAction(e, unit, var0); + break; + } + case SMART_EVENT_DATA_SET: + { + if (e.event.dataSet.id != var0 || e.event.dataSet.value != var1) + return; + RecalcTimer(e, e.event.dataSet.cooldownMin, e.event.dataSet.cooldownMax); + ProcessAction(e, unit, var0, var1); + break; + } + case SMART_EVENT_PASSENGER_REMOVED: + case SMART_EVENT_PASSENGER_BOARDED: + { + if (!unit) + return; + RecalcTimer(e, e.event.minMax.repeatMin, e.event.minMax.repeatMax); + ProcessAction(e, unit); + break; + } + case SMART_EVENT_TIMED_EVENT_TRIGGERED: + { + if (e.event.timedEvent.id == var0) ProcessAction(e, unit); - break; - } - case SMART_EVENT_TIMED_EVENT_TRIGGERED: - { - if (e.event.timedEvent.id == var0) - ProcessAction(e, unit); - break; - } - case SMART_EVENT_GOSSIP_SELECT: - { -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript: Gossip Select: menu %u action %u", var0, var1);//little help for scripters + break; + } + case SMART_EVENT_GOSSIP_SELECT: + { +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript: Gossip Select: menu %u action %u", var0, var1); //little help for scripters #endif - if (e.event.gossip.sender != var0 || e.event.gossip.action != var1) - return; - ProcessAction(e, unit, var0, var1); - break; - } - case SMART_EVENT_GAME_EVENT_START: - case SMART_EVENT_GAME_EVENT_END: - { - if (e.event.gameEvent.gameEventId != var0) - return; - ProcessAction(e, NULL, var0); - break; - } - case SMART_EVENT_GO_STATE_CHANGED: - { - if (e.event.goStateChanged.state != var0) - return; - ProcessAction(e, unit, var0, var1); - break; - } - case SMART_EVENT_GO_EVENT_INFORM: - { - if (e.event.eventInform.eventId != var0) - return; - ProcessAction(e, NULL, var0); - break; - } - case SMART_EVENT_ACTION_DONE: + if (e.event.gossip.sender != var0 || e.event.gossip.action != var1) + return; + ProcessAction(e, unit, var0, var1); + break; + } + case SMART_EVENT_GAME_EVENT_START: + case SMART_EVENT_GAME_EVENT_END: + { + if (e.event.gameEvent.gameEventId != var0) + return; + ProcessAction(e, NULL, var0); + break; + } + case SMART_EVENT_GO_STATE_CHANGED: + { + if (e.event.goStateChanged.state != var0) + return; + ProcessAction(e, unit, var0, var1); + break; + } + case SMART_EVENT_GO_EVENT_INFORM: + { + if (e.event.eventInform.eventId != var0) + return; + ProcessAction(e, NULL, var0); + break; + } + case SMART_EVENT_ACTION_DONE: + { + if (e.event.doAction.eventId != var0) + return; + ProcessAction(e, unit, var0); + break; + } + case SMART_EVENT_FRIENDLY_HEALTH_PCT: + { + if (!me || !me->IsInCombat()) + return; + + ObjectList* _targets = NULL; + + switch (e.GetTargetType()) { - if (e.event.doAction.eventId != var0) - return; - ProcessAction(e, unit, var0); + case SMART_TARGET_CREATURE_RANGE: + case SMART_TARGET_CREATURE_GUID: + case SMART_TARGET_CREATURE_DISTANCE: + case SMART_TARGET_CLOSEST_CREATURE: + case SMART_TARGET_CLOSEST_PLAYER: + case SMART_TARGET_PLAYER_RANGE: + case SMART_TARGET_PLAYER_DISTANCE: + _targets = GetTargets(e); break; + default: + return; } - case SMART_EVENT_FRIENDLY_HEALTH_PCT: - { - if (!me || !me->IsInCombat()) - return; - ObjectList* _targets = NULL; + if (!_targets) + return; + + Unit* target = NULL; - switch (e.GetTargetType()) + for (ObjectList::const_iterator itr = _targets->begin(); itr != _targets->end(); ++itr) + { + if (IsUnit(*itr) && me->IsFriendlyTo((*itr)->ToUnit()) && (*itr)->ToUnit()->IsAlive() && (*itr)->ToUnit()->IsInCombat()) { - case SMART_TARGET_CREATURE_RANGE: - case SMART_TARGET_CREATURE_GUID: - case SMART_TARGET_CREATURE_DISTANCE: - case SMART_TARGET_CLOSEST_CREATURE: - case SMART_TARGET_CLOSEST_PLAYER: - case SMART_TARGET_PLAYER_RANGE: - case SMART_TARGET_PLAYER_DISTANCE: - _targets = GetTargets(e); - break; - default: - return; - } + uint32 healthPct = uint32((*itr)->ToUnit()->GetHealthPct()); - if (!_targets) - return; + if (healthPct > e.event.friendlyHealthPct.maxHpPct || healthPct < e.event.friendlyHealthPct.minHpPct) + continue; - Unit* target = NULL; + target = (*itr)->ToUnit(); + break; + } + } - for (ObjectList::const_iterator itr = _targets->begin(); itr != _targets->end(); ++itr) - { - if (IsUnit(*itr) && me->IsFriendlyTo((*itr)->ToUnit()) && (*itr)->ToUnit()->IsAlive() && (*itr)->ToUnit()->IsInCombat()) - { - uint32 healthPct = uint32((*itr)->ToUnit()->GetHealthPct()); + delete _targets; - if (healthPct > e.event.friendlyHealthPct.maxHpPct || healthPct < e.event.friendlyHealthPct.minHpPct) - continue; + if (!target) + return; - target = (*itr)->ToUnit(); - break; - } - } + ProcessTimedAction(e, e.event.friendlyHealthPct.repeatMin, e.event.friendlyHealthPct.repeatMax, target); + break; + } + case SMART_EVENT_DISTANCE_CREATURE: + { + if (!me) + return; - delete _targets; + WorldObject* creature = NULL; - if (!target) + if (e.event.distance.guid != 0) + { + creature = FindCreatureNear(me, e.event.distance.guid); + + if (!creature) return; - ProcessTimedAction(e, e.event.friendlyHealthPct.repeatMin, e.event.friendlyHealthPct.repeatMax, target); - break; + if (!me->IsInRange(creature, 0, (float)e.event.distance.dist)) + return; } - case SMART_EVENT_DISTANCE_CREATURE: + else if (e.event.distance.entry != 0) { - if (!me) - return; + std::list<Creature*> list; + me->GetCreatureListWithEntryInGrid(list, e.event.distance.entry, (float)e.event.distance.dist); - WorldObject* creature = NULL; + if (!list.empty()) + creature = list.front(); + } - if (e.event.distance.guid != 0) - { - creature = FindCreatureNear(me, e.event.distance.guid); + if (creature) + ProcessTimedAction(e, e.event.distance.repeat, e.event.distance.repeat); - if (!creature) - return; + break; + } + case SMART_EVENT_DISTANCE_GAMEOBJECT: + { + if (!me) + return; - if (!me->IsInRange(creature, 0, (float)e.event.distance.dist)) - return; - } - else if (e.event.distance.entry != 0) - { - std::list<Creature*> list; - me->GetCreatureListWithEntryInGrid(list, e.event.distance.entry, (float)e.event.distance.dist); + WorldObject* gameobject = NULL; - if (!list.empty()) - creature = list.front(); - } + if (e.event.distance.guid != 0) + { + gameobject = FindGameObjectNear(me, e.event.distance.guid); - if (creature) - ProcessTimedAction(e, e.event.distance.repeat, e.event.distance.repeat); + if (!gameobject) + return; - break; + if (!me->IsInRange(gameobject, 0, (float)e.event.distance.dist)) + return; } - case SMART_EVENT_DISTANCE_GAMEOBJECT: + else if (e.event.distance.entry != 0) { - if (!me) - return; + std::list<GameObject*> list; + me->GetGameObjectListWithEntryInGrid(list, e.event.distance.entry, (float)e.event.distance.dist); - WorldObject* gameobject = NULL; - - if (e.event.distance.guid != 0) - { - gameobject = FindGameObjectNear(me, e.event.distance.guid); - - if (!gameobject) - return; - - if (!me->IsInRange(gameobject, 0, (float)e.event.distance.dist)) - return; - } - else if (e.event.distance.entry != 0) - { - std::list<GameObject*> list; - me->GetGameObjectListWithEntryInGrid(list, e.event.distance.entry, (float)e.event.distance.dist); - - if (!list.empty()) - gameobject = list.front(); - } + if (!list.empty()) + gameobject = list.front(); + } - if (gameobject) - ProcessTimedAction(e, e.event.distance.repeat, e.event.distance.repeat); + if (gameobject) + ProcessTimedAction(e, e.event.distance.repeat, e.event.distance.repeat); - break; - } - case SMART_EVENT_COUNTER_SET: - if (e.event.counter.id != var0 || GetCounterValue(e.event.counter.id) != e.event.counter.value) - return; + break; + } + case SMART_EVENT_COUNTER_SET: + if (e.event.counter.id != var0 || GetCounterValue(e.event.counter.id) != e.event.counter.value) + return; - ProcessTimedAction(e, e.event.counter.cooldownMin, e.event.counter.cooldownMax); - break; - default: - sLog->outErrorDb("SmartScript::ProcessEvent: Unhandled Event type %u", e.GetEventType()); - break; + ProcessTimedAction(e, e.event.counter.cooldownMin, e.event.counter.cooldownMax); + break; + default: + sLog->outErrorDb("SmartScript::ProcessEvent: Unhandled Event type %u", e.GetEventType()); + break; } } @@ -3887,23 +3919,23 @@ void SmartScript::InitTimer(SmartScriptHolder& e) switch (e.GetEventType()) { //set only events which have initial timers - case SMART_EVENT_UPDATE: - case SMART_EVENT_UPDATE_IC: - case SMART_EVENT_UPDATE_OOC: - RecalcTimer(e, e.event.minMaxRepeat.min, e.event.minMaxRepeat.max); - break; - case SMART_EVENT_OOC_LOS: - case SMART_EVENT_IC_LOS: - // Xinef: wtf is this bullshit? cooldown should be processed AFTER action is done, not before... - //RecalcTimer(e, e.event.los.cooldownMin, e.event.los.cooldownMax); - //break; - case SMART_EVENT_DISTANCE_CREATURE: - case SMART_EVENT_DISTANCE_GAMEOBJECT: - RecalcTimer(e, e.event.distance.repeat, e.event.distance.repeat); - break; - default: - e.active = true; - break; + case SMART_EVENT_UPDATE: + case SMART_EVENT_UPDATE_IC: + case SMART_EVENT_UPDATE_OOC: + RecalcTimer(e, e.event.minMaxRepeat.min, e.event.minMaxRepeat.max); + break; + case SMART_EVENT_OOC_LOS: + case SMART_EVENT_IC_LOS: + // Xinef: wtf is this bullshit? cooldown should be processed AFTER action is done, not before... + //RecalcTimer(e, e.event.los.cooldownMin, e.event.los.cooldownMax); + //break; + case SMART_EVENT_DISTANCE_CREATURE: + case SMART_EVENT_DISTANCE_GAMEOBJECT: + RecalcTimer(e, e.event.distance.repeat, e.event.distance.repeat); + break; + default: + e.active = true; + break; } } void SmartScript::RecalcTimer(SmartScriptHolder& e, uint32 min, uint32 max) @@ -3945,41 +3977,41 @@ void SmartScript::UpdateTimer(SmartScriptHolder& e, uint32 const diff) e.active = true;//activate events with cooldown switch (e.GetEventType())//process ONLY timed events { - case SMART_EVENT_UPDATE: - case SMART_EVENT_UPDATE_OOC: - case SMART_EVENT_UPDATE_IC: - case SMART_EVENT_HEALTH_PCT: - case SMART_EVENT_TARGET_HEALTH_PCT: - case SMART_EVENT_MANA_PCT: - case SMART_EVENT_TARGET_MANA_PCT: - case SMART_EVENT_RANGE: - case SMART_EVENT_VICTIM_CASTING: - case SMART_EVENT_FRIENDLY_HEALTH: - case SMART_EVENT_FRIENDLY_IS_CC: - case SMART_EVENT_FRIENDLY_MISSING_BUFF: - case SMART_EVENT_HAS_AURA: - case SMART_EVENT_TARGET_BUFFED: - case SMART_EVENT_IS_BEHIND_TARGET: - case SMART_EVENT_FRIENDLY_HEALTH_PCT: - case SMART_EVENT_DISTANCE_CREATURE: - case SMART_EVENT_DISTANCE_GAMEOBJECT: + case SMART_EVENT_UPDATE: + case SMART_EVENT_UPDATE_OOC: + case SMART_EVENT_UPDATE_IC: + case SMART_EVENT_HEALTH_PCT: + case SMART_EVENT_TARGET_HEALTH_PCT: + case SMART_EVENT_MANA_PCT: + case SMART_EVENT_TARGET_MANA_PCT: + case SMART_EVENT_RANGE: + case SMART_EVENT_VICTIM_CASTING: + case SMART_EVENT_FRIENDLY_HEALTH: + case SMART_EVENT_FRIENDLY_IS_CC: + case SMART_EVENT_FRIENDLY_MISSING_BUFF: + case SMART_EVENT_HAS_AURA: + case SMART_EVENT_TARGET_BUFFED: + case SMART_EVENT_IS_BEHIND_TARGET: + case SMART_EVENT_FRIENDLY_HEALTH_PCT: + case SMART_EVENT_DISTANCE_CREATURE: + case SMART_EVENT_DISTANCE_GAMEOBJECT: + { + ProcessEvent(e); + if (e.GetScriptType() == SMART_SCRIPT_TYPE_TIMED_ACTIONLIST) { - ProcessEvent(e); - if (e.GetScriptType() == SMART_SCRIPT_TYPE_TIMED_ACTIONLIST) + e.enableTimed = false;//disable event if it is in an ActionList and was processed once + for (SmartAIEventList::iterator i = mTimedActionList.begin(); i != mTimedActionList.end(); ++i) { - e.enableTimed = false;//disable event if it is in an ActionList and was processed once - for (SmartAIEventList::iterator i = mTimedActionList.begin(); i != mTimedActionList.end(); ++i) + //find the first event which is not the current one and enable it + if (i->event_id > e.event_id) { - //find the first event which is not the current one and enable it - if (i->event_id > e.event_id) - { - i->enableTimed = true; - break; - } + i->enableTimed = true; + break; } } - break; } + break; + } } } else @@ -4043,7 +4075,7 @@ void SmartScript::OnUpdate(uint32 const diff) if (!mRemIDs.empty()) { for (std::list<uint32>::const_iterator i = mRemIDs.begin(); i != mRemIDs.end(); ++i) - RemoveStoredEvent(*i); + RemoveStoredEvent(*i); // xinef: clear list after cleaning... mRemIDs.clear(); @@ -4059,7 +4091,8 @@ void SmartScript::OnUpdate(uint32 const diff) mTextTimer = 0; mUseTextTimer = false; ProcessEventsFor(SMART_EVENT_TEXT_OVER, NULL, textID, entry); - } else mTextTimer -= diff; + } + else mTextTimer -= diff; } } @@ -4067,28 +4100,29 @@ void SmartScript::FillScript(SmartAIEventList e, WorldObject* obj, AreaTriggerEn { if (e.empty()) { - //if (obj) -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + if (obj) sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript: EventMap for Entry %u is empty but is using SmartScript.", obj->GetEntry()); #endif - //if (at) -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS + +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + if (at) sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript: EventMap for AreaTrigger %u is empty but is using SmartScript.", at->id); #endif return; } for (SmartAIEventList::iterator i = e.begin(); i != e.end(); ++i) { - #ifndef TRINITY_DEBUG - if ((*i).event.event_flags & SMART_EVENT_FLAG_DEBUG_ONLY) - continue; - #endif +#ifndef TRINITY_DEBUG + if ((*i).event.event_flags & SMART_EVENT_FLAG_DEBUG_ONLY) + continue; +#endif if ((*i).event.event_flags & SMART_EVENT_FLAG_DIFFICULTY_ALL)//if has instance flag add only if in it { if (obj && obj->GetMap()->IsDungeon()) { - if ((1 << (obj->GetMap()->GetSpawnMode()+1)) & (*i).event.event_flags) + if ((1 << (obj->GetMap()->GetSpawnMode() + 1)) & (*i).event.event_flags) { mEvents.push_back((*i)); } @@ -4133,29 +4167,30 @@ void SmartScript::OnInitialize(WorldObject* obj, AreaTriggerEntry const* at) { switch (obj->GetTypeId()) { - case TYPEID_UNIT: - mScriptType = SMART_SCRIPT_TYPE_CREATURE; - me = obj->ToCreature(); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::OnInitialize: source is Creature %u", me->GetEntry()); + case TYPEID_UNIT: + mScriptType = SMART_SCRIPT_TYPE_CREATURE; + me = obj->ToCreature(); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::OnInitialize: source is Creature %u", me->GetEntry()); #endif - break; - case TYPEID_GAMEOBJECT: - mScriptType = SMART_SCRIPT_TYPE_GAMEOBJECT; - go = obj->ToGameObject(); -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS - sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::OnInitialize: source is GameObject %u", go->GetEntry()); + break; + case TYPEID_GAMEOBJECT: + mScriptType = SMART_SCRIPT_TYPE_GAMEOBJECT; + go = obj->ToGameObject(); +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) + sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::OnInitialize: source is GameObject %u", go->GetEntry()); #endif - break; - default: - sLog->outError("SmartScript::OnInitialize: Unhandled TypeID !WARNING!"); - return; + break; + default: + sLog->outError("SmartScript::OnInitialize: Unhandled TypeID !WARNING!"); + return; } - } else if (at) + } + else if (at) { mScriptType = SMART_SCRIPT_TYPE_AREATRIGGER; trigger = at; -#ifdef ENABLE_EXTRAS && ENABLE_EXTRA_LOGS +#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::OnInitialize: source is AreaTrigger %u", trigger->id); #endif } @@ -4224,7 +4259,7 @@ void SmartScript::DoAction(int32 param) uint32 SmartScript::GetData(uint32 id) { - return 0; +return 0; } void SmartScript::SetData(uint32 id, uint32 value) @@ -4237,7 +4272,7 @@ void SmartScript::SetGUID(uint64 guid, int32 id) uint64 SmartScript::GetGUID(int32 id) { - return 0; +return 0; } void SmartScript::MovepointStart(uint32 id) @@ -4254,7 +4289,7 @@ void SmartScript::SetMovePathEndAction(SMART_ACTION action) uint32 SmartScript::DoChat(int8 id, uint64 whisperGuid) { - return 0; +return 0; }*/ // SmartScript end |