diff --git a/Source/ACE.Server/Command/Handlers/DeveloperCommands.cs b/Source/ACE.Server/Command/Handlers/DeveloperCommands.cs
index 672559f8d3..93e89e10a5 100644
--- a/Source/ACE.Server/Command/Handlers/DeveloperCommands.cs
+++ b/Source/ACE.Server/Command/Handlers/DeveloperCommands.cs
@@ -2663,5 +2663,19 @@ public static void HandleRemoveVitae(Session session, params string[] parameters
if (player != session.Player)
session.Network.EnqueueSend(new GameMessageSystemChat("Removed vitae for {player.Name}", ChatMessageType.Broadcast));
}
+
+ [CommandHandler("fast", AccessLevel.Developer, CommandHandlerFlag.RequiresWorld)]
+ public static void HandleFast(Session session, params string[] parameters)
+ {
+ var spell = new Spell(SpellId.QuicknessSelf8);
+ session.Player.CreateEnchantment(session.Player, session.Player, spell);
+ }
+
+ [CommandHandler("slow", AccessLevel.Developer, CommandHandlerFlag.RequiresWorld)]
+ public static void HandleSlow(Session session, params string[] parameters)
+ {
+ var spell = new Spell(SpellId.SlownessSelf8);
+ session.Player.CreateEnchantment(session.Player, session.Player, spell);
+ }
}
}
diff --git a/Source/ACE.Server/Entity/Spell.cs b/Source/ACE.Server/Entity/Spell.cs
index 9ca69e97ed..778128a5aa 100644
--- a/Source/ACE.Server/Entity/Spell.cs
+++ b/Source/ACE.Server/Entity/Spell.cs
@@ -267,6 +267,33 @@ public bool HasItemCategory
}
}
+ ///
+ /// Returns TRUE for any spells which could potentially affect the run rate,
+ /// such as spells which alter run / quickness / strength
+ ///
+ public bool UpdatesRunRate
+ {
+ get
+ {
+ if (_spell == null)
+ return false;
+
+ // this is commented out as below in UpdatesMaxVitals
+ // i forget the exact reasoning, are all the proper hooks in places for each vitae %,
+ // and not just add/remove?
+ /*if (_spell.Id == 666) // vitae
+ return true;*/
+
+ if (StatModType.HasFlag(EnchantmentTypeFlags.Attribute) && (StatModKey == (uint)PropertyAttribute.Strength || StatModKey == (uint)PropertyAttribute.Quickness))
+ return true;
+
+ if (StatModType.HasFlag(EnchantmentTypeFlags.Skill) && StatModKey == (uint)Skill.Run)
+ return true;
+
+ return false;
+ }
+ }
+
///
/// Returns a list of MaxVitals affected by this spell
///
@@ -279,6 +306,15 @@ public List UpdatesMaxVitals
if (_spell == null)
return maxVitals;
+ /*if (_spell.Id == 666) // Vitae
+ {
+ maxVitals.Add(PropertyAttribute2nd.MaxHealth);
+ maxVitals.Add(PropertyAttribute2nd.MaxStamina);
+ maxVitals.Add(PropertyAttribute2nd.MaxMana);
+
+ return maxVitals;
+ }*/
+
if (StatModType.HasFlag(EnchantmentTypeFlags.SecondAtt) && StatModKey != 0)
maxVitals.Add((PropertyAttribute2nd)StatModKey);
@@ -296,14 +332,6 @@ public List UpdatesMaxVitals
break;
}
}
-
- //if (_spell.Id == 666) // Vitae
- //{
- // maxVitals.Add(PropertyAttribute2nd.MaxHealth);
- // maxVitals.Add(PropertyAttribute2nd.MaxStamina);
- // maxVitals.Add(PropertyAttribute2nd.MaxMana);
- //}
-
return maxVitals;
}
}
diff --git a/Source/ACE.Server/Managers/PropertyManager.cs b/Source/ACE.Server/Managers/PropertyManager.cs
index a3c1125b6c..853b41a36f 100644
--- a/Source/ACE.Server/Managers/PropertyManager.cs
+++ b/Source/ACE.Server/Managers/PropertyManager.cs
@@ -504,6 +504,7 @@ public static void LoadDefaultProperties()
("pk_server_safe_training_academy", new Property(false, "set this to TRUE to disable pk fighting in training academy and time to exit starter town safely")),
("pkl_server", new Property(false, "set this to TRUE for pink servers")),
("quest_info_enabled", new Property(false, "toggles the /myquests player command")),
+ ("runrate_add_hooks", new Property(false, "if TRUE, adds some runrate hooks that were missing from retail (exhaustion done, raise skill/attribute")),
("require_spell_comps", new Property(true, "if FALSE spell components are no longer required to be in inventory to cast spells. defaults to enabled, as in retail")),
("salvage_handle_overages", new Property(false, "in retail, if 2 salvage bags were combined beyond 100 structure, the overages would be lost")),
("show_dot_messages", new Property(false, "enabled, shows combat messages for DoT damage ticks. defaults to disabled, as in retail")),
diff --git a/Source/ACE.Server/Network/GameAction/Actions/GameActionMoveToState.cs b/Source/ACE.Server/Network/GameAction/Actions/GameActionMoveToState.cs
index 220daf41cf..a690245429 100644
--- a/Source/ACE.Server/Network/GameAction/Actions/GameActionMoveToState.cs
+++ b/Source/ACE.Server/Network/GameAction/Actions/GameActionMoveToState.cs
@@ -11,6 +11,7 @@ public static class GameActionMoveToState
public static void Handle(ClientMessage message, Session session)
{
var moveToState = new MoveToState(session.Player, message.Payload);
+ session.Player.CurrentMoveToState = moveToState;
session.Player.SetRequestedLocation(moveToState.Position);
diff --git a/Source/ACE.Server/Network/Motion/InterpretedMotionState.cs b/Source/ACE.Server/Network/Motion/InterpretedMotionState.cs
index 900484ae94..a21990e86f 100644
--- a/Source/ACE.Server/Network/Motion/InterpretedMotionState.cs
+++ b/Source/ACE.Server/Network/Motion/InterpretedMotionState.cs
@@ -85,6 +85,11 @@ public MovementStateFlag BuildMovementFlags()
return flags;
}
+
+ public bool HasMovement()
+ {
+ return (ForwardCommand != MotionCommand.Invalid && ForwardCommand != MotionCommand.Ready) || TurnCommand != MotionCommand.Invalid || SidestepCommand != MotionCommand.Invalid;
+ }
}
public static class InterpretedMotionStateExtensions
diff --git a/Source/ACE.Server/Network/Motion/MoveToState.cs b/Source/ACE.Server/Network/Motion/MoveToState.cs
index a3f1bfbddc..7406b3bb61 100644
--- a/Source/ACE.Server/Network/Motion/MoveToState.cs
+++ b/Source/ACE.Server/Network/Motion/MoveToState.cs
@@ -26,6 +26,8 @@ public class MoveToState
public bool Contact; // verify: contact (indicates if player is on ground), or sticky bit?
public bool StandingLongJump;
+ public MoveToState() { }
+
public MoveToState(WorldObject wo, BinaryReader reader)
{
WorldObject = wo;
diff --git a/Source/ACE.Server/Network/Motion/MovementData.cs b/Source/ACE.Server/Network/Motion/MovementData.cs
index 0c25061677..b08f08b1fa 100644
--- a/Source/ACE.Server/Network/Motion/MovementData.cs
+++ b/Source/ACE.Server/Network/Motion/MovementData.cs
@@ -29,6 +29,8 @@ public class MovementData
public TurnToObject TurnToObject;
public TurnToHeading TurnToHeading;
+ public MovementData() { }
+
public MovementData(WorldObject wo)
{
WorldObject = wo;
@@ -37,7 +39,7 @@ public MovementData(WorldObject wo)
public MovementData(WorldObject wo, Motion motion)
{
WorldObject = wo;
- var sequence = wo.Sequences;
+ //var sequence = wo.Sequences;
// do this here, or in network writer?
IsAutonomous = motion.IsAutonomous;
diff --git a/Source/ACE.Server/Physics/Animation/MotionTable.cs b/Source/ACE.Server/Physics/Animation/MotionTable.cs
index 52b65371ce..9ded0575f8 100644
--- a/Source/ACE.Server/Physics/Animation/MotionTable.cs
+++ b/Source/ACE.Server/Physics/Animation/MotionTable.cs
@@ -17,9 +17,10 @@ public class MotionTable
public Dictionary> Links;
public uint DefaultStyle;
- public static Dictionary WalkSpeed;
- public static Dictionary RunSpeed;
- public static Dictionary TurnSpeed;
+ // TODO: use proper ConcurrentDictionary
+ public static Dictionary WalkSpeed { get; set; }
+ public static Dictionary RunSpeed { get; set; }
+ public static Dictionary TurnSpeed { get; set; }
static MotionTable()
{
@@ -499,7 +500,7 @@ public static float GetRunSpeed(uint motionTableID)
return 0.0f;
var speed = GetAnimDist(motionData);
- RunSpeed.Add(motionTableID, speed);
+ RunSpeed[motionTableID] = speed;
return speed;
}
@@ -517,7 +518,7 @@ public static float GetTurnSpeed(uint motionTableID)
return 0.0f;
var speed = Math.Abs(motionData.Omega.Z);
- TurnSpeed.Add(motionTableID, speed);
+ TurnSpeed[motionTableID] = speed;
return speed;
}
diff --git a/Source/ACE.Server/WorldObjects/Creature_Vitals.cs b/Source/ACE.Server/WorldObjects/Creature_Vitals.cs
index 4158e4f982..d2557aa370 100644
--- a/Source/ACE.Server/WorldObjects/Creature_Vitals.cs
+++ b/Source/ACE.Server/WorldObjects/Creature_Vitals.cs
@@ -197,11 +197,13 @@ public float GetStanceMod(CreatureVital vital)
// does not apply for mana?
if (vital.Vital == PropertyAttribute2nd.MaxMana) return 1.0f;
+ var forwardCommand = CurrentMovementData.MovementType == MovementType.Invalid ? CurrentMovementData.Invalid.State.ForwardCommand : MotionCommand.Invalid;
+
// combat mode / running
- if (CombatMode != CombatMode.NonCombat || CurrentMotionCommand == MotionCommand.RunForward)
+ if (CombatMode != CombatMode.NonCombat || forwardCommand == MotionCommand.RunForward)
return 0.5f;
- switch (CurrentMotionCommand)
+ switch (forwardCommand)
{
// TODO: verify multipliers
default:
diff --git a/Source/ACE.Server/WorldObjects/Managers/EnchantmentManager.cs b/Source/ACE.Server/WorldObjects/Managers/EnchantmentManager.cs
index 296221ffc7..c099696cae 100644
--- a/Source/ACE.Server/WorldObjects/Managers/EnchantmentManager.cs
+++ b/Source/ACE.Server/WorldObjects/Managers/EnchantmentManager.cs
@@ -319,12 +319,6 @@ public virtual void Remove(BiotaPropertiesEnchantmentRegistry entry, bool sound
if (sound && entry.SpellCategory != SpellCategory_Cooldown)
Player.Session.Network.EnqueueSend(new GameMessageSound(Player.Guid, Sound.SpellExpire, 1.0f));
-
- if (entry.SpellCategory != SpellCategory_Cooldown)
- {
- var spell = new Spell(spellID);
- Player.HandleMaxVitalUpdate(spell);
- }
}
else
{
@@ -472,12 +466,7 @@ public virtual void Dispel(BiotaPropertiesEnchantmentRegistry entry)
WorldObject.ChangesDetected = true;
if (Player != null)
- {
Player.Session.Network.EnqueueSend(new GameEventMagicDispelEnchantment(Player.Session, (ushort)entry.SpellId, entry.LayerId));
-
- var spell = new Spell(spellID);
- Player.HandleMaxVitalUpdate(spell);
- }
}
///
@@ -492,12 +481,6 @@ public virtual void Dispel(List entries)
{
if (WorldObject.Biota.TryRemoveEnchantment(entry, out _, WorldObject.BiotaDatabaseLock))
WorldObject.ChangesDetected = true;
-
- if (Player != null)
- {
- var spell = new Spell(entry.SpellId);
- Player.HandleMaxVitalUpdate(spell);
- }
}
if (Player != null)
Player.Session.Network.EnqueueSend(new GameEventMagicDispelMultipleEnchantments(Player.Session, entries));
diff --git a/Source/ACE.Server/WorldObjects/Managers/EnchantmentManagerWithCaching.cs b/Source/ACE.Server/WorldObjects/Managers/EnchantmentManagerWithCaching.cs
index cdcb4053cb..ecf2ed5067 100644
--- a/Source/ACE.Server/WorldObjects/Managers/EnchantmentManagerWithCaching.cs
+++ b/Source/ACE.Server/WorldObjects/Managers/EnchantmentManagerWithCaching.cs
@@ -52,6 +52,12 @@ public override void Remove(BiotaPropertiesEnchantmentRegistry entry, bool sound
base.Remove(entry, sound);
ClearCache();
+
+ if (entry.SpellCategory != SpellCategory_Cooldown)
+ {
+ var spell = new Spell(entry.SpellId);
+ Player.HandleSpellHooks(spell);
+ }
}
///
@@ -99,6 +105,12 @@ public override void Dispel(BiotaPropertiesEnchantmentRegistry entry)
base.Dispel(entry);
ClearCache();
+
+ if (Player != null)
+ {
+ var spell = new Spell(entry.SpellId);
+ Player.HandleSpellHooks(spell);
+ }
}
///
@@ -109,6 +121,15 @@ public override void Dispel(List entries)
base.Dispel(entries);
ClearCache();
+
+ if (Player != null)
+ {
+ foreach (var entry in entries)
+ {
+ var spell = new Spell(entry.SpellId);
+ Player.HandleSpellHooks(spell);
+ }
+ }
}
diff --git a/Source/ACE.Server/WorldObjects/Monster_Navigation.cs b/Source/ACE.Server/WorldObjects/Monster_Navigation.cs
index 5eab0ac03e..edf7e43db8 100644
--- a/Source/ACE.Server/WorldObjects/Monster_Navigation.cs
+++ b/Source/ACE.Server/WorldObjects/Monster_Navigation.cs
@@ -349,8 +349,24 @@ public void GetMovementSpeed()
///
public float GetRunRate()
{
+ var burden = 0.0f;
+
+ // assuming burden only applies to players...
+ if (this is Player player)
+ {
+ var strength = Strength.Current;
+
+ var capacity = EncumbranceSystem.EncumbranceCapacity((int)strength, player.AugmentationIncreasedCarryingCapacity);
+ burden = EncumbranceSystem.GetBurden(capacity, EncumbranceVal ?? 0);
+
+ // TODO: find this exact formula in client
+ // technically this would be based on when the player releases / presses the movement key after stamina > 0
+ if (player.IsExhausted)
+ burden = 3.0f;
+ }
+
var runSkill = GetCreatureSkill(Skill.Run).Current;
- var runRate = MovementSystem.GetRunRate(0.0f, (int)runSkill, 1.0f);
+ var runRate = MovementSystem.GetRunRate(burden, (int)runSkill, 1.0f);
return (float)runRate;
}
diff --git a/Source/ACE.Server/WorldObjects/Player.cs b/Source/ACE.Server/WorldObjects/Player.cs
index 5faa635f55..b98d71ed9b 100644
--- a/Source/ACE.Server/WorldObjects/Player.cs
+++ b/Source/ACE.Server/WorldObjects/Player.cs
@@ -753,22 +753,54 @@ public void HandleActionJump(JumpPack jump)
///
public void OnExhausted()
{
- // adjust player speed if running
- if (CurrentMotionCommand == MotionCommand.RunForward && !IsJumping)
- {
- // verify - forced commands from server should be non-autonomous, but could have been sent as autonomous in retail?
- // if set to autonomous here, the desired effect doesn't happen
- // motion.IsAutonomous = true;
- var motion = new Motion(this, MotionCommand.RunForward);
-
- CurrentMotionState = motion;
+ // adjust player speed if they are currently pressing movement keys
+ HandleRunRateUpdate();
- if (CurrentLandblock != null)
- EnqueueBroadcastMotion(motion);
- }
Session.Network.EnqueueSend(new GameEventCommunicationTransientString(Session, "You're Exhausted!"));
}
+ ///
+ /// Detects changes in the player's RunRate --
+ /// If there are changes, re-broadcasts player movement packet
+ ///
+ public bool HandleRunRateUpdate()
+ {
+ //Console.WriteLine($"{Name}.HandleRunRateUpdates()");
+
+ if (CurrentMovementData.MovementType != MovementType.Invalid)
+ return false;
+
+ var prevState = CurrentMovementData.Invalid.State;
+
+ var movementData = new MovementData(this, CurrentMoveToState);
+ var currentState = movementData.Invalid.State;
+
+ var changed = currentState.ForwardSpeed != prevState.ForwardSpeed ||
+ currentState.TurnSpeed != prevState.TurnSpeed ||
+ currentState.SidestepSpeed != prevState.SidestepSpeed;
+
+ if (!changed)
+ return false;
+
+ //Console.WriteLine($"Old: {prevState.ForwardSpeed}, New: {currentState.ForwardSpeed}");
+
+ if (!CurrentMovementData.Invalid.State.HasMovement() || IsJumping)
+ return false;
+
+ //Console.WriteLine($"{Name}.OnRunRateChanged()");
+
+ CurrentMovementData = new MovementData(this, CurrentMoveToState);
+
+ // verify - forced commands from server should be non-autonomous, but could have been sent as autonomous in retail?
+ // if set to autonomous here, the desired effect doesn't happen
+ CurrentMovementData.IsAutonomous = false;
+
+ var movementEvent = new GameMessageUpdateMotion(this, CurrentMovementData);
+ EnqueueBroadcast(movementEvent); // broadcast to all players, including self
+
+ return true;
+ }
+
///
/// Returns a modifier for a player's Run, Jump, Melee Defense, and Missile Defense skills if they are overburdened
///
diff --git a/Source/ACE.Server/WorldObjects/Player_Attributes.cs b/Source/ACE.Server/WorldObjects/Player_Attributes.cs
index 124bb04759..bf2f446eb4 100644
--- a/Source/ACE.Server/WorldObjects/Player_Attributes.cs
+++ b/Source/ACE.Server/WorldObjects/Player_Attributes.cs
@@ -3,6 +3,7 @@
using ACE.DatLoader;
using ACE.Entity.Enum;
using ACE.Entity.Enum.Properties;
+using ACE.Server.Managers;
using ACE.Server.Network;
using ACE.Server.Network.GameMessages;
using ACE.Server.Network.GameMessages.Messages;
@@ -55,6 +56,10 @@ public void RaiseAttributeGameAction(PropertyAttribute attribute, uint amount)
{
Session.Network.EnqueueSend(abilityUpdate, soundEvent, message);
}
+
+ // retail was missing the 'raise attribute' runrate hook here
+ if ((attribute == PropertyAttribute.Strength || attribute == PropertyAttribute.Quickness) && PropertyManager.GetBool("runrate_add_hooks").Item)
+ HandleRunRateUpdate();
}
else
{
diff --git a/Source/ACE.Server/WorldObjects/Player_Magic.cs b/Source/ACE.Server/WorldObjects/Player_Magic.cs
index 525accd1ff..c07f61597f 100644
--- a/Source/ACE.Server/WorldObjects/Player_Magic.cs
+++ b/Source/ACE.Server/WorldObjects/Player_Magic.cs
@@ -1422,6 +1422,12 @@ public bool VerifySpell(uint spellId, bool builtInSpell = false)
// send error message?
}
+ public void HandleSpellHooks(Spell spell)
+ {
+ HandleMaxVitalUpdate(spell);
+ HandleRunRateUpdate(spell);
+ }
+
///
/// Called when an enchantment is added or removed,
/// checks if the spell affects the max vitals,
@@ -1447,5 +1453,13 @@ public void HandleMaxVitalUpdate(Spell spell)
});
actionChain.EnqueueChain();
}
+
+ public bool HandleRunRateUpdate(Spell spell)
+ {
+ if (!spell.UpdatesRunRate)
+ return false;
+
+ return HandleRunRateUpdate();
+ }
}
}
diff --git a/Source/ACE.Server/WorldObjects/Player_Networking.cs b/Source/ACE.Server/WorldObjects/Player_Networking.cs
index d6bb218cbd..0a46cb5390 100644
--- a/Source/ACE.Server/WorldObjects/Player_Networking.cs
+++ b/Source/ACE.Server/WorldObjects/Player_Networking.cs
@@ -228,7 +228,8 @@ public void BroadcastMovement(MoveToState moveToState)
EnqueueBroadcast(false, movementEvent); // shouldn't need to go to originating player?
// TODO: use real motion / animation system from physics
- CurrentMotionCommand = movementData.Invalid.State.ForwardCommand;
+ //CurrentMotionCommand = movementData.Invalid.State.ForwardCommand;
+ CurrentMovementData = movementData;
}
private EnvironChangeType? currentFogColor;
diff --git a/Source/ACE.Server/WorldObjects/Player_Skills.cs b/Source/ACE.Server/WorldObjects/Player_Skills.cs
index e4f6284b8c..58f78388ac 100644
--- a/Source/ACE.Server/WorldObjects/Player_Skills.cs
+++ b/Source/ACE.Server/WorldObjects/Player_Skills.cs
@@ -249,6 +249,10 @@ public void RaiseSkillGameAction(Skill skill, uint amount)
Session.Network.EnqueueSend(new GameMessagePrivateUpdateSkill(this, creatureSkill));
Session.Network.EnqueueSend(new GameMessageSound(Guid, Sound.RaiseTrait, 1f));
Session.Network.EnqueueSend(new GameMessageSystemChat(messageText, ChatMessageType.Advancement));
+
+ // retail was missing the 'raise skill' runrate hook here
+ if (skill == Skill.Run && PropertyManager.GetBool("runrate_add_hooks").Item)
+ HandleRunRateUpdate();
}
else if (prevXP != creatureSkill.ExperienceSpent)
{
diff --git a/Source/ACE.Server/WorldObjects/Player_Vitals.cs b/Source/ACE.Server/WorldObjects/Player_Vitals.cs
index 12ea81be45..5533a6cbf4 100644
--- a/Source/ACE.Server/WorldObjects/Player_Vitals.cs
+++ b/Source/ACE.Server/WorldObjects/Player_Vitals.cs
@@ -5,6 +5,7 @@
using ACE.Entity;
using ACE.Entity.Enum;
using ACE.Entity.Enum.Properties;
+using ACE.Server.Managers;
using ACE.Server.Network;
using ACE.Server.Network.GameEvent.Events;
using ACE.Server.Network.GameMessages;
@@ -176,22 +177,30 @@ public override void SetMaxVitals()
/// The actual change in the vital, after clamping between 0 and MaxVital
public override int UpdateVital(CreatureVital vital, int newVal)
{
+ var prevVal = vital.Current;
+
var change = base.UpdateVital(vital, newVal);
- if (change != 0)
- {
- Session.Network.EnqueueSend(new GameMessagePrivateUpdateAttribute2ndLevel(this, vital.ToEnum(), vital.Current));
+ if (change == 0)
+ return 0;
- if (Fellowship != null)
- FellowVitalUpdate = true;
- }
+ Session.Network.EnqueueSend(new GameMessagePrivateUpdateAttribute2ndLevel(this, vital.ToEnum(), vital.Current));
+
+ if (Fellowship != null)
+ FellowVitalUpdate = true;
// check for exhaustion
if (vital.Vital == PropertyAttribute2nd.Stamina || vital.Vital == PropertyAttribute2nd.MaxStamina)
{
- if (change != 0 && vital.Current <= 0)
+ if (newVal == 0)
+ {
OnExhausted();
-
+ }
+ // retail was missing the 'exhausted done' automatic hook here
+ else if (prevVal == 0 && PropertyManager.GetBool("runrate_add_hooks").Item)
+ {
+ HandleRunRateUpdate();
+ }
}
return change;
}
diff --git a/Source/ACE.Server/WorldObjects/WorldObject_Magic.cs b/Source/ACE.Server/WorldObjects/WorldObject_Magic.cs
index 7344976eda..0dd21e8183 100644
--- a/Source/ACE.Server/WorldObjects/WorldObject_Magic.cs
+++ b/Source/ACE.Server/WorldObjects/WorldObject_Magic.cs
@@ -1344,7 +1344,7 @@ public EnchantmentStatus CreateEnchantment(WorldObject target, WorldObject caste
{
playerTarget.Session.Network.EnqueueSend(new GameEventMagicUpdateEnchantment(playerTarget.Session, new Enchantment(playerTarget, addResult.Enchantment)));
- playerTarget.HandleMaxVitalUpdate(spell);
+ playerTarget.HandleSpellHooks(spell);
}
if (playerTarget == null && target.Wielder is Player wielder)
diff --git a/Source/ACE.Server/WorldObjects/WorldObject_Properties.cs b/Source/ACE.Server/WorldObjects/WorldObject_Properties.cs
index 18bbdca74d..5ac9ef2fd1 100644
--- a/Source/ACE.Server/WorldObjects/WorldObject_Properties.cs
+++ b/Source/ACE.Server/WorldObjects/WorldObject_Properties.cs
@@ -12,6 +12,7 @@
using ACE.Entity.Enum.Properties;
using ACE.Server.Entity;
using ACE.Server.Managers;
+using ACE.Server.Network.Structure;
namespace ACE.Server.WorldObjects
{
@@ -558,13 +559,15 @@ public void RemovePosition(PositionType positionType)
}
}
-
// ========================================
// ======== Physics Desc Properties =======
// ========================================
// used in CalculatedPhysicsDescriptionFlag()
public Motion CurrentMotionState { get; set; }
- public MotionCommand CurrentMotionCommand { get; set; }
+
+ public MoveToState CurrentMoveToState { get; set; } = new MoveToState();
+ public MovementData CurrentMovementData { get; set; } = new MovementData();
+
public Placement? Placement // Sometimes known as AnimationFrame
{