Core/AI: Implemented conversation ai (#30538)

This commit is contained in:
ModoX
2024-12-28 23:25:10 +01:00
committed by GitHub
parent d8bcf5fcb6
commit 309ba22a15
19 changed files with 382 additions and 202 deletions

View File

@@ -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)