Skip to content

Commit 0e9a0f9

Browse files
authored
Obsolete Point3D/GameLocation (#472)
Mitigate jerky movement when pathing is activated
2 parents 4896f47 + 0ac11e6 commit 0e9a0f9

File tree

353 files changed

+4392
-6803
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

353 files changed

+4392
-6803
lines changed

DOLServer/ConsolePacketLib.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
using log4net;
3232
using DOL.Database;
3333
using DOL.GS.Profession;
34+
using DOL.GS.Geometry;
3435

3536
namespace DOLGameServerConsole
3637
{
@@ -163,6 +164,7 @@ public void SendDisableSkill(ICollection<Tuple<Skill, int>> skills) { }
163164
public void SendUpdateIcons(IList changedEffects, ref int lastUpdateEffectsCount) { }
164165
public void SendLevelUpSound() { }
165166
public void SendRegionEnterSound(byte soundId) { }
167+
public void SendSoundEffect(ushort soundId, Position position, ushort radius) { }
166168
public void SendSoundEffect(ushort soundId, ushort zoneId, ushort x, ushort y, ushort z, ushort radius) { }
167169
public void SendDebugMessage(string format, params object[] parameters) { }
168170
public void SendDebugPopupMessage(string format, params object[] parameters) { }
@@ -179,7 +181,9 @@ public void SendQuestUpdate(AbstractQuest quest) { }
179181
public void SendConcentrationList() { }
180182
public void SendUpdateCraftingSkills() { }
181183
public void SendChangeTarget(GameObject newTarget) { }
184+
[Obsolete("Use .SendChangeGroundTarget(Coordinate) instead!")]
182185
public void SendChangeGroundTarget(Point3D newTarget) { }
186+
public void SendChangeGroundTarget(Coordinate newTarget) { }
183187
public void SendPetWindow(GameLiving pet, ePetWindowAction windowAction, eAggressionState aggroState, eWalkState walkState) { }
184188
public void SendKeepInfo(IGameKeep keep) { }
185189
public void SendKeepRealmUpdate(IGameKeep keep) { }
@@ -243,6 +247,7 @@ public void SendMarketExplorerWindow(IList<InventoryItem> items, byte page, byte
243247
public void SendConsignmentMerchantMoney(long money) { }
244248
public void SendMinotaurRelicMapRemove(byte id) { }
245249
public void SendMinotaurRelicMapUpdate(byte id, ushort region, int x, int y, int z) { }
250+
public void SendMinotaurRelicMapUpdate(byte id, Position position) { }
246251
public virtual void SendMinotaurRelicWindow(GamePlayer player, int spell, bool flag) { }
247252
public virtual void SendMinotaurRelicBarUpdate(GamePlayer player, int xp) { }
248253
public virtual void SendBlinkPanel(byte flag) { }

GameServer/GameClient.cs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
using DOL.Network;
3333

3434
using log4net;
35+
using DOL.GS.Geometry;
3536

3637
namespace DOL.GS
3738
{
@@ -723,18 +724,10 @@ public void SavePlayer()
723724
//<**loki**>
724725
if (Properties.KICK_IDLE_PLAYER_STATUS)
725726
{
726-
//Time playing
727727
var connectedtime = DateTime.Now.Subtract(m_account.LastLogin).TotalMinutes;
728-
//Lets get our player from DB.
729-
var getp = GameServer.Database.FindObjectByKey<DOLCharacters>(m_player.InternalID);
730-
//Let get saved poistion from DB.
731-
int[] oldloc = { getp.Xpos, getp.Ypos, getp.Zpos, getp.Direction, getp.Region };
732-
//Lets get current player Gloc.
733-
int[] currentloc = { m_player.X, m_player.Y, m_player.Z, m_player.Heading, m_player.CurrentRegionID };
734-
//Compapre Old and Current.
735-
bool check = oldloc.SequenceEqual(currentloc);
736-
//If match
737-
if (check)
728+
var dbCharacter = GameServer.Database.FindObjectByKey<DOLCharacters>(m_player.InternalID);
729+
730+
if (dbCharacter.GetPosition() == Player.Position)
738731
{
739732
if (connectedtime > Properties.KICK_IDLE_PLAYER_TIME)
740733
{

GameServer/Geometry/Angle.cs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System;
2+
3+
namespace DOL.GS.Geometry;
4+
5+
public struct Angle
6+
{
7+
private const int STEPS_TO_CIRCUMVOLUTION = 360 * 4096;
8+
private const int HEADING_TO_STEPS = STEPS_TO_CIRCUMVOLUTION / 4096;
9+
private const int DEGREE_TO_STEPS = STEPS_TO_CIRCUMVOLUTION / 360;
10+
private const double RADIANS_TO_STEPS = STEPS_TO_CIRCUMVOLUTION / 2 / Math.PI;
11+
12+
private int steps;
13+
14+
///<remarks>for internal use only</remarks>
15+
private static Angle Steps(int steps)
16+
{
17+
steps %= STEPS_TO_CIRCUMVOLUTION;
18+
if (steps < 0) steps += STEPS_TO_CIRCUMVOLUTION;
19+
return new() { steps = steps };
20+
}
21+
22+
public static Angle Heading(int heading)
23+
=> Steps(heading * HEADING_TO_STEPS);
24+
25+
public static Angle Degrees(int degrees)
26+
=> Steps(degrees * DEGREE_TO_STEPS);
27+
28+
public static Angle Radians(double radians)
29+
=> Steps((int)Math.Round(radians * RADIANS_TO_STEPS));
30+
31+
public double InRadians => steps / RADIANS_TO_STEPS;
32+
public ushort InDegrees => (ushort)(steps / DEGREE_TO_STEPS);
33+
public ushort InHeading => (ushort)(steps / HEADING_TO_STEPS);
34+
35+
public override bool Equals(object obj)
36+
{
37+
if (obj is Angle angle) return angle.steps == steps;
38+
return false;
39+
}
40+
41+
public override int GetHashCode()
42+
=> base.GetHashCode();
43+
44+
public override string ToString()
45+
=> steps.ToString();
46+
47+
public static bool operator ==(Angle a, Angle b)
48+
=> a.Equals(b);
49+
50+
public static bool operator !=(Angle a, Angle b)
51+
=> !a.Equals(b);
52+
53+
public static Angle operator +(Angle a, Angle b)
54+
=> Steps(a.steps + b.steps);
55+
56+
public static Angle operator -(Angle a, Angle b)
57+
=> Steps(a.steps - b.steps);
58+
59+
public static readonly Angle Zero = new() { steps = 0 };
60+
}

GameServer/Geometry/Coordinate.cs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
namespace DOL.GS.Geometry;
2+
3+
public struct Coordinate
4+
{
5+
private Vector coordinate { get; init; }
6+
7+
public int X => coordinate.X;
8+
public int Y => coordinate.Y;
9+
public int Z => coordinate.Z;
10+
11+
public static Coordinate Create(int x = 0, int y = 0, int z = 0)
12+
=> new() { coordinate = Vector.Create(x, y, z) };
13+
14+
public Coordinate With(int? x = null, int? y = null, int? z = null)
15+
=> new() { coordinate = Vector.Create(x ?? X, y ?? Y, z ?? Z) };
16+
17+
public double DistanceTo(Position pos, bool ignoreZ = false)
18+
=> DistanceTo(pos.Coordinate, ignoreZ);
19+
20+
public double DistanceTo(Coordinate loc, bool ignoreZ = false)
21+
{
22+
if (Equals(Nowhere) || loc.Equals(Nowhere)) return double.PositiveInfinity;
23+
24+
if (ignoreZ) return (loc - this).Length2D;
25+
else return (loc - this).Length;
26+
}
27+
28+
public Angle GetOrientationTo(Coordinate loc)
29+
=> (loc - this).Orientation;
30+
31+
public static Coordinate operator +(Coordinate loc, Vector v)
32+
=> new() { coordinate = loc.coordinate + v };
33+
34+
public static Coordinate operator -(Coordinate loc, Vector v)
35+
=> new() { coordinate = loc.coordinate - v };
36+
37+
public static Vector operator -(Coordinate locA, Coordinate locB)
38+
=> Vector.Create(x: locA.X - locB.X, y: locA.Y - locB.Y, z: locA.Z - locB.Z);
39+
40+
public static bool operator ==(Coordinate a, Coordinate b)
41+
=> a.Equals(b);
42+
43+
public static bool operator !=(Coordinate a, Coordinate b)
44+
=> !a.Equals(b);
45+
46+
public override bool Equals(object obj)
47+
{
48+
if (obj is Coordinate loc)
49+
{
50+
return X == loc.X && Y == loc.Y && Z == loc.Z;
51+
}
52+
return false;
53+
}
54+
55+
public override int GetHashCode()
56+
=> base.GetHashCode();
57+
58+
public override string ToString()
59+
=> $"{X}, {Y}, {Z}";
60+
61+
public readonly static Coordinate Nowhere = Create(-1, -1, -1);
62+
public readonly static Coordinate Zero = Create(0, 0, 0);
63+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System;
2+
3+
namespace DOL.GS.Geometry;
4+
5+
public static class CoordinateTransitionExtensions
6+
{
7+
[Obsolete("This extension is transitional and going to be removed.")]
8+
public static Point3D ToPoint3D(this Coordinate coordinate)
9+
=> new Point3D(coordinate.X, coordinate.Y, coordinate.Z);
10+
11+
[Obsolete("This extension is transitional and going to be removed.")]
12+
public static Coordinate ToCoordinate(this IPoint3D point)
13+
=> Coordinate.Create(point.X, point.Y, point.Z);
14+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using DOL.Database;
2+
3+
namespace DOL.GS.Geometry;
4+
5+
public static class DataObjectPositionExtensions
6+
{
7+
public static Position GetPosition(this Mob mob)
8+
=> Position.Create(mob.Region, mob.X, mob.Y, mob.Z, Angle.Heading(mob.Heading));
9+
10+
public static Position GetPosition(this Teleport teleport)
11+
=> Position.Create((ushort)teleport.RegionID, teleport.X, teleport.Y, teleport.Z, Angle.Heading(teleport.Heading));
12+
13+
public static Position GetSourcePosition(this ZonePoint zonePoint)
14+
=> Position.Create(zonePoint.SourceRegion, zonePoint.SourceX, zonePoint.SourceY, zonePoint.SourceZ);
15+
16+
public static Position GetTargetPosition(this ZonePoint zonePoint)
17+
=> Position.Create(zonePoint.TargetRegion, zonePoint.TargetX, zonePoint.TargetY, zonePoint.TargetZ, Angle.Heading(zonePoint.TargetHeading));
18+
19+
public static Position GetPosition(this DOLCharacters dolc)
20+
=> Position.Create((ushort)dolc.Region, dolc.Xpos, dolc.Ypos, dolc.Zpos, Angle.Heading(dolc.Direction));
21+
22+
public static void SetPosition(this DOLCharacters dolc, Position pos)
23+
{
24+
dolc.Region = pos.RegionID;
25+
dolc.Xpos = pos.X;
26+
dolc.Ypos = pos.Y;
27+
dolc.Zpos = pos.Z;
28+
dolc.Direction = pos.Orientation.InHeading;
29+
}
30+
31+
public static Position GetBindPosition(this DOLCharacters dolc)
32+
=> Position.Create((ushort)dolc.BindRegion, dolc.BindXpos, dolc.BindYpos, dolc.BindZpos, Angle.Heading(dolc.BindHeading));
33+
34+
public static Position GetPosition(this DBKeep dbKeep)
35+
=> Position.Create(dbKeep.Region, dbKeep.X, dbKeep.Y, dbKeep.Z, Angle.Degrees(dbKeep.Heading));
36+
37+
public static void SetPosition(this DBKeep dbKeep, Position pos)
38+
{
39+
dbKeep.Region = pos.RegionID;
40+
dbKeep.X = pos.X;
41+
dbKeep.Y = pos.Y;
42+
dbKeep.Z = pos.Z;
43+
dbKeep.Heading = (ushort)pos.Orientation.InDegrees;
44+
}
45+
}

GameServer/Geometry/LinePath.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System;
2+
using System.Linq;
3+
4+
namespace DOL.GS.Geometry;
5+
6+
public class LinePath
7+
{
8+
private Coordinate[] wayPoints = Array.Empty<Coordinate>();
9+
private int indexCounter = 0;
10+
11+
public static LinePath Create(Coordinate[] wayPoints)
12+
=> new LinePath() { wayPoints = wayPoints };
13+
14+
public Coordinate Start => wayPoints.Length == 0 ? Coordinate.Nowhere : wayPoints.First();
15+
16+
public Coordinate End => wayPoints.Length == 0 ? Coordinate.Nowhere : wayPoints.Last();
17+
18+
public void SelectNextWayPoint() => indexCounter++;
19+
20+
public Coordinate CurrentWayPoint => (indexCounter < PointCount - 1) ? wayPoints[indexCounter] : Coordinate.Nowhere;
21+
22+
public int PointCount => wayPoints.Length;
23+
}

GameServer/Geometry/Motion.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System;
2+
3+
namespace DOL.GS.Geometry;
4+
5+
public class Motion
6+
{
7+
public static Motion Create(Position start, Coordinate destination, short withSpeed)
8+
=> new Motion() { Start = start, Destination = destination, Speed = withSpeed };
9+
10+
public int StartTimeInMilliSeconds { get; } = Environment.TickCount;
11+
public Position Start { get; init; } = Position.Nowhere;
12+
public Coordinate Destination { get; init; } = Coordinate.Nowhere;
13+
public short Speed { get; init; } = 0;
14+
15+
public Position CurrentPosition
16+
=> GetPositonAfter(Environment.TickCount - StartTimeInMilliSeconds);
17+
public double FullDistance => Destination.DistanceTo(Start, ignoreZ: true);
18+
public double RemainingDistance => Destination.DistanceTo(CurrentPosition, ignoreZ: true);
19+
20+
public Position GetPositonAfter(int elapsedTimeInMilliSeconds)
21+
{
22+
if (Speed == 0 || Start.Coordinate == Destination) return Start;
23+
24+
var distanceTravelled = Speed * elapsedTimeInMilliSeconds * 0.001;
25+
if (Destination == Coordinate.Nowhere) return Start + Vector.Create(Start.Orientation, distanceTravelled);
26+
27+
var movementVector = Destination - Start.Coordinate;
28+
if (distanceTravelled > FullDistance) return Position.Create(Start.RegionID, Destination, movementVector.Orientation);
29+
30+
return Start.With(movementVector.Orientation) + movementVector * (distanceTravelled / FullDistance);
31+
}
32+
}

GameServer/Geometry/Position.cs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
namespace DOL.GS.Geometry;
2+
3+
public struct Position
4+
{
5+
public ushort RegionID { get; init; } = 0;
6+
public Coordinate Coordinate { get; init; } = Coordinate.Zero;
7+
public Angle Orientation { get; init; } = Angle.Zero;
8+
9+
public int X => Coordinate.X;
10+
public int Y => Coordinate.Y;
11+
public int Z => Coordinate.Z;
12+
13+
public Region Region => WorldMgr.GetRegion(RegionID);
14+
15+
public Position() { }
16+
17+
public static Position Create(ushort regionID, int x, int y, int z, ushort heading)
18+
=> new() { RegionID = regionID, Coordinate = Coordinate.Create(x, y, z), Orientation = Angle.Heading(heading) };
19+
20+
public static Position Create(ushort regionID, int x = 0, int y = 0, int z = 0, Angle? orientation = null)
21+
=> new() { RegionID = regionID, Coordinate = Coordinate.Create(x, y, z), Orientation = orientation ?? Angle.Zero };
22+
23+
public static Position CreateInZone(ushort zoneID, int x = 0, int y = 0, int z = 0, ushort heading = 0)
24+
{
25+
var zone = WorldMgr.GetZone(zoneID);
26+
return Create(zone.ZoneRegion.ID, x + zone.Offset.X, y + zone.Offset.Y, z + zone.Offset.Z, heading);
27+
}
28+
29+
public static Position Create(ushort regionID, Coordinate coordinate, ushort heading = 0)
30+
=> new() { RegionID = regionID, Coordinate = coordinate, Orientation = Angle.Heading(heading) };
31+
32+
public static Position Create(ushort regionID, Coordinate coordinate, Angle orientation)
33+
=> new() { RegionID = regionID, Coordinate = coordinate, Orientation = orientation };
34+
35+
public Position With(ushort? regionID = null, int? x = null, int? y = null, int? z = null, ushort? heading = null)
36+
{
37+
var newOrientation = heading != null ? Angle.Heading((ushort)heading) : Orientation;
38+
var newRegionID = regionID ?? RegionID;
39+
return Create(newRegionID, Coordinate.With(x, y, z), newOrientation);
40+
}
41+
42+
public Position With(Coordinate coordinate)
43+
=> Create(RegionID, coordinate, Orientation);
44+
45+
public Position With(Angle orientation)
46+
=> Create(RegionID, Coordinate, orientation);
47+
48+
public Position TurnedAround()
49+
=> With(orientation: Orientation + Angle.Degrees(180));
50+
51+
public static Position operator +(Position a, Vector b)
52+
=> a.With(coordinate: a.Coordinate + b);
53+
54+
public static Position operator -(Position a, Vector b)
55+
=> a.With(coordinate: a.Coordinate - b);
56+
57+
public static bool operator ==(Position a, Position b)
58+
=> a.Equals(b);
59+
60+
public static bool operator !=(Position a, Position b)
61+
=> !a.Equals(b);
62+
63+
public override bool Equals(object obj)
64+
{
65+
if (obj is Position otherPos)
66+
{
67+
return otherPos.RegionID == RegionID
68+
&& otherPos.Coordinate.Equals(Coordinate)
69+
&& otherPos.Orientation == Orientation;
70+
}
71+
return false;
72+
}
73+
74+
public override int GetHashCode()
75+
=> base.GetHashCode();
76+
77+
public override string ToString()
78+
=> $"({Coordinate}, {Orientation.InHeading})";
79+
80+
public readonly static Position Nowhere = Create(regionID: ushort.MaxValue, Coordinate.Nowhere, Angle.Zero);
81+
public readonly static Position Zero = new();
82+
}

0 commit comments

Comments
 (0)