aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatan Shukry <matanshukry@gmail.com>2021-03-06 15:20:39 +0200
committerGitHub <noreply@github.com>2021-03-06 14:20:39 +0100
commit1b4c4d216478c57a562247815dfba0e5d2c9f192 (patch)
tree16056e76933acfd58fce09800f0bbcd247bdb79a /src
parent56e9560661adca81fc1e9a297cb6823cf7a6cb22 (diff)
Core/SAI: Implement quest source for SAI (#26170)
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp43
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp47
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.h6
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.cpp26
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h7
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, //