diff --git a/Source/Framework/Constants/SmartAIConst.cs b/Source/Framework/Constants/SmartAIConst.cs index b1c42836b..f033dac75 100644 --- a/Source/Framework/Constants/SmartAIConst.cs +++ b/Source/Framework/Constants/SmartAIConst.cs @@ -360,8 +360,9 @@ namespace Framework.Constants PlayAnimkit = 128, ScenePlay = 129, // sceneId SceneCancel = 130, // sceneId - // 131 - 135 : 3.3.5 reserved + // 131 - 134 : 3.3.5 reserved PlayCinematic = 135, // reserved for future uses + SetMovementSpeed = 136, // movementType, speedInteger, speedFraction End = 131 } diff --git a/Source/Game/AI/SmartScripts/SmartAIManager.cs b/Source/Game/AI/SmartScripts/SmartAIManager.cs index 93018fdb4..e3a55b82b 100644 --- a/Source/Game/AI/SmartScripts/SmartAIManager.cs +++ b/Source/Game/AI/SmartScripts/SmartAIManager.cs @@ -1245,6 +1245,22 @@ namespace Game.AI Log.outError(LogFilter.Sql, $"Entry {e.entryOrGuid} SourceType {e.GetScriptType()} Event {e.event_id} Action {e.GetActionType()} uses invalid data type {e.Action.auraType.type} (value range 0-TOTAL_AURAS), skipped."); return false; } + break; + } + case SmartActions.SetMovementSpeed: + { + if (e.Action.movementSpeed.movementType >= (int)MovementGeneratorType.Max) + { + Log.outError(LogFilter.Sql, $"SmartAIMgr: Entry {e.entryOrGuid} SourceType {e.GetScriptType()} Event {e.event_id} Action {e.GetActionType()} uses invalid movementType {e.Action.movementSpeed.movementType}, skipped."); + return false; + } + + if (e.Action.movementSpeed.speedInteger == 0 && e.Action.movementSpeed.speedFraction == 0) + { + Log.outError(LogFilter.Sql, $"SmartAIMgr: Entry {e.entryOrGuid} SourceType {e.GetScriptType()} Event {e.event_id} Action {e.GetActionType()} uses speed 0, skipped."); + return false; + } + break; } case SmartActions.StartClosestWaypoint: @@ -2325,6 +2341,9 @@ namespace Game.AI [FieldOffset(4)] public Scene scene; + [FieldOffset(4)] + public MovementSpeed movementSpeed; + [FieldOffset(4)] public Raw raw; @@ -2816,6 +2835,12 @@ namespace Game.AI { public uint sceneId; } + public struct MovementSpeed + { + public uint movementType; + public uint speedInteger; + public uint speedFraction; + } public struct Raw { public uint param1; diff --git a/Source/Game/AI/SmartScripts/SmartScript.cs b/Source/Game/AI/SmartScripts/SmartScript.cs index c2604b308..6ab8b6240 100644 --- a/Source/Game/AI/SmartScripts/SmartScript.cs +++ b/Source/Game/AI/SmartScripts/SmartScript.cs @@ -2622,6 +2622,22 @@ namespace Game.AI playerTarget.GetSceneMgr().CancelSceneBySceneId(e.Action.scene.sceneId); } + break; + } + case SmartActions.SetMovementSpeed: + { + var targets = GetTargets(e, unit); + if (targets.Empty()) + break; + + uint speedInteger = e.Action.movementSpeed.speedInteger; + uint speedFraction = e.Action.movementSpeed.speedFraction; + float speed = (float)((float)speedInteger + (float)speedFraction / Math.Pow(10, Math.Floor(Math.Log10((float)(speedFraction != 0 ? speedFraction : 1)) + 1))); + + foreach (WorldObject target in targets) + if (IsCreature(target)) + me.SetSpeed((UnitMoveType)e.Action.movementSpeed.movementType, speed); + break; } default: