From 9f05b762adaacde4423cf999ec79f54a5a4eb9f2 Mon Sep 17 00:00:00 2001 From: Hondacrx Date: Wed, 3 Sep 2025 21:27:53 -0400 Subject: [PATCH] Core/SAI: Implemented action type SMART_ACTION_DESTROY_CONVERSATION Port From (https://github.com/TrinityCore/TrinityCore/commit/e9e7059a23618e58e57dc3b24eb218505ca3f746) --- Source/Framework/Constants/SmartAIConst.cs | 1 + Source/Game/AI/SmartScripts/SmartAIManager.cs | 25 +++++++++++++++++-- Source/Game/AI/SmartScripts/SmartScript.cs | 22 ++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/Source/Framework/Constants/SmartAIConst.cs b/Source/Framework/Constants/SmartAIConst.cs index be7c27610..7bdb01e35 100644 --- a/Source/Framework/Constants/SmartAIConst.cs +++ b/Source/Framework/Constants/SmartAIConst.cs @@ -391,6 +391,7 @@ namespace Framework.Constants DoAction = 151, CompleteQuest = 152, // QuestId. Regular quests with objectives can't be completed with this action (only quests with QUEST_FLAGS_COMPLETION_EVENT, QUEST_FLAGS_COMPLETION_AREA_TRIGGER or QUEST_FLAGS_TRACKING_EVENT) CreditQuestObjectiveTalkTo = 153, + DestroyConversation = 154, // conversation_template.id, isPrivate, range EnterVehicle = 155, // seat id BoardPassenger = 156, // seat id ExitVehicle = 157, diff --git a/Source/Game/AI/SmartScripts/SmartAIManager.cs b/Source/Game/AI/SmartScripts/SmartAIManager.cs index 42a695b1e..a59dcb181 100644 --- a/Source/Game/AI/SmartScripts/SmartAIManager.cs +++ b/Source/Game/AI/SmartScripts/SmartAIManager.cs @@ -821,6 +821,7 @@ namespace Game.AI SmartActions.DoAction => Marshal.SizeOf(typeof(SmartAction.DoAction)), SmartActions.CompleteQuest => Marshal.SizeOf(typeof(SmartAction.Quest)), SmartActions.CreditQuestObjectiveTalkTo => 0, + SmartActions.DestroyConversation => Marshal.SizeOf(typeof(SmartAction.DestroyConversation)), SmartActions.EnterVehicle => Marshal.SizeOf(typeof(SmartAction.EnterVehicle)), SmartActions.BoardPassenger => Marshal.SizeOf(typeof(SmartAction.EnterVehicle)), SmartActions.ExitVehicle => 0, @@ -870,7 +871,7 @@ namespace Game.AI } return false; - }; + } if (!actionUsesStringParam() && !e.Action.param_string.IsEmpty()) Log.outWarn(LogFilter.Sql, $"SmartAIMgr: {e} has unused action_param_string with value {e.Action.param_string}, it should be NULL."); @@ -1804,7 +1805,7 @@ namespace Game.AI } return true; - }; + } if (e.Action.equip.slot1 != 0 && !isValidEquipmentSlot(e.Action.equip.slot1, 0)) return false; @@ -2234,6 +2235,17 @@ namespace Game.AI } break; } + case SmartActions.DestroyConversation: + { + if (Global.ConversationDataStorage.GetConversationTemplate(e.Action.destroyConversation.id) == null) + { + Log.outError(LogFilter.Sql, $"SmartAIMgr: SMART_ACTION_DESTROY_CONVERSATION {e} uses invalid entry {e.Action.destroyConversation.id}, skipped."); + return false; + } + + TC_SAI_IS_BOOLEAN_VALID(e, e.Action.destroyConversation.isPrivate); + break; + } // No longer supported case SmartActions.CallAreaexploredoreventhappens: case SmartActions.CallGroupeventhappens: @@ -3276,6 +3288,9 @@ namespace Game.AI [FieldOffset(4)] public DoAction doAction; + [FieldOffset(4)] + public DestroyConversation destroyConversation; + [FieldOffset(4)] public EnterVehicle enterVehicle; @@ -3833,6 +3848,12 @@ namespace Game.AI { public uint actionId; } + public struct DestroyConversation + { + public uint id; + public uint isPrivate; + public uint range; + } public struct EnterVehicle { public uint seatId; diff --git a/Source/Game/AI/SmartScripts/SmartScript.cs b/Source/Game/AI/SmartScripts/SmartScript.cs index aa9765b15..874ffb308 100644 --- a/Source/Game/AI/SmartScripts/SmartScript.cs +++ b/Source/Game/AI/SmartScripts/SmartScript.cs @@ -2708,6 +2708,28 @@ namespace Game.AI } break; } + case SmartActions.DestroyConversation: + { + void work(Conversation conversation) + { + if (conversation.GetEntry() != e.Action.destroyConversation.id) + return; + + if (conversation.IsPrivateObject()) + { + if (e.Action.destroyConversation.isPrivate == 0 || !targets.Any(target => target.GetGUID() == conversation.GetPrivateObjectOwner())) + return; + } + else if (e.Action.destroyConversation.isPrivate != 0) + return; + + conversation.Remove(); + } + + ConversationWorker worker = new(PhasingHandler.GetAlwaysVisiblePhaseShift(), work); + Cell.VisitGridObjects(GetBaseObject(), worker, e.Action.destroyConversation.range); + break; + } default: Log.outError(LogFilter.Sql, "SmartScript.ProcessAction: Entry {0} SourceType {1}, Event {2}, Unhandled Action type {3}", e.EntryOrGuid, e.GetScriptType(), e.EventId, e.GetActionType()); break;