using System.Collections.Generic;
using System.IO;
using ACE.Entity.Enum;
using ACE.Server.Entity;
using ACE.Server.WorldObjects;
namespace ACE.Server.Network.Structure
{
///
/// Information related to movement and animation
///
public class InterpretedMotionState
{
public MovementStateFlag Flags;
public MovementData MovementData;
public MotionStance CurrentStyle;
public MotionCommand ForwardCommand;
public MotionCommand SidestepCommand;
public MotionCommand TurnCommand;
public float ForwardSpeed = 1.0f;
public float SidestepSpeed = 1.0f;
public float TurnSpeed = 1.0f;
// commands: list of length commandListLength
public List Commands;
public InterpretedMotionState()
{
ForwardCommand = MotionCommand.Ready;
}
public InterpretedMotionState(InterpretedMotionState state)
{
// copy constructor
Flags = state.Flags;
MovementData = state.MovementData;
CurrentStyle = state.CurrentStyle;
ForwardCommand = state.ForwardCommand;
SidestepCommand = state.SidestepCommand;
TurnCommand = state.TurnCommand;
ForwardSpeed = state.ForwardSpeed;
SidestepSpeed = state.SidestepSpeed;
TurnSpeed = state.TurnSpeed;
if (state.Commands != null)
{
Commands = new List();
foreach (var command in state.Commands)
Commands.Add(new MotionItem(command));
}
}
public InterpretedMotionState(MovementData data)
{
MovementData = data;
CurrentStyle = data.CurrentStyle;
Flags = BuildMovementFlags();
}
public InterpretedMotionState(MovementData data, Motion motion)
{
MovementData = data;
CurrentStyle = data.CurrentStyle;
var state = motion.MotionState;
ForwardCommand = state.ForwardCommand;
SidestepCommand = state.SidestepCommand;
TurnCommand = state.TurnCommand;
ForwardSpeed = state.ForwardSpeed;
SidestepSpeed = state.SidestepSpeed;
TurnSpeed = state.TurnSpeed;
Commands = state.Commands;
Flags = BuildMovementFlags();
}
///
/// Builds the MovementFlags based on the current state
///
public MovementStateFlag BuildMovementFlags()
{
var flags = MovementStateFlag.Invalid;
if (CurrentStyle != 0 && CurrentStyle != MotionStance.Invalid)
flags |= MovementStateFlag.CurrentStyle;
if (ForwardCommand != MotionCommand.Invalid)
flags |= MovementStateFlag.ForwardCommand;
if (SidestepCommand != MotionCommand.Invalid)
flags |= MovementStateFlag.SideStepCommand;
if (TurnCommand != MotionCommand.Invalid)
flags |= MovementStateFlag.TurnCommand;
if (ForwardSpeed != 1.0f)
flags |= MovementStateFlag.ForwardSpeed;
if (SidestepSpeed != 1.0f)
flags |= MovementStateFlag.SideStepSpeed;
if (TurnSpeed != 1.0f)
flags |= MovementStateFlag.TurnSpeed;
return flags;
}
public void AddCommand(WorldObject worldObject, MotionCommand motionCommand, float speed = 1.0f)
{
if (Commands == null)
Commands = new List();
Commands.Add(new MotionItem(worldObject, motionCommand, speed));
}
public bool HasMovement()
{
return (ForwardCommand != MotionCommand.Invalid && ForwardCommand != MotionCommand.Ready) || TurnCommand != MotionCommand.Invalid || SidestepCommand != MotionCommand.Invalid;
}
}
public static class InterpretedMotionStateExtensions
{
public static void Write(this BinaryWriter writer, InterpretedMotionState state)
{
var numCommands = state.Commands != null ? state.Commands.Count : 0;
writer.Write((uint)state.Flags | (uint)numCommands << 7);
// for MotionStance / MotionCommand, write as ushort
if ((state.Flags & MovementStateFlag.CurrentStyle) != 0)
writer.Write((ushort)state.CurrentStyle);
if ((state.Flags & MovementStateFlag.ForwardCommand) != 0)
writer.Write((ushort)state.ForwardCommand);
if ((state.Flags & MovementStateFlag.SideStepCommand) != 0)
writer.Write((ushort)state.SidestepCommand);
if ((state.Flags & MovementStateFlag.TurnCommand) != 0)
writer.Write((ushort)state.TurnCommand);
if ((state.Flags & MovementStateFlag.ForwardSpeed) != 0)
writer.Write(state.ForwardSpeed);
if ((state.Flags & MovementStateFlag.SideStepSpeed) != 0)
writer.Write(state.SidestepSpeed);
if ((state.Flags & MovementStateFlag.TurnSpeed) != 0)
writer.Write(state.TurnSpeed);
if (numCommands > 0)
{
foreach (var motion in state.Commands)
writer.Write(motion);
}
// align to DWORD boundary
writer.Align();
}
}
}