diff options
| author | Meji <alvaro.megias@outlook.com> | 2023-07-09 11:59:35 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-07-09 11:59:35 +0200 |
| commit | d015711fbb7a8bf57f7bb64ba8113c942d5125de (patch) | |
| tree | 1f89cd7221e829a6c49f80208e8e7508d2f6e1c0 /src/server/game/AI/SmartScripts | |
| parent | 996485e90e2a1ae75a4b93b33bd807f85060ca26 (diff) | |
Core/SAI: Implemented new source type SMART_SCRIPT_TYPE_EVENT (3) (#28816)
Diffstat (limited to 'src/server/game/AI/SmartScripts')
| -rw-r--r-- | src/server/game/AI/SmartScripts/SmartAI.cpp | 16 | ||||
| -rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.cpp | 106 | ||||
| -rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.h | 5 | ||||
| -rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.cpp | 12 | ||||
| -rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.h | 28 |
5 files changed, 118 insertions, 49 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index 372ba77f711..3918f415f9d 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -1242,10 +1242,26 @@ public: } }; +class SmartEventTrigger : public EventScript +{ +public: + SmartEventTrigger() : EventScript("SmartEventTrigger") { } + + void OnTrigger(WorldObject* object, WorldObject* invoker, uint32 eventId) override + { + TC_LOG_DEBUG("scripts.ai", "Event {} is using SmartEventTrigger script", eventId); + SmartScript script; + // Set invoker as BaseObject if there isn't target for GameEvents::Trigger + script.OnInitialize(Coalesce<WorldObject>(object, invoker), nullptr, nullptr, nullptr, eventId); + script.ProcessEventsFor(SMART_EVENT_SEND_EVENT_TRIGGER, invoker->ToUnit(), 0, 0, false, nullptr, invoker->ToGameObject()); + } +}; + void AddSC_SmartScripts() { new SmartTrigger(); new SmartAreaTriggerEntityScript(); new SmartScene(); new SmartQuest(); + new SmartEventTrigger(); } diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 47c5dd279fd..b27e0847c3f 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -54,6 +54,7 @@ SmartScript::SmartScript() areaTrigger = nullptr; sceneTemplate = nullptr; quest = nullptr; + event = 0; mEventPhase = 0; mPathId = 0; mTextTimer = 0; @@ -217,6 +218,7 @@ void SmartScript::ResetBaseObject() me = m; go = nullptr; areaTrigger = nullptr; + player = nullptr; } } @@ -227,6 +229,7 @@ void SmartScript::ResetBaseObject() me = nullptr; go = o; areaTrigger = nullptr; + player = nullptr; } } } @@ -3169,6 +3172,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui case SMART_EVENT_FOLLOW_COMPLETED: case SMART_EVENT_ON_SPELLCLICK: case SMART_EVENT_ON_DESPAWN: + case SMART_EVENT_SEND_EVENT_TRIGGER: ProcessAction(e, unit, var0, var1, bvar, spell, gob); break; case SMART_EVENT_GOSSIP_HELLO: @@ -3910,7 +3914,7 @@ void SmartScript::RetryLater(SmartScriptHolder& e, bool ignoreChanceRoll) e.runOnce = false; } -void SmartScript::FillScript(SmartAIEventList e, WorldObject* obj, AreaTriggerEntry const* at, SceneTemplate const* scene, Quest const* quest) +void SmartScript::FillScript(SmartAIEventList e, WorldObject* obj, AreaTriggerEntry const* at, SceneTemplate const* scene, Quest const* quest, uint32 event) { if (e.empty()) { @@ -3922,6 +3926,8 @@ void SmartScript::FillScript(SmartAIEventList e, WorldObject* obj, AreaTriggerEn TC_LOG_DEBUG("scripts.ai", "SmartScript: EventMap for SceneId {} is empty but is using SmartScript.", scene->SceneId); if (quest) TC_LOG_DEBUG("scripts.ai", "SmartScript: EventMap for Quest {} is empty but is using SmartScript.", quest->GetQuestId()); + if (event) + TC_LOG_DEBUG("scripts.ai", "SmartScript: EventMap for Event {} is empty but is using SmartScript.", event); return; } for (SmartScriptHolder& scriptholder : e) @@ -3969,43 +3975,49 @@ void SmartScript::FillScript(SmartAIEventList e, WorldObject* obj, AreaTriggerEn void SmartScript::GetScript() { SmartAIEventList e; - if (me) - { - e = sSmartScriptMgr->GetScript(-((int32)me->GetSpawnId()), mScriptType); - if (e.empty()) - e = sSmartScriptMgr->GetScript((int32)me->GetEntry(), mScriptType); - FillScript(std::move(e), me, nullptr, nullptr, nullptr); - } - else if (go) - { - e = sSmartScriptMgr->GetScript(-((int32)go->GetSpawnId()), mScriptType); - if (e.empty()) - e = sSmartScriptMgr->GetScript((int32)go->GetEntry(), mScriptType); - FillScript(std::move(e), go, nullptr, nullptr, nullptr); - } - else if (trigger) - { - e = sSmartScriptMgr->GetScript((int32)trigger->ID, mScriptType); - FillScript(std::move(e), nullptr, trigger, nullptr, nullptr); - } - else if (areaTrigger) - { - e = sSmartScriptMgr->GetScript((int32)areaTrigger->GetEntry(), mScriptType); - FillScript(std::move(e), areaTrigger, nullptr, nullptr, nullptr); - } - else if (sceneTemplate) - { - e = sSmartScriptMgr->GetScript(sceneTemplate->SceneId, mScriptType); - FillScript(std::move(e), nullptr, nullptr, sceneTemplate, nullptr); - } - else if (quest) + + // We must use script type to avoid ambiguities + switch (mScriptType) { - e = sSmartScriptMgr->GetScript(quest->GetQuestId(), mScriptType); - FillScript(std::move(e), nullptr, nullptr, nullptr, quest); + case SMART_SCRIPT_TYPE_CREATURE: + e = sSmartScriptMgr->GetScript(-((int32)me->GetSpawnId()), mScriptType); + if (e.empty()) + e = sSmartScriptMgr->GetScript((int32)me->GetEntry(), mScriptType); + FillScript(std::move(e), me, nullptr, nullptr, nullptr, 0); + break; + case SMART_SCRIPT_TYPE_GAMEOBJECT: + e = sSmartScriptMgr->GetScript(-((int32)go->GetSpawnId()), mScriptType); + if (e.empty()) + e = sSmartScriptMgr->GetScript((int32)go->GetEntry(), mScriptType); + FillScript(std::move(e), go, nullptr, nullptr, nullptr, 0); + break; + case SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY: + case SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY_SERVERSIDE: + e = sSmartScriptMgr->GetScript((int32)areaTrigger->GetEntry(), mScriptType); + FillScript(std::move(e), areaTrigger, nullptr, nullptr, nullptr, 0); + break; + case SMART_SCRIPT_TYPE_AREATRIGGER: + e = sSmartScriptMgr->GetScript((int32)trigger->ID, mScriptType); + FillScript(std::move(e), nullptr, trigger, nullptr, nullptr, 0); + break; + case SMART_SCRIPT_TYPE_SCENE: + e = sSmartScriptMgr->GetScript(sceneTemplate->SceneId, mScriptType); + FillScript(std::move(e), nullptr, nullptr, sceneTemplate, nullptr, 0); + break; + case SMART_SCRIPT_TYPE_QUEST: + e = sSmartScriptMgr->GetScript(quest->GetQuestId(), mScriptType); + FillScript(std::move(e), nullptr, nullptr, nullptr, quest, 0); + break; + case SMART_SCRIPT_TYPE_EVENT: + e = sSmartScriptMgr->GetScript((int32)event, mScriptType); + FillScript(std::move(e), nullptr, nullptr, nullptr, nullptr, event); + break; + default: + break; } } -void SmartScript::OnInitialize(WorldObject* obj, AreaTriggerEntry const* at, SceneTemplate const* scene, Quest const* qst) +void SmartScript::OnInitialize(WorldObject* obj, AreaTriggerEntry const* at, SceneTemplate const* scene, Quest const* qst, uint32 evnt) { if (at) { @@ -4049,6 +4061,32 @@ void SmartScript::OnInitialize(WorldObject* obj, AreaTriggerEntry const* at, Sce TC_LOG_DEBUG("scripts.ai", "SmartScript::OnInitialize: source is Quest with id {}, triggered by player {}", qst->GetQuestId(), player->GetGUID().ToString()); } + else if (evnt) + { + mScriptType = SMART_SCRIPT_TYPE_EVENT; + event = evnt; + + if (obj->IsPlayer()) + { + player = obj->ToPlayer(); + TC_LOG_DEBUG("scripts.ai", "SmartScript::OnInitialize: source is Event {}, triggered by player {}", event, player->GetGUID().ToString()); + } + else if (obj->IsCreature()) + { + me = obj->ToCreature(); + TC_LOG_DEBUG("scripts.ai", "SmartScript::OnInitialize: source is Event {}, triggered by creature {}", event, me->GetEntry()); + } + else if (obj->IsGameObject()) + { + go = obj->ToGameObject(); + TC_LOG_DEBUG("scripts.ai", "SmartScript::OnInitialize: source is Event {}, triggered by gameobject {}", event, go->GetEntry()); + } + else + { + TC_LOG_ERROR("misc", "SmartScript::OnInitialize: source is Event {}, missing trigger WorldObject", event); + return; + } + } else if (obj) // Handle object based scripts { switch (obj->GetTypeId()) diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index 7a92199c7a8..6e3068e5f38 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -38,9 +38,9 @@ class TC_GAME_API SmartScript SmartScript(); ~SmartScript(); - void OnInitialize(WorldObject* obj, AreaTriggerEntry const* at = nullptr, SceneTemplate const* scene = nullptr, Quest const* qst = nullptr); + void OnInitialize(WorldObject* obj, AreaTriggerEntry const* at = nullptr, SceneTemplate const* scene = nullptr, Quest const* qst = nullptr, uint32 evnt = 0); void GetScript(); - void FillScript(SmartAIEventList e, WorldObject* obj, AreaTriggerEntry const* at, SceneTemplate const* scene, Quest const* quest); + void FillScript(SmartAIEventList e, WorldObject* obj, AreaTriggerEntry const* at, SceneTemplate const* scene, Quest const* quest, uint32 event = 0); void ProcessEventsFor(SMART_EVENT e, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, SpellInfo const* spell = nullptr, GameObject* gob = nullptr, std::string const& varString = ""); void ProcessEvent(SmartScriptHolder& e, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, SpellInfo const* spell = nullptr, GameObject* gob = nullptr, std::string const& varString = ""); @@ -122,6 +122,7 @@ class TC_GAME_API SmartScript AreaTrigger* areaTrigger; SceneTemplate const* sceneTemplate; Quest const* quest; + uint32 event; SmartScriptType mScriptType; uint32 mEventPhase; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 9ae7999e86f..b20f669bcd8 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -137,6 +137,15 @@ void SmartAIMgr::LoadSmartAIFromDB() } break; } + case SMART_SCRIPT_TYPE_EVENT: + { + if (!sObjectMgr->IsValidEvent((uint32)temp.entryOrGuid)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Event id ({}) does not exist, skipped loading.", uint32(temp.entryOrGuid)); + continue; + } + break; + } case SMART_SCRIPT_TYPE_QUEST: { if (!sObjectMgr->GetQuestTemplate((uint32)temp.entryOrGuid)) @@ -451,6 +460,7 @@ SmartScriptHolder& SmartAIMgr::FindLinkedEvent(SmartAIEventList& list, uint32 li case SMART_EVENT_SCENE_TRIGGER: case SMART_EVENT_SCENE_CANCEL: case SMART_EVENT_SCENE_COMPLETE: + case SMART_EVENT_SEND_EVENT_TRIGGER: return true; default: return false; @@ -804,6 +814,7 @@ bool SmartAIMgr::CheckUnusedEventParams(SmartScriptHolder const& e) case SMART_EVENT_ON_SPELL_FAILED: return sizeof(SmartEvent::spellCast); case SMART_EVENT_ON_SPELL_START: return sizeof(SmartEvent::spellCast); case SMART_EVENT_ON_DESPAWN: return NO_PARAMS; + case SMART_EVENT_SEND_EVENT_TRIGGER: return NO_PARAMS; default: TC_LOG_WARN("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} is using an event with no unused params specified in SmartAIMgr::CheckUnusedEventParams(), please report this.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); @@ -1442,6 +1453,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) case SMART_EVENT_SCENE_CANCEL: case SMART_EVENT_SCENE_COMPLETE: case SMART_EVENT_SCENE_TRIGGER: + case SMART_EVENT_SEND_EVENT_TRIGGER: break; // Unused case SMART_EVENT_TARGET_HEALTH_PCT: diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 9406fbedb00..966b5fd2b0f 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -186,8 +186,9 @@ enum SMART_EVENT SMART_EVENT_ON_SPELL_FAILED = 84, // SpellID, CooldownMin, CooldownMax SMART_EVENT_ON_SPELL_START = 85, // SpellID, CooldownMin, CooldownMax SMART_EVENT_ON_DESPAWN = 86, // NONE + SMART_EVENT_SEND_EVENT_TRIGGER = 87, // NONE - SMART_EVENT_END = 87 + SMART_EVENT_END = 88 }; struct SmartEvent @@ -1444,18 +1445,18 @@ struct SmartTarget enum SmartScriptType { - SMART_SCRIPT_TYPE_CREATURE = 0, //done - SMART_SCRIPT_TYPE_GAMEOBJECT = 1, //done - SMART_SCRIPT_TYPE_AREATRIGGER = 2, //done - SMART_SCRIPT_TYPE_EVENT = 3, // - SMART_SCRIPT_TYPE_GOSSIP = 4, // - SMART_SCRIPT_TYPE_QUEST = 5, //done - SMART_SCRIPT_TYPE_SPELL = 6, // - SMART_SCRIPT_TYPE_TRANSPORT = 7, // - SMART_SCRIPT_TYPE_INSTANCE = 8, // - SMART_SCRIPT_TYPE_TIMED_ACTIONLIST = 9, // - SMART_SCRIPT_TYPE_SCENE = 10, //done - SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY = 11, + SMART_SCRIPT_TYPE_CREATURE = 0, + SMART_SCRIPT_TYPE_GAMEOBJECT = 1, + SMART_SCRIPT_TYPE_AREATRIGGER = 2, + SMART_SCRIPT_TYPE_EVENT = 3, + SMART_SCRIPT_TYPE_GOSSIP = 4, // NYI + SMART_SCRIPT_TYPE_QUEST = 5, + SMART_SCRIPT_TYPE_SPELL = 6, // NYI + SMART_SCRIPT_TYPE_TRANSPORT = 7, // NYI + SMART_SCRIPT_TYPE_INSTANCE = 8, // NYI + SMART_SCRIPT_TYPE_TIMED_ACTIONLIST = 9, + SMART_SCRIPT_TYPE_SCENE = 10, + SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY = 11, SMART_SCRIPT_TYPE_AREATRIGGER_ENTITY_SERVERSIDE = 12, SMART_SCRIPT_TYPE_MAX }; @@ -1582,6 +1583,7 @@ const uint32 SmartAIEventMask[SMART_EVENT_END][2] = {SMART_EVENT_ON_SPELL_FAILED, SMART_SCRIPT_TYPE_MASK_CREATURE }, {SMART_EVENT_ON_SPELL_START, SMART_SCRIPT_TYPE_MASK_CREATURE }, {SMART_EVENT_ON_DESPAWN, SMART_SCRIPT_TYPE_MASK_CREATURE }, + {SMART_EVENT_SEND_EVENT_TRIGGER, SMART_SCRIPT_TYPE_MASK_EVENT } }; enum SmartEventFlags |
