Skip to content

Commit

Permalink
positions, part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
Mishura4 committed Jun 2, 2024
1 parent 04e4e02 commit a873193
Show file tree
Hide file tree
Showing 60 changed files with 1,629 additions and 1,694 deletions.
5 changes: 5 additions & 0 deletions DOLServer/ConsolePacketLib.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
using DOL.Database;
using System.Numerics;
using DOL.GS.Profession;
using DOL.GS.Geometry;

namespace DOLGameServerConsole
{
Expand Down Expand Up @@ -162,6 +163,7 @@ public void SendDisableSkill(ICollection<Tuple<Skill, int>> skills) { }
public void SendUpdateIcons(IList changedEffects, ref int lastUpdateEffectsCount) { }
public void SendLevelUpSound() { }
public void SendRegionEnterSound(byte soundId) { }
public void SendSoundEffect(ushort soundId, Position position, ushort radius) { }
public void SendSoundEffect(ushort soundId, ushort zoneId, ushort x, ushort y, ushort z, ushort radius) { }
public void SendDebugMessage(string format, params object[] parameters) { }
public void SendDebugPopupMessage(string format, params object[] parameters) { }
Expand All @@ -178,7 +180,9 @@ public void SendQuestUpdate(IQuestPlayerData quest) { }
public void SendConcentrationList() { }
public void SendUpdateCraftingSkills() { }
public void SendChangeTarget(GameObject newTarget) { }
[Obsolete("Use .SendChangeGroundTarget(Coordinate) instead!")]
public void SendChangeGroundTarget(Vector3 newTarget) { }
public void SendChangeGroundTarget(Coordinate newTarget) { }
public void SendPetWindow(GameLiving pet, ePetWindowAction windowAction, eAggressionState aggroState, eWalkState walkState) { }
public void SendKeepInfo(IGameKeep keep) { }
public void SendKeepRealmUpdate(IGameKeep keep) { }
Expand Down Expand Up @@ -242,6 +246,7 @@ public void SendMarketExplorerWindow(IList<InventoryItem> items, byte page, byte
public void SendConsignmentMerchantMoney(long money) { }
public void SendMinotaurRelicMapRemove(byte id) { }
public void SendMinotaurRelicMapUpdate(byte id, ushort region, int x, int y, int z) { }
public void SendMinotaurRelicMapUpdate(byte id, Position position) { }
public virtual void SendMinotaurRelicWindow(GamePlayer player, int spell, bool flag) { }
public virtual void SendMinotaurRelicBarUpdate(GamePlayer player, int xp) { }
public virtual void SendBlinkPanel(byte flag) { }
Expand Down
52 changes: 26 additions & 26 deletions GameServer/DOL.Geometry/Circle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,32 @@

namespace DOL.Geometry
{
/// <summary>
/// Geometry utilities for circles
/// </summary>
public class Circle
{
/// <summary>
/// Gets a uniformly picked random point in the entire circle area
/// </summary>
/// <param name="center"></param>
/// <param name="radius"></param>
/// <returns></returns>
public static Vector3 GetRandomPosition(Vector3 center, int radius)
{
// http://stackoverflow.com/questions/5837572/generate-a-random-point-within-a-circle-uniformly
// We need to use rejection sampling to uniformly end up with a point
/// <summary>
/// Geometry utilities for circles
/// </summary>
public class Circle
{
/// <summary>
/// Gets a uniformly picked random point in the entire circle area
/// </summary>
/// <param name="center"></param>
/// <param name="radius"></param>
/// <returns></returns>
public static Vector3 GetRandomPosition(Vector3 center, int radius)
{
// http://stackoverflow.com/questions/5837572/generate-a-random-point-within-a-circle-uniformly
// We need to use rejection sampling to uniformly end up with a point

// Pick a random point in the area of the unit circle
// on avg this should terminate in 1.42 tries
Vector3 vector;
do
{
vector = new Vector3(Rand.Double() * 2 - 1, Rand.Double() * 2 - 1, 0);
} while (vector.SumComponentSqrs() > 1); // x^2 + y^2 > 1^2
// Pick a random point in the area of the unit circle
// on avg this should terminate in 1.42 tries
Vector3 vector;
do
{
vector = new Vector3(Rand.Double() * 2 - 1, Rand.Double() * 2 - 1, 0);
} while (vector.SumComponentSqrs() > 1); // x^2 + y^2 > 1^2

// Use the point from the unit circle to pick our point
return center + vector * radius;
}
}
// Use the point from the unit circle to pick our point
return center + vector * radius;
}
}
}
13 changes: 3 additions & 10 deletions GameServer/GameClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -748,16 +748,9 @@ public void SavePlayer()
{
//Time playing
var connectedtime = DateTime.Now.Subtract(m_account.LastLogin).TotalMinutes;
//Lets get our player from DB.
var getp = GameServer.Database.FindObjectByKey<DOLCharacters>(m_player.InternalID);
//Let get saved poistion from DB.
int[] oldloc = { getp.Xpos, getp.Ypos, getp.Zpos, getp.Direction, getp.Region };
//Lets get current player Gloc.
int[] currentloc = { (int)m_player.Position.X, (int)m_player.Position.Y, (int)m_player.Position.Z, m_player.Heading, m_player.CurrentRegionID };
//Compapre Old and Current.
bool check = oldloc.SequenceEqual(currentloc);
//If match
if (check)
var dbCharacter = GameServer.Database.FindObjectByKey<DOLCharacters>(m_player.InternalID);

if (dbCharacter.GetPosition() == Player.Position)
{
if (connectedtime > Properties.KICK_IDLE_PLAYER_TIME)
{
Expand Down
60 changes: 60 additions & 0 deletions GameServer/Geometry/Angle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System;

namespace DOL.GS.Geometry;

public struct Angle
{
private const int STEPS_TO_CIRCUMVOLUTION = 360 * 4096;
private const int HEADING_TO_STEPS = STEPS_TO_CIRCUMVOLUTION / 4096;
private const int DEGREE_TO_STEPS = STEPS_TO_CIRCUMVOLUTION / 360;
private const double RADIANS_TO_STEPS = STEPS_TO_CIRCUMVOLUTION / 2 / Math.PI;

private int steps;

///<remarks>for internal use only</remarks>
private static Angle Steps(int steps)
{
steps %= STEPS_TO_CIRCUMVOLUTION;
if (steps < 0) steps += STEPS_TO_CIRCUMVOLUTION;
return new() { steps = steps };
}

public static Angle Heading(int heading)
=> Steps(heading * HEADING_TO_STEPS);

public static Angle Degrees(int degrees)
=> Steps(degrees * DEGREE_TO_STEPS);

public static Angle Radians(double radians)
=> Steps((int)Math.Round(radians * RADIANS_TO_STEPS));

public double InRadians => steps / RADIANS_TO_STEPS;
public ushort InDegrees => (ushort)(steps / DEGREE_TO_STEPS);
public ushort InHeading => (ushort)(steps / HEADING_TO_STEPS);

public override bool Equals(object obj)
{
if (obj is Angle angle) return angle.steps == steps;
return false;
}

public override int GetHashCode()
=> base.GetHashCode();

public override string ToString()
=> steps.ToString();

public static bool operator ==(Angle a, Angle b)
=> a.Equals(b);

public static bool operator !=(Angle a, Angle b)
=> !a.Equals(b);

public static Angle operator +(Angle a, Angle b)
=> Steps(a.steps + b.steps);

public static Angle operator -(Angle a, Angle b)
=> Steps(a.steps - b.steps);

public static readonly Angle Zero = new() { steps = 0 };
}
63 changes: 63 additions & 0 deletions GameServer/Geometry/Coordinate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
namespace DOL.GS.Geometry;

public struct Coordinate
{
private Vector coordinate { get; init; }

public int X => coordinate.X;
public int Y => coordinate.Y;
public int Z => coordinate.Z;

public static Coordinate Create(int x = 0, int y = 0, int z = 0)
=> new() { coordinate = Vector.Create(x, y, z) };

public Coordinate With(int? x = null, int? y = null, int? z = null)
=> new() { coordinate = Vector.Create(x ?? X, y ?? Y, z ?? Z) };

public double DistanceTo(Position pos, bool ignoreZ = false)
=> DistanceTo(pos.Coordinate, ignoreZ);

public double DistanceTo(Coordinate loc, bool ignoreZ = false)
{
if (Equals(Nowhere) || loc.Equals(Nowhere)) return double.PositiveInfinity;

if (ignoreZ) return (loc - this).Length2D;
else return (loc - this).Length;
}

public Angle GetOrientationTo(Coordinate loc)
=> (loc - this).Orientation;

public static Coordinate operator +(Coordinate loc, Vector v)
=> new() { coordinate = loc.coordinate + v };

public static Coordinate operator -(Coordinate loc, Vector v)
=> new() { coordinate = loc.coordinate - v };

public static Vector operator -(Coordinate locA, Coordinate locB)
=> Vector.Create(x: locA.X - locB.X, y: locA.Y - locB.Y, z: locA.Z - locB.Z);

public static bool operator ==(Coordinate a, Coordinate b)
=> a.Equals(b);

public static bool operator !=(Coordinate a, Coordinate b)
=> !a.Equals(b);

public override bool Equals(object obj)
{
if (obj is Coordinate loc)
{
return X == loc.X && Y == loc.Y && Z == loc.Z;
}
return false;
}

public override int GetHashCode()
=> base.GetHashCode();

public override string ToString()
=> $"{X}, {Y}, {Z}";

public readonly static Coordinate Nowhere = Create(-1, -1, -1);
public readonly static Coordinate Zero = Create(0, 0, 0);
}
19 changes: 19 additions & 0 deletions GameServer/Geometry/CoordinateTransitionExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using DOL.Geometry;
using System;

namespace DOL.GS.Geometry;

public static class CoordinateTransitionExtensions
{
[Obsolete("This extension is transitional and going to be removed.")]
public static Point3D ToPoint3D(this Coordinate coordinate)
=> new Point3D(coordinate.X, coordinate.Y, coordinate.Z);

[Obsolete("This extension is transitional and going to be removed.")]
public static Point2D ToPoint2D(this Coordinate coordinate)
=> new Point2D(coordinate.X, coordinate.Y);

[Obsolete("This extension is transitional and going to be removed.")]
public static Coordinate ToCoordinate(this IPoint3D point)
=> Coordinate.Create(point.X, point.Y, point.Z);
}
45 changes: 45 additions & 0 deletions GameServer/Geometry/DataObjectPositionExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using DOL.Database;

namespace DOL.GS.Geometry;

public static class DataObjectPositionExtensions
{
public static Position GetPosition(this Mob mob)
=> Position.Create(mob.Region, mob.X, mob.Y, mob.Z, Angle.Heading(mob.Heading));

public static Position GetPosition(this Teleport teleport)
=> Position.Create((ushort)teleport.RegionID, teleport.X, teleport.Y, teleport.Z, Angle.Heading(teleport.Heading));

public static Position GetSourcePosition(this ZonePoint zonePoint)
=> Position.Create(zonePoint.SourceRegion, zonePoint.SourceX, zonePoint.SourceY, zonePoint.SourceZ);

public static Position GetTargetPosition(this ZonePoint zonePoint)
=> Position.Create(zonePoint.TargetRegion, zonePoint.TargetX, zonePoint.TargetY, zonePoint.TargetZ, Angle.Heading(zonePoint.TargetHeading));

public static Position GetPosition(this DOLCharacters dolc)
=> Position.Create((ushort)dolc.Region, dolc.Xpos, dolc.Ypos, dolc.Zpos, Angle.Heading(dolc.Direction));

public static void SetPosition(this DOLCharacters dolc, Position pos)
{
dolc.Region = pos.RegionID;
dolc.Xpos = pos.X;
dolc.Ypos = pos.Y;
dolc.Zpos = pos.Z;
dolc.Direction = pos.Orientation.InHeading;
}

public static Position GetBindPosition(this DOLCharacters dolc)
=> Position.Create((ushort)dolc.BindRegion, dolc.BindXpos, dolc.BindYpos, dolc.BindZpos, Angle.Heading(dolc.BindHeading));

public static Position GetPosition(this DBKeep dbKeep)
=> Position.Create(dbKeep.Region, dbKeep.X, dbKeep.Y, dbKeep.Z, Angle.Degrees(dbKeep.Heading));

public static void SetPosition(this DBKeep dbKeep, Position pos)
{
dbKeep.Region = pos.RegionID;
dbKeep.X = pos.X;
dbKeep.Y = pos.Y;
dbKeep.Z = pos.Z;
dbKeep.Heading = (ushort)pos.Orientation.InDegrees;
}
}
23 changes: 23 additions & 0 deletions GameServer/Geometry/LinePath.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Linq;

namespace DOL.GS.Geometry;

public class LinePath
{
private Coordinate[] wayPoints = Array.Empty<Coordinate>();
private int indexCounter = 0;

public static LinePath Create(Coordinate[] wayPoints)
=> new LinePath() { wayPoints = wayPoints };

public Coordinate Start => wayPoints.Length == 0 ? Coordinate.Nowhere : wayPoints.First();

public Coordinate End => wayPoints.Length == 0 ? Coordinate.Nowhere : wayPoints.Last();

public void SelectNextWayPoint() => indexCounter++;

public Coordinate CurrentWayPoint => (indexCounter < PointCount - 1) ? wayPoints[indexCounter] : Coordinate.Nowhere;

public int PointCount => wayPoints.Length;
}
32 changes: 32 additions & 0 deletions GameServer/Geometry/Motion.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;

namespace DOL.GS.Geometry;

public class Motion
{
public static Motion Create(Position start, Coordinate destination, short withSpeed)
=> new Motion() { Start = start, Destination = destination, Speed = withSpeed };

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

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

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

var distanceTravelled = Speed * elapsedTimeInMilliSeconds * 0.001;
if (Destination == Coordinate.Nowhere) return Start + Vector.Create(Start.Orientation, distanceTravelled);

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

return Start.With(movementVector.Orientation) + movementVector * (distanceTravelled / FullDistance);
}
}
Loading

0 comments on commit a873193

Please sign in to comment.