diff options
| author | ModoX <moardox@gmail.com> | 2024-12-28 23:25:10 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-28 23:25:10 +0100 |
| commit | 309ba22a15e5e0b4321b99f7157ccb18e0adc8dd (patch) | |
| tree | f40e4b0b27df733b348144b3813b932f8aeb3268 /src/server/game/Scripting | |
| parent | d8bcf5fcb655d9931f7c74883ca19c0428e2a8ae (diff) | |
Core/AI: Implemented conversation ai (#30538)
Diffstat (limited to 'src/server/game/Scripting')
| -rw-r--r-- | src/server/game/Scripting/ScriptMgr.cpp | 118 | ||||
| -rw-r--r-- | src/server/game/Scripting/ScriptMgr.h | 29 |
2 files changed, 80 insertions, 67 deletions
diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index e69b64a73fa..99f25980a0d 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -21,6 +21,7 @@ #include "AreaTriggerAI.h" #include "ChatCommand.h" #include "Conversation.h" +#include "ConversationAI.h" #include "Creature.h" #include "CreatureAI.h" #include "CreatureAIImpl.h" @@ -382,7 +383,7 @@ public: /// This hook is responsible for swapping Creature, GameObject and AreaTrigger AI's template<typename ObjectType, typename ScriptType, typename Base> -class CreatureGameObjectAreaTriggerScriptRegistrySwapHooks +class CreatureGameObjectAreaTriggerConversationScriptRegistrySwapHooks : public ScriptRegistrySwapHookBase { template<typename W> @@ -484,6 +485,24 @@ class CreatureGameObjectAreaTriggerScriptRegistrySwapHooks "The AI should be null here!"); } + // Hook which is called before a conversation is swapped + static void UnloadResetScript(Conversation* conversation) + { + // Remove deletable events only, + // otherwise it causes crashes with non-deletable spell events. + conversation->m_Events.KillAllEvents(false); + + conversation->AI()->OnRemove(); + } + + static void UnloadDestroyScript(Conversation* conversation) + { + conversation->AI_Destroy(); + + ASSERT(!conversation->AI(), + "The AI should be null here!"); + } + // Hook which is called after a creature was swapped static void LoadInitializeScript(Creature* creature) { @@ -543,6 +562,20 @@ class CreatureGameObjectAreaTriggerScriptRegistrySwapHooks at->AI()->OnCreate(nullptr); } + // Hook which is called after a conversation was swapped + static void LoadInitializeScript(Conversation* conversation) + { + ASSERT(!conversation->AI(), + "The AI should be null here!"); + + conversation->AI_Initialize(); + } + + static void LoadResetScript(Conversation* conversation) + { + conversation->AI()->OnCreate(nullptr); + } + static Creature* GetEntityFromMap(std::common_type<Creature>, Map* map, ObjectGuid const& guid) { return map->GetCreature(guid); @@ -558,6 +591,11 @@ class CreatureGameObjectAreaTriggerScriptRegistrySwapHooks return map->GetAreaTrigger(guid); } + static Conversation* GetEntityFromMap(std::common_type<Conversation>, Map* map, ObjectGuid const& guid) + { + return map->GetConversation(guid); + } + static auto VisitObjectsToSwapOnMap(std::unordered_set<uint32> const& idsToRemove) { return [&idsToRemove](Map* map, auto&& visitor) @@ -731,24 +769,32 @@ private: // This hook is responsible for swapping CreatureAI's template<typename Base> class ScriptRegistrySwapHooks<CreatureScript, Base> - : public CreatureGameObjectAreaTriggerScriptRegistrySwapHooks< + : public CreatureGameObjectAreaTriggerConversationScriptRegistrySwapHooks< Creature, CreatureScript, Base > { }; // This hook is responsible for swapping GameObjectAI's template<typename Base> class ScriptRegistrySwapHooks<GameObjectScript, Base> - : public CreatureGameObjectAreaTriggerScriptRegistrySwapHooks< + : public CreatureGameObjectAreaTriggerConversationScriptRegistrySwapHooks< GameObject, GameObjectScript, Base > { }; // This hook is responsible for swapping AreaTriggerAI's template<typename Base> class ScriptRegistrySwapHooks<AreaTriggerEntityScript, Base> - : public CreatureGameObjectAreaTriggerScriptRegistrySwapHooks< + : public CreatureGameObjectAreaTriggerConversationScriptRegistrySwapHooks< AreaTrigger, AreaTriggerEntityScript, Base > { }; +// This hook is responsible for swapping ConversationAI's +template<typename Base> +class ScriptRegistrySwapHooks<ConversationScript, Base> + : public CreatureGameObjectAreaTriggerConversationScriptRegistrySwapHooks< + Conversation, ConversationScript, Base + > { +}; + /// This hook is responsible for swapping BattlefieldScripts template<typename Base> class ScriptRegistrySwapHooks<BattlefieldScript, Base> @@ -955,7 +1001,7 @@ class SpecializedScriptRegistry<ScriptType, true> friend class ScriptRegistrySwapHooks; template<typename, typename, typename> - friend class CreatureGameObjectAreaTriggerScriptRegistrySwapHooks; + friend class CreatureGameObjectAreaTriggerConversationScriptRegistrySwapHooks; public: SpecializedScriptRegistry() { } @@ -1752,6 +1798,19 @@ bool ScriptMgr::OnAreaTrigger(Player* player, AreaTriggerEntry const* trigger, b return entered ? tmpscript->OnTrigger(player, trigger) : tmpscript->OnExit(player, trigger); } +bool ScriptMgr::CanCreateConversationAI(uint32 scriptId) const +{ + return !!ScriptRegistry<ConversationScript>::Instance()->GetScriptById(scriptId); +} + +ConversationAI* ScriptMgr::GetConversationAI(Conversation* conversation) +{ + ASSERT(conversation); + + GET_SCRIPT_RET(ConversationScript, conversation->GetScriptId(), tmpscript, nullptr); + return tmpscript->GetAI(conversation); +} + Battlefield* ScriptMgr::CreateBattlefield(uint32 scriptId, Map* map) { GET_SCRIPT_RET(BattlefieldScript, scriptId, tmpscript, nullptr); @@ -2279,40 +2338,6 @@ void ScriptMgr::ModifySpellDamageTaken(Unit* target, Unit* attacker, int32& dama FOREACH_SCRIPT(UnitScript)->ModifySpellDamageTaken(target, attacker, damage, spellInfo); } -// Conversation -void ScriptMgr::OnConversationCreate(Conversation* conversation, Unit* creator) -{ - ASSERT(conversation); - - GET_SCRIPT(ConversationScript, conversation->GetScriptId(), tmpscript); - tmpscript->OnConversationCreate(conversation, creator); -} - -void ScriptMgr::OnConversationStart(Conversation* conversation) -{ - ASSERT(conversation); - - GET_SCRIPT(ConversationScript, conversation->GetScriptId(), tmpscript); - tmpscript->OnConversationStart(conversation); -} - -void ScriptMgr::OnConversationLineStarted(Conversation* conversation, uint32 lineId, Player* sender) -{ - ASSERT(conversation); - ASSERT(sender); - - GET_SCRIPT(ConversationScript, conversation->GetScriptId(), tmpscript); - tmpscript->OnConversationLineStarted(conversation, lineId, sender); -} - -void ScriptMgr::OnConversationUpdate(Conversation* conversation, uint32 diff) -{ - ASSERT(conversation); - - GET_SCRIPT(ConversationScript, conversation->GetScriptId(), tmpscript); - tmpscript->OnConversationUpdate(conversation, diff); -} - // Scene void ScriptMgr::OnSceneStart(Player* player, uint32 sceneInstanceID, SceneTemplate const* sceneTemplate) { @@ -3172,20 +3197,9 @@ ConversationScript::ConversationScript(char const* name) ConversationScript::~ConversationScript() = default; -void ConversationScript::OnConversationCreate(Conversation* /*conversation*/, Unit* /*creator*/) -{ -} - -void ConversationScript::OnConversationStart(Conversation* /*conversation*/ ) -{ -} - -void ConversationScript::OnConversationLineStarted(Conversation* /*conversation*/, uint32 /*lineId*/, Player* /*sender*/) -{ -} - -void ConversationScript::OnConversationUpdate(Conversation* /*conversation*/, uint32 /*diff*/) +ConversationAI* ConversationScript::GetAI(Conversation* /*conversation*/) const { + return nullptr; } SceneScript::SceneScript(char const* name) diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 31a5842a383..d7746b01e04 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -38,6 +38,7 @@ class BattlegroundMap; class BattlegroundScript; class Channel; class Conversation; +class ConversationAI; class Creature; class CreatureAI; class DynamicObject; @@ -911,17 +912,8 @@ class TC_GAME_API ConversationScript : public ScriptObject ~ConversationScript(); - // Called when Conversation is created but not added to Map yet. - virtual void OnConversationCreate(Conversation* conversation, Unit* creator); - - // Called when Conversation is started - virtual void OnConversationStart(Conversation* conversation); - - // Called when player sends CMSG_CONVERSATION_LINE_STARTED with valid conversation guid - virtual void OnConversationLineStarted(Conversation* conversation, uint32 lineId, Player* sender); - - // Called for each update tick - virtual void OnConversationUpdate(Conversation* conversation, uint32 diff); + // Called when a ConversationAI object is needed for the conversation. + virtual ConversationAI* GetAI(Conversation* conversation) const; }; class TC_GAME_API SceneScript : public ScriptObject @@ -1279,10 +1271,8 @@ class TC_GAME_API ScriptMgr public: /* ConversationScript */ - void OnConversationCreate(Conversation* conversation, Unit* creator); - void OnConversationStart(Conversation* conversation); - void OnConversationLineStarted(Conversation* conversation, uint32 lineId, Player* sender); - void OnConversationUpdate(Conversation* conversation, uint32 diff); + bool CanCreateConversationAI(uint32 scriptId) const; + ConversationAI* GetConversationAI(Conversation* conversation); public: /* SceneScript */ @@ -1405,6 +1395,15 @@ class GenericAreaTriggerEntityScript : public AreaTriggerEntityScript }; #define RegisterAreaTriggerAI(ai_name) new GenericAreaTriggerEntityScript<ai_name>(#ai_name) +template <class AI> +class GenericConversationScript : public ConversationScript +{ +public: + GenericConversationScript(char const* name) : ConversationScript(name) {} + ConversationAI* GetAI(Conversation* conversation) const override { return new AI(conversation); } +}; +#define RegisterConversationAI(ai_name) new GenericConversationScript<ai_name>(#ai_name) + template<class Script> class GenericBattlegroundMapScript : public BattlegroundMapScript { |
