diff options
author | Matan Shukry <matanshukry@gmail.com> | 2021-03-06 15:20:39 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-06 14:20:39 +0100 |
commit | 1b4c4d216478c57a562247815dfba0e5d2c9f192 (patch) | |
tree | 16056e76933acfd58fce09800f0bbcd247bdb79a /src | |
parent | 56e9560661adca81fc1e9a297cb6823cf7a6cb22 (diff) |
Core/SAI: Implement quest source for SAI (#26170)
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartAI.cpp | 43 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.cpp | 47 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScript.h | 6 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.cpp | 26 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartScriptMgr.h | 7 |
5 files changed, 109 insertions, 20 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index 4efc142e480..7ec6926b802 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -1164,9 +1164,52 @@ public: } }; +class SmartQuest : public QuestScript +{ +public: + SmartQuest() : QuestScript("SmartQuest") { } + + // Called when a quest status change + void OnQuestStatusChange(Player* player, Quest const* quest, QuestStatus /*oldStatus*/, QuestStatus newStatus) + { + SmartScript smartScript; + smartScript.OnInitialize(nullptr, nullptr, nullptr, quest); + switch (newStatus) + { + case QUEST_STATUS_INCOMPLETE: + smartScript.ProcessEventsFor(SMART_EVENT_QUEST_ACCEPTED, player); + break; + case QUEST_STATUS_COMPLETE: + smartScript.ProcessEventsFor(SMART_EVENT_QUEST_COMPLETION, player); + break; + case QUEST_STATUS_FAILED: + smartScript.ProcessEventsFor(SMART_EVENT_QUEST_FAIL, player); + break; + case QUEST_STATUS_REWARDED: + smartScript.ProcessEventsFor(SMART_EVENT_QUEST_REWARDED, player); + break; + case QUEST_STATUS_NONE: + default: + break; + } + } + + // Called when a quest objective data change + void OnQuestObjectiveChange(Player* player, Quest const* quest, QuestObjective const& objective, int32 /*oldAmount*/, int32 /*newAmount*/) + { + if (player->IsQuestObjectiveComplete(objective)) + { + SmartScript smartScript; + smartScript.OnInitialize(nullptr, nullptr, nullptr, quest); + smartScript.ProcessEventsFor(SMART_EVENT_QUEST_OBJ_COPLETETION, player, objective.ID); + } + } +}; + void AddSC_SmartScripts() { new SmartTrigger(); new SmartAreaTriggerEntityScript(); new SmartScene(); + new SmartQuest(); } diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index fbe1717ec54..ed45c8bfea8 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -50,6 +50,7 @@ SmartScript::SmartScript() trigger = nullptr; areaTrigger = nullptr; sceneTemplate = nullptr; + quest = nullptr; mEventPhase = 0; mPathId = 0; mTextTimer = 0; @@ -3041,6 +3042,20 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui ProcessAction(e, unit, var0, var1, bvar, spell, gob); break; } + case SMART_EVENT_QUEST_ACCEPTED: + case SMART_EVENT_QUEST_COMPLETION: + case SMART_EVENT_QUEST_REWARDED: + case SMART_EVENT_QUEST_FAIL: + { + ProcessAction(e, unit); + break; + } + case SMART_EVENT_QUEST_OBJ_COPLETETION: + { + if (var0 == (e.event.questObjective.id)) + ProcessAction(e, unit); + break; + } //no params case SMART_EVENT_AGGRO: case SMART_EVENT_DEATH: @@ -3051,11 +3066,6 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui 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: @@ -3712,7 +3722,7 @@ void SmartScript::OnUpdate(uint32 const diff) } } -void SmartScript::FillScript(SmartAIEventList e, WorldObject* obj, AreaTriggerEntry const* at, SceneTemplate const* scene) +void SmartScript::FillScript(SmartAIEventList e, WorldObject* obj, AreaTriggerEntry const* at, SceneTemplate const* scene, Quest const* quest) { if (e.empty()) { @@ -3722,6 +3732,8 @@ void SmartScript::FillScript(SmartAIEventList e, WorldObject* obj, AreaTriggerEn TC_LOG_DEBUG("scripts.ai", "SmartScript: EventMap for AreaTrigger %u is empty but is using SmartScript.", at->ID); if (scene) TC_LOG_DEBUG("scripts.ai", "SmartScript: EventMap for SceneId %u is empty but is using SmartScript.", scene->SceneId); + if (quest) + TC_LOG_DEBUG("scripts.ai", "SmartScript: EventMap for Quest %u is empty but is using SmartScript.", quest->GetQuestId()); return; } for (SmartAIEventList::iterator i = e.begin(); i != e.end(); ++i) @@ -3774,33 +3786,38 @@ void SmartScript::GetScript() e = sSmartScriptMgr->GetScript(-((int32)me->GetSpawnId()), mScriptType); if (e.empty()) e = sSmartScriptMgr->GetScript((int32)me->GetEntry(), mScriptType); - FillScript(std::move(e), me, nullptr, nullptr); + 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); + 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); + 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); + FillScript(std::move(e), areaTrigger, nullptr, nullptr, nullptr); } else if (sceneTemplate) { e = sSmartScriptMgr->GetScript(sceneTemplate->SceneId, mScriptType); - FillScript(std::move(e), nullptr, nullptr, sceneTemplate); + FillScript(std::move(e), nullptr, nullptr, sceneTemplate, nullptr); + } + else if (quest) + { + e = sSmartScriptMgr->GetScript(quest->GetQuestId(), mScriptType); + FillScript(std::move(e), nullptr, nullptr, nullptr, quest); } } -void SmartScript::OnInitialize(WorldObject* obj, AreaTriggerEntry const* at, SceneTemplate const* scene) +void SmartScript::OnInitialize(WorldObject* obj, AreaTriggerEntry const* at, SceneTemplate const* scene, Quest const* qst) { if (obj)//handle object based scripts { @@ -3838,6 +3855,12 @@ void SmartScript::OnInitialize(WorldObject* obj, AreaTriggerEntry const* at, Sce sceneTemplate = scene; TC_LOG_DEBUG("scripts.ai", "SmartScript::OnInitialize: source is Scene with id %u", scene->SceneId); } + else if (qst) + { + mScriptType = SMART_SCRIPT_TYPE_QUEST; + quest = qst; + TC_LOG_DEBUG("scripts.ai", "SmartScript::OnInitialize: source is Quest with id %u", qst->GetQuestId()); + } else { TC_LOG_ERROR("misc", "SmartScript::OnInitialize: !WARNING! Initialized objects are NULL."); diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index 0da9a6dc1a8..def103140be 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -25,6 +25,7 @@ class AreaTrigger; class Creature; class GameObject; class Player; +class Quest; class SpellInfo; class Unit; class WorldObject; @@ -37,9 +38,9 @@ class TC_GAME_API SmartScript SmartScript(); ~SmartScript(); - void OnInitialize(WorldObject* obj, AreaTriggerEntry const* at = nullptr, SceneTemplate const* scene = nullptr); + void OnInitialize(WorldObject* obj, AreaTriggerEntry const* at = nullptr, SceneTemplate const* scene = nullptr, Quest const* qst = nullptr); void GetScript(); - void FillScript(SmartAIEventList e, WorldObject* obj, AreaTriggerEntry const* at, SceneTemplate const* scene); + void FillScript(SmartAIEventList e, WorldObject* obj, AreaTriggerEntry const* at, SceneTemplate const* scene, Quest const* quest); 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 = ""); @@ -125,6 +126,7 @@ class TC_GAME_API SmartScript AreaTriggerEntry const* trigger; AreaTrigger* areaTrigger; SceneTemplate const* sceneTemplate; + Quest const* quest; SmartScriptType mScriptType; uint32 mEventPhase; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 0744033199a..0d6b1ae3f92 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -186,6 +186,15 @@ void SmartAIMgr::LoadSmartAIFromDB() } break; } + case SMART_SCRIPT_TYPE_QUEST: + { + if (!sObjectMgr->GetQuestTemplate((uint32)temp.entryOrGuid)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Quest entry (%u) does not exist, skipped loading.", uint32(temp.entryOrGuid)); + continue; + } + break; + } case SMART_SCRIPT_TYPE_SCENE: { if (!sObjectMgr->GetSceneTemplate((uint32)temp.entryOrGuid)) @@ -1009,6 +1018,18 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) return false; } break; + case SMART_EVENT_QUEST_OBJ_COPLETETION: + if (!sObjectMgr->GetQuestObjective(e.event.questObjective.id)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Event SMART_EVENT_QUEST_OBJ_COPLETETION using invalid objective id %u, skipped.", e.event.questObjective.id); + return false; + } + break; + case SMART_EVENT_QUEST_ACCEPTED: + case SMART_EVENT_QUEST_COMPLETION: + case SMART_EVENT_QUEST_REWARDED: + case SMART_EVENT_QUEST_FAIL: + break; case SMART_EVENT_LINK: case SMART_EVENT_GO_LOOT_STATE_CHANGED: case SMART_EVENT_GO_EVENT_INFORM: @@ -1026,11 +1047,6 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) case SMART_EVENT_EVADE: case SMART_EVENT_REACHED_HOME: case SMART_EVENT_RESET: - 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_WAYPOINT_START: case SMART_EVENT_WAYPOINT_REACHED: diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index a49a3af99c5..6c97f3cff4c 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -280,6 +280,11 @@ struct SmartEvent struct { + uint32 id; + } questObjective; + + struct + { uint32 emote; uint32 cooldownMin; uint32 cooldownMax; @@ -1394,7 +1399,7 @@ enum SmartScriptType SMART_SCRIPT_TYPE_AREATRIGGER = 2, //done SMART_SCRIPT_TYPE_EVENT = 3, // SMART_SCRIPT_TYPE_GOSSIP = 4, // - SMART_SCRIPT_TYPE_QUEST = 5, // + SMART_SCRIPT_TYPE_QUEST = 5, //done SMART_SCRIPT_TYPE_SPELL = 6, // SMART_SCRIPT_TYPE_TRANSPORT = 7, // SMART_SCRIPT_TYPE_INSTANCE = 8, // |