Skip to content

Commit

Permalink
Collapse Motion class inheritance
Browse files Browse the repository at this point in the history
Replace .GetLocationAfter with .GetPositionAfter (and return Position)
Replace .CurrentLocation with CurrentPosition accordingly
.Start is now a Position
  • Loading branch information
NetDwarf committed Sep 23, 2023
1 parent 5f8c6ef commit 524d244
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 69 deletions.
68 changes: 11 additions & 57 deletions GameServer/Geometry/Motion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,77 +2,31 @@

namespace DOL.GS.Geometry;

public interface IMotion
{
int StartTimeInMilliSeconds { get; }
Coordinate Start { get; init; }
Coordinate Destination { get; }
short Speed { get; init; }
Coordinate CurrentLocation { get; }
double FullDistance { get; }
double RemainingDistance { get; }

Angle GetDirection();
}

public class Motion
{
public static IMotion Create(Position start, Coordinate destination, short withSpeed)
{
if (destination.Equals(Coordinate.Nowhere)) return new GoAheadMotion() { Start = start.Coordinate, Speed = withSpeed, Direction = start.Orientation };
else if (start.Equals(destination)) return new GoAheadMotion() { Start = start.Coordinate, Speed = 0, Direction = start.Orientation };
else return new MotionToDestination() { Start = start.Coordinate, Destination = destination, Speed = withSpeed };
}
}
public static Motion Create(Position start, Coordinate destination, short withSpeed)
=> new Motion() { Start = start, Destination = destination, Speed = withSpeed };

public class MotionToDestination : IMotion
{
public int StartTimeInMilliSeconds { get; } = Environment.TickCount;
public Coordinate Start { get; init; } = Coordinate.Nowhere;
public Position Start { get; init; } = Position.Nowhere;
public Coordinate Destination { get; init; } = Coordinate.Nowhere;
public short Speed { get; init; } = 0;

public Coordinate CurrentLocation
=> GetLocationAfter(Environment.TickCount - StartTimeInMilliSeconds);
public Position CurrentPosition
=> GetPositonAfter(Environment.TickCount - StartTimeInMilliSeconds);
public double FullDistance => Destination.DistanceTo(Start, ignoreZ: true);
public double RemainingDistance => Destination.DistanceTo(CurrentPosition, ignoreZ: true);

public Coordinate GetLocationAfter(int elapsedTimeInMilliSeconds)
public Position GetPositonAfter(int elapsedTimeInMilliSeconds)
{
if (Speed == 0) return Start;
if (Speed == 0 || Start.Coordinate == Destination) return Start;

var distanceTravelled = Speed * elapsedTimeInMilliSeconds * 0.001;
if (distanceTravelled > FullDistance) return Destination;

var progress = distanceTravelled / FullDistance;
if (progress > 1) return Destination;
else return Start + (Destination - Start) * progress;
}
if (Destination == Coordinate.Nowhere) return Start + Vector.Create(Start.Orientation, distanceTravelled);

public Angle GetDirection()
=> Start.GetOrientationTo(Destination);
}
var movementVector = Destination - Start.Coordinate;
if (distanceTravelled > FullDistance) return Position.Create(Start.RegionID, Destination, movementVector.Orientation);

public class GoAheadMotion : IMotion
{
public int StartTimeInMilliSeconds { get; } = Environment.TickCount;
public Coordinate Start { get; init; } = Coordinate.Nowhere;
public Coordinate Destination { get => Coordinate.Nowhere; }
public short Speed { get; init; } = 0;
public Angle Direction { get; init; }

public Coordinate CurrentLocation
=> GetLocationAfter(Environment.TickCount - StartTimeInMilliSeconds);
public double FullDistance => double.PositiveInfinity;
public double RemainingDistance => double.PositiveInfinity;

public Coordinate GetLocationAfter(int elapsedTimeInMilliSeconds)
{
if (Speed == 0) return Start;
var timeElapsedInSeconds = elapsedTimeInMilliSeconds * 0.001;
var distanceTravelled = Speed * timeElapsedInSeconds;
return Start + Vector.Create(Direction, distanceTravelled);
return Start.With(movementVector.Orientation) + movementVector * (distanceTravelled / FullDistance);
}

public Angle GetDirection() => Direction;
}
2 changes: 1 addition & 1 deletion GameServer/Geometry/Position.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ public struct Position
private const ushort NO_REGION_ID = ushort.MaxValue;

public ushort RegionID { get; init; } = 0;
public Coordinate Coordinate { get; init; } = Coordinate.Nowhere;
public Coordinate Coordinate { get; init; } = Coordinate.Zero;
public Angle Orientation { get; init; } = Angle.Zero;

public int X => Coordinate.X;
Expand Down
2 changes: 1 addition & 1 deletion GameServer/Geometry/Vector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,5 @@ public override int GetHashCode()
public static Vector operator -(Vector vecA, Vector vecB)
=> Create(vecA.X - vecB.X, vecA.Y - vecB.Y, vecA.Z - vecB.Z);

public static Vector Zero => Vector.Create(0, 0, 0);
public static readonly Vector Zero = Vector.Create(0, 0, 0);
}
16 changes: 8 additions & 8 deletions GameServer/gameobjects/GameLiving.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5744,34 +5744,34 @@ public int MovementStartTick

public override Position Position
{
get => Position.Create(CurrentRegionID, Motion.CurrentLocation, Motion.GetDirection());
set { CurrentRegionID = value.RegionID; Motion = Geometry.Motion.Create(value, Motion.Destination, Motion.Speed); }
get => Motion.CurrentPosition;
set { CurrentRegionID = value.RegionID; Motion = Motion.Create(value, Motion.Destination, Motion.Speed); }
}

protected virtual IMotion Motion { get; set; } = new GoAheadMotion();
protected virtual Motion Motion { get; set; } = new Motion();

[Obsolete("Use .Position.X instead!")]
public override int X
{
set => Position = Position.Create(CurrentRegionID, coordinate: Motion.Start.With(x: value), Orientation);
set => Position = Motion.Start.With(x: value);
}

[Obsolete("Use .Position.Y instead!")]
public override int Y
{
set => Position = Position.Create(CurrentRegionID, coordinate: Motion.Start.With(y: value), Orientation);
set => Position = Motion.Start.With(y: value);
}

[Obsolete("Use .Position.Z instead!")]
public override int Z
{
set => Position = Position.Create(CurrentRegionID, coordinate: Motion.Start.With(z: value), Orientation);
set => Position = Motion.Start.With(z: value);
}

public override Angle Orientation
{
get => Motion.GetDirection();
set => Position = Position.Create(CurrentRegionID, Motion.Start, value);
get => Position.Orientation;
set => Position = Motion.Start.With(orientation: value);
}

public override ushort CurrentRegionID
Expand Down
2 changes: 1 addition & 1 deletion GameServer/gameobjects/GameNPC.cs
Original file line number Diff line number Diff line change
Expand Up @@ -795,7 +795,7 @@ public ushort SpawnHeading
public short ZSpeedFactor
=> (short)((Motion.Destination.Z - Motion.Start.Z) / Motion.FullDistance);

protected override IMotion Motion
protected override Motion Motion
{
set
{
Expand Down
2 changes: 1 addition & 1 deletion GameServer/gameobjects/GamePlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10329,7 +10329,7 @@ public Zone LastPositionUpdateZone
set { m_lastPositionUpdateZone = value; }
}

public Coordinate LastUpdateLocation => Motion.Start;
public Coordinate LastUpdateLocation => Motion.Start.Coordinate;

/// <summary>
/// Holds the players max Z for fall damage
Expand Down

0 comments on commit 524d244

Please sign in to comment.