aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/AI/SmartScripts
diff options
context:
space:
mode:
authorMeji <alvaro.megias@outlook.com>2023-07-09 11:59:35 +0200
committerGitHub <noreply@github.com>2023-07-09 11:59:35 +0200
commitd015711fbb7a8bf57f7bb64ba8113c942d5125de (patch)
tree1f89cd7221e829a6c49f80208e8e7508d2f6e1c0 /src/server/game/AI/SmartScripts
parent996485e90e2a1ae75a4b93b33bd807f85060ca26 (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.cpp16
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp106
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.h5
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.cpp12
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h28
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