diff options
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.cpp | 41 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.h | 24 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.cpp | 21 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.h | 9 |
4 files changed, 72 insertions, 23 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 8edd17ca2ba..969dc87faba 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -81,7 +81,7 @@ void SmartScript::ProcessEventsFor(SMART_EVENT e, Unit* unit, uint32 var0, uint3 if (eventType == SMART_EVENT_LINK)//special handling continue; - if (eventType == e /*&& (!i->event.event_phase_mask || IsInPhase(i->event.event_phase_mask)) && !(i->event.event_flags & SMART_EVENT_FLAG_NOT_REPEATABLE && i->runOnce)*/) + if (eventType == e) if (sConditionMgr->IsObjectMeetingSmartEventConditions(i->entryOrGuid, i->event_id, i->source_type, unit, GetBaseObject())) ProcessEvent(*i, unit, var0, var1, bvar, spell, gob); } @@ -2907,6 +2907,14 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui ProcessAction(e, unit, var0, var1); break; } + case SMART_EVENT_EVENT_PHASE_CHANGE: + { + if (!IsInPhase(e.event.eventPhaseChange.phasemask)) + return; + + ProcessAction(e, GetLastInvoker()); + break; + } case SMART_EVENT_GAME_EVENT_START: case SMART_EVENT_GAME_EVENT_END: { @@ -3427,3 +3435,34 @@ Unit* SmartScript::GetLastInvoker(Unit* invoker) const return nullptr; } + +void SmartScript::IncPhase(uint32 p) +{ + // protect phase from overflowing + SetPhase(std::min<uint32>(SMART_EVENT_PHASE_12, mEventPhase + p)); +} + +void SmartScript::DecPhase(uint32 p) +{ + if (p >= mEventPhase) + SetPhase(0); + else + SetPhase(mEventPhase - p); +} + +void SmartScript::SetPhase(uint32 p) +{ + uint32 oldPhase = mEventPhase; + + mEventPhase = p; + + if (oldPhase != mEventPhase) + ProcessEventsFor(SMART_EVENT_EVENT_PHASE_CHANGE); +} + +bool SmartScript::IsInPhase(uint32 p) const +{ + if (mEventPhase == 0) + return false; + return ((1 << (mEventPhase - 1)) & p) != 0; +} diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index 203d1d0b996..cf10f7d15f4 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -232,28 +232,12 @@ class TC_GAME_API SmartScript CounterMap mCounterList; private: - void IncPhase(uint32 p) - { - // protect phase from overflowing - mEventPhase = std::min<uint32>(SMART_EVENT_PHASE_12, mEventPhase + p); - } - void DecPhase(uint32 p) - { - if (p >= mEventPhase) - mEventPhase = 0; - else - mEventPhase -= p; - } - - bool IsInPhase(uint32 p) const - { - if (mEventPhase == 0) - return false; - return ((1 << (mEventPhase - 1)) & p) != 0; - } + void IncPhase(uint32 p); + void DecPhase(uint32 p); - void SetPhase(uint32 p = 0) { mEventPhase = p; } + void SetPhase(uint32 p); + bool IsInPhase(uint32 p) const; SmartAIEventList mEvents; SmartAIEventList mInstallEvents; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 139826f8efb..d2910208155 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -676,6 +676,27 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) if (!IsTextValid(e, e.event.textOver.textGroupID)) return false; break; + case SMART_EVENT_EVENT_PHASE_CHANGE: + { + if (!e.event.eventPhaseChange.phasemask) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u has no param set, event won't be executed!.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); + return false; + } + + if (e.event.eventPhaseChange.phasemask > SMART_EVENT_PHASE_ALL) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid phasemask %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.event.eventPhaseChange.phasemask); + return false; + } + + if (e.event.event_phase_mask && !(e.event.event_phase_mask & e.event.eventPhaseChange.phasemask)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses event phasemask %u and incompatible event_param1 %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.event.event_phase_mask, e.event.eventPhaseChange.phasemask); + return false; + } + break; + } case SMART_EVENT_IS_BEHIND_TARGET: { if (!IsMinMaxValid(e, e.event.behindTarget.cooldownMin, e.event.behindTarget.cooldownMax)) diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 02c7b3c550f..29b76ae0dd9 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -177,7 +177,7 @@ enum SMART_EVENT SMART_EVENT_JUST_CREATED = 63, // none SMART_EVENT_GOSSIP_HELLO = 64, // noReportUse (for GOs) SMART_EVENT_FOLLOW_COMPLETED = 65, // none - // 66 unused + SMART_EVENT_EVENT_PHASE_CHANGE = 66, // event phase mask (<= SMART_EVENT_PHASE_ALL) SMART_EVENT_IS_BEHIND_TARGET = 67, // cooldownMin, CooldownMax SMART_EVENT_GAME_EVENT_START = 68, // game_event.Entry SMART_EVENT_GAME_EVENT_END = 69, // game_event.Entry @@ -388,6 +388,11 @@ struct SmartEvent struct { + uint32 phasemask; + } eventPhaseChange; + + struct + { uint32 cooldownMin; uint32 cooldownMax; } behindTarget; @@ -1417,7 +1422,7 @@ const uint32 SmartAIEventMask[SMART_EVENT_END][2] = {SMART_EVENT_JUST_CREATED, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT }, {SMART_EVENT_GOSSIP_HELLO, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT }, {SMART_EVENT_FOLLOW_COMPLETED, SMART_SCRIPT_TYPE_MASK_CREATURE }, - {66, 0 }, // unused + {SMART_EVENT_EVENT_PHASE_CHANGE, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT }, {SMART_EVENT_IS_BEHIND_TARGET, SMART_SCRIPT_TYPE_MASK_CREATURE }, {SMART_EVENT_GAME_EVENT_START, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT }, {SMART_EVENT_GAME_EVENT_END, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT }, |