diff --git a/DOLServer/ConsolePacketLib.cs b/DOLServer/ConsolePacketLib.cs index f507babb12..69e5b0976e 100644 --- a/DOLServer/ConsolePacketLib.cs +++ b/DOLServer/ConsolePacketLib.cs @@ -31,6 +31,7 @@ using log4net; using DOL.Database; using DOL.GS.Profession; +using DOL.GS.Geometry; namespace DOLGameServerConsole { @@ -163,6 +164,7 @@ public void SendDisableSkill(ICollection> 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) { } @@ -179,7 +181,9 @@ public void SendQuestUpdate(AbstractQuest quest) { } public void SendConcentrationList() { } public void SendUpdateCraftingSkills() { } public void SendChangeTarget(GameObject newTarget) { } + [Obsolete("Use .SendChangeGroundTarget(Coordinate) instead!")] public void SendChangeGroundTarget(Point3D 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) { } @@ -243,6 +247,7 @@ public void SendMarketExplorerWindow(IList 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) { } diff --git a/GameServer/GameClient.cs b/GameServer/GameClient.cs index d6237dbc73..138da54f38 100644 --- a/GameServer/GameClient.cs +++ b/GameServer/GameClient.cs @@ -32,6 +32,7 @@ using DOL.Network; using log4net; +using DOL.GS.Geometry; namespace DOL.GS { @@ -723,18 +724,10 @@ public void SavePlayer() //<**loki**> if (Properties.KICK_IDLE_PLAYER_STATUS) { - //Time playing var connectedtime = DateTime.Now.Subtract(m_account.LastLogin).TotalMinutes; - //Lets get our player from DB. - var getp = GameServer.Database.FindObjectByKey(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 = { m_player.X, m_player.Y, m_player.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(m_player.InternalID); + + if (dbCharacter.GetPosition() == Player.Position) { if (connectedtime > Properties.KICK_IDLE_PLAYER_TIME) { diff --git a/GameServer/Geometry/Angle.cs b/GameServer/Geometry/Angle.cs new file mode 100644 index 0000000000..d1cf60b9ea --- /dev/null +++ b/GameServer/Geometry/Angle.cs @@ -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; + + ///for internal use only + 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 }; +} \ No newline at end of file diff --git a/GameServer/Geometry/Coordinate.cs b/GameServer/Geometry/Coordinate.cs new file mode 100644 index 0000000000..68a18de61b --- /dev/null +++ b/GameServer/Geometry/Coordinate.cs @@ -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); +} \ No newline at end of file diff --git a/GameServer/Geometry/CoordinateTransitionExtensions.cs b/GameServer/Geometry/CoordinateTransitionExtensions.cs new file mode 100644 index 0000000000..0f37be8cca --- /dev/null +++ b/GameServer/Geometry/CoordinateTransitionExtensions.cs @@ -0,0 +1,14 @@ +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 Coordinate ToCoordinate(this IPoint3D point) + => Coordinate.Create(point.X, point.Y, point.Z); +} \ No newline at end of file diff --git a/GameServer/Geometry/DataObjectPositionExtensions.cs b/GameServer/Geometry/DataObjectPositionExtensions.cs new file mode 100644 index 0000000000..6be47cd953 --- /dev/null +++ b/GameServer/Geometry/DataObjectPositionExtensions.cs @@ -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; + } +} \ No newline at end of file diff --git a/GameServer/Geometry/LinePath.cs b/GameServer/Geometry/LinePath.cs new file mode 100644 index 0000000000..e66766233f --- /dev/null +++ b/GameServer/Geometry/LinePath.cs @@ -0,0 +1,23 @@ +using System; +using System.Linq; + +namespace DOL.GS.Geometry; + +public class LinePath +{ + private Coordinate[] wayPoints = Array.Empty(); + 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; +} \ No newline at end of file diff --git a/GameServer/Geometry/Motion.cs b/GameServer/Geometry/Motion.cs new file mode 100644 index 0000000000..f3d1529602 --- /dev/null +++ b/GameServer/Geometry/Motion.cs @@ -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); + } +} \ No newline at end of file diff --git a/GameServer/Geometry/Position.cs b/GameServer/Geometry/Position.cs new file mode 100644 index 0000000000..1e694c08b0 --- /dev/null +++ b/GameServer/Geometry/Position.cs @@ -0,0 +1,82 @@ +namespace DOL.GS.Geometry; + +public struct Position +{ + public ushort RegionID { get; init; } = 0; + public Coordinate Coordinate { get; init; } = Coordinate.Zero; + public Angle Orientation { get; init; } = Angle.Zero; + + public int X => Coordinate.X; + public int Y => Coordinate.Y; + public int Z => Coordinate.Z; + + public Region Region => WorldMgr.GetRegion(RegionID); + + public Position() { } + + public static Position Create(ushort regionID, int x, int y, int z, ushort heading) + => new() { RegionID = regionID, Coordinate = Coordinate.Create(x, y, z), Orientation = Angle.Heading(heading) }; + + public static Position Create(ushort regionID, int x = 0, int y = 0, int z = 0, Angle? orientation = null) + => new() { RegionID = regionID, Coordinate = Coordinate.Create(x, y, z), Orientation = orientation ?? Angle.Zero }; + + public static Position CreateInZone(ushort zoneID, int x = 0, int y = 0, int z = 0, ushort heading = 0) + { + var zone = WorldMgr.GetZone(zoneID); + return Create(zone.ZoneRegion.ID, x + zone.Offset.X, y + zone.Offset.Y, z + zone.Offset.Z, heading); + } + + public static Position Create(ushort regionID, Coordinate coordinate, ushort heading = 0) + => new() { RegionID = regionID, Coordinate = coordinate, Orientation = Angle.Heading(heading) }; + + public static Position Create(ushort regionID, Coordinate coordinate, Angle orientation) + => new() { RegionID = regionID, Coordinate = coordinate, Orientation = orientation }; + + public Position With(ushort? regionID = null, int? x = null, int? y = null, int? z = null, ushort? heading = null) + { + var newOrientation = heading != null ? Angle.Heading((ushort)heading) : Orientation; + var newRegionID = regionID ?? RegionID; + return Create(newRegionID, Coordinate.With(x, y, z), newOrientation); + } + + public Position With(Coordinate coordinate) + => Create(RegionID, coordinate, Orientation); + + public Position With(Angle orientation) + => Create(RegionID, Coordinate, orientation); + + public Position TurnedAround() + => With(orientation: Orientation + Angle.Degrees(180)); + + public static Position operator +(Position a, Vector b) + => a.With(coordinate: a.Coordinate + b); + + public static Position operator -(Position a, Vector b) + => a.With(coordinate: a.Coordinate - b); + + public static bool operator ==(Position a, Position b) + => a.Equals(b); + + public static bool operator !=(Position a, Position b) + => !a.Equals(b); + + public override bool Equals(object obj) + { + if (obj is Position otherPos) + { + return otherPos.RegionID == RegionID + && otherPos.Coordinate.Equals(Coordinate) + && otherPos.Orientation == Orientation; + } + return false; + } + + public override int GetHashCode() + => base.GetHashCode(); + + public override string ToString() + => $"({Coordinate}, {Orientation.InHeading})"; + + public readonly static Position Nowhere = Create(regionID: ushort.MaxValue, Coordinate.Nowhere, Angle.Zero); + public readonly static Position Zero = new(); +} \ No newline at end of file diff --git a/GameServer/Geometry/Vector.cs b/GameServer/Geometry/Vector.cs new file mode 100644 index 0000000000..5526ddadee --- /dev/null +++ b/GameServer/Geometry/Vector.cs @@ -0,0 +1,80 @@ +using System; + +namespace DOL.GS.Geometry; + +public struct Vector +{ + public int X { get; init; } + public int Y { get; init; } + public int Z { get; init; } + + public double Length => Math.Sqrt(X * X + Y * Y + Z * Z); + public double Length2D => Math.Sqrt(X * X + Y * Y); + public Angle Orientation => Angle.Radians(-Math.Atan2(X,Y)); + + public static Vector Create(int x = 0, int y = 0, int z = 0) + => new() { X = x, Y = y, Z = z }; + + // Coordinate calculation functions in DOL are standard trigonometric functions, but + // with some adjustments to account for the different coordinate system that DOL uses + // compared to the standard Cartesian coordinates used in trigonometry. + // + // DOL Heading grid: + // 2048/180° + // | + // 1024/90° ------- 3072/270° (+x) + // | + // 0 (+y) + // + // The Cartesian grid is 0 at the right side of the X-axis and increases counter-clockwise. + // The DOL Heading grid is 0 at the bottom of the Y-axis and increases clockwise. + // General trigonometry and the System.Math library use the Cartesian grid. + public static Vector Create(Angle orientation, double length, int z = 0) + { + var distanceXY = Math.Sqrt(length * length - z * z); + if(length < 0) distanceXY *= -1; + return Create( + x: (int)Math.Round(Math.Sin(-orientation.InRadians) * distanceXY), + y: (int)Math.Round(Math.Cos(orientation.InRadians) * distanceXY), + z: z); + } + + public Vector RotatedClockwise(Angle angle) + { + var cos = Math.Cos(angle.InRadians); + var sin = Math.Sin(angle.InRadians); + return Create( + x: (int)Math.Round(cos * X - sin * Y), + y: (int)Math.Round(cos * Y + sin * X), + z: Z); + } + + public override string ToString() + => $"{X}, {Y}, {Z}"; + + public override bool Equals(object obj) + { + if(obj is Vector vector) + { + return vector.X == X && vector.Y == Y && vector.Z == Z; + } + else return false; + } + + public override int GetHashCode() + => base.GetHashCode(); + + public static Vector operator *(Vector vec, double factor) + => Create((int)(vec.X * factor), (int)(vec.Y * factor), (int)(vec.Z * factor)); + + public static Vector operator *(double factor, Vector vec) + => vec * factor; + + public static Vector operator +(Vector vecA, Vector vecB) + => Create(vecA.X + vecB.X, vecA.Y + vecB.Y, vecA.Z + vecB.Z); + + public static Vector operator -(Vector vecA, Vector vecB) + => Create(vecA.X - vecB.X, vecA.Y - vecB.Y, vecA.Z - vecB.Z); + + public static readonly Vector Zero = Vector.Create(0, 0, 0); +} \ No newline at end of file diff --git a/GameServer/ai/brain/BD Pets/BDPetBrain.cs b/GameServer/ai/brain/BD Pets/BDPetBrain.cs index 9b31d29d4b..9b32f21f85 100644 --- a/GameServer/ai/brain/BD Pets/BDPetBrain.cs +++ b/GameServer/ai/brain/BD Pets/BDPetBrain.cs @@ -19,6 +19,7 @@ using System; using DOL.Events; using DOL.GS; +using DOL.GS.Geometry; namespace DOL.AI.Brain { @@ -121,57 +122,48 @@ public override bool CheckFormation(ref int x, ref int y, ref int z) if (!Body.AttackState && Body.Attackers.Count == 0) { GameNPC commander = (GameNPC)Owner; - double heading = ((double)commander.Heading) * Point2D.HEADING_TO_RADIAN; + var heading = commander.Orientation.InRadians; + var commanderOrientation = commander.Orientation; //Get which place we should put minion int i = 0; //How much do we want to slide back and left/right - int perp_slide = 0; - int par_slide = 0; for (; i < commander.ControlledNpcList.Length; i++) { if (commander.ControlledNpcList[i] == this) break; } - switch (commander.Formation) - { - case GameNPC.eFormationType.Triangle: - par_slide = BASEFORMATIONDIST; - perp_slide = BASEFORMATIONDIST; - if (i != 0) - par_slide = BASEFORMATIONDIST * 2; - break; - case GameNPC.eFormationType.Line: - par_slide = BASEFORMATIONDIST * (i + 1); - break; - case GameNPC.eFormationType.Protect: - switch (i) - { - case 0: - par_slide = -BASEFORMATIONDIST * 2; - break; - case 1: - case 2: - par_slide = -BASEFORMATIONDIST; - perp_slide = BASEFORMATIONDIST; - break; - } - break; - } - //Slide backwards - every pet will need to do this anyways - x += (int)(((double)commander.FormationSpacing * par_slide) * Math.Cos(heading - Math.PI / 2)); - y += (int)(((double)commander.FormationSpacing * par_slide) * Math.Sin(heading - Math.PI / 2)); - //In addition with sliding backwards, slide the other two pets sideways - switch (i) - { - case 1: - x += (int)(((double)commander.FormationSpacing * perp_slide) * Math.Cos(heading - Math.PI)); - y += (int)(((double)commander.FormationSpacing * perp_slide) * Math.Sin(heading - Math.PI)); - break; - case 2: - x += (int)(((double)commander.FormationSpacing * perp_slide) * Math.Cos(heading)); - y += (int)(((double)commander.FormationSpacing * perp_slide) * Math.Sin(heading)); - break; - } + var offset = Vector.Zero; + var spacing = BASEFORMATIONDIST * commander.FormationSpacing; + switch (commander.Formation) + { + case GameNPC.eFormationType.Triangle: + switch (i) + { + case 0: offset = Vector.Create(0, -spacing); break; + case 1: offset = Vector.Create(spacing, -spacing * 2); break; + case 2: offset = Vector.Create(-spacing, -spacing * 2); break; + } + break; + case GameNPC.eFormationType.Line: + switch (i) + { + case 0: offset = Vector.Create(0, -spacing); break; + case 1: offset = Vector.Create(0, -spacing * 2); break; + case 2: offset = Vector.Create(0, -spacing * 3); break; + } + break; + case GameNPC.eFormationType.Protect: + switch (i) + { + case 0: offset = Vector.Create(0, spacing * 2); break; + case 1: offset = Vector.Create(spacing, spacing); break; + case 2: offset = Vector.Create(-spacing, spacing); break; + } + break; + } + offset = offset.RotatedClockwise(commanderOrientation); + x += offset.X; + y += offset.Y; return true; } return false; diff --git a/GameServer/ai/brain/ControlledNpcBrain.cs b/GameServer/ai/brain/ControlledNpcBrain.cs index 92c010cbb0..89ef50062f 100644 --- a/GameServer/ai/brain/ControlledNpcBrain.cs +++ b/GameServer/ai/brain/ControlledNpcBrain.cs @@ -28,6 +28,7 @@ using DOL.GS.RealmAbilities; using DOL.GS.SkillHandler; using log4net; +using DOL.GS.Geometry; namespace DOL.AI.Brain { @@ -48,9 +49,7 @@ public class ControlledNpcBrain : StandardMobBrain, IControlledBrain public static readonly short MIN_ENEMY_FOLLOW_DIST = 90; public static readonly short MAX_ENEMY_FOLLOW_DIST = 512; - protected int m_tempX = 0; - protected int m_tempY = 0; - protected int m_tempZ = 0; + protected Coordinate tempPosition = Coordinate.Nowhere; /// /// Holds the controlling player of this brain @@ -236,8 +235,8 @@ public virtual eAggressionState AggressionState Body.TargetObject = null; if (WalkState == eWalkState.Follow) FollowOwner(); - else if (m_tempX > 0 && m_tempY > 0 && m_tempZ > 0) - Body.PathTo(new Point3D(m_tempX, m_tempY, m_tempZ), Body.MaxSpeed); + else if (!tempPosition.Equals(Coordinate.Nowhere)) + Body.PathTo(tempPosition, Body.MaxSpeed); } AttackMostWanted(); } @@ -276,9 +275,7 @@ public virtual void Follow(GameObject target) /// public virtual void Stay() { - m_tempX = Body.X; - m_tempY = Body.Y; - m_tempZ = Body.Z; + tempPosition = Body.Coordinate; WalkState = eWalkState.Stay; Body.StopFollowing(); } @@ -288,12 +285,10 @@ public virtual void Stay() /// public virtual void ComeHere() { - m_tempX = Body.X; - m_tempY = Body.Y; - m_tempZ = Body.Z; + tempPosition = Body.Coordinate; WalkState = eWalkState.ComeHere; Body.StopFollowing(); - Body.PathTo(Owner, Body.MaxSpeed); + Body.PathTo(Owner.Coordinate, Body.MaxSpeed); } /// @@ -302,12 +297,10 @@ public virtual void ComeHere() /// public virtual void Goto(GameObject target) { - m_tempX = Body.X; - m_tempY = Body.Y; - m_tempZ = Body.Z; + tempPosition = Body.Coordinate; WalkState = eWalkState.GoTarget; Body.StopFollowing(); - Body.PathTo(target, Body.MaxSpeed); + Body.PathTo(target.Coordinate, Body.MaxSpeed); } public virtual void SetAggressionState(eAggressionState state) @@ -994,7 +987,7 @@ protected override GameLiving CalculateNextAttackTarget() if (living.IsMezzed || living.IsAlive == false || living.ObjectState != GameObject.eObjectState.Active || - Body.GetDistanceTo(living, 0) > MAX_AGGRO_LIST_DISTANCE || + Body.GetDistanceTo(living.Position, 0) > MAX_AGGRO_LIST_DISTANCE || GameServer.ServerRules.IsAllowedToAttack(this.Body, living, true) == false) { removable.Add(living); @@ -1111,9 +1104,9 @@ owner_npc.TargetObject is GameLiving && { FollowOwner(); } - else if (m_tempX > 0 && m_tempY > 0 && m_tempZ > 0) + else if (!tempPosition.Equals(Coordinate.Nowhere)) { - Body.PathTo(new Point3D(m_tempX, m_tempY, m_tempZ), Body.MaxSpeed); + Body.PathTo(tempPosition, Body.MaxSpeed); } } } diff --git a/GameServer/ai/brain/DragonBrain.cs b/GameServer/ai/brain/DragonBrain.cs index c133190e91..424dc0a48a 100644 --- a/GameServer/ai/brain/DragonBrain.cs +++ b/GameServer/ai/brain/DragonBrain.cs @@ -218,7 +218,7 @@ private bool CheckTether() { GameDragon dragon = Body as GameDragon; if (dragon == null) return false; - return !dragon.IsWithinRadius( dragon.SpawnPoint, dragon.TetherRange ); + return dragon.Coordinate.DistanceTo(dragon.SpawnPosition) > dragon.TetherRange; } #endregion diff --git a/GameServer/ai/brain/Guards/KeepGuardBrain.cs b/GameServer/ai/brain/Guards/KeepGuardBrain.cs index 6081b0faa7..d45bd112fd 100644 --- a/GameServer/ai/brain/Guards/KeepGuardBrain.cs +++ b/GameServer/ai/brain/Guards/KeepGuardBrain.cs @@ -75,18 +75,18 @@ public override void Think() // Tolakram - always clear the aggro list so if this is done by mistake the list will correctly re-fill on next think ClearAggroList(); - if (guard.GetDistanceTo(guard.SpawnPoint, 0) > 50) + if (guard.Coordinate.DistanceTo(guard.SpawnPosition, ignoreZ: true) > 50) { guard.WalkToSpawn(); } } //Eden - Portal Keeps Guards max distance - if (guard.Level > 200 && !guard.IsWithinRadius(guard.SpawnPoint, 2000)) + if (guard.Level > 200 && guard.Coordinate.DistanceTo(guard.SpawnPosition) > 2000) { ClearAggroList(); guard.WalkToSpawn(); } - else if (guard.InCombat == false && guard.IsWithinRadius(guard.SpawnPoint, 6000) == false) + else if (guard.InCombat == false && guard.Coordinate.DistanceTo(guard.SpawnPosition) > 6000) { ClearAggroList(); guard.WalkToSpawn(); @@ -127,7 +127,7 @@ protected override void CheckPlayerAggro() if (Body is GuardStealther == false && player.IsStealthed) continue; - WarMapMgr.AddGroup((byte)player.CurrentZone.ID, player.X, player.Y, player.Name, (byte)player.Realm); + WarMapMgr.AddGroup(player.Position, player.Name, (byte)player.Realm); if (DOL.GS.ServerProperties.Properties.ENABLE_DEBUG) { @@ -164,7 +164,7 @@ protected override void CheckNPCAggro() continue; } - WarMapMgr.AddGroup((byte)player.CurrentZone.ID, player.X, player.Y, player.Name, (byte)player.Realm); + WarMapMgr.AddGroup(player.Position, player.Name, (byte)player.Realm); if (DOL.GS.ServerProperties.Properties.ENABLE_DEBUG) { diff --git a/GameServer/ai/brain/Npcs/AggressiveBrain.cs b/GameServer/ai/brain/Npcs/AggressiveBrain.cs index 119e12fcdd..d44a2f66c1 100644 --- a/GameServer/ai/brain/Npcs/AggressiveBrain.cs +++ b/GameServer/ai/brain/Npcs/AggressiveBrain.cs @@ -358,7 +358,7 @@ public override void Notify(DOLEvent e, object sender, EventArgs args) { if (e == GameNPCEvent.ArriveAtSpawnPoint) { - Body.TurnTo(Body.SpawnHeading); + Body.TurnTo(Body.SpawnPosition.Orientation); return; } diff --git a/GameServer/ai/brain/RoundsBrain.cs b/GameServer/ai/brain/RoundsBrain.cs index 9d93ffd201..d859224eaa 100644 --- a/GameServer/ai/brain/RoundsBrain.cs +++ b/GameServer/ai/brain/RoundsBrain.cs @@ -52,7 +52,7 @@ public override void AddToAggroList(GameLiving living, int aggroamount) { //save current position in path go to here and reload path point //insert path in pathpoint - PathPoint temporaryPathPoint = new PathPoint(Body.X, Body.Y, Body.Z, Body.CurrentSpeed, Body.CurrentWayPoint.Type); + PathPoint temporaryPathPoint = new PathPoint(Body.Coordinate, Body.CurrentSpeed, Body.CurrentWayPoint.Type); temporaryPathPoint.Next = Body.CurrentWayPoint; temporaryPathPoint.Prev = Body.CurrentWayPoint.Prev; Body.CurrentWayPoint = temporaryPathPoint; diff --git a/GameServer/ai/brain/StandardMobBrain.cs b/GameServer/ai/brain/StandardMobBrain.cs index 31e5c124e6..4f589e0a91 100644 --- a/GameServer/ai/brain/StandardMobBrain.cs +++ b/GameServer/ai/brain/StandardMobBrain.cs @@ -30,6 +30,7 @@ using DOL.Language; using log4net; using System.Numerics; +using DOL.GS.Geometry; namespace DOL.AI.Brain { @@ -118,7 +119,7 @@ public override void Think() // check for returning to home if to far away if (Body.MaxDistance != 0 && !Body.IsReturningHome) { - int distance = Body.GetDistanceTo( Body.SpawnPoint ); + int distance = (int)Body.Coordinate.DistanceTo(Body.SpawnPosition); int maxdistance = Body.MaxDistance > 0 ? Body.MaxDistance : -Body.MaxDistance * AggroRange / 100; if (maxdistance > 0 && distance > maxdistance) { @@ -130,33 +131,25 @@ public override void Think() //If this NPC can randomly walk around, we allow it to walk around if (!Body.AttackState && CanRandomWalk && !Body.IsRoaming && Util.Chance(DOL.GS.ServerProperties.Properties.GAMENPC_RANDOMWALK_CHANCE)) { - IPoint3D target = CalcRandomWalkTarget(); - if (target != null) - { - if (Util.IsNearDistance(target.X, target.Y, target.Z, Body.X, Body.Y, Body.Z, GameNPC.CONST_WALKTOTOLERANCE)) - { - Body.TurnTo(Body.GetHeading(target)); - } - else - { - Body.PathTo(target, 50); - } - - Body.FireAmbientSentence(GameNPC.eAmbientTrigger.roaming); - } + var target = GetRandomWalkTarget(); + if (target.DistanceTo(Body.Coordinate) <= GameNPC.CONST_WALKTOTOLERANCE) + { + Body.TurnTo(target); + } + else + { + Body.PathTo(target, 50); + } + + Body.FireAmbientSentence(GameNPC.eAmbientTrigger.roaming); } //If the npc can move, and the npc is not casting, not moving, and not attacking or in combat else if (Body.MaxSpeedBase > 0 && Body.CurrentSpellHandler == null && !Body.IsMoving && !Body.AttackState && !Body.InCombat && !Body.IsMovingOnPath) { - //If the npc is not at it's spawn position, we tell it to walk to it's spawn position - //Satyr: If we use a tolerance to stop their Way back home we also need the same - //Tolerance to check if we need to go home AGAIN, otherwise we might be told to go home - //for a few units only and this may end before the next Arrive-At-Target Event is fired and in this case - //We would never lose the state "IsReturningHome", which is then followed by other erros related to agro again to players - if ( !Util.IsNearDistance( Body.X, Body.Y, Body.Z, Body.SpawnPoint.X, Body.SpawnPoint.Y, Body.SpawnPoint.Z, GameNPC.CONST_WALKTOTOLERANCE ) ) + if (Body.Coordinate.DistanceTo(Body.SpawnPosition) > GameNPC.CONST_WALKTOTOLERANCE) Body.WalkToSpawn(); - else if (Body.Heading != Body.SpawnHeading) - Body.Heading = Body.SpawnHeading; + else if (Body.Orientation != Body.SpawnPosition.Orientation) + Body.Orientation = Body.SpawnPosition.Orientation; } //Mob will now always walk on their path @@ -177,7 +170,7 @@ public override void Think() } //If we are not attacking, and not casting, and not moving, and we aren't facing our spawn heading, we turn to the spawn heading - if( !Body.IsMovingOnPath && !Body.InCombat && !Body.AttackState && !Body.IsCasting && !Body.IsMoving && Body.IsWithinRadius( Body.SpawnPoint, 500 ) == false ) + if( !Body.IsMovingOnPath && !Body.InCombat && !Body.AttackState && !Body.IsCasting && !Body.IsMoving && Body.Coordinate.DistanceTo(Body.SpawnPosition) > 500) { Body.WalkToSpawn(); // Mobs do not walk back at 2x their speed.. Body.IsReturningHome = false; // We are returning to spawn but not the long walk home, so aggro still possible @@ -327,6 +320,17 @@ public virtual bool CheckFormation(ref int x, ref int y, ref int z) return false; } + public virtual Coordinate GetFormationCoordinate(Coordinate loc) + { + var x = loc.X; + var y = loc.Y; + var z = loc.Z; + var isNotInFormation = !CheckFormation(ref x, ref y, ref z); + if(isNotInFormation) return Coordinate.Nowhere; + + return Coordinate.Create(x,y,z); + } + /// /// Checks the Abilities /// @@ -655,7 +659,7 @@ protected virtual GameLiving CalculateNextAttackTarget() if (living.IsAlive == false || living.ObjectState != GameObject.eObjectState.Active || living.IsStealthed || - Body.GetDistanceTo(living, 0) > MAX_AGGRO_LIST_DISTANCE || + Body.GetDistanceTo(living.Position, 0) > MAX_AGGRO_LIST_DISTANCE || GameServer.ServerRules.IsAllowedToAttack(Body, living, true) == false) { removable.Add(living); @@ -1551,26 +1555,33 @@ defaut roaming range is defined in CanRandomWalk method } } - public virtual IPoint3D CalcRandomWalkTarget() - { - if (PathCalculator.IsSupported(Body)) - { - int radius = Body.RoamingRange > 0 ? Body.RoamingRange : 500; - var target = PathingMgr.Instance.GetRandomPointAsync(Body.CurrentZone, new Vector3(Body.X, Body.Y, Body.Z), radius); - if (target.HasValue) - return new Point3D(target.Value.X, target.Value.Y, target.Value.Z); - } + [Obsolete("Use GetRandomWalkTarget() instead.")] + public virtual IPoint3D CalcRandomWalkTarget() + { + var randomPos = GetRandomWalkTarget(); + return new Point3D(randomPos.X, randomPos.Y, randomPos.Z); + } - int maxRoamingRadius = Body.CurrentRegion.IsDungeon ? 5 : 500; + public virtual Coordinate GetRandomWalkTarget() + { + if (PathCalculator.IsSupported(Body)) + { + int radius = Body.RoamingRange > 0 ? Body.RoamingRange : 500; + var target = PathingMgr.Instance.GetRandomPointAsync(Body.CurrentZone, Body.Coordinate, radius); + if (target.HasValue) + return Coordinate.Create(x: (int)target.Value.X, y: (int)target.Value.Y, z: (int)target.Value.Z); + } - if (Body.RoamingRange > 0) - maxRoamingRadius = Body.RoamingRange; + int maxRoamingRadius = Body.CurrentRegion.IsDungeon ? 5 : 500; - double targetX = Body.SpawnPoint.X + Util.Random( -maxRoamingRadius, maxRoamingRadius); - double targetY = Body.SpawnPoint.Y + Util.Random( -maxRoamingRadius, maxRoamingRadius); + if (Body.RoamingRange > 0) + maxRoamingRadius = Body.RoamingRange; - return new Point3D( (int)targetX, (int)targetY, Body.SpawnPoint.Z ); - } + double targetX = Body.SpawnPosition.X + Util.Random(-maxRoamingRadius, maxRoamingRadius); + double targetY = Body.SpawnPosition.Y + Util.Random(-maxRoamingRadius, maxRoamingRadius); + + return Coordinate.Create(x: (int)targetX, y: (int)targetY, z: Body.SpawnPosition.Z); + } #endregion #region DetectDoor @@ -1578,7 +1589,7 @@ public virtual void DetectDoor() { ushort range= (ushort)((ThinkInterval/800)*Body.CurrentWayPoint.MaxSpeed); - foreach (IDoor door in Body.CurrentRegion.GetDoorsInRadius(Body.X, Body.Y, Body.Z, range, false)) + foreach (IDoor door in Body.CurrentRegion.GetDoorsInRadius(Body.Coordinate, range, false)) { if (door is GameKeepDoor) { diff --git a/GameServer/behaviour/AbstractTrigger.cs b/GameServer/behaviour/AbstractTrigger.cs index 8ae1e55af9..08b2adc0a2 100644 --- a/GameServer/behaviour/AbstractTrigger.cs +++ b/GameServer/behaviour/AbstractTrigger.cs @@ -17,9 +17,8 @@ * */ using System; -using System.Text; using DOL.Events; -using DOL.GS.Behaviour.Attributes;using DOL.GS.Behaviour; +using DOL.GS.Behaviour.Attributes; using System.Reflection; using log4net; diff --git a/GameServer/behaviour/Actions/MoveToAction.cs b/GameServer/behaviour/Actions/MoveToAction.cs index 45f9cdbf46..b04e8ab35c 100644 --- a/GameServer/behaviour/Actions/MoveToAction.cs +++ b/GameServer/behaviour/Actions/MoveToAction.cs @@ -17,14 +17,12 @@ * */ using System; -using System.Collections.Generic; -using System.Text; -using DOL.GS.PacketHandler; using DOL.Events; using DOL.GS.Behaviour.Attributes;using DOL.GS.Behaviour; namespace DOL.GS.Behaviour.Actions { + [Obsolete("This is going to be removed.")] [ActionAttribute(ActionType = eActionType.MoveTo)] public class MoveToAction : AbstractAction { @@ -42,13 +40,13 @@ public override void Perform(DOLEvent e, object sender, EventArgs args) if (P is GameLocation) { - GameLocation location = (GameLocation)P; - npc.MoveTo(location.RegionID, location.X, location.Y, location.Z, location.Heading); + var location = (GameLocation)P; + npc.MoveTo(location.Position); } else { GamePlayer player = BehaviourUtils.GuessGamePlayerFromNotify(e, sender, args); - npc.MoveTo(player.CurrentRegionID, player.X, player.Y, player.Z, (ushort)player.Heading); + npc.MoveTo(player.Position); } } } diff --git a/GameServer/behaviour/Actions/TeleportAction.cs b/GameServer/behaviour/Actions/TeleportAction.cs index 2bd5fafd9d..a44f3c7090 100644 --- a/GameServer/behaviour/Actions/TeleportAction.cs +++ b/GameServer/behaviour/Actions/TeleportAction.cs @@ -17,16 +17,15 @@ * */ using System; -using System.Collections.Generic; -using System.Text; using DOL.GS.PacketHandler; using DOL.Events; using DOL.GS.Behaviour.Attributes; -using DOL.GS.Behaviour; using DOL.Language; +using DOL.GS.Geometry; namespace DOL.GS.Behaviour.Actions { + [Obsolete("This is going to be removed.")] [ActionAttribute(ActionType = eActionType.Teleport,DefaultValueQ=0)] public class TeleportAction : AbstractAction { @@ -53,9 +52,8 @@ public override void Perform(DOLEvent e, object sender, EventArgs args) player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "Behaviour.TeleportAction.TeleportedToLoc", player, location.Name), eChatType.CT_System, eChatLoc.CL_SystemWindow); } - location.X += Util.Random(-radius, radius); - location.Y += Util.Random(-radius, radius); - player.MoveTo(location.RegionID, location.X, location.Y, location.Z, location.Heading); + var randomOffset = Vector.Create(x: Util.Random(-radius, radius), y: Util.Random(-radius, radius)); + player.MoveTo(location.Position + randomOffset); } } } diff --git a/GameServer/behaviour/Actions/WalkToAction.cs b/GameServer/behaviour/Actions/WalkToAction.cs index e3f9f53990..0a44171082 100644 --- a/GameServer/behaviour/Actions/WalkToAction.cs +++ b/GameServer/behaviour/Actions/WalkToAction.cs @@ -17,14 +17,13 @@ * */ using System; -using System.Collections.Generic; -using System.Text; -using DOL.GS.PacketHandler; using DOL.Events; -using DOL.GS.Behaviour.Attributes;using DOL.GS.Behaviour; +using DOL.GS.Behaviour.Attributes; +using DOL.GS.Geometry; namespace DOL.GS.Behaviour.Actions { + [Obsolete("This is going to be removed.")] [ActionAttribute(ActionType = eActionType.WalkTo,DefaultValueQ=eDefaultValueConstants.NPC)] public class WalkToAction : AbstractAction { @@ -37,15 +36,13 @@ public WalkToAction(GameNPC defaultNPC, Object p, Object q) public WalkToAction(GameNPC defaultNPC, IPoint3D destination, GameNPC npc) : this(defaultNPC, (object) destination,(object) npc) { } - - public override void Perform(DOLEvent e, object sender, EventArgs args) { GamePlayer player = BehaviourUtils.GuessGamePlayerFromNotify(e, sender, args); - IPoint3D location = (P is IPoint3D) ? (IPoint3D)P : player; + var destination = (P is IPoint3D) ? P.ToCoordinate() : player.Coordinate; - Q.WalkTo(location, Q.CurrentSpeed); + Q.WalkTo(destination, Q.CurrentSpeed); } } diff --git a/GameServer/behaviour/BehaviourUtils.cs b/GameServer/behaviour/BehaviourUtils.cs index 3f6e1708ef..bbea8f88bd 100644 --- a/GameServer/behaviour/BehaviourUtils.cs +++ b/GameServer/behaviour/BehaviourUtils.cs @@ -111,14 +111,6 @@ public static object ConvertObject(object obj,object defaultValue, Type destinat { result = (CustomDialogResponse)obj; } - else if (destinationType == typeof(GameLocation)) - { - result = (GameLocation)obj; - } - else if (destinationType == typeof(IPoint3D)) - { - result = (IPoint3D)obj; - } else if (destinationType == typeof(PathPoint)) { result = (PathPoint)obj; diff --git a/GameServer/commands/gmcommands/AddHookPoint.cs b/GameServer/commands/gmcommands/AddHookPoint.cs index 6b23185b15..436dfb572d 100644 --- a/GameServer/commands/gmcommands/AddHookPoint.cs +++ b/GameServer/commands/gmcommands/AddHookPoint.cs @@ -53,10 +53,11 @@ public void OnCommand(GameClient client, string[] args) DBKeepHookPoint dbkeephp = new DBKeepHookPoint(); dbkeephp.HookPointID = id; dbkeephp.KeepComponentSkinID = skin; - dbkeephp.X = client.Player.X - comp.X; - dbkeephp.Y = client.Player.Y - comp.Y; - dbkeephp.Z = client.Player.Z - comp.Z; - dbkeephp.Heading = client.Player.Heading - comp.Heading; + var keepComponentOffsetToPlayer = client.Player.Coordinate - comp.Coordinate; + dbkeephp.X = keepComponentOffsetToPlayer.X; + dbkeephp.Y = keepComponentOffsetToPlayer.Y; + dbkeephp.Z = keepComponentOffsetToPlayer.Z; + dbkeephp.Heading = (client.Player.Orientation - comp.Orientation).InHeading; GameServer.Database.AddObject(dbkeephp); } catch (Exception e) diff --git a/GameServer/commands/gmcommands/GMinfo.cs b/GameServer/commands/gmcommands/GMinfo.cs index f82893bab6..a32cdee44c 100644 --- a/GameServer/commands/gmcommands/GMinfo.cs +++ b/GameServer/commands/gmcommands/GMinfo.cs @@ -141,7 +141,7 @@ public void OnCommand(GameClient client, string[] args) if (respawn.Hours > 0) hours = respawn.Hours + " hours "; info.Add(" + Respawn: " + days + hours + respawn.Minutes + " minutes " + respawn.Seconds + " seconds"); - info.Add(" + SpawnPoint: " + target.SpawnPoint.X + ", " + target.SpawnPoint.Y + ", " + target.SpawnPoint.Z); + info.Add(" + SpawnPoint: " + target.SpawnPosition.X + ", " + target.SpawnPosition.Y + ", " + target.SpawnPosition.Z); } if (target.QuestListToGive.Count > 0) @@ -228,7 +228,7 @@ public void OnCommand(GameClient client, string[] args) info.Add(" "); info.Add(" + Mob_ID: " + target.InternalID); - info.Add(" + Position: " + target.X + ", " + target.Y + ", " + target.Z + ", " + target.Heading); + info.Add(" + Position: " + target.Coordinate + ", " + target.Orientation.InHeading); info.Add(" + OID: " + target.ObjectID); info.Add(" + Package ID: " + target.PackageID); @@ -450,7 +450,7 @@ public void OnCommand(GameClient client, string[] args) } info.Add(" "); - info.Add(" Location: X= " + target.X + " ,Y= " + target.Y + " ,Z= " + target.Z); + info.Add(" Coordinate: X= " + target.Position.X + " ,Y= " + target.Position.Y + " ,Z= " + target.Position.Z); } #endregion StaticItem @@ -499,10 +499,10 @@ public void OnCommand(GameClient client, string[] args) info.Add(" + Statut : " + statut); info.Add(" + Type : " + DoorRequestHandler.m_handlerDoorID / 100000000); info.Add(" "); - info.Add(" + X : " + target.X); - info.Add(" + Y : " + target.Y); - info.Add(" + Z : " + target.Z); - info.Add(" + Heading : " + target.Heading); + info.Add(" + X : " + target.Position.X); + info.Add(" + Y : " + target.Position.Y); + info.Add(" + Z : " + target.Position.Z); + info.Add(" + Heading : " + target.Orientation.InHeading); } #endregion Door @@ -544,6 +544,8 @@ public void OnCommand(GameClient client, string[] args) info.Add( " "); info.Add( " + Climbing : " + target.Climbing); info.Add( " "); + info.Add( " + X : " + target.Position.X); + info.Add( " + Y : " + target.Position.Y); info.Add( " + ComponentX : " + target.ComponentX); info.Add( " + ComponentY : " + target.ComponentY); info.Add( " + ComponentHeading : " + target.ComponentHeading); @@ -560,10 +562,10 @@ public void OnCommand(GameClient client, string[] args) info.Add(" + Keep Manager : " + GameServer.KeepManager.GetType().FullName); info.Add(" + Frontiers"); } - else if (GameServer.KeepManager.GetBattleground(target.CurrentRegionID) != null) + else if (GameServer.KeepManager.GetBattleground(target.Position.RegionID) != null) { info.Add(" + Keep Manager : " + GameServer.KeepManager.GetType().FullName); - Battleground bg = GameServer.KeepManager.GetBattleground(client.Player.CurrentRegionID); + Battleground bg = GameServer.KeepManager.GetBattleground(client.Player.Position.RegionID); info.Add(" + Battleground (" + bg.MinLevel + " to " + bg.MaxLevel + ", max RL: " + bg.MaxRealmLevel + ")"); } else @@ -697,8 +699,8 @@ public void OnCommand(GameClient client, string[] args) info.Add(" Zone ID: "+ client.Player.CurrentZone.ID); info.Add(" Zone IsDungeon: "+ client.Player.CurrentZone.IsDungeon); info.Add(" Zone SkinID: "+ client.Player.CurrentZone.ZoneSkinID); - info.Add(" Zone X: "+ client.Player.CurrentZone.XOffset); - info.Add(" Zone Y: "+ client.Player.CurrentZone.YOffset); + info.Add(" Zone X: "+ client.Player.CurrentZone.Offset.X); + info.Add(" Zone Y: "+ client.Player.CurrentZone.Offset.Y); info.Add(" Zone Width: "+ client.Player.CurrentZone.Width); info.Add(" Zone Height: "+ client.Player.CurrentZone.Height); info.Add(" Zone DivingEnabled: " + client.Player.CurrentZone.IsDivingEnabled); diff --git a/GameServer/commands/gmcommands/Instance.cs b/GameServer/commands/gmcommands/Instance.cs index d6e526962f..9d26bf6ea5 100644 --- a/GameServer/commands/gmcommands/Instance.cs +++ b/GameServer/commands/gmcommands/Instance.cs @@ -19,8 +19,8 @@ using System; using DOL.GS.PacketHandler; using System.Reflection; -using System.Collections; using DOL.Database; +using DOL.GS.Geometry; //By dinberg - so its him who you blame ;) namespace DOL.GS.Commands @@ -88,10 +88,10 @@ public void OnCommand(GameClient client, string[] args) //Create the database entry... DBInstanceXElement element = new DBInstanceXElement(); - element.Heading = client.Player.Heading; - element.X = client.Player.X; - element.Y = client.Player.Y; - element.Z = client.Player.Z; + element.Heading = client.Player.Orientation.InHeading; + element.X = client.Player.Position.X; + element.Y = client.Player.Position.Y; + element.Z = client.Player.Position.Z; element.InstanceID = key; element.ClassType = args[2]; @@ -155,12 +155,7 @@ public void OnCommand(GameClient client, string[] args) obj.Name = element.ObjectId.Substring(0, 18); obj.GuildName = element.ObjectId.Substring(18); - obj.X = element.X; - obj.Y = element.Y; - obj.Z = element.Z; - obj.Heading = element.Heading; - - obj.CurrentRegion = client.Player.CurrentRegion; + obj.Position = Position.Create(client.Player.CurrentRegionID, element.X, element.Y, element.Z, element.Heading); // now make sure model is visible if (obj is GameNPC && obj.Model == 0) @@ -296,31 +291,25 @@ public void OnCommand(GameClient client, string[] args) else { // start with some generic coordinates that seem to work well in many instance zones - int x = 32361; - int y = 31744; - int z = 16003; - ushort heading = 1075; + var entrancePosition = Position.Create(regionID: newInstance.ID, x: 32361, y: 31744, z: 16003, heading: 1075); // If you're having trouble zoning into an instance then try adding an entrance element so it can be used here - if (newInstance.InstanceEntranceLocation != null) + if (newInstance.EntrancePosition.Coordinate != Coordinate.Nowhere) { - x = newInstance.InstanceEntranceLocation.X; - y = newInstance.InstanceEntranceLocation.Y; - z = newInstance.InstanceEntranceLocation.Z; - heading = newInstance.InstanceEntranceLocation.Heading; + entrancePosition = newInstance.EntrancePosition; } // save current position for use with /instance exit - GameLocation saveLocation = new GameLocation(player.Name + "_exit", player.CurrentRegionID, player.X, player.Y, player.Z); - player.TempProperties.setProperty(saveLocation.Name, saveLocation); + var savePosition = player.Position.With(orientation: Angle.Zero); + player.TempProperties.setProperty(player.Name + "_exit", savePosition); bool success = true; - if (!player.MoveTo(newInstance.ID, x, y, z, heading)) + if (!player.MoveTo(entrancePosition)) { SendMessage(client, "MoveTo to entrance failed, now trying to move to current location inside the instance."); - if (!player.MoveTo(newInstance.ID, player.X, player.Y, player.Z, player.Heading)) + if (!player.MoveTo(player.Position.With(regionID: newInstance.ID))) { SendMessage(client, "That failed as well. Either add an entrance to this instance or move in the world to a corresponding instance location."); success = false; @@ -345,18 +334,18 @@ public void OnCommand(GameClient client, string[] args) return; } - GameLocation saveLocation = player.TempProperties.getProperty(player.Name + "_exit", null) as GameLocation; + var savePosition = player.TempProperties.getProperty(player.Name + "_exit", Position.Nowhere); - if (saveLocation == null) + if (savePosition == Position.Nowhere) { ushort sourceRegion = (player.CurrentRegion as BaseInstance).Skin; - if (!player.MoveTo(sourceRegion, player.X, player.Y, player.Z, player.Heading)) - player.MoveToBind(); + var wasZoningSuccessful = player.MoveTo(player.Position.With(regionID: sourceRegion)); + if (!wasZoningSuccessful) player.MoveToBind(); } else { - player.MoveTo(saveLocation.RegionID, saveLocation.X, saveLocation.Y, saveLocation.Z, saveLocation.Heading); + player.MoveTo(savePosition); } } break; diff --git a/GameServer/commands/gmcommands/KeepComponent.cs b/GameServer/commands/gmcommands/KeepComponent.cs index 445403b134..a9a5a92ad5 100644 --- a/GameServer/commands/gmcommands/KeepComponent.cs +++ b/GameServer/commands/gmcommands/KeepComponent.cs @@ -20,6 +20,7 @@ using System.Linq; using DOL.Database; +using DOL.GS.Geometry; using DOL.GS.Keeps; using DOL.GS.PacketHandler; using DOL.Language; @@ -50,7 +51,7 @@ public void OnCommand(GameClient client, string[] args) return; } - AbstractGameKeep myKeep = GameServer.KeepManager.GetKeepCloseToSpot(client.Player.CurrentRegionID, client.Player, WorldMgr.OBJ_UPDATE_DISTANCE); + AbstractGameKeep myKeep = GameServer.KeepManager.GetKeepCloseToSpot(client.Player.Position, WorldMgr.OBJ_UPDATE_DISTANCE); if (myKeep == null) { @@ -113,41 +114,19 @@ public void OnCommand(GameClient client, string[] args) } GameKeepComponent component = new GameKeepComponent(); - component.X = client.Player.X; - component.Y = client.Player.Y; - component.Z = client.Player.Z; - component.ComponentHeading = (client.Player.Heading - myKeep.Heading) / 1024; - component.Heading = (ushort)(component.ComponentHeading * 1024 + myKeep.Heading); + component.Position = client.Player.Position + .With(Angle.Degrees(component.ComponentHeading * 90) + myKeep.Orientation); + component.ComponentHeading = (client.Player.Orientation - myKeep.Orientation).InHeading / 1024; component.Keep = myKeep; - //todo good formula - //component.ComponentX = (component.X - myKeep.X) / 148; - //component.ComponentY = (component.Y - myKeep.Y) / 148; - - double angle = myKeep.Heading * ((Math.PI * 2) / 360); // angle*2pi/360; - - //component.ComponentX = (int)((148 * Math.Sin(angle) * myKeep.X - 148 * Math.Sin(angle) * client.Player.X + client.Player.Y - myKeep.Y) - // / (148 * Math.Sin(angle) - 148 * 148 * 2 * Math.Sin(angle) * Math.Cos(angle))); - //component.ComponentY = (int)((myKeep.Y - client.Player.Y + 148 * Math.Sin(angle) * component.ComponentX) / (148 * Math.Cos(angle))); + var angle = myKeep.Orientation.InRadians; component.ComponentX = CalcCX(client.Player, myKeep, angle); component.ComponentY = CalcCY(client.Player, myKeep, angle); - /* - x = (component.X-myKeep.X)/148 = a*cos(t) - b*sin(t) - y = (component.Y-myKeep.Y)/148 = a*sin(t) + b*cos(t) - a = sqrt((x+b*sin(t))^2 + (y-b*cos(t))^2) - a = sqrt(x²+y²+b² +2*x*b*sin(t)-2*y*b*cos(t)) - b = sqrt((x-a*cos(t))^2 + (y-a*sin(t))^2) - b = sqrt(x²+y²+a²-2*x*a*cos(t)-2*y*a*sin(t)) - 0 = 2x²+2y²-2*x*a*cos(t)-2*y*a*sin(t)+2*x*sqrt(x²+y²+a²-2*x*a*cos(t)-2*y*a*sin(t))*sin(t)-2*y*sqrt(x²+y²+a²-2*x*a*cos(t)-2*y*a*sin(t))*cos(t) - pfff - so must find an other way to find it.... - */ component.Name = myKeep.Name; component.Model = INVISIBLE_MODEL; component.Skin = skin; component.Level = (byte)myKeep.Level; - component.CurrentRegion = client.Player.CurrentRegion; component.Health = component.MaxHealth; component.ID = myKeep.KeepComponents.Count; component.Keep.KeepComponents.Add(component); @@ -162,23 +141,14 @@ so must find an other way to find it.... #region Move case "move": { - GameKeepComponent component = client.Player.TargetObject as GameKeepComponent; + var component = client.Player.TargetObject as GameKeepComponent; - component.X = client.Player.X; - component.Y = client.Player.Y; - component.Z = client.Player.Z; - component.ComponentHeading = (client.Player.Heading - myKeep.Heading) / 1024; - component.Heading = (ushort)(component.ComponentHeading * 1024 + myKeep.Heading); + component.Position = client.Player.Position + .With(Angle.Heading(component.ComponentHeading * 1024) + myKeep.Orientation); + component.ComponentHeading = (client.Player.Orientation - myKeep.Orientation).InDegrees / 90; component.Keep = myKeep; - //todo good formula - //component.ComponentX = (component.X - myKeep.X) / 148; - //component.ComponentY = (myKeep.Y - component.Y) / 148; - double angle = myKeep.Heading * ((Math.PI * 2) / 360); // angle*2pi/360; - - //component.ComponentX = (int)((148 * Math.Sin(angle) * myKeep.X - 148 * Math.Sin(angle) * client.Player.X + client.Player.Y - myKeep.Y) - // / (148 * Math.Sin(angle) - 148 * 148 * 2 * Math.Sin(angle) * Math.Cos(angle))); - //component.ComponentY = (int)((myKeep.Y - client.Player.Y + 148 * Math.Sin(angle) * component.ComponentX) / (148 * Math.Cos(angle))); + var angle = myKeep.Orientation.InRadians; component.ComponentX = CalcCX(client.Player, myKeep, angle); component.ComponentY = CalcCY(client.Player, myKeep, angle); @@ -201,7 +171,7 @@ so must find an other way to find it.... GameKeepComponent component = client.Player.TargetObject as GameKeepComponent; component.ComponentHeading = amount; - component.Heading = (ushort)(component.ComponentHeading * 1024 + myKeep.Heading); + component.Orientation = Angle.Heading(component.ComponentHeading * 1024) + myKeep.Orientation; client.Out.SendKeepInfo(myKeep); client.Out.SendKeepComponentInfo(component); @@ -328,28 +298,32 @@ so must find an other way to find it.... public int CalcCX(GamePlayer player, AbstractGameKeep myKeep, double angle) { + var keepPos = myKeep.Position; + var playerPos = player.Position; if (Math.Abs(Math.Sin(angle)) < 0.0001) //for approximations, == 0 wont work. { - return (player.X - myKeep.X) / 148; + return (playerPos.X - keepPos.X) / 148; } else { - return (int)((148 * Math.Sin(angle) * myKeep.X - 148 * Math.Sin(angle) * player.X + player.Y - myKeep.Y) - / (148 * Math.Sin(angle) - 148 * 148 * 2 * Math.Sin(angle) * Math.Cos(angle))); + return (int)((148 * Math.Sin(angle) * keepPos.X - 148 * Math.Sin(angle) * playerPos.X + playerPos.Y - keepPos.Y) + / (148 * Math.Sin(angle) - 148 * 148 * 2 * Math.Sin(angle) * Math.Cos(angle))); } } public int CalcCY(GamePlayer player, AbstractGameKeep myKeep, double angle) { + var keepPos = myKeep.Position; + var playerPos = player.Position; if (Math.Abs(Math.Sin(angle)) < 0.0001) { - return (myKeep.Y - player.Y) / 148; + return (keepPos.Y - playerPos.Y) / 148; } else { - int cx = (int)((148 * Math.Sin(angle) * myKeep.X - 148 * Math.Sin(angle) * player.X + player.Y - myKeep.Y) + int cx = (int)((148 * Math.Sin(angle) * keepPos.X - 148 * Math.Sin(angle) * playerPos.X + playerPos.Y - keepPos.Y) / (148 * Math.Sin(angle) - 148 * 148 * 2 * Math.Sin(angle) * Math.Cos(angle))); - return (int)((myKeep.Y - player.Y + 148 * Math.Sin(angle) * cx) / (148 * Math.Cos(angle))); + return (int)((keepPos.Y - playerPos.Y + 148 * Math.Sin(angle) * cx) / (148 * Math.Cos(angle))); } } } diff --git a/GameServer/commands/gmcommands/Minorelic.cs b/GameServer/commands/gmcommands/Minorelic.cs index 43b26a5ba7..d9fd225d82 100644 --- a/GameServer/commands/gmcommands/Minorelic.cs +++ b/GameServer/commands/gmcommands/Minorelic.cs @@ -64,15 +64,15 @@ public void OnCommand(GameClient client, string[] args) return; } - DBMinotaurRelic relic = new DBMinotaurRelic(); + var relic = new DBMinotaurRelic(); relic.Name = args[2]; - relic.SpawnHeading = client.Player.Heading; - relic.SpawnX = client.Player.X; - relic.SpawnY = client.Player.Y; - relic.SpawnZ = client.Player.Z; - relic.SpawnRegion = client.Player.CurrentRegionID; + relic.SpawnHeading = client.Player.Position.Orientation.InHeading; + relic.SpawnX = client.Player.Position.X; + relic.SpawnY = client.Player.Position.Y; + relic.SpawnZ = client.Player.Position.Z; + relic.SpawnRegion = client.Player.Position.RegionID; relic.relicTarget = args[4].ToLower(); @@ -110,17 +110,7 @@ public void OnCommand(GameClient client, string[] args) MinotaurRelic relic = client.Player.TargetObject as MinotaurRelic; - relic.Heading = client.Player.Heading; - relic.X = client.Player.X; - relic.Y = client.Player.Y; - relic.Z = client.Player.Z; - relic.CurrentRegionID = client.Player.CurrentRegionID; - - relic.SpawnHeading = client.Player.Heading; - relic.SpawnX = client.Player.X; - relic.SpawnY = client.Player.Y; - relic.SpawnZ = client.Player.Z; - relic.SpawnRegion = client.Player.CurrentRegionID; + relic.Position = client.Player.Position; relic.SaveIntoDatabase(); @@ -246,11 +236,11 @@ public void OnCommand(GameClient client, string[] args) info.Add("==========================="); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.MinoRelic.Info.PositionInfo")); info.Add("==========================="); - info.Add(LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.MinoRelic.Info.SpawnX", relic.SpawnX)); - info.Add(LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.MinoRelic.Info.SpawnY", relic.SpawnX)); - info.Add(LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.MinoRelic.Info.SpawnZ", relic.SpawnZ)); - info.Add(LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.MinoRelic.Info.SpawnHeading" + relic.SpawnHeading)); - info.Add(LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.MinoRelic.Info.SpawnRegion", relic.SpawnRegion)); + info.Add(LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.MinoRelic.Info.SpawnX", relic.SpawnPosition.X)); + info.Add(LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.MinoRelic.Info.SpawnY", relic.SpawnPosition.Y)); + info.Add(LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.MinoRelic.Info.SpawnZ", relic.SpawnPosition.Z)); + info.Add(LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.MinoRelic.Info.SpawnHeading" + relic.SpawnPosition.Orientation.InHeading)); + info.Add(LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.MinoRelic.Info.SpawnRegion", relic.SpawnPosition.RegionID)); info.Add("==========================="); info.Add(LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.MinoRelic.Info.SpellInfo")); info.Add("==========================="); diff --git a/GameServer/commands/gmcommands/Player.cs b/GameServer/commands/gmcommands/Player.cs index 5f6ad69e14..e608dc013b 100644 --- a/GameServer/commands/gmcommands/Player.cs +++ b/GameServer/commands/gmcommands/Player.cs @@ -1503,8 +1503,7 @@ public void OnCommand(GameClient client, string[] args) player.Health = player.MaxHealth; player.Mana = player.MaxMana; player.Endurance = player.MaxEndurance; - player.MoveTo(client.Player.CurrentRegionID, client.Player.X, client.Player.Y, client.Player.Z, - client.Player.Heading); + player.MoveTo(client.Player.Position); client.Out.SendMessage("You resurrected " + player.Name + " successfully!", eChatType.CT_Important, eChatLoc.CL_SystemWindow); @@ -1537,8 +1536,7 @@ public void OnCommand(GameClient client, string[] args) aplayer.Player.Health = aplayer.Player.MaxHealth; aplayer.Player.Mana = aplayer.Player.MaxMana; aplayer.Player.Endurance = aplayer.Player.MaxEndurance; - aplayer.Player.MoveTo(client.Player.CurrentRegionID, client.Player.X, client.Player.Y, client.Player.Z, - client.Player.Heading); + aplayer.Player.MoveTo(client.Player.Position); aplayer.Player.StopReleaseTimer(); aplayer.Player.Out.SendPlayerRevive(aplayer.Player); @@ -1560,8 +1558,7 @@ public void OnCommand(GameClient client, string[] args) hplayer.Player.Health = hplayer.Player.MaxHealth; hplayer.Player.Mana = hplayer.Player.MaxMana; hplayer.Player.Endurance = hplayer.Player.MaxEndurance; - hplayer.Player.MoveTo(client.Player.CurrentRegionID, client.Player.X, client.Player.Y, client.Player.Z, - client.Player.Heading); + hplayer.Player.MoveTo(client.Player.Position); hplayer.Player.StopReleaseTimer(); hplayer.Player.Out.SendPlayerRevive(hplayer.Player); @@ -1583,8 +1580,7 @@ public void OnCommand(GameClient client, string[] args) mplayer.Player.Health = mplayer.Player.MaxHealth; mplayer.Player.Mana = mplayer.Player.MaxMana; mplayer.Player.Endurance = mplayer.Player.MaxEndurance; - mplayer.Player.MoveTo(client.Player.CurrentRegionID, client.Player.X, client.Player.Y, client.Player.Z, - client.Player.Heading); + mplayer.Player.MoveTo(client.Player.Position); mplayer.Player.StopReleaseTimer(); mplayer.Player.Out.SendPlayerRevive(mplayer.Player); @@ -1606,8 +1602,7 @@ public void OnCommand(GameClient client, string[] args) selfplayer.Health = selfplayer.MaxHealth; selfplayer.Mana = selfplayer.MaxMana; selfplayer.Endurance = selfplayer.MaxEndurance; - selfplayer.MoveTo(client.Player.CurrentRegionID, client.Player.X, client.Player.Y, client.Player.Z, - client.Player.Heading); + selfplayer.MoveTo(client.Player.Position); selfplayer.Out.SendMessage("You revive yourself.", eChatType.CT_Important, eChatLoc.CL_SystemWindow); @@ -1633,8 +1628,7 @@ public void OnCommand(GameClient client, string[] args) allplayer.Player.Health = allplayer.Player.MaxHealth; allplayer.Player.Mana = allplayer.Player.MaxMana; allplayer.Player.Endurance = allplayer.Player.MaxEndurance; - allplayer.Player.MoveTo(client.Player.CurrentRegionID, client.Player.X, client.Player.Y, client.Player.Z, - client.Player.Heading); + allplayer.Player.MoveTo(client.Player.Position); allplayer.Player.StopReleaseTimer(); allplayer.Player.Out.SendPlayerRevive(allplayer.Player); @@ -1807,8 +1801,7 @@ public void OnCommand(GameClient client, string[] args) if (pname.Player.GuildName == guild && guild != "") { count++; - pname.Player.MoveTo(client.Player.CurrentRegionID, client.Player.X, client.Player.Y, client.Player.Z, - client.Player.Heading); + pname.Player.MoveTo(client.Player.Position); } } @@ -1834,8 +1827,7 @@ public void OnCommand(GameClient client, string[] args) { foreach (GameLiving groupedplayers in pname.Player.Group.GetMembersInTheGroup()) { - groupedplayers.MoveTo(client.Player.CurrentRegionID, client.Player.X, client.Player.Y, client.Player.Z, - client.Player.Heading); + groupedplayers.MoveTo(client.Player.Position); count++; } } @@ -1864,8 +1856,7 @@ public void OnCommand(GameClient client, string[] args) { foreach (GamePlayer cgplayers in cg.Members.Keys) { - cgplayers.MoveTo(client.Player.CurrentRegionID, client.Player.X, client.Player.Y, client.Player.Z, - client.Player.Heading); + cgplayers.MoveTo(client.Player.Position); count++; } } @@ -1895,8 +1886,7 @@ public void OnCommand(GameClient client, string[] args) { foreach (GamePlayer cgplayers in cg.Members.Keys) { - cgplayers.MoveTo(client.Player.CurrentRegionID, client.Player.X, client.Player.Y, client.Player.Z, - client.Player.Heading); + cgplayers.MoveTo(client.Player.Position); count++; } } @@ -2015,10 +2005,8 @@ public void OnCommand(GameClient client, string[] args) client.Out.SendMessage("\"" + player.Name + "\", " + player.CurrentRegionID + ", " + - player.X + ", " + - player.Y + ", " + - player.Z + ", " + - player.Heading, + player.Coordinate + ", " + + player.Orientation.InHeading, eChatType.CT_System, eChatLoc.CL_SystemWindow); } break; diff --git a/GameServer/commands/gmcommands/Teleport.cs b/GameServer/commands/gmcommands/Teleport.cs index 6918875491..7c30cc008e 100644 --- a/GameServer/commands/gmcommands/Teleport.cs +++ b/GameServer/commands/gmcommands/Teleport.cs @@ -115,11 +115,11 @@ private void AddTeleport(GameClient client, String teleportID, String type) Teleport teleport = new Teleport(); teleport.TeleportID = teleportID; teleport.Realm = (int)realm; - teleport.RegionID = player.CurrentRegion.ID; - teleport.X = player.X; - teleport.Y = player.Y; - teleport.Z = player.Z; - teleport.Heading = player.Heading; + teleport.RegionID = player.Position.RegionID; + teleport.X = player.Position.X; + teleport.Y = player.Position.Y; + teleport.Z = player.Position.Z; + teleport.Heading = player.Position.Orientation.InHeading; teleport.Type = type; if (!WorldMgr.AddTeleportLocation(teleport)) diff --git a/GameServer/commands/gmcommands/addbind.cs b/GameServer/commands/gmcommands/addbind.cs index ce97283bbe..158c93c6c5 100644 --- a/GameServer/commands/gmcommands/addbind.cs +++ b/GameServer/commands/gmcommands/addbind.cs @@ -46,10 +46,10 @@ public void OnCommand(GameClient client, string[] args) } } BindPoint bp = new BindPoint(); - bp.X = client.Player.X; - bp.Y = client.Player.Y; - bp.Z = client.Player.Z; - bp.Region = client.Player.CurrentRegionID; + bp.X = client.Player.Position.X; + bp.Y = client.Player.Position.Y; + bp.Z = client.Player.Position.Z; + bp.Region = client.Player.Position.RegionID; bp.Radius = bindRadius; GameServer.Database.AddObject(bp); client.Player.CurrentRegion.AddArea(new Area.BindArea("bind point", bp)); diff --git a/GameServer/commands/gmcommands/area.cs b/GameServer/commands/gmcommands/area.cs index c7c304adfc..c43855965e 100644 --- a/GameServer/commands/gmcommands/area.cs +++ b/GameServer/commands/gmcommands/area.cs @@ -77,9 +77,9 @@ public void OnCommand(GameClient client, string[] args) } area.Sound = byte.Parse(args[6]); area.Region = client.Player.CurrentRegionID; - area.X = client.Player.X; - area.Y = client.Player.Y; - area.Z = client.Player.Z; + area.X = client.Player.Position.X; + area.Y = client.Player.Position.Y; + area.Z = client.Player.Position.Z; Assembly gasm = Assembly.GetAssembly(typeof(GameServer)); AbstractArea newArea = (AbstractArea)gasm.CreateInstance(area.ClassType, false); diff --git a/GameServer/commands/gmcommands/cast.cs b/GameServer/commands/gmcommands/cast.cs index 68dbc5dc9d..1cfa2d2e43 100644 --- a/GameServer/commands/gmcommands/cast.cs +++ b/GameServer/commands/gmcommands/cast.cs @@ -23,6 +23,7 @@ using DOL.GS.PacketHandler; using DOL.Language; using DOL.GS.Effects; +using DOL.GS.Geometry; namespace DOL.GS.Commands { @@ -150,7 +151,7 @@ public void OnCommand(GameClient client, string[] args) case "sound": DisplayMessage(client, LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.Cast.SoundPlayed", id.ToString())); - client.Player.Out.SendSoundEffect((ushort)id, 0, 0, 0, 0, 0); + client.Player.Out.SendSoundEffect((ushort)id, Position.Zero, 0); break; #endregion #region Default diff --git a/GameServer/commands/gmcommands/debugjump.cs b/GameServer/commands/gmcommands/debugjump.cs index 6f027ebcda..1efb73f451 100644 --- a/GameServer/commands/gmcommands/debugjump.cs +++ b/GameServer/commands/gmcommands/debugjump.cs @@ -17,6 +17,7 @@ * */ using System; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using DOL.Language; @@ -44,23 +45,24 @@ public void OnCommand(GameClient client, string[] args) return; } - Zone z = WorldMgr.GetZone(zoneID); - if (z == null) + var zone = WorldMgr.GetZone(zoneID); + if (zone == null) { DisplayMessage(client, LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.DebugJump.UnknownZoneID", args[1])); return; } - - ushort RegionID = z.ZoneRegion.ID; - int X = z.XOffset + Convert.ToInt32(args[2]); - int Y = z.YOffset + Convert.ToInt32(args[3]); - int Z = Convert.ToInt32(args[4]); - ushort Heading = Convert.ToUInt16(args[5]); - if (!CheckExpansion(client, RegionID)) - return; + if (!CheckExpansion(client, zone.ZoneRegion.ID)) + return; - client.Player.MoveTo(RegionID, X, Y, Z, Heading); + var jumpPositionInZone = Position.Create( + x: Convert.ToInt32(args[2]), + y: Convert.ToInt32(args[3]), + z: Convert.ToInt32(args[4]), + heading: Convert.ToUInt16(args[4]), + regionID: zone.ZoneRegion.ID); + var jumpPosition = jumpPositionInZone + zone.Offset; + client.Player.MoveTo(jumpPosition); } public bool CheckExpansion(GameClient client, ushort RegionID) diff --git a/GameServer/commands/gmcommands/door.cs b/GameServer/commands/gmcommands/door.cs index 7b0efd9755..9d8714c961 100644 --- a/GameServer/commands/gmcommands/door.cs +++ b/GameServer/commands/gmcommands/door.cs @@ -181,10 +181,10 @@ private void add(GameClient client, GameDoor targetDoor) door.Type = DoorID/100000000; door.Level = 20; door.Realm = 6; - door.X = targetDoor.X; - door.Y = targetDoor.Y; - door.Z = targetDoor.Z; - door.Heading = targetDoor.Heading; + door.X = targetDoor.Position.X; + door.Y = targetDoor.Position.Y; + door.Z = targetDoor.Position.Z; + door.Heading = targetDoor.Orientation.InHeading; door.Health = 2545; GameServer.Database.AddObject(door); (targetDoor).AddToWorld(); @@ -213,10 +213,10 @@ private void update(GameClient client, GameDoor targetDoor) door.Realm = (byte) targetDoor.Realm; door.Health = targetDoor.Health; door.Locked = targetDoor.Locked; - door.X = client.Player.X; - door.Y = client.Player.Y; - door.Z = client.Player.Z; - door.Heading = client.Player.Heading; + door.X = client.Player.Position.X; + door.Y = client.Player.Position.Y; + door.Z = client.Player.Position.Z; + door.Heading = client.Player.Orientation.InHeading; GameServer.Database.AddObject(door); (targetDoor).AddToWorld(); client.Player.Out.SendMessage("Added door " + DoorID + " to the database", eChatType.CT_Important, @@ -389,10 +389,10 @@ private void info(GameClient client, GameDoor targetDoor) info.Add(" + Health : " + targetDoor.Health + " / " + targetDoor.MaxHealth); info.Add(" + Statut : " + statut); info.Add(" + Type : " + doorType); - info.Add(" + X : " + targetDoor.X); - info.Add(" + Y : " + targetDoor.Y); - info.Add(" + Z : " + targetDoor.Z); - info.Add(" + Heading : " + targetDoor.Heading); + info.Add(" + X : " + targetDoor.Position.X); + info.Add(" + Y : " + targetDoor.Position.Y); + info.Add(" + Z : " + targetDoor.Position.Z); + info.Add(" + Heading : " + targetDoor.Orientation.InHeading); client.Out.SendCustomTextWindow("Door Information", info); } diff --git a/GameServer/commands/gmcommands/gmappeal.cs b/GameServer/commands/gmcommands/gmappeal.cs index 41f0bdf871..fb2a0320af 100644 --- a/GameServer/commands/gmcommands/gmappeal.cs +++ b/GameServer/commands/gmcommands/gmappeal.cs @@ -23,6 +23,7 @@ using DOL.GS.PacketHandler; using DOL.Language; using DOL.GS.Appeal; +using DOL.GS.Geometry; namespace DOL.GS.Commands { @@ -404,9 +405,9 @@ public void OnCommand(GameClient client, string[] args) GamePlayer p = client.Player.TempProperties.getProperty("AppealAssist"); if (p.ObjectState == GameObject.eObjectState.Active) { - GameLocation oldlocation = new GameLocation("old", client.Player.CurrentRegionID, client.Player.X, client.Player.Y, client.Player.Z); - client.Player.TempProperties.setProperty("AppealJumpOld", oldlocation); - client.Player.MoveTo(p.CurrentRegionID, p.X, p.Y, p.Z, p.Heading); + var oldPosition = client.Player.Position; + client.Player.TempProperties.setProperty("AppealJumpOld", oldPosition); + client.Player.MoveTo(p.Position); } break; } @@ -418,9 +419,9 @@ public void OnCommand(GameClient client, string[] args) } case "jumpback": { - GameLocation jumpback = client.Player.TempProperties.getProperty("AppealJumpOld"); + var jumpback = client.Player.TempProperties.getProperty("AppealJumpOld", Position.Nowhere); - if (jumpback != null) + if (jumpback != Position.Nowhere) { client.Player.MoveTo(jumpback); //client.Player.TempProperties.removeProperty("AppealJumpOld"); diff --git a/GameServer/commands/gmcommands/gmrelic.cs b/GameServer/commands/gmcommands/gmrelic.cs index d806192aaa..1d8e0ca188 100644 --- a/GameServer/commands/gmcommands/gmrelic.cs +++ b/GameServer/commands/gmcommands/gmrelic.cs @@ -40,14 +40,14 @@ public void OnCommand(GameClient client, string[] args) DBRelic relic = new DBRelic(); - relic.Heading = client.Player.Heading; + relic.Heading = client.Player.Orientation.InHeading; relic.OriginalRealm = int.Parse(args[2]); relic.Realm = 0; - relic.Region = client.Player.CurrentRegionID; + relic.Region = client.Player.Position.RegionID; relic.relicType = (args[1] == "strength") ? 0 : 1; - relic.X = client.Player.X; - relic.Y = client.Player.Y; - relic.Z = client.Player.Z; + relic.X = client.Player.Position.X; + relic.Y = client.Player.Position.Y; + relic.Z = client.Player.Position.Z; relic.RelicID = Util.Random(100); GameServer.Database.AddObject(relic); RelicMgr.Init(); diff --git a/GameServer/commands/gmcommands/gmrelicpad.cs b/GameServer/commands/gmcommands/gmrelicpad.cs index 44d2ae3888..2e5223afdb 100644 --- a/GameServer/commands/gmcommands/gmrelicpad.cs +++ b/GameServer/commands/gmcommands/gmrelicpad.cs @@ -45,11 +45,7 @@ public void OnCommand(GameClient client, string[] args) pad.Name = args[2]; pad.Realm = (eRealm)byte.Parse(args[3]); pad.Emblem = emblem; - pad.CurrentRegionID = client.Player.CurrentRegionID; - pad.X = client.Player.X; - pad.Y = client.Player.Y; - pad.Z = client.Player.Z; - pad.Heading = client.Player.Heading; + pad.Position = client.Player.Position; pad.AddToWorld(); pad.SaveIntoDatabase(); } diff --git a/GameServer/commands/gmcommands/jump.cs b/GameServer/commands/gmcommands/jump.cs index fa7aef5ce5..50f0b22712 100644 --- a/GameServer/commands/gmcommands/jump.cs +++ b/GameServer/commands/gmcommands/jump.cs @@ -21,6 +21,7 @@ using DOL.GS.PacketHandler; using DOL.Language; using System.Collections.Generic; +using DOL.GS.Geometry; namespace DOL.GS.Commands { @@ -64,14 +65,14 @@ public void OnCommand(GameClient client, string[] args) { var target = client.Player.TargetObject; var player = client.Player; - player.MoveTo(target.CurrentRegionID, target.X, target.Y, target.Z, target.Heading); + player.MoveTo(target.Position); return; } #endregion #region Jump to GT if (args.Length == 3 && args[1].ToLower() == "to" && args[2].ToLower() == "gt") { - client.Player.MoveTo(client.Player.CurrentRegionID, client.Player.GroundTarget.X, client.Player.GroundTarget.Y, client.Player.GroundTarget.Z, client.Player.Heading); + client.Player.MoveTo(client.Player.GroundTargetPosition.With(orientation: client.Player.Orientation)); return; } #endregion Jump to GT @@ -89,7 +90,7 @@ public void OnCommand(GameClient client, string[] args) } if (house != null) { - client.Player.MoveTo(house.OutdoorJumpPoint); + client.Player.MoveTo(house.OutdoorJumpPosition); } else { @@ -101,7 +102,7 @@ public void OnCommand(GameClient client, string[] args) #region Jump t region # if (args.Length == 4 && args[1] == "to" && args[2] == "region") { - client.Player.MoveTo(Convert.ToUInt16(args[3]), client.Player.X, client.Player.Y, client.Player.Z, client.Player.Heading); + client.Player.MoveTo(client.Player.Position.With(regionID: Convert.ToUInt16(args[3]))); return; } #endregion Jump t region # @@ -150,7 +151,7 @@ public void OnCommand(GameClient client, string[] args) } else { - client.Player.MoveTo(jumpTarget.CurrentRegionID, jumpTarget.X, jumpTarget.Y, jumpTarget.Z, jumpTarget.Heading); + client.Player.MoveTo(jumpTarget.Position); } return; } @@ -165,7 +166,7 @@ public void OnCommand(GameClient client, string[] args) if (clientc.Player.CurrentHouse != null && clientc.Player.InHouse) clientc.Player.CurrentHouse.Enter(client.Player); else - client.Player.MoveTo(clientc.Player.CurrentRegionID, clientc.Player.X, clientc.Player.Y, clientc.Player.Z, client.Player.Heading); + client.Player.MoveTo(clientc.Player.Position.With(client.Player.Orientation)); return; } @@ -201,7 +202,7 @@ public void OnCommand(GameClient client, string[] args) } client.Out.SendMessage(LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.Jump.JumpToX", npcs[0].CurrentRegion.Description), eChatType.CT_System, eChatLoc.CL_SystemWindow); - client.Player.MoveTo(jumpTarget.CurrentRegionID, jumpTarget.X, jumpTarget.Y, jumpTarget.Z, jumpTarget.Heading); + client.Player.MoveTo(jumpTarget.Position); return; } @@ -218,8 +219,11 @@ public void OnCommand(GameClient client, string[] args) client.Out.SendMessage(LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.Jump.JumpToX", clientc.Player.CurrentRegion.Description), eChatType.CT_System, eChatLoc.CL_SystemWindow); if (clientc.Player.CurrentHouse != null && clientc.Player.InHouse) clientc.Player.CurrentHouse.Enter(client.Player); - else - client.Player.MoveTo(clientc.Player.CurrentRegionID, clientc.Player.X, clientc.Player.Y, clientc.Player.Z, client.Player.Heading); + else + { + var jumpPosition = clientc.Player.Position.With(client.Player.Orientation); + client.Player.MoveTo(jumpPosition); + } return; } return; @@ -228,18 +232,21 @@ public void OnCommand(GameClient client, string[] args) #region Jump to X Y Z else if (args.Length == 5 && args[1] == "to") { - client.Player.MoveTo(client.Player.CurrentRegionID, Convert.ToInt32(args[2]), Convert.ToInt32(args[3]), Convert.ToInt32(args[4]), client.Player.Heading); + var jumpPosition = Position.Create( + client.Player.CurrentRegionID, + x: Convert.ToInt32(args[2]), + y: Convert.ToInt32(args[3]), + z: Convert.ToInt32(args[4]), + client.Player.Orientation); + client.Player.MoveTo(jumpPosition); return; } #endregion Jump to X Y Z #region Jump rel +/-X +/-Y +/-Z else if (args.Length == 5 && args[1] == "rel") { - client.Player.MoveTo(client.Player.CurrentRegionID, - client.Player.X + Convert.ToInt32(args[2]), - client.Player.Y + Convert.ToInt32(args[3]), - client.Player.Z + Convert.ToInt32(args[4]), - client.Player.Heading); + var offset = Vector.Create(x:Convert.ToInt32(args[2]), y: Convert.ToInt32(args[3]), z: Convert.ToInt32(args[4])); + client.Player.MoveTo(client.Player.Position + offset); return; } #endregion Jump rel +/-X +/-Y +/-Z @@ -248,7 +255,13 @@ public void OnCommand(GameClient client, string[] args) { if (CheckExpansion(client, client, (ushort)Convert.ToUInt16(args[5]))) { - client.Player.MoveTo(Convert.ToUInt16(args[5]), Convert.ToInt32(args[2]), Convert.ToInt32(args[3]), Convert.ToInt32(args[4]), client.Player.Heading); + var jumpPosition = Position.Create( + regionID: Convert.ToUInt16(args[5]), + x: Convert.ToInt32(args[2]), + y: Convert.ToInt32(args[3]), + z: Convert.ToInt32(args[4]), + client.Player.Orientation); + client.Player.MoveTo(jumpPosition); return; } return; @@ -264,7 +277,8 @@ public void OnCommand(GameClient client, string[] args) client.Out.SendMessage(LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.Jump.PlayerIsNotInGame", args[1]), eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } - clientc.Player.MoveTo(clientc.Player.CurrentRegionID, Convert.ToInt32(args[3]), Convert.ToInt32(args[4]), Convert.ToInt32(args[5]), clientc.Player.Heading); + var jumpPosition = Position.Create(clientc.Player.CurrentRegionID, x: Convert.ToInt32(args[3]), y: Convert.ToInt32(args[4]), z: Convert.ToInt32(args[5]), clientc.Player.Orientation); + clientc.Player.MoveTo(jumpPosition); return; } #endregion Jump PlayerName to X Y Z @@ -280,7 +294,13 @@ public void OnCommand(GameClient client, string[] args) } if (CheckExpansion(clientc, clientc, (ushort)Convert.ToUInt16(args[6]))) { - clientc.Player.MoveTo(Convert.ToUInt16(args[6]), Convert.ToInt32(args[3]), Convert.ToInt32(args[4]), Convert.ToInt32(args[5]), clientc.Player.Heading); + var jumpPosition = Position.Create( + regionID: Convert.ToUInt16(args[6]), + x: Convert.ToInt32(args[3]), + y: Convert.ToInt32(args[4]), + z: Convert.ToInt32(args[5]), + clientc.Player.Orientation); + clientc.Player.MoveTo(jumpPosition); return; } return; @@ -316,9 +336,13 @@ public void OnCommand(GameClient client, string[] args) if (CheckExpansion(clientto, clientc, clientto.Player.CurrentRegionID)) { if (clientto.Player.CurrentHouse != null && clientto.Player.InHouse) + { clientto.Player.CurrentHouse.Enter(clientc.Player); + } else - clientc.Player.MoveTo(clientto.Player.CurrentRegionID, clientto.Player.X, clientto.Player.Y, clientto.Player.Z, client.Player.Heading); + { + clientc.Player.MoveTo(clientto.Player.Position.With(client.Player.Orientation)); + } return; } return; @@ -328,22 +352,22 @@ public void OnCommand(GameClient client, string[] args) #region push/pop else if (args.Length > 1 && args[1] == "push") { - Stack locations; + Stack positions; - locations = client.Player.TempProperties.getProperty(TEMP_KEY_JUMP, null) as Stack; + positions = client.Player.TempProperties.getProperty(TEMP_KEY_JUMP, null) as Stack; - if (locations == null) + if (positions == null) { - locations = new Stack(3); - client.Player.TempProperties.setProperty(TEMP_KEY_JUMP, locations); + positions = new Stack(3); + client.Player.TempProperties.setProperty(TEMP_KEY_JUMP, positions); } - locations.Push(new GameLocation("temploc", client.Player.CurrentRegionID, client.Player.X, client.Player.Y, client.Player.Z, client.Player.Heading)); + positions.Push(client.Player.Position); string message = LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.Jump.Pushed"); - if (locations.Count > 1) - message += " " + LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.Jump.PushedTotal", locations.Count); + if (positions.Count > 1) + message += " " + LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.Jump.PushedTotal", positions.Count); message += " - " + LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.Jump.PopInstructions"); @@ -351,23 +375,23 @@ public void OnCommand(GameClient client, string[] args) } else if (args.Length > 1 && args[1] == "pop") { - Stack locations; + Stack positions; - locations = client.Player.TempProperties.getProperty(TEMP_KEY_JUMP, null) as Stack; + positions = client.Player.TempProperties.getProperty(TEMP_KEY_JUMP, null) as Stack; - if (locations == null || locations.Count < 1) + if (positions == null || positions.Count < 1) { client.Out.SendMessage(LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.Jump.NothingPushed"), eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } - GameLocation jumploc = locations.Pop(); + var jumpPosition = positions.Pop(); // slight abuse of the stack principle, but convenient to always have your last popped loc jumpable - if (locations.Count < 1) - locations.Push(jumploc); + if (positions.Count < 1) + positions.Push(jumpPosition); - client.Player.MoveTo(jumploc.RegionID, jumploc.X, jumploc.Y, jumploc.Z, jumploc.Heading); + client.Player.MoveTo(jumpPosition); } #endregion push/pop #region DisplaySyntax diff --git a/GameServer/commands/gmcommands/keep.cs b/GameServer/commands/gmcommands/keep.cs index 239f2affe1..bb86d0ed31 100644 --- a/GameServer/commands/gmcommands/keep.cs +++ b/GameServer/commands/gmcommands/keep.cs @@ -18,6 +18,7 @@ */ using System; using DOL.Database; +using DOL.GS.Geometry; using DOL.GS.Keeps; using DOL.Language; @@ -92,7 +93,7 @@ public void OnCommand(GameClient client, string[] args) } AbstractGameKeep myKeep = (AbstractGameKeep)client.Player.TempProperties.getProperty(TEMP_KEEP_LAST, null); - if (myKeep == null) myKeep = GameServer.KeepManager.GetKeepCloseToSpot(client.Player.CurrentRegionID, client.Player, 10000); + if (myKeep == null) myKeep = GameServer.KeepManager.GetKeepCloseToSpot(client.Player.Position, 10000); switch (args[1]) { @@ -144,11 +145,7 @@ public void OnCommand(GameClient client, string[] args) keep.Level = (byte)ServerProperties.Properties.STARTING_KEEP_LEVEL; keep.BaseLevel = 50; keep.Realm = client.Player.Realm; - keep.Region = client.Player.CurrentRegionID; - keep.X = client.Player.X; - keep.Y = client.Player.Y; - keep.Z = client.Player.Z; - keep.Heading = client.Player.Heading; + keep.Position = client.Player.Position; if ((int)keepType < 8) { @@ -2037,11 +2034,7 @@ public void OnCommand(GameClient client, string[] args) keep.Name = keepName; keep.KeepID = keepid; keep.Level = 0; - keep.Region = client.Player.CurrentRegionID; - keep.X = client.Player.X; - keep.Y = client.Player.Y; - keep.Z = client.Player.Z; - keep.Heading = client.Player.Heading; + keep.SetPosition(client.Player.Position); keep.BaseLevel = baseLevel; GameServer.Database.AddObject(keep); @@ -2132,11 +2125,7 @@ public void OnCommand(GameClient client, string[] args) keep.Name = keepName; keep.KeepID = keepid; keep.Level = 0; - keep.Region = client.Player.CurrentRegionID; - keep.X = client.Player.X; - keep.Y = client.Player.Y; - keep.Z = client.Player.Z; - keep.Heading = client.Player.Heading; + keep.SetPosition(client.Player.Position); keep.BaseLevel = baselevel; GameServer.Database.AddObject(keep); @@ -2150,12 +2139,8 @@ public void OnCommand(GameClient client, string[] args) { (door as GameObject).RemoveFromWorld(); GameKeepDoor d = new GameKeepDoor(); - d.CurrentRegionID = (ushort)keep.Region; d.Name = door.Name; - d.Heading = (ushort)door.Heading; - d.X = door.X; - d.Y = door.Y; - d.Z = door.Z; + d.Position = Position.Create(keep.Region, door.Coordinate, door.Orientation); d.Level = 0; d.Model = 0xFFFF; d.DoorID = door.DoorID; @@ -2425,11 +2410,7 @@ public void OnCommand(GameClient client, string[] args) else { FrontiersPortalStone stone = new FrontiersPortalStone(); - stone.CurrentRegion = client.Player.CurrentRegion; - stone.X = client.Player.X; - stone.Y = client.Player.Y; - stone.Z = client.Player.Z; - stone.Heading = client.Player.Heading; + stone.Position = client.Player.Position; stone.SaveIntoDatabase(); stone.AddToWorld(); } @@ -2464,11 +2445,7 @@ public void OnCommand(GameClient client, string[] args) { GameKeepBanner banner = new GameKeepBanner(); banner.BannerType = bannerType; - banner.CurrentRegion = client.Player.CurrentRegion; - banner.X = client.Player.X; - banner.Y = client.Player.Y; - banner.Z = client.Player.Z; - banner.Heading = client.Player.Heading; + banner.Position = client.Player.Position; banner.SaveIntoDatabase(); foreach (AbstractArea area in banner.CurrentAreas) @@ -2507,10 +2484,7 @@ public void OnCommand(GameClient client, string[] args) if (args.Length < 3) { // simple move to player location - myKeep.X = client.Player.X; - myKeep.Y = client.Player.Y; - myKeep.Z = client.Player.Z; - myKeep.Heading = client.Player.Heading; + myKeep.Position = client.Player.Position; } else if (args.Length < 4) { @@ -2537,22 +2511,7 @@ public void OnCommand(GameClient client, string[] args) break; case "h": - - if (amount < 0 && myKeep.Heading - Math.Abs(amount) < 0) - { - int diff = myKeep.Heading - Math.Abs(amount); - myKeep.Heading = (ushort)(4095 + diff); - } - else - { - myKeep.Heading += (ushort)amount; - } - - if (myKeep.Heading > 4095) - { - myKeep.Heading = (ushort)(myKeep.Heading - 4095); - } - + myKeep.Orientation += Angle.Heading((ushort)amount); break; default: diff --git a/GameServer/commands/gmcommands/keepguard.cs b/GameServer/commands/gmcommands/keepguard.cs index 0ea46cf1e1..a61f5893e5 100644 --- a/GameServer/commands/gmcommands/keepguard.cs +++ b/GameServer/commands/gmcommands/keepguard.cs @@ -215,11 +215,7 @@ public void OnCommand(GameClient client, string[] args) } else { - guard.CurrentRegion = client.Player.CurrentRegion; - guard.X = client.Player.X; - guard.Y = client.Player.Y; - guard.Z = client.Player.Z; - guard.Heading = client.Player.Heading; + guard.Position = client.Player.Position; guard.Realm = guard.CurrentZone.Realm; guard.LoadedFromScript = false; guard.SaveIntoDatabase(); @@ -296,7 +292,7 @@ public void OnCommand(GameClient client, string[] args) } GameKeepGuard guard = client.Player.TargetObject as GameKeepGuard; - DBKeepPosition pos = guard.Position; + DBKeepPosition pos = guard.DbKeepPosition; if (pos != null) { PositionMgr.RemovePosition(pos); @@ -344,7 +340,7 @@ public void OnCommand(GameClient client, string[] args) { RemoveAllTempPathObjects(client); - PathPoint startpoint = new PathPoint(client.Player.X, client.Player.Y, client.Player.Z, 5000, ePathType.Once); + PathPoint startpoint = new PathPoint(client.Player.Coordinate, 5000, ePathType.Once); client.Player.TempProperties.setProperty(TEMP_PATH_FIRST, startpoint); client.Player.TempProperties.setProperty(TEMP_PATH_LAST, startpoint); client.Player.Out.SendMessage(LanguageMgr.GetTranslation(client.Account.Language, "GMCommands.KeepGuard.Path.CreationStarted"), eChatType.CT_System, eChatLoc.CL_SystemWindow); @@ -376,7 +372,7 @@ public void OnCommand(GameClient client, string[] args) } } - PathPoint newpp = new PathPoint(client.Player.X, client.Player.Y, client.Player.Z, speedlimit, path.Type); + PathPoint newpp = new PathPoint(client.Player.Coordinate, speedlimit, path.Type); path.Next = newpp; newpp.Prev = path; client.Player.TempProperties.setProperty(TEMP_PATH_LAST, newpp); @@ -452,11 +448,7 @@ public void OnCommand(GameClient client, string[] args) private void CreateTempPathObject(GameClient client, PathPoint pp, string name) { GameStaticItem obj = new GameStaticItem(); - obj.X = pp.X; - obj.Y = pp.Y; - obj.Z = pp.Z; - obj.CurrentRegion = client.Player.CurrentRegion; - obj.Heading = client.Player.Heading; + obj.Position = client.Player.Position.With(coordinate: pp.Coordinate); obj.Name = name; obj.Model = 488; obj.Emblem = 0; diff --git a/GameServer/commands/gmcommands/merchant.cs b/GameServer/commands/gmcommands/merchant.cs index 4a2f763df3..6bbb0c9893 100644 --- a/GameServer/commands/gmcommands/merchant.cs +++ b/GameServer/commands/gmcommands/merchant.cs @@ -99,11 +99,7 @@ public void OnCommand(GameClient client, string[] args) return; } //Fill the object variables - merchant.X = client.Player.X; - merchant.Y = client.Player.Y; - merchant.Z = client.Player.Z; - merchant.CurrentRegion = client.Player.CurrentRegion; - merchant.Heading = client.Player.Heading; + merchant.Position = client.Player.Position; merchant.Level = 1; merchant.Realm = client.Player.Realm; merchant.Name = LanguageMgr.GetTranslation(ServerProperties.Properties.SERV_LANGUAGE, "GMCommands.Merchant.NewName"); @@ -419,11 +415,7 @@ public void OnCommand(GameClient client, string[] args) return; } //Fill the object variables - merchant.X = targetMerchant.X; - merchant.Y = targetMerchant.Y; - merchant.Z = targetMerchant.Z; - merchant.CurrentRegion = targetMerchant.CurrentRegion; - merchant.Heading = targetMerchant.Heading; + merchant.Position = targetMerchant.Position; merchant.Level = targetMerchant.Level; merchant.Realm = targetMerchant.Realm; merchant.Name = targetMerchant.Name; diff --git a/GameServer/commands/gmcommands/mob.cs b/GameServer/commands/gmcommands/mob.cs index 9c354c0b7b..2ff3063420 100644 --- a/GameServer/commands/gmcommands/mob.cs +++ b/GameServer/commands/gmcommands/mob.cs @@ -26,6 +26,7 @@ using DOL.AI.Brain; using DOL.Database; using DOL.GS.Effects; +using DOL.GS.Geometry; using DOL.GS.Housing; using DOL.GS.Movement; using DOL.GS.PacketHandler; @@ -317,11 +318,7 @@ private void create(GameClient client, string[] args) } //Fill the object variables - mob.X = client.Player.X; - mob.Y = client.Player.Y; - mob.Z = client.Player.Z; - mob.CurrentRegion = client.Player.CurrentRegion; - mob.Heading = client.Player.Heading; + mob.Position = client.Player.Position; mob.Level = 1; mob.Realm = (eRealm)realm; mob.Name = "New Mob"; @@ -384,11 +381,7 @@ private void fastcreate(GameClient client, string[] args) GameNPC mob = new GameNPC(); //Fill the object variables - mob.X = client.Player.X; - mob.Y = client.Player.Y; - mob.Z = client.Player.Z; - mob.CurrentRegion = client.Player.CurrentRegion; - mob.Heading = client.Player.Heading; + mob.Position = client.Player.Position; mob.Level = level; mob.Realm = 0; mob.Name = name; @@ -462,13 +455,8 @@ private void nfastcreate(GameClient client, string[] args) GameNPC mob = new GameNPC(); //Fill the object variables - int x = client.Player.X + Util.Random(-radius, radius); - int y = client.Player.Y + Util.Random(-radius, radius); - mob.X = FastMath.Abs(x); - mob.Y = FastMath.Abs(y); - mob.Z = client.Player.Z; - mob.CurrentRegion = client.Player.CurrentRegion; - mob.Heading = client.Player.Heading; + var offset = Vector.Create(x: DOL.GS.Util.Random(-radius, radius),y: DOL.GS.Util.Random(-radius, radius)); + mob.Position = client.Player.Position + offset; mob.Level = level; mob.Realm = (eRealm)realm; mob.Name = name; @@ -522,13 +510,8 @@ private void nrandcreate(GameClient client, string[] args) GameNPC mob = new GameNPC(); //Fill the object variables - int x = client.Player.X + DOL.GS.Util.Random(-radius, radius); - int y = client.Player.Y + DOL.GS.Util.Random(-radius, radius); - mob.X = FastMath.Abs(x); - mob.Y = FastMath.Abs(y); - mob.Z = client.Player.Z; - mob.CurrentRegion = client.Player.CurrentRegion; - mob.Heading = client.Player.Heading; + var offset = Vector.Create(x: DOL.GS.Util.Random(-radius, radius),y: DOL.GS.Util.Random(-radius, radius)); + mob.Position = client.Player.Position + offset; mob.Level = (byte)Util.Random(10, 50); mob.Realm = (eRealm)Util.Random(1, 3); mob.Name = "rand_" + i; @@ -1022,20 +1005,17 @@ private void damagetype(GameClient client, GameNPC targetMob, string[] args) private void movehere(GameClient client, GameNPC targetMob, string[] args) { - targetMob.MoveTo(client.Player.CurrentRegionID, client.Player.X, client.Player.Y, client.Player.Z, client.Player.Heading); + targetMob.MoveTo(client.Player.Position); targetMob.SaveIntoDatabase(); client.Out.SendMessage("Target Mob '" + targetMob.Name + "' moved to your location!", eChatType.CT_System, eChatLoc.CL_SystemWindow); } + private string PositionToText(Position pos) + => $"{pos.RegionID}, {pos.X}, {pos.Y}, {pos.Z}, {pos.Orientation.InHeading}"; + private void location(GameClient client, GameNPC targetMob, string[] args) { - client.Out.SendMessage("\"" + targetMob.Name + "\", " + - targetMob.CurrentRegionID + ", " + - targetMob.X + ", " + - targetMob.Y + ", " + - targetMob.Z + ", " + - targetMob.Heading, - eChatType.CT_System, eChatLoc.CL_SystemWindow); + client.Out.SendMessage("\"" + targetMob.Name + "\", " + PositionToText(targetMob.Position), eChatType.CT_System, eChatLoc.CL_SystemWindow); } private void remove(GameClient client, GameNPC targetMob, string[] args) @@ -1136,8 +1116,7 @@ private void fly(GameClient client, GameNPC targetMob, string[] args) targetMob.Flags ^= GameNPC.eFlags.FLYING; - if (targetMob.IsFlying) - targetMob.MoveTo(targetMob.CurrentRegionID, targetMob.X, targetMob.Y, targetMob.Z + height, targetMob.Heading); + if (targetMob.IsFlying) targetMob.MoveTo(targetMob.Position + Vector.Create(z: height)); targetMob.SaveIntoDatabase(); @@ -1298,7 +1277,7 @@ private void info(GameClient client, GameNPC targetMob, string[] args) hours = respawn.Hours + " hours "; info.Add(" + Respawn: " + days + hours + respawn.Minutes + " minutes " + respawn.Seconds + " seconds"); - info.Add(" + SpawnPoint: " + targetMob.SpawnPoint.X + ", " + targetMob.SpawnPoint.Y + ", " + targetMob.SpawnPoint.Z); + info.Add(" + SpawnPoint: " + targetMob.SpawnPosition.X + ", " + targetMob.SpawnPosition.Y + ", " + targetMob.SpawnPosition.Z); } info.Add(" "); @@ -1367,7 +1346,8 @@ private void info(GameClient client, GameNPC targetMob, string[] args) info.Add(" "); - info.Add(" + Position (X, Y, Z, H): " + targetMob.X + ", " + targetMob.Y + ", " + targetMob.Z + ", " + targetMob.Heading); + info.Add(" + Position (X, Y, Z, H): " + targetMob.Position.X + ", " + targetMob.Position.Y + ", " + targetMob.Position.Z + + ", " + targetMob.Orientation.InHeading); if (targetMob.GuildName != null && targetMob.GuildName.Length > 0) info.Add(" + Guild: " + targetMob.GuildName); @@ -2365,11 +2345,7 @@ void setClass(GameClient client, GameNPC targetMob, string[] args) targetMob.StopAttack(); targetMob.StopCurrentSpellcast(); - mob.X = targetMob.X; - mob.Y = targetMob.Y; - mob.Z = targetMob.Z; - mob.CurrentRegion = targetMob.CurrentRegion; - mob.Heading = targetMob.Heading; + mob.Position = targetMob.Position; mob.Level = targetMob.Level; mob.Realm = targetMob.Realm; mob.Name = targetMob.Name; @@ -2532,11 +2508,7 @@ private void copy(GameClient client, GameNPC targetMob, string[] args) } //Fill the object variables - mob.X = client.Player.X; - mob.Y = client.Player.Y; - mob.Z = client.Player.Z; - mob.CurrentRegion = client.Player.CurrentRegion; - mob.Heading = client.Player.Heading; + mob.Position = client.Player.Position; mob.Level = targetMob.Level; mob.Realm = targetMob.Realm; mob.Name = targetMob.Name; @@ -2661,11 +2633,7 @@ private void npctemplate(GameClient client, GameNPC targetMob, string[] args) if (targetMob == null) { GameNPC mob = new GameNPC(template); - mob.X = client.Player.X; - mob.Y = client.Player.Y; - mob.Z = client.Player.Z; - mob.Heading = client.Player.Heading; - mob.CurrentRegion = client.Player.CurrentRegion; + mob.Position = client.Player.Position; mob.AddToWorld(); DisplayMessage(client, $"Created npc based on template {id}" ); } diff --git a/GameServer/commands/gmcommands/npc.cs b/GameServer/commands/gmcommands/npc.cs index be6f02088b..0972accb9d 100644 --- a/GameServer/commands/gmcommands/npc.cs +++ b/GameServer/commands/gmcommands/npc.cs @@ -23,6 +23,7 @@ using System.Collections; using System.Collections.Generic; using DOL.GS.PacketHandler; +using DOL.GS.Geometry; namespace DOL.GS.Commands { @@ -199,16 +200,12 @@ public void OnCommand(GameClient client, string[] args) speed = Convert.ToInt16(args[3]); } - int X = 0; - int Y = 0; - int Z = 0; + var coordinate = Coordinate.Nowhere; switch (args[2].ToLower()) { case "me": { - X = client.Player.X; - Y = client.Player.Y; - Z = client.Player.Z; + coordinate = client.Player.Coordinate; break; } @@ -219,9 +216,7 @@ public void OnCommand(GameClient client, string[] args) { if (targetplayer.Name.ToLower() == args[2].ToLower()) { - X = targetplayer.X; - Y = targetplayer.Y; - Z = targetplayer.Z; + coordinate = targetplayer.Coordinate; break; } } @@ -230,9 +225,7 @@ public void OnCommand(GameClient client, string[] args) { if (target.Name.ToLower() == args[2].ToLower()) { - X = target.X; - Y = target.Y; - Z = target.Z; + coordinate = target.Coordinate; break; } } @@ -240,13 +233,13 @@ public void OnCommand(GameClient client, string[] args) } } - if (X == 0 && Y == 0 && Z == 0) + if (coordinate.Equals(Coordinate.Nowhere)) { client.Out.SendMessage("Can't find name " + args[2].ToLower() + " near your target.", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } - npc.PathTo(new Point3D(X, Y, Z), speed); + npc.PathTo(coordinate, speed); client.Out.SendMessage("Your target is walking to your location!", eChatType.CT_System, eChatLoc.CL_SystemWindow); break; } diff --git a/GameServer/commands/gmcommands/object.cs b/GameServer/commands/gmcommands/object.cs index 8576092c2a..135676d513 100644 --- a/GameServer/commands/gmcommands/object.cs +++ b/GameServer/commands/gmcommands/object.cs @@ -108,17 +108,14 @@ public void OnCommand(GameClient client, string[] args) } info.Add(" "); - info.Add(" Location: X= " + targetObject.X + " ,Y= " + targetObject.Y + " ,Z= " + targetObject.Z); + info.Add(" Coordinate: X= " + targetObject.Position.X + " ,Y= " + targetObject.Position.Y + " ,Z= " + targetObject.Position.Z); client.Out.SendCustomTextWindow( "[ " + name + " ]", info ); break; } case "movehere": { - targetObject.X = client.Player.X; - targetObject.Y = client.Player.Y; - targetObject.Z = client.Player.Z; - targetObject.Heading = client.Player.Heading; + targetObject.Position = client.Player.Position; targetObject.SaveIntoDatabase(); break; } @@ -278,11 +275,7 @@ public void OnCommand(GameClient client, string[] args) ChatUtil.SendSystemMessage(client, "There was an error creating an instance of " + targetObject.GetType().FullName + "!"); return; } - item.X = client.Player.X; - item.Y = client.Player.Y; - item.Z = client.Player.Z; - item.CurrentRegion = client.Player.CurrentRegion; - item.Heading = client.Player.Heading; + item.Position = client.Player.Position; item.Level = targetObject.Level; item.Name = targetObject.Name; item.Model = targetObject.Model; @@ -399,11 +392,7 @@ GameStaticItem CreateItem(GameClient client, string itemClassName) //Fill the object variables obj.LoadedFromScript = false; - obj.X = client.Player.X; - obj.Y = client.Player.Y; - obj.Z = client.Player.Z; - obj.CurrentRegion = client.Player.CurrentRegion; - obj.Heading = client.Player.Heading; + obj.Position = client.Player.Position; obj.Name = "New Object"; obj.Model = 100; obj.Emblem = 0; diff --git a/GameServer/commands/gmcommands/path.cs b/GameServer/commands/gmcommands/path.cs index db427706a9..0e5b63d71b 100644 --- a/GameServer/commands/gmcommands/path.cs +++ b/GameServer/commands/gmcommands/path.cs @@ -20,6 +20,7 @@ using System.Collections; using System.Linq; using DOL.Database; +using DOL.GS.Geometry; using DOL.GS.Movement; using DOL.GS.PacketHandler; @@ -51,11 +52,7 @@ private void CreateTempPathObject(GameClient client, PathPoint pp, String name) //Create a new object GameStaticItem obj = new GameStaticItem(); //Fill the object variables - obj.X = pp.X; - obj.Y = pp.Y; - obj.Z = pp.Z + 1; // raise a bit off of ground level - obj.CurrentRegion = client.Player.CurrentRegion; - obj.Heading = client.Player.Heading; + obj.Position = client.Player.Position.With(coordinate: pp.Coordinate + Vector.Create(z: 1)); obj.Name = name; obj.Model = 488; obj.Emblem = 0; @@ -103,7 +100,7 @@ private void PathCreate(GameClient client) //Remove old temp objects RemoveAllTempPathObjects(client); - PathPoint startpoint = new PathPoint(client.Player.X, client.Player.Y, client.Player.Z, 5000, ePathType.Once); + PathPoint startpoint = new PathPoint(client.Player.Coordinate, 5000, ePathType.Once); client.Player.TempProperties.setProperty(TEMP_PATH_FIRST, startpoint); client.Player.TempProperties.setProperty(TEMP_PATH_LAST, startpoint); client.Player.Out.SendMessage("Path creation started! You can add new pathpoints via /path add now!", eChatType.CT_System, eChatLoc.CL_SystemWindow); @@ -146,7 +143,7 @@ private void PathAdd(GameClient client, string[] args) } } - PathPoint newpp = new PathPoint(client.Player.X, client.Player.Y, client.Player.Z, speedlimit, path.Type); + PathPoint newpp = new PathPoint(client.Player.Coordinate, speedlimit, path.Type); newpp.WaitTime = waittime * 10; path.Next = newpp; newpp.Prev = path; diff --git a/GameServer/commands/gmcommands/siegeweapon.cs b/GameServer/commands/gmcommands/siegeweapon.cs index 0d8e0242bd..d1fb751114 100644 --- a/GameServer/commands/gmcommands/siegeweapon.cs +++ b/GameServer/commands/gmcommands/siegeweapon.cs @@ -42,10 +42,7 @@ public void OnCommand(GameClient client, string[] args) case "miniram": { GameSiegeRam ram = new GameSiegeRam(); - ram.X = client.Player.X; - ram.Y = client.Player.Y; - ram.Z = client.Player.Z; - ram.CurrentRegion = client.Player.CurrentRegion; + ram.Position = client.Player.Position; ram.Model = 2605; ram.Level = 0; ram.Name = "mini ram"; @@ -56,10 +53,7 @@ public void OnCommand(GameClient client, string[] args) case "lightram": { GameSiegeRam ram = new GameSiegeRam(); - ram.X = client.Player.X; - ram.Y = client.Player.Y; - ram.Z = client.Player.Z; - ram.CurrentRegion = client.Player.CurrentRegion; + ram.Position = client.Player.Position; ram.Model = 2600; ram.Level = 1; ram.Name = "light ram"; @@ -70,10 +64,7 @@ public void OnCommand(GameClient client, string[] args) case "mediumram": { GameSiegeRam ram = new GameSiegeRam(); - ram.X = client.Player.X; - ram.Y = client.Player.Y; - ram.Z = client.Player.Z; - ram.CurrentRegion = client.Player.CurrentRegion; + ram.Position = client.Player.Position; ram.Model = 2601; ram.Level = 2; ram.Name = "medium ram"; @@ -84,10 +75,7 @@ public void OnCommand(GameClient client, string[] args) case "heavyram": { GameSiegeRam ram = new GameSiegeRam(); - ram.X = client.Player.X; - ram.Y = client.Player.Y; - ram.Z = client.Player.Z; - ram.CurrentRegion = client.Player.CurrentRegion; + ram.Position = client.Player.Position; ram.Model = 2602; ram.Level = 3; ram.Name = "heavy ram"; @@ -98,10 +86,7 @@ public void OnCommand(GameClient client, string[] args) case "catapult": { GameSiegeCatapult cat = new GameSiegeCatapult(); - cat.X = client.Player.X; - cat.Y = client.Player.Y; - cat.Z = client.Player.Z; - cat.CurrentRegion = client.Player.CurrentRegion; + cat.Position = client.Player.Position; cat.Model = 0xA26; cat.Level = 3; cat.Name = "catapult"; @@ -112,10 +97,7 @@ public void OnCommand(GameClient client, string[] args) case "ballista": { GameSiegeBallista bal = new GameSiegeBallista(); - bal.X = client.Player.X; - bal.Y = client.Player.Y; - bal.Z = client.Player.Z; - bal.CurrentRegion = client.Player.CurrentRegion; + bal.Position = client.Player.Position; bal.Model = 0x0A55; bal.Level = 3; bal.Name = "field ballista"; @@ -126,10 +108,7 @@ public void OnCommand(GameClient client, string[] args) case "cauldron": { GameSiegeRam ram = new GameSiegeRam(); - ram.X = client.Player.X; - ram.Y = client.Player.Y; - ram.Z = client.Player.Z; - ram.CurrentRegion = client.Player.CurrentRegion; + ram.Position = client.Player.Position; ram.Model = 0xA2F; ram.Level = 3; ram.Name = "cauldron of boiling oil"; @@ -140,10 +119,7 @@ public void OnCommand(GameClient client, string[] args) case "trebuchet": { GameSiegeTrebuchet tre = new GameSiegeTrebuchet(); - tre.X = client.Player.X; - tre.Y = client.Player.Y; - tre.Z = client.Player.Z; - tre.CurrentRegion = client.Player.CurrentRegion; + tre.Position = client.Player.Position; tre.Model = 0xA2E; tre.Level = 3; tre.Name = "trebuchet"; diff --git a/GameServer/commands/gmcommands/walk.cs b/GameServer/commands/gmcommands/walk.cs index a210e5da5f..04008e465a 100644 --- a/GameServer/commands/gmcommands/walk.cs +++ b/GameServer/commands/gmcommands/walk.cs @@ -17,6 +17,7 @@ * */ using System; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; namespace DOL.GS.Commands @@ -79,7 +80,8 @@ public void OnCommand(GameClient client, string[] args) return; } - targetNPC.PathTo(new Point3D((targetNPC.X + xoff), (targetNPC.Y + yoff), (targetNPC.Z + zoff)), speed); + var offset = Vector.Create(x: xoff, y: yoff, z: zoff); + targetNPC.WalkTo(targetNPC.Coordinate + offset, speed); } } } \ No newline at end of file diff --git a/GameServer/commands/gmcommands/zone.cs b/GameServer/commands/gmcommands/zone.cs index 30f5e3fbda..94bf3f5517 100644 --- a/GameServer/commands/gmcommands/zone.cs +++ b/GameServer/commands/gmcommands/zone.cs @@ -23,6 +23,7 @@ using DOL.GS; using DOL.GS.PacketHandler; using DOL.Database; +using DOL.GS.Geometry; namespace DOL.GS.Commands { @@ -58,8 +59,8 @@ public void OnCommand(GameClient client, string[] args) info.Add(" Zone ID: " + client.Player.CurrentZone.ID); info.Add(" Zone IsDungeon: " + client.Player.CurrentZone.IsDungeon); info.Add(" Zone SkinID: " + client.Player.CurrentZone.ZoneSkinID); - info.Add(" Zone X: " + client.Player.CurrentZone.XOffset); - info.Add(" Zone Y: " + client.Player.CurrentZone.YOffset); + info.Add(" Zone X: " + client.Player.CurrentZone.Offset.X); + info.Add(" Zone Y: " + client.Player.CurrentZone.Offset.Y); info.Add(" Zone Width: " + client.Player.CurrentZone.Width); info.Add(" Zone Height: " + client.Player.CurrentZone.Height); info.Add(" Zone DivingEnabled: " + client.Player.CurrentZone.IsDivingEnabled); @@ -130,7 +131,7 @@ public void OnCommand(GameClient client, string[] args) // Update water level and diving flag for the new zone client.Out.SendPlayerPositionAndObjectID(); - client.Player.MoveTo(client.Player.CurrentRegionID, client.Player.X, client.Player.Y, client.Player.Z + 1, client.Player.Heading); + client.Player.MoveTo(client.Player.Position + Vector.Create(z: 1)); DisplayMessage(client, string.Format("Waterlevel for {0}:{1} changed to {2}.", zone.ID, zone.Description, waterlevel)); return; diff --git a/GameServer/commands/playercommands/Boat.cs b/GameServer/commands/playercommands/Boat.cs index bbe84c38fc..c59a34aa92 100644 --- a/GameServer/commands/playercommands/Boat.cs +++ b/GameServer/commands/playercommands/Boat.cs @@ -62,13 +62,9 @@ public void OnCommand(GameClient client, string[] args) InventoryItem item = client.Player.Inventory.GetFirstItemByID("scout_boat", eInventorySlot.Min_Inv, eInventorySlot.Max_Inv); playerBoat.BoatID = System.Guid.NewGuid().ToString(); playerBoat.Name = client.Player.Name + "'s scout boat"; - playerBoat.X = client.Player.X; - playerBoat.Y = client.Player.Y; - playerBoat.Z = client.Player.Z; + playerBoat.Position = client.Player.Position; playerBoat.Model = 2648; - playerBoat.Heading = client.Player.Heading; playerBoat.Realm = client.Player.Realm; - playerBoat.CurrentRegionID = client.Player.CurrentRegionID; playerBoat.OwnerID = client.Player.InternalID; playerBoat.MaxSpeedBase = 500; client.Player.Inventory.RemoveItem(item); @@ -94,13 +90,9 @@ public void OnCommand(GameClient client, string[] args) InventoryItem item = client.Player.Inventory.GetFirstItemByID("warship", eInventorySlot.Min_Inv, eInventorySlot.Max_Inv); playerBoat.BoatID = System.Guid.NewGuid().ToString(); playerBoat.Name = client.Player.Name + "'s warship"; - playerBoat.X = client.Player.X; - playerBoat.Y = client.Player.Y; - playerBoat.Z = client.Player.Z; + playerBoat.Position = client.Player.Position; playerBoat.Model = 2647; - playerBoat.Heading = client.Player.Heading; playerBoat.Realm = client.Player.Realm; - playerBoat.CurrentRegionID = client.Player.CurrentRegionID; playerBoat.OwnerID = client.Player.InternalID; playerBoat.MaxSpeedBase = 400; client.Player.Inventory.RemoveItem(item); @@ -126,13 +118,9 @@ public void OnCommand(GameClient client, string[] args) InventoryItem item = client.Player.Inventory.GetFirstItemByID("galleon", eInventorySlot.Min_Inv, eInventorySlot.Max_Inv); playerBoat.BoatID = System.Guid.NewGuid().ToString(); playerBoat.Name = client.Player.Name + "'s galleon"; - playerBoat.X = client.Player.X; - playerBoat.Y = client.Player.Y; - playerBoat.Z = client.Player.Z; + playerBoat.Position = client.Player.Position; playerBoat.Model = 2646; - playerBoat.Heading = client.Player.Heading; playerBoat.Realm = client.Player.Realm; - playerBoat.CurrentRegionID = client.Player.CurrentRegionID; playerBoat.OwnerID = client.Player.InternalID; playerBoat.MaxSpeedBase = 300; client.Player.Inventory.RemoveItem(item); @@ -158,13 +146,9 @@ public void OnCommand(GameClient client, string[] args) InventoryItem item = client.Player.Inventory.GetFirstItemByID("skiff", eInventorySlot.Min_Inv, eInventorySlot.Max_Inv); playerBoat.BoatID = System.Guid.NewGuid().ToString(); playerBoat.Name = client.Player.Name + "'s skiff"; - playerBoat.X = client.Player.X; - playerBoat.Y = client.Player.Y; - playerBoat.Z = client.Player.Z; + playerBoat.Position = client.Player.Position; playerBoat.Model = 1616; - playerBoat.Heading = client.Player.Heading; playerBoat.Realm = client.Player.Realm; - playerBoat.CurrentRegionID = client.Player.CurrentRegionID; playerBoat.OwnerID = client.Player.InternalID; playerBoat.MaxSpeedBase = 250; client.Player.Inventory.RemoveItem(item); @@ -190,13 +174,9 @@ public void OnCommand(GameClient client, string[] args) InventoryItem item = client.Player.Inventory.GetFirstItemByID("Viking_Longship", eInventorySlot.Min_Inv, eInventorySlot.Max_Inv); playerBoat.BoatID = System.Guid.NewGuid().ToString(); playerBoat.Name = client.Player.Name + "'s Viking longship"; - playerBoat.X = client.Player.X; - playerBoat.Y = client.Player.Y; - playerBoat.Z = client.Player.Z; + playerBoat.Position = client.Player.Position; playerBoat.Model = 1615; - playerBoat.Heading = client.Player.Heading; playerBoat.Realm = client.Player.Realm; - playerBoat.CurrentRegionID = client.Player.CurrentRegionID; playerBoat.OwnerID = client.Player.InternalID; playerBoat.MaxSpeedBase = 500; client.Player.Inventory.RemoveItem(item); @@ -222,13 +202,9 @@ public void OnCommand(GameClient client, string[] args) InventoryItem item = client.Player.Inventory.GetFirstItemByID("ps_longship", eInventorySlot.Min_Inv, eInventorySlot.Max_Inv); playerBoat.BoatID = System.Guid.NewGuid().ToString(); playerBoat.Name = client.Player.Name + "'s Longship"; - playerBoat.X = client.Player.X; - playerBoat.Y = client.Player.Y; - playerBoat.Z = client.Player.Z; + playerBoat.Position = client.Player.Position; playerBoat.Model = 1595; - playerBoat.Heading = client.Player.Heading; playerBoat.Realm = client.Player.Realm; - playerBoat.CurrentRegionID = client.Player.CurrentRegionID; playerBoat.OwnerID = client.Player.InternalID; playerBoat.MaxSpeedBase = 600; client.Player.Inventory.RemoveItem(item); @@ -254,13 +230,9 @@ public void OnCommand(GameClient client, string[] args) InventoryItem item = client.Player.Inventory.GetFirstItemByID("stygian_ship", eInventorySlot.Min_Inv, eInventorySlot.Max_Inv); playerBoat.BoatID = System.Guid.NewGuid().ToString(); playerBoat.Name = client.Player.Name + "'s Stygian ship"; - playerBoat.X = client.Player.X; - playerBoat.Y = client.Player.Y; - playerBoat.Z = client.Player.Z; + playerBoat.Position = client.Player.Position; playerBoat.Model = 1612; - playerBoat.Heading = client.Player.Heading; playerBoat.Realm = client.Player.Realm; - playerBoat.CurrentRegionID = client.Player.CurrentRegionID; playerBoat.OwnerID = client.Player.InternalID; playerBoat.MaxSpeedBase = 500; client.Player.Inventory.RemoveItem(item); @@ -286,13 +258,9 @@ public void OnCommand(GameClient client, string[] args) InventoryItem item = client.Player.Inventory.GetFirstItemByID("atlantean_ship", eInventorySlot.Min_Inv, eInventorySlot.Max_Inv); playerBoat.BoatID = System.Guid.NewGuid().ToString(); playerBoat.Name = client.Player.Name + "'s Atlantean ship"; - playerBoat.X = client.Player.X; - playerBoat.Y = client.Player.Y; - playerBoat.Z = client.Player.Z; + playerBoat.Position = client.Player.Position; playerBoat.Model = 1613; - playerBoat.Heading = client.Player.Heading; playerBoat.Realm = client.Player.Realm; - playerBoat.CurrentRegionID = client.Player.CurrentRegionID; playerBoat.OwnerID = client.Player.InternalID; playerBoat.MaxSpeedBase = 800; client.Player.Inventory.RemoveItem(item); @@ -318,13 +286,9 @@ public void OnCommand(GameClient client, string[] args) InventoryItem item = client.Player.Inventory.GetFirstItemByID("British_Cog", eInventorySlot.Min_Inv, eInventorySlot.Max_Inv); playerBoat.BoatID = System.Guid.NewGuid().ToString(); playerBoat.Name = client.Player.Name + "'s British Cog"; - playerBoat.X = client.Player.X; - playerBoat.Y = client.Player.Y; - playerBoat.Z = client.Player.Z; + playerBoat.Position = client.Player.Position; playerBoat.Model = 1614; - playerBoat.Heading = client.Player.Heading; playerBoat.Realm = client.Player.Realm; - playerBoat.CurrentRegionID = client.Player.CurrentRegionID; playerBoat.OwnerID = client.Player.InternalID; playerBoat.MaxSpeedBase = 700; client.Player.Inventory.RemoveItem(item); @@ -361,12 +325,8 @@ public void OnCommand(GameClient client, string[] args) curBoat.GuildName = client.Player.Guild.Name; } - curBoat.X = client.Player.X; - curBoat.Y = client.Player.Y; - curBoat.Z = client.Player.Z; - curBoat.Heading = client.Player.Heading; + curBoat.Position = client.Player.Position; curBoat.Realm = client.Player.Realm; - curBoat.CurrentRegionID = client.Player.CurrentRegionID; curBoat.Riders = new GamePlayer[32]; BlankBrain brain = new BlankBrain(); curBoat.SetOwnBrain(brain); diff --git a/GameServer/commands/playercommands/GroundAssist.cs b/GameServer/commands/playercommands/GroundAssist.cs index 4ad4cba024..da717b0bc1 100644 --- a/GameServer/commands/playercommands/GroundAssist.cs +++ b/GameServer/commands/playercommands/GroundAssist.cs @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using DOL.Language; @@ -64,13 +65,13 @@ public void OnCommand(GameClient client, string[] args) return; } - if (target.GroundTarget == null || (target.GroundTarget.X == 0 && target.GroundTarget.Y == 0 && target.GroundTarget.Z == 0)) + if (target.GroundTargetPosition == Position.Nowhere) { client.Out.SendMessage(LanguageMgr.GetTranslation(client, "Scripts.Players.Groundassist.NoTarget", target.Name), eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } - client.Player.Out.SendChangeGroundTarget(target.GroundTarget); - client.Player.SetGroundTarget(target.GroundTarget.X, target.GroundTarget.Y, target.GroundTarget.Z); + client.Player.Out.SendChangeGroundTarget(target.GroundTargetPosition.Coordinate); + client.Player.GroundTargetPosition = target.GroundTargetPosition; } } } \ No newline at end of file diff --git a/GameServer/commands/playercommands/facegloc.cs b/GameServer/commands/playercommands/facegloc.cs index 7dad6dc260..7bb6bc96e7 100644 --- a/GameServer/commands/playercommands/facegloc.cs +++ b/GameServer/commands/playercommands/facegloc.cs @@ -24,6 +24,7 @@ * */ using System; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using DOL.Language; @@ -59,8 +60,7 @@ public void OnCommand(GameClient client, string[] args) return; } - ushort direction = client.Player.GetHeading( new Point2D( x, y ) ); - client.Player.Heading = direction; + client.Player.TurnTo(Coordinate.Create(x: x, y: y )); client.Out.SendPlayerJump(true); } } diff --git a/GameServer/commands/playercommands/faceloc.cs b/GameServer/commands/playercommands/faceloc.cs index 0022087ae9..ba9a19bd1a 100644 --- a/GameServer/commands/playercommands/faceloc.cs +++ b/GameServer/commands/playercommands/faceloc.cs @@ -23,6 +23,7 @@ * Desc: Implements /faceloc command * */ +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using DOL.Language; @@ -64,11 +65,10 @@ public void OnCommand(GameClient client, string[] args) client.Out.SendMessage(LanguageMgr.GetTranslation(client, "Scripts.Players.Faceloc.Invalid"), eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } - int Xoffset = client.Player.CurrentZone.XOffset; - int Yoffset = client.Player.CurrentZone.YOffset; - Point2D gloc = new Point2D( Xoffset + x, Yoffset + y ); - ushort direction = client.Player.GetHeading(gloc); - client.Player.Heading = direction; + int xOffset = client.Player.CurrentZone.Offset.X; + int yOffset = client.Player.CurrentZone.Offset.Y; + var gloc = Coordinate.Create(x: x + xOffset, y: y + yOffset ); + client.Player.TurnTo(gloc); client.Out.SendPlayerJump(true); } } diff --git a/GameServer/commands/playercommands/gloc.cs b/GameServer/commands/playercommands/gloc.cs index b6c64fe64a..05c8ccce33 100644 --- a/GameServer/commands/playercommands/gloc.cs +++ b/GameServer/commands/playercommands/gloc.cs @@ -33,7 +33,8 @@ public void OnCommand(GameClient client, string[] args) return; DisplayMessage(client, LanguageMgr.GetTranslation(client, "Scripts.Players.Gloc.At", - client.Player.X, client.Player.Y, client.Player.Z, client.Player.Heading, client.Player.CurrentRegionID, + client.Player.Position.X, client.Player.Position.Y, client.Player.Position.Z, + client.Player.Position.Orientation.InHeading, client.Player.Position.RegionID, client.Player.CurrentRegion is BaseInstance ? string.Format("Skin:{0}", client.Player.CurrentRegion.Skin) : "")); } } diff --git a/GameServer/commands/playercommands/gtrange.cs b/GameServer/commands/playercommands/gtrange.cs index 99b63d3288..8a421089ff 100644 --- a/GameServer/commands/playercommands/gtrange.cs +++ b/GameServer/commands/playercommands/gtrange.cs @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using DOL.Language; @@ -33,9 +34,9 @@ public void OnCommand(GameClient client, string[] args) if (IsSpammingCommand(client.Player, "gtrange")) return; - if (client.Player.GroundTarget != null) + if (client.Player.GroundTargetPosition != Position.Nowhere) { - int range = client.Player.GetDistanceTo( client.Player.GroundTarget ); + var range = (int)client.Player.Coordinate.DistanceTo(client.Player.GroundTargetPosition); client.Out.SendMessage(LanguageMgr.GetTranslation(client, "Scripts.Players.Gtrange.Range", range), eChatType.CT_System, eChatLoc.CL_SystemWindow); } else diff --git a/GameServer/commands/playercommands/guild.cs b/GameServer/commands/playercommands/guild.cs index 05c479eff3..98ef9a004f 100644 --- a/GameServer/commands/playercommands/guild.cs +++ b/GameServer/commands/playercommands/guild.cs @@ -2097,7 +2097,7 @@ public void OnCommand(GameClient client, string[] args) client.Out.SendMessage(LanguageMgr.GetTranslation(client.Account.Language, "Scripts.Player.Guild.NotMember"), eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } - AbstractGameKeep keep = GameServer.KeepManager.GetKeepCloseToSpot(client.Player.CurrentRegionID, client.Player, WorldMgr.VISIBILITY_DISTANCE); + AbstractGameKeep keep = GameServer.KeepManager.GetKeepCloseToSpot(client.Player.Position, WorldMgr.VISIBILITY_DISTANCE); if (keep == null) { client.Out.SendMessage(LanguageMgr.GetTranslation(client.Account.Language, "Scripts.Player.Guild.ClaimNotNear"), eChatType.CT_System, eChatLoc.CL_SystemWindow); diff --git a/GameServer/commands/playercommands/house.cs b/GameServer/commands/playercommands/house.cs index 777b1c9f9a..9b625ef028 100644 --- a/GameServer/commands/playercommands/house.cs +++ b/GameServer/commands/playercommands/house.cs @@ -150,7 +150,7 @@ public void HouseAdmin(GamePlayer player, string [] args) } } - ArrayList houses = (ArrayList)HouseMgr.GetHousesCloseToSpot(player.CurrentRegionID, player.X, player.Y, 700); + ArrayList houses = (ArrayList)HouseMgr.GetHousesCloseToSpot(player.Position, 700); if (houses.Count != 1) { DisplayMessage(player.Client, LanguageMgr.GetTranslation(player.Client, "Scripts.Players.House.FarAway")); diff --git a/GameServer/commands/playercommands/houseface.cs b/GameServer/commands/playercommands/houseface.cs index 0475ac4fca..0a48efffa7 100644 --- a/GameServer/commands/playercommands/houseface.cs +++ b/GameServer/commands/playercommands/houseface.cs @@ -1,4 +1,5 @@ using DOL.GS; +using DOL.GS.Geometry; using DOL.GS.Housing; using DOL.GS.PacketHandler; using DOL.Language; @@ -36,8 +37,7 @@ public void OnCommand(GameClient client, string[] args) House house = HouseMgr.GetHouse(housenumber); - ushort direction = client.Player.GetHeading(house); - client.Player.Heading = direction; + client.Player.TurnTo(house.Position.Coordinate); client.Out.SendPlayerJump(true); DisplayMessage(client, LanguageMgr.GetTranslation(client, "Scripts.Players.Houseface.Faced", housenumber)); } diff --git a/GameServer/commands/playercommands/knock.cs b/GameServer/commands/playercommands/knock.cs index 7002ae47b4..a71fad0592 100644 --- a/GameServer/commands/playercommands/knock.cs +++ b/GameServer/commands/playercommands/knock.cs @@ -53,7 +53,7 @@ public void OnCommand(GameClient client, string[] args) } bool done = false; - foreach (House house in HouseMgr.GetHousesCloseToSpot(client.Player.CurrentRegionID, client.Player.X, client.Player.Y, 650)) + foreach (House house in HouseMgr.GetHousesCloseToSpot(client.Player.Position, 650)) { client.Player.Emote(eEmote.Knock); foreach (GamePlayer player in house.GetAllPlayersInHouse()) diff --git a/GameServer/commands/playercommands/where.cs b/GameServer/commands/playercommands/where.cs index 6c134ac189..affd70582c 100644 --- a/GameServer/commands/playercommands/where.cs +++ b/GameServer/commands/playercommands/where.cs @@ -47,8 +47,8 @@ public void OnCommand(GameClient client, string[] args) return; } GameNPC npc = npcs[0]; - ushort heading = targetnpc.GetHeading(npc); - string directionstring = GetDirectionFromHeading(heading, client); + var orientation = targetnpc.Coordinate.GetOrientationTo(npc.Coordinate); + string directionstring = LanguageMgr.GetCardinalDirection(client.Account.Language, orientation); targetnpc.SayTo(client.Player, eChatLoc.CL_SystemWindow, LanguageMgr.GetTranslation(client, "Scripts.Players.Where.Found", npc.Name, directionstring)); targetnpc.TurnTo(npc, 10000); targetnpc.Emote(eEmote.Point); @@ -145,29 +145,5 @@ public bool CheckTargetIsGuard(GameLiving target) } return false; } - - public string GetDirectionFromHeading(ushort heading, GameClient client) - { - // Using translations from /yell command - if (heading < 0) - heading += 4096; - if (heading >= 3840 || heading <= 256) - return LanguageMgr.GetTranslation(client, "Scripts.Players.Yell.South"); - else if (heading > 256 && heading < 768) - return LanguageMgr.GetTranslation(client, "Scripts.Players.Yell.SouthWest"); - else if (heading >= 768 && heading <= 1280) - return LanguageMgr.GetTranslation(client, "Scripts.Players.Yell.West"); - else if (heading > 1280 && heading < 1792) - return LanguageMgr.GetTranslation(client, "Scripts.Players.Yell.NorthWest"); - else if (heading >= 1792 && heading <= 2304) - return LanguageMgr.GetTranslation(client, "Scripts.Players.Yell.North"); - else if (heading > 2304 && heading < 2816) - return LanguageMgr.GetTranslation(client, "Scripts.Players.Yell.NorthEast"); - else if (heading >= 2816 && heading <= 3328) - return LanguageMgr.GetTranslation(client, "Scripts.Players.Yell.East"); - else if (heading > 3328 && heading < 3840) - return LanguageMgr.GetTranslation(client, "Scripts.Players.Yell.SouthEast"); - return ""; - } } } \ No newline at end of file diff --git a/GameServer/commands/playercommands/yell.cs b/GameServer/commands/playercommands/yell.cs index 144106e6f5..cc2e51437a 100644 --- a/GameServer/commands/playercommands/yell.cs +++ b/GameServer/commands/playercommands/yell.cs @@ -50,21 +50,9 @@ public void OnCommand(GameClient client, string[] args) { if (player != client.Player) { - ushort headingtotarget = player.GetHeading(client.Player); - if( headingtotarget < 0 ) - headingtotarget += 4096; - - string direction = ""; - if( headingtotarget >= 3840 || headingtotarget <= 256 ) direction = LanguageMgr.GetTranslation(player.Client.Account.Language, "Scripts.Players.Yell.South"); - else if( headingtotarget > 256 && headingtotarget <= 768 ) direction = LanguageMgr.GetTranslation(player.Client.Account.Language, "Scripts.Players.Yell.SouthWest"); - else if( headingtotarget > 768 && headingtotarget <= 1280 ) direction = LanguageMgr.GetTranslation(player.Client.Account.Language, "Scripts.Players.Yell.West"); - else if( headingtotarget > 1280 && headingtotarget <= 1792 ) direction = LanguageMgr.GetTranslation(player.Client.Account.Language, "Scripts.Players.Yell.NorthWest"); - else if( headingtotarget > 1792 && headingtotarget <= 2304 ) direction = LanguageMgr.GetTranslation(player.Client.Account.Language, "Scripts.Players.Yell.North"); - else if( headingtotarget > 2304 && headingtotarget <= 2816 ) direction = LanguageMgr.GetTranslation(player.Client.Account.Language, "Scripts.Players.Yell.NorthEast"); - else if( headingtotarget > 2816 && headingtotarget <= 3328 ) direction = LanguageMgr.GetTranslation(player.Client.Account.Language, "Scripts.Players.Yell.East"); - else if( headingtotarget > 3328 && headingtotarget <= 3840 ) direction = LanguageMgr.GetTranslation(player.Client.Account.Language, "Scripts.Players.Yell.SouthEast"); - - player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "Scripts.Players.Yell.FromDirection", client.Player.Name, direction), eChatType.CT_Help, eChatLoc.CL_SystemWindow); + var directionToTarget = player.Coordinate.GetOrientationTo(client.Player.Coordinate); + var cardinalDirection = LanguageMgr.GetCardinalDirection(player.Client.Account.Language, directionToTarget); + player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "Scripts.Players.Yell.FromDirection", client.Player.Name, cardinalDirection), eChatType.CT_Help, eChatLoc.CL_SystemWindow); } else client.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "Scripts.Players.Yell.YouYell"), eChatType.CT_Help, eChatLoc.CL_SystemWindow); diff --git a/GameServer/craft/SiegeCrafting.cs b/GameServer/craft/SiegeCrafting.cs index e8efcb708d..209efabbc3 100644 --- a/GameServer/craft/SiegeCrafting.cs +++ b/GameServer/craft/SiegeCrafting.cs @@ -100,11 +100,7 @@ protected override void BuildCraftedItem(GamePlayer player, Recipe recipe) siegeweapon.ItemId = product.Id_nb; siegeweapon.LoadFromDatabase(product); - siegeweapon.CurrentRegion = player.CurrentRegion; - siegeweapon.Heading = player.Heading; - siegeweapon.X = player.X; - siegeweapon.Y = player.Y; - siegeweapon.Z = player.Z; + siegeweapon.Position = player.Position; siegeweapon.Realm = player.Realm; siegeweapon.AddToWorld(); } diff --git a/GameServer/database/converters/Version002.cs b/GameServer/database/converters/Version002.cs index edb5424ba3..9068671da1 100644 --- a/GameServer/database/converters/Version002.cs +++ b/GameServer/database/converters/Version002.cs @@ -19,6 +19,7 @@ using System; using log4net; using DOL.Database; +using DOL.GS.Geometry; namespace DOL.GS.DatabaseConverters { @@ -63,7 +64,7 @@ public void ConvertDatabase() Region region = WorldMgr.GetRegion(mob.Region); if (region != null) { - Zone zone = region.GetZone(mob.X, mob.Y); + Zone zone = region.GetZone(mob.GetPosition().Coordinate); if (zone != null) { mob.Realm = (byte)zone.Realm; diff --git a/GameServer/events/gameobjects/WalkToEventArgs.cs b/GameServer/events/gameobjects/WalkToEventArgs.cs index c414e3195b..30e5a4324c 100644 --- a/GameServer/events/gameobjects/WalkToEventArgs.cs +++ b/GameServer/events/gameobjects/WalkToEventArgs.cs @@ -18,6 +18,7 @@ */ using System; using DOL.GS; +using DOL.GS.Geometry; namespace DOL.Events { @@ -26,7 +27,7 @@ namespace DOL.Events /// public class WalkToEventArgs : EventArgs { - public WalkToEventArgs(IPoint3D target, int speed) + public WalkToEventArgs(Coordinate target, int speed) { Target = target; Speed = speed; @@ -35,7 +36,7 @@ public WalkToEventArgs(IPoint3D target, int speed) /// /// The spot to walk to. /// - public IPoint3D Target { get; private set; } + public Coordinate Target { get; private set; } /// /// The speed to walk at. diff --git a/GameServer/gameobjects/Animist/TurretPet.cs b/GameServer/gameobjects/Animist/TurretPet.cs index d1795fcc12..cadac658ab 100644 --- a/GameServer/gameobjects/Animist/TurretPet.cs +++ b/GameServer/gameobjects/Animist/TurretPet.cs @@ -74,9 +74,9 @@ public override void StartAttack(GameObject attackTarget) TargetObject = attackTarget; if (TargetObject.Realm == 0 || Realm == 0) - m_lastAttackTickPvE = m_CurrentRegion.Time; + m_lastAttackTickPvE = CurrentRegion.Time; else - m_lastAttackTickPvP = m_CurrentRegion.Time; + m_lastAttackTickPvP = CurrentRegion.Time; if (m_attackers.Count == 0) { diff --git a/GameServer/gameobjects/Atlantis/Teleporter/AncientBoundDjinn.cs b/GameServer/gameobjects/Atlantis/Teleporter/AncientBoundDjinn.cs index 0e779a3656..2c4b3b94fc 100644 --- a/GameServer/gameobjects/Atlantis/Teleporter/AncientBoundDjinn.cs +++ b/GameServer/gameobjects/Atlantis/Teleporter/AncientBoundDjinn.cs @@ -23,6 +23,7 @@ using DOL.Database; using DOL.GS.PacketHandler; using DOL.GS.Housing; +using DOL.GS.Geometry; namespace DOL.GS { @@ -47,13 +48,9 @@ public AncientBoundDjinn(DjinnStone djinnStone) : base() LoadTemplate(npcTemplate); - CurrentRegion = djinnStone.CurrentRegion; - Heading = djinnStone.Heading; Realm = eRealm.None; Flags ^= GameNPC.eFlags.FLYING | GameNPC.eFlags.PEACE; - X = djinnStone.X; - Y = djinnStone.Y; - Z = djinnStone.Z + HoverHeight; + Position = djinnStone.Position + Vector.Create(z: HoverHeight); base.Size = Size; } diff --git a/GameServer/gameobjects/CustomNPC/ConsignmentMerchant.cs b/GameServer/gameobjects/CustomNPC/ConsignmentMerchant.cs index f2b10a0896..44f47d4c39 100644 --- a/GameServer/gameobjects/CustomNPC/ConsignmentMerchant.cs +++ b/GameServer/gameobjects/CustomNPC/ConsignmentMerchant.cs @@ -22,6 +22,7 @@ using System.Reflection; using DOL.Database; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.Housing; using DOL.GS.PacketHandler; using DOL.GS.PacketHandler.Client.v168; @@ -82,45 +83,43 @@ public virtual int LastDBSlot #region Token return - private static readonly Dictionary _itemXdestination = - new Dictionary + private static readonly Dictionary _itemXdestination = + new Dictionary { // Item Id_nb, new Tuple<>(Region, X, Y, Z, Heading) // ALBION - {"entrancehousingalb", new GameLocation("", 2, 584832, 561279, 3576, 2144)}, - {"marketcaerwent", new GameLocation("", 2, 557035, 560048, 3624, 1641)}, - {"marketrilan", new GameLocation("", 2, 559906, 491141, 3392, 1829)}, - {"marketbrisworthy", new GameLocation("", 2, 489474, 489323, 3600, 3633)}, - {"marketstoneleigh", new GameLocation("", 2, 428964, 490962, 3624, 1806)}, - {"marketchiltern", new GameLocation("", 2, 428128, 557606, 3624, 3888)}, - {"marketsherborne", new GameLocation("", 2, 428840, 622221, 3248, 1813)}, - {"marketaylesbury", new GameLocation("", 2, 492794, 621373, 3624, 1643)}, - {"marketoldsarum", new GameLocation("", 2, 560030, 622022, 3624, 1819)}, - {"marketdalton", new GameLocation("", 2, 489334, 559242, 3720, 1821)}, - + {"entrancehousingalb", Position.Create(regionID: 2, x: 584832, y: 561279, z: 3576, heading: 2144)}, + {"marketcaerwent", Position.Create(regionID: 2, x: 557035, y: 560048, z: 3624, heading: 1641)}, + {"marketrilan", Position.Create(regionID: 2, x: 559906, y: 491141, z: 3392, heading: 1829)}, + {"marketbrisworthy", Position.Create(regionID: 2, x: 489474, y: 489323, z: 3600, heading: 3633)}, + {"marketstoneleigh", Position.Create(regionID: 2, x: 428964, y: 490962, z: 3624, heading: 1806)}, + {"marketchiltern", Position.Create(regionID: 2, x: 428128, y: 557606, z: 3624, heading: 3888)}, + {"marketsherborne", Position.Create(regionID: 2, x: 428840, y: 622221, z: 3248, heading: 1813)}, + {"marketaylesbury", Position.Create(regionID: 2, x: 492794, y: 621373, z: 3624, heading: 1643)}, + {"marketoldsarum", Position.Create(regionID: 2, x: 560030, y: 622022, z: 3624, heading: 1819)}, + {"marketdalton", Position.Create(regionID: 2, x: 489334, y: 559242, z: 3720, heading: 1821)}, // MIDGARD - {"entrancehousingmid", new GameLocation("", 102, 526881, 561661, 3633, 80)}, - {"marketerikstaad", new GameLocation("", 102, 554099, 565239, 3624, 504)}, - {"marketarothi", new GameLocation("", 102, 558093, 485250, 3488, 1231)}, - {"marketkaupang", new GameLocation("", 102, 625574, 483303, 3592, 2547)}, - {"marketstavgaard", new GameLocation("", 102, 686901, 490396, 3744, 332)}, - {"marketcarlingford", new GameLocation("", 102, 625056, 557887, 3696, 1366)}, - {"marketholmestrand", new GameLocation("", 102, 686903, 556050, 3712, 313)}, - {"marketnittedal", new GameLocation("", 102, 689199, 616329, 3488, 1252)}, - {"marketfrisia", new GameLocation("", 102, 622620, 615491, 3704, 804)}, - {"marketwyndham", new GameLocation("", 102, 555839, 621432, 3744, 314)}, - + {"entrancehousingmid", Position.Create(regionID: 102, x: 526881, y: 561661, z: 3633, heading: 80)}, + {"marketerikstaad", Position.Create(regionID: 102, x: 554099, y: 565239, z: 3624, heading: 504)}, + {"marketarothi", Position.Create(regionID: 102, x: 558093, y: 485250, z: 3488, heading: 1231)}, + {"marketkaupang", Position.Create(regionID: 102, x: 625574, y: 483303, z: 3592, heading: 2547)}, + {"marketstavgaard", Position.Create(regionID: 102, x: 686901, y: 490396, z: 3744, heading: 332)}, + {"marketcarlingford", Position.Create(regionID: 102, x: 625056, y: 557887, z: 3696, heading: 1366)}, + {"marketholmestrand", Position.Create(regionID: 102, x: 686903, y: 556050, z: 3712, heading: 313)}, + {"marketnittedal", Position.Create(regionID: 102, x: 689199, y: 616329, z: 3488, heading: 1252)}, + {"marketfrisia", Position.Create(regionID: 102, x: 622620, y: 615491, z: 3704, heading: 804)}, + {"marketwyndham", Position.Create(regionID: 102, x: 555839, y: 621432, z: 3744, heading: 314)}, // HIBERNIA - {"entrancehousinghib", new GameLocation("", 202, 555246, 526470, 3008, 1055)}, - {"marketmeath", new GameLocation("", 202, 564448, 559995, 3008, 1024)}, - {"marketkilcullen", new GameLocation("", 202, 618653, 561227, 3032, 3087)}, - {"marketaberillan", new GameLocation("", 202, 615145, 619457, 3008, 3064)}, - {"markettorrylin", new GameLocation("", 202, 566890, 620027, 3008, 1500)}, - {"markettullamore", new GameLocation("", 202, 560999, 692301, 3032, 1030)}, - {"marketbroughshane", new GameLocation("", 202, 618653, 692296, 3032, 3090)}, - {"marketmoycullen", new GameLocation("", 202, 495552, 686733, 2960, 1077)}, - {"marketsaeranthal", new GameLocation("", 202, 493148, 620361, 2952, 2471)}, - {"marketdunshire", new GameLocation("", 202, 495494, 555646, 2960, 1057)}, + {"entrancehousinghib", Position.Create(regionID: 202, x: 555246, y: 526470, z: 3008, heading: 1055)}, + {"marketmeath", Position.Create(regionID: 202, x: 564448, y: 559995, z: 3008, heading: 1024)}, + {"marketkilcullen", Position.Create(regionID: 202, x: 618653, y: 561227, z: 3032, heading: 3087)}, + {"marketaberillan", Position.Create(regionID: 202, x: 615145, y: 619457, z: 3008, heading: 3064)}, + {"markettorrylin", Position.Create(regionID: 202, x: 566890, y: 620027, z: 3008, heading: 1500)}, + {"markettullamore", Position.Create(regionID: 202, x: 560999, y: 692301, z: 3032, heading: 1030)}, + {"marketbroughshane", Position.Create(regionID: 202, x: 618653, y: 692296, z: 3032, heading: 3090)}, + {"marketmoycullen", Position.Create(regionID: 202, x: 495552, y: 686733, z: 2960, heading: 1077)}, + {"marketsaeranthal", Position.Create(regionID: 202, x: 493148, y: 620361, z: 2952, heading: 2471)}, + {"marketdunshire", Position.Create(regionID: 202, x: 495494, y: 555646, z: 2960, heading: 1057)}, }; public override bool ReceiveItem(GameLiving source, InventoryItem item) @@ -138,8 +137,7 @@ public override bool ReceiveItem(GameLiving source, InventoryItem item) if (item != null) { - GameLocation destination; - if (_itemXdestination.TryGetValue(item.Id_nb, out destination)) + if (_itemXdestination.TryGetValue(item.Id_nb, out Position destination)) { player.MoveTo(destination); player.Inventory.RemoveItem(item); diff --git a/GameServer/gameobjects/CustomNPC/GameBoatStableMaster.cs b/GameServer/gameobjects/CustomNPC/GameBoatStableMaster.cs index 73c0a8a852..aa693da446 100644 --- a/GameServer/gameobjects/CustomNPC/GameBoatStableMaster.cs +++ b/GameServer/gameobjects/CustomNPC/GameBoatStableMaster.cs @@ -26,6 +26,7 @@ using DOL.GS.PacketHandler; using log4net; using DOL.GS.Finance; +using DOL.GS.Geometry; namespace DOL.GS { @@ -130,7 +131,7 @@ public override bool ReceiveItem(GameLiving source, InventoryItem item) String destination = item.Name.Substring(LanguageMgr.GetTranslation(ServerProperties.Properties.DB_LANGUAGE, "GameStableMaster.ReceiveItem.TicketTo").Length); PathPoint path = MovementMgr.LoadPath(item.Id_nb); //PathPoint path = MovementMgr.Instance.LoadPath(this.Name + "=>" + destination); - if ((path != null) && ((Math.Abs(path.X - this.X)) < 500) && ((Math.Abs(path.Y - this.Y)) < 500)) + if ((path != null) && ((Math.Abs(path.Coordinate.X - Coordinate.X)) < 500) && ((Math.Abs(path.Coordinate.Y - Coordinate.Y)) < 500)) { player.Inventory.RemoveCountFromStack(item, 1); InventoryLogging.LogInventoryAction(player, this, eInventoryActionType.Merchant, item.Template); @@ -138,11 +139,7 @@ public override bool ReceiveItem(GameLiving source, InventoryItem item) GameTaxiBoat boat = new GameTaxiBoat(); boat.Name = "Boat to " + destination; boat.Realm = source.Realm; - boat.X = path.X; - boat.Y = path.Y; - boat.Z = path.Z; - boat.CurrentRegion = CurrentRegion; - boat.Heading = path.GetHeading( path.Next ); + boat.Position = Position.Create(CurrentRegion.ID, path.Coordinate, path.AngleToNextPathPoint); boat.AddToWorld(); boat.CurrentWayPoint = path; GameEventMgr.AddHandler(boat, GameNPCEvent.PathMoveEnds, new DOLEventHandler(OnHorseAtPathEnd)); diff --git a/GameServer/gameobjects/CustomNPC/GameStableMaster.cs b/GameServer/gameobjects/CustomNPC/GameStableMaster.cs index e510db8fd4..3f41b53fbf 100644 --- a/GameServer/gameobjects/CustomNPC/GameStableMaster.cs +++ b/GameServer/gameobjects/CustomNPC/GameStableMaster.cs @@ -27,6 +27,7 @@ using log4net; using System.Linq; using DOL.GS.Finance; +using DOL.GS.Geometry; namespace DOL.GS { @@ -129,7 +130,7 @@ public override bool ReceiveItem(GameLiving source, InventoryItem item) { PathPoint path = MovementMgr.LoadPath(item.Id_nb); - if ((path != null) && ((Math.Abs(path.X - this.X)) < 500) && ((Math.Abs(path.Y - this.Y)) < 500)) + if ((path != null) && ((Math.Abs(path.Coordinate.X - Coordinate.X)) < 500) && ((Math.Abs(path.Coordinate.Y - Coordinate.Y)) < 500)) { player.Inventory.RemoveCountFromStack(item, 1); InventoryLogging.LogInventoryAction(player, this, eInventoryActionType.Merchant, item.Template); @@ -207,11 +208,7 @@ public override bool ReceiveItem(GameLiving source, InventoryItem item) } mount.Realm = source.Realm; - mount.X = path.X; - mount.Y = path.Y; - mount.Z = path.Z; - mount.CurrentRegion = CurrentRegion; - mount.Heading = path.GetHeading( path.Next ); + mount.Position = Position.Create(CurrentRegion.ID, path.Coordinate, path.AngleToNextPathPoint); mount.AddToWorld(); mount.CurrentWayPoint = path; GameEventMgr.AddHandler(mount, GameNPCEvent.PathMoveEnds, new DOLEventHandler(OnHorseAtPathEnd)); diff --git a/GameServer/gameobjects/CustomNPC/GameSummoner.cs b/GameServer/gameobjects/CustomNPC/GameSummoner.cs index fb19a6b9c6..4da1e9c0d8 100644 --- a/GameServer/gameobjects/CustomNPC/GameSummoner.cs +++ b/GameServer/gameobjects/CustomNPC/GameSummoner.cs @@ -18,6 +18,7 @@ */ using DOL.AI; using DOL.AI.Brain; +using DOL.GS.Geometry; namespace DOL.GS { @@ -141,18 +142,10 @@ protected virtual void SummonPet() m_pet = new GameNPC(PetTemplate); if (m_pet != null) { - m_pet.CurrentRegion = CurrentRegion; - // Summon pet to the left or right of the summoner - ushort sideHeading = (ushort)(Heading + 900); - if (Util.Random(1) < 1) - sideHeading += 1800; - Point2D point = GetPointFromHeading(sideHeading, PetSummonDistance); - m_pet.X = point.X; - m_pet.Y = point.Y; - m_pet.Z = Z; - - m_pet.Heading = Heading; + var petOrientationOffset = Util.Random(1) < 1 ? Angle.Heading(1800) : Angle.Heading(900); + m_pet.Position = Position + Vector.Create(Orientation + petOrientationOffset, PetSummonDistance); + m_pet.Realm = eRealm.None; m_pet.LoadedFromScript = true; m_pet.MaxDistance = PetMaxDistance; diff --git a/GameServer/gameobjects/CustomNPC/Hastener.cs b/GameServer/gameobjects/CustomNPC/Hastener.cs index aacd5c901d..d7df1d36ec 100644 --- a/GameServer/gameobjects/CustomNPC/Hastener.cs +++ b/GameServer/gameobjects/CustomNPC/Hastener.cs @@ -104,7 +104,7 @@ public override bool WhisperReceive(GameLiving source, string str) AbstractGameKeep portalKeep = GameServer.KeepManager.GetBGPK(player); if (portalKeep != null) { - player.MoveTo((ushort)portalKeep.Region, portalKeep.X, portalKeep.Y, portalKeep.Z, (ushort)portalKeep.Heading); + player.MoveTo(portalKeep.Position); } } } diff --git a/GameServer/gameobjects/CustomNPC/Recharger.cs b/GameServer/gameobjects/CustomNPC/Recharger.cs index 739b76ec07..97fc928188 100644 --- a/GameServer/gameobjects/CustomNPC/Recharger.cs +++ b/GameServer/gameobjects/CustomNPC/Recharger.cs @@ -54,7 +54,7 @@ public override bool Interact(GamePlayer player) if (!base.Interact(player)) return false; - TurnTo(player.X, player.Y); + TurnTo(player.Coordinate); SayTo(player, eChatLoc.CL_ChatWindow, LanguageMgr.GetTranslation(player.Client.Account.Language, "Scripts.Recharger.Interact")); return true; } diff --git a/GameServer/gameobjects/CustomNPC/Teleporters/AllRealmsTeleporter.cs b/GameServer/gameobjects/CustomNPC/Teleporters/AllRealmsTeleporter.cs index 0c74d1f528..b021302048 100644 --- a/GameServer/gameobjects/CustomNPC/Teleporters/AllRealmsTeleporter.cs +++ b/GameServer/gameobjects/CustomNPC/Teleporters/AllRealmsTeleporter.cs @@ -544,15 +544,15 @@ protected Teleport GetTeleportLocation(GamePlayer player, string text, eRealm re } else { - IGameLocation location = house.OutdoorJumpPoint; + var position = house.OutdoorJumpPosition; Teleport teleport = new Teleport(); teleport.TeleportID = "personal"; teleport.Realm = (int)player.Realm; - teleport.RegionID = location.RegionID; - teleport.X = location.X; - teleport.Y = location.Y; - teleport.Z = location.Z; - teleport.Heading = location.Heading; + teleport.RegionID = position.RegionID; + teleport.X = position.X; + teleport.Y = position.Y; + teleport.Z = position.Z; + teleport.Heading = position.Orientation.InHeading; return teleport; } } @@ -562,16 +562,14 @@ protected Teleport GetTeleportLocation(GamePlayer player, string text, eRealm re if (text.ToLower() == "hearth") { // Check if player has set a house bind - if (!(player.BindHouseRegion > 0)) + if (!(player.BindHousePosition.RegionID > 0)) { SayTo(player, "Sorry, you haven't set any house bind point yet."); return null; } // Check if the house at the player's house bind location still exists - ArrayList houses = (ArrayList)HouseMgr.GetHousesCloseToSpot((ushort)player. - BindHouseRegion, player.BindHouseXpos, player. - BindHouseYpos, 700); + ArrayList houses = (ArrayList)HouseMgr.GetHousesCloseToSpot(player.BindHousePosition, 700); if (houses.Count == 0) { SayTo(player, "I'm afraid I can't teleport you to your hearth since the house at your " + @@ -611,11 +609,11 @@ protected Teleport GetTeleportLocation(GamePlayer player, string text, eRealm re Teleport teleport = new Teleport(); teleport.TeleportID = "hearth"; teleport.Realm = (int)player.Realm; - teleport.RegionID = player.BindHouseRegion; - teleport.X = player.BindHouseXpos; - teleport.Y = player.BindHouseYpos; - teleport.Z = player.BindHouseZpos; - teleport.Heading = player.BindHouseHeading; + teleport.RegionID = player.BindHousePosition.RegionID; + teleport.X = player.BindHousePosition.X; + teleport.Y = player.BindHousePosition.Y; + teleport.Z = player.BindHousePosition.Z; + teleport.Heading = player.BindHousePosition.Orientation.InHeading; return teleport; } @@ -629,15 +627,15 @@ protected Teleport GetTeleportLocation(GamePlayer player, string text, eRealm re } else { - IGameLocation location = house.OutdoorJumpPoint; + var position = house.OutdoorJumpPosition; Teleport teleport = new Teleport(); teleport.TeleportID = "guild house"; teleport.Realm = (int)player.Realm; - teleport.RegionID = location.RegionID; - teleport.X = location.X; - teleport.Y = location.Y; - teleport.Z = location.Z; - teleport.Heading = location.Heading; + teleport.RegionID = position.RegionID; + teleport.X = position.X; + teleport.Y = position.Y; + teleport.Z = position.Z; + teleport.Heading = position.Orientation.InHeading; return teleport; } } diff --git a/GameServer/gameobjects/CustomNPC/Teleporters/ThroneRoomTeleporter.cs b/GameServer/gameobjects/CustomNPC/Teleporters/ThroneRoomTeleporter.cs index 5c78432f1c..9c970aeeff 100644 --- a/GameServer/gameobjects/CustomNPC/Teleporters/ThroneRoomTeleporter.cs +++ b/GameServer/gameobjects/CustomNPC/Teleporters/ThroneRoomTeleporter.cs @@ -20,6 +20,7 @@ using System.Linq; using DOL.Database; +using DOL.GS.Geometry; namespace DOL.GS { @@ -135,7 +136,7 @@ public override bool WhisperReceive(GameLiving source, string text) if (teleport != null) { SayTo(player, "Very well ..."); - player.MoveTo((ushort)teleport.RegionID, teleport.X, teleport.Y, teleport.Z, (ushort)teleport.Heading); + player.MoveTo(teleport.GetPosition()); } return true; diff --git a/GameServer/gameobjects/Dragons/Cuuldurach.cs b/GameServer/gameobjects/Dragons/Cuuldurach.cs index 11acf24b7c..f0ead7a9cf 100644 --- a/GameServer/gameobjects/Dragons/Cuuldurach.cs +++ b/GameServer/gameobjects/Dragons/Cuuldurach.cs @@ -24,7 +24,7 @@ using System.Reflection; using System.Collections; using DOL.AI.Brain; - +using DOL.GS.Geometry; namespace DOL.GS { @@ -59,9 +59,9 @@ public override bool CheckAddSpawns() for (int glimmer = 1; glimmer <= 10; ++glimmer) { isMessenger = Util.Chance(25); + var spawnCoordinate = Coordinate + Vector.Create(x: Util.Random(300, 600), y: Util.Random(300, 600)); glimmerSpawn = SpawnTimedAdd((isMessenger) ? 620 : 621+Util.Random(2), - (isMessenger) ? Util.Random(47, 53) : Util.Random(57, 63), - X + Util.Random(300, 600), Y + Util.Random(300, 600), 60, isMessenger); + (isMessenger) ? Util.Random(47, 53) : Util.Random(57, 63), spawnCoordinate, 60, isMessenger); // We got a messenger, tell it who its master is and which exit // to run to. @@ -84,7 +84,7 @@ public override bool CheckAddSpawns() /// 3 = SE, 4 = NE). /// /// Coordinates. - private Point3D GetExitCoordinates(int exitNo) + private Coordinate GetExitCoordinates(int exitNo) { // Get target coordinates (hardcoded). Yeah I know, this is // ugly, but to get this right NPC pathing is a must; as it @@ -93,11 +93,11 @@ private Point3D GetExitCoordinates(int exitNo) switch (exitNo) { - case 1: return new Point3D(407292, 704008, 0); - case 2: return new Point3D(406158, 707745, 0); - case 3: return new Point3D(410302, 708563, 0); - case 4: return new Point3D(411117, 704696, 0); - default: return SpawnPoint; + case 1: return Coordinate.Create(x: 407292, y: 704008 ); + case 2: return Coordinate.Create(x: 406158, y: 707745 ); + case 3: return Coordinate.Create(x: 410302, y: 708563 ); + case 4: return Coordinate.Create(x: 411117, y: 704696 ); + default: return SpawnPosition.Coordinate; } } @@ -113,7 +113,7 @@ public override void OnRetrieverArrived(GameNPC sender) // Spawn nasty adds. if (m_messengerList.Contains(sender)) - SpawnGlimmers(Util.Random(7, 10), sender.X, sender.Y); + SpawnGlimmers(Util.Random(7, 10), sender.Coordinate); } /// @@ -121,15 +121,13 @@ public override void OnRetrieverArrived(GameNPC sender) /// retriever has reported back from, then make these spawns aggro the /// raid inside the lair. /// - /// - /// - /// - private void SpawnGlimmers(int numAdds, int x, int y) + private void SpawnGlimmers(int numAdds, Coordinate coordinate) { GameNPC glimmer; for (int add = 0; add < numAdds; ++add) { - glimmer = SpawnTimedAdd(624+Util.Random(2), Util.Random(62, 68), x + Util.Random(250), y + Util.Random(250), 120, false); + var randomSpawnCoordinate = coordinate + Vector.Create(x: Util.Random(250), y: Util.Random(250)); + glimmer = SpawnTimedAdd(624+Util.Random(2), Util.Random(62, 68), randomSpawnCoordinate, 120, false); if (glimmer != null && glimmer.Brain is StandardMobBrain && this.Brain is DragonBrain) { diff --git a/GameServer/gameobjects/Dragons/GameDragon.cs b/GameServer/gameobjects/Dragons/GameDragon.cs index 396cc94dff..bd27d48729 100644 --- a/GameServer/gameobjects/Dragons/GameDragon.cs +++ b/GameServer/gameobjects/Dragons/GameDragon.cs @@ -27,7 +27,7 @@ using DOL.Events; using DOL.GS.ServerProperties; using DOL.AI.Brain; - +using DOL.GS.Geometry; namespace DOL.GS { @@ -94,7 +94,7 @@ public override void LoadFromDatabase(DataObject obj) String[] dragonName = Name.Split(new char[] { ' ' }); WorldMgr.GetRegion(CurrentRegionID).AddArea(new Area.Circle(String.Format("{0}'s Lair", dragonName[0]), - X, Y, 0, LairRadius + 200)); + Coordinate, LairRadius + 200)); } public override bool HasAbility(string keyName) @@ -375,16 +375,7 @@ public virtual bool CheckAddSpawns() private INpcTemplate m_addTemplate; - /// - /// Create an add from the specified template. - /// - /// - /// - /// - /// - /// - /// - protected GameNPC SpawnTimedAdd(int templateID, int level, int x, int y, int uptime, bool isRetriever) + protected GameNPC SpawnTimedAdd(int templateID, int level, Coordinate coordinate, int uptime, bool isRetriever) { GameNPC add = null; @@ -406,12 +397,8 @@ protected GameNPC SpawnTimedAdd(int templateID, int level, int x, int y, int upt { add.SetOwnBrain(new RetrieverMobBrain()); } - add.CurrentRegion = this.CurrentRegion; - add.Heading = (ushort)(Util.Random(0, 4095)); add.Realm = 0; - add.X = x; - add.Y = y; - add.Z = Z; + add.Position = Position.Create(CurrentRegion.ID, coordinate, Angle.Heading(Util.Random(0, 4095))); add.CurrentSpeed = 0; add.Level = (byte)level; add.RespawnInterval = -1; @@ -617,7 +604,7 @@ private int CastGlare(RegionTimer timer) GameObject oldTarget = TargetObject; TargetObject = GlareTarget; - Z = SpawnPoint.Z; // this is a fix to correct Z errors that sometimes happen during dragon fights + Position = Position.With(z: SpawnPosition.Z); // this is a fix to correct Z errors that sometimes happen during dragon fights TurnTo(GlareTarget); CastSpell(Glare, SkillBase.GetSpellLine(GlobalSpellsLines.Mob_Spells)); GlareTarget = null; @@ -765,38 +752,21 @@ private void ThrowLiving(GameLiving target) TurnTo(target); - Point3D targetPosition = PositionOfTarget(target, 700, Heading, Util.Random(300, 500) ); + var throwPosition = GetThrowPosition(target, 700, Orientation, Util.Random(300, 500) ); if (target is GamePlayer) { - target.MoveTo(target.CurrentRegionID, targetPosition.X, targetPosition.Y, targetPosition.Z, target.Heading); + target.MoveTo(throwPosition); } else if (target is GameNPC) { - (target as GameNPC).MoveInRegion(target.CurrentRegionID, targetPosition.X, targetPosition.Y, targetPosition.Z, target.Heading, true); + (target as GameNPC).MoveWithoutRemovingFromWorld(throwPosition, true); target.ChangeHealth(this, eHealthChangeType.Spell, (int)(target.Health * -0.35)); } } - /// - /// Calculate the target position with given height and displacement. - /// - /// Current object X position. - /// Current object Y position. - /// Current object Z position. - /// Height the object is to be lifted to. - /// The direction the object is displaced in. - /// The amount the object is displaced by. - /// - private Point3D PositionOfTarget( IPoint3D target, int height, int heading, int displacement) - { - Point3D targetPoint; - - targetPoint = new Point3D( target.GetPointFromHeading( (ushort)heading, displacement ), target.Z + height ); - - return targetPoint; - } - + private Position GetThrowPosition(GameObject target, int height, Angle orientation, int distance) + => target.Position + Vector.Create(orientation, distance) + Vector.Create(z: height); #endregion #region Stun diff --git a/GameServer/gameobjects/Dragons/Gjalpinulva.cs b/GameServer/gameobjects/Dragons/Gjalpinulva.cs index 238aa58dd7..51b4af2d2c 100644 --- a/GameServer/gameobjects/Dragons/Gjalpinulva.cs +++ b/GameServer/gameobjects/Dragons/Gjalpinulva.cs @@ -24,7 +24,7 @@ using System.Reflection; using System.Collections; using DOL.AI.Brain; - +using DOL.GS.Geometry; namespace DOL.GS { @@ -61,9 +61,8 @@ public override bool CheckAddSpawns() for (int dog = 1; dog <= 10; ++dog) { isRetriever = Util.Chance(25); - dogSpawn = SpawnTimedAdd((isRetriever) ? 610 : 611, - (isRetriever) ? Util.Random(47, 53) : 37, - X + Util.Random(300, 600), Y + Util.Random(300, 600), 60, isRetriever); + var spawnCoordinate = Coordinate + Vector.Create(x: Util.Random(300, 600), y: Util.Random(300, 600)); + dogSpawn = SpawnTimedAdd((isRetriever) ? 610 : 611, (isRetriever) ? Util.Random(47, 53) : 37, spawnCoordinate, 60, isRetriever); // We got a retriever, tell it who its master is and which exit // to run to. @@ -86,7 +85,7 @@ public override bool CheckAddSpawns() /// 3 = SE, 4 = NE). /// /// Coordinates. - private Point3D GetExitCoordinates(int exitNo) + private Coordinate GetExitCoordinates(int exitNo) { // Get target coordinates (hardcoded). Yeah I know, this is // ugly, but to get this right NPC pathing is a must; as it @@ -95,11 +94,11 @@ private Point3D GetExitCoordinates(int exitNo) switch (exitNo) { - case 1: return new Point3D(707026, 1019564, 0); - case 2: return new Point3D(706924, 1023596, 0); - case 3: return new Point3D(711441, 1023175, 0); - case 4: return new Point3D(710708, 1018894, 0); - default: return SpawnPoint; + case 1: return Coordinate.Create(x: 707026, y: 1019564 ); + case 2: return Coordinate.Create(x: 706924, y: 1023596 ); + case 3: return Coordinate.Create(x: 711441, y: 1023175 ); + case 4: return Coordinate.Create(x: 710708, y: 1018894 ); + default: return SpawnPosition.Coordinate; } } @@ -115,7 +114,7 @@ public override void OnRetrieverArrived(GameNPC sender) // Spawn nasty adds. if (m_retrieverList.Contains(sender)) - SpawnDrakulvs(Util.Random(7, 10), sender.X, sender.Y); + SpawnDrakulvs(Util.Random(7, 10), sender.Coordinate); } /// @@ -126,14 +125,15 @@ public override void OnRetrieverArrived(GameNPC sender) /// /// /// - private void SpawnDrakulvs(int numAdds, int x, int y) + private void SpawnDrakulvs(int numAdds, Coordinate coordinate) { GameNPC drakulv; bool isDisciple = false; for (int add = 0; add < numAdds; ++add) { isDisciple = Util.Chance(25); - drakulv = SpawnTimedAdd((isDisciple) ? 613 : 612, Util.Random(62, 68), x + Util.Random(250), y + Util.Random(250), 120, false); + var randomCoordinate = coordinate + Vector.Create(x: Util.Random(250), y: Util.Random(250)); + drakulv = SpawnTimedAdd((isDisciple) ? 613 : 612, Util.Random(62, 68), randomCoordinate, 120, false); if (drakulv != null && drakulv.Brain is StandardMobBrain && this.Brain is DragonBrain) { diff --git a/GameServer/gameobjects/Dragons/Golestandt.cs b/GameServer/gameobjects/Dragons/Golestandt.cs index aabd7be0ce..8ede1590bd 100644 --- a/GameServer/gameobjects/Dragons/Golestandt.cs +++ b/GameServer/gameobjects/Dragons/Golestandt.cs @@ -24,7 +24,7 @@ using log4net; using System.Reflection; using System.Collections; - +using DOL.GS.Geometry; namespace DOL.GS { @@ -50,7 +50,8 @@ public override bool CheckAddSpawns() int numAdds = Math.Max(1, PlayersInLair / 2); for (int add = 1; add <= numAdds; ++add) { - SpawnTimedAdd(600, Util.Random(57, 60), X + Util.Random(300, 600), Y + Util.Random(300, 600), 30, false); // granite giant pounder lvl 57-60 + var spawnCoordinate = Coordinate + Vector.Create(x: Util.Random(300, 600), y: Util.Random(300, 600)); + SpawnTimedAdd(600, Util.Random(57, 60), spawnCoordinate, 30, false); // granite giant pounder lvl 57-60 } return true; } diff --git a/GameServer/gameobjects/GameDoor.cs b/GameServer/gameobjects/GameDoor.cs index 5775b7503e..7e4195200a 100644 --- a/GameServer/gameobjects/GameDoor.cs +++ b/GameServer/gameobjects/GameDoor.cs @@ -20,21 +20,8 @@ using DOL.Database; using DOL.GS.PacketHandler; using DOL.Language; -using System.Collections; -using System.Collections.Generic; -using System.Reflection; -using DOL.GS.Utils; -using DOL.GS.Quests; using System.Threading; -using DOL.AI.Brain; -using DOL.Events; -using DOL.GS.Effects; -using DOL.GS.Keeps; -using DOL.GS.PropertyCalc; -using DOL.GS.SkillHandler; -using DOL.GS.Spells; -using DOL.GS.Styles; -using DOL.GS.PacketHandler.Client.v168; +using DOL.GS.Geometry; namespace DOL.GS { @@ -45,7 +32,6 @@ public class GameDoor : GameLiving, IDoor { private bool m_openDead = false; private static Timer m_timer; - protected volatile uint m_lastUpdateTickCount = uint.MinValue; private readonly object m_LockObject = new object(); private uint m_flags = 0; @@ -83,10 +69,7 @@ public override void LoadFromDatabase(DataObject obj) if (curZone == null) return; this.CurrentRegion = curZone.ZoneRegion; m_name = m_dbdoor.Name; - m_Heading = (ushort)m_dbdoor.Heading; - m_x = m_dbdoor.X; - m_y = m_dbdoor.Y; - m_z = m_dbdoor.Z; + Position = Position.Create(regionID: CurrentRegion.ID, x: m_dbdoor.X, y: m_dbdoor.Y, z: m_dbdoor.Z, heading: (ushort)m_dbdoor.Heading ); m_level = 0; m_model = 0xFFFF; m_doorID = m_dbdoor.InternalID; @@ -263,7 +246,7 @@ public virtual void Close(GameLiving closer = null) /// public virtual void NPCManipulateDoorRequest(GameNPC npc, bool open) { - npc.TurnTo(this.X, this.Y); + npc.TurnTo(Coordinate); if (open && m_state != eDoorState.Open) this.Open(); else if (!open && m_state != eDoorState.Closed) @@ -320,16 +303,6 @@ public override void Die(GameObject killer) base.Die(killer); StartHealthRegeneration(); } - - /// - /// Broadcasts the Door Update to all players around - /// - public override void BroadcastUpdate() - { - base.BroadcastUpdate(); - - m_lastUpdateTickCount = (uint)Environment.TickCount; - } private static long m_healthregentimer = 0; diff --git a/GameServer/gameobjects/GameGravestone.cs b/GameServer/gameobjects/GameGravestone.cs index db3ed821ef..39b45548cf 100644 --- a/GameServer/gameobjects/GameGravestone.cs +++ b/GameServer/gameobjects/GameGravestone.cs @@ -16,11 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ -using System; - -using DOL.Database; +using DOL.GS.Geometry; using DOL.Language; -using DOL.GS.PacketHandler; namespace DOL.GS { @@ -44,11 +41,7 @@ public GameGravestone(GamePlayer player, long xpValue):base() //the same startingspots when we restart! m_saveInDB = false; m_name = LanguageMgr.GetTranslation(player.Client.Account.Language, "GameGravestone.GameGravestone.Grave", player.Name); - m_Heading = player.Heading; - m_x = player.X; - m_y = player.Y; - m_z = player.Z; - CurrentRegionID = player.CurrentRegionID; + Position = player.Position; m_level = 0; if (player.Realm == eRealm.Albion) diff --git a/GameServer/gameobjects/GameHouseVault.cs b/GameServer/gameobjects/GameHouseVault.cs index 3c4a4d0b41..8970f353d4 100644 --- a/GameServer/gameobjects/GameHouseVault.cs +++ b/GameServer/gameobjects/GameHouseVault.cs @@ -20,6 +20,7 @@ using System.Collections; using System.Collections.Generic; using DOL.Database; +using DOL.GS.Geometry; using DOL.GS.Housing; namespace DOL.GS @@ -112,17 +113,12 @@ public bool Attach(House house, DBHouseHookpointItem hookedItem) _hookedItem = hookedItem; - IPoint3D position = house.GetHookpointLocation(hookedItem.HookpointID); - if (position == null) - return false; + var coordinate = house.GetHookPointCoordinate(hookedItem.HookpointID); + if (coordinate == Coordinate.Nowhere) return false; CurrentHouse = house; - CurrentRegionID = house.RegionID; InHouse = true; - X = position.X; - Y = position.Y; - Z = position.Z; - Heading = (ushort) (hookedItem.Heading%4096); + Position = Position.Create(house.RegionID, coordinate, hookedItem.Heading); AddToWorld(); return true; diff --git a/GameServer/gameobjects/GameInventoryItem.cs b/GameServer/gameobjects/GameInventoryItem.cs index 1bd35e484a..2fedea084f 100644 --- a/GameServer/gameobjects/GameInventoryItem.cs +++ b/GameServer/gameobjects/GameInventoryItem.cs @@ -26,6 +26,7 @@ using DOL.GS.Spells; using log4net; +using DOL.GS.Geometry; namespace DOL.GS { @@ -229,12 +230,8 @@ public virtual WorldInventoryItem Drop(GamePlayer player) { WorldInventoryItem worldItem = new WorldInventoryItem(this); - Point2D itemloc = player.GetPointFromHeading(player.Heading, 30); - worldItem.X = itemloc.X; - worldItem.Y = itemloc.Y; - worldItem.Z = player.Z; - worldItem.Heading = player.Heading; - worldItem.CurrentRegionID = player.CurrentRegionID; + var itemPosition = player.Position + Vector.Create(player.Orientation, length: 30); + worldItem.Position = itemPosition; worldItem.AddOwner(player); worldItem.AddToWorld(); diff --git a/GameServer/gameobjects/GameLiving.cs b/GameServer/gameobjects/GameLiving.cs index e054d56830..9a9811c1c2 100644 --- a/GameServer/gameobjects/GameLiving.cs +++ b/GameServer/gameobjects/GameLiving.cs @@ -35,6 +35,7 @@ using DOL.GS.Styles; using DOL.Language; using DOL.GS.RealmAbilities; +using DOL.GS.Geometry; namespace DOL.GS { @@ -1963,8 +1964,8 @@ protected virtual AttackData MakeAttack(GameObject target, InventoryItem weapon, bool preCheck = false; if (ad.Target is GamePlayer) //only start if we are behind the player { - float angle = ad.Target.GetAngle( ad.Attacker ); - if (angle >= 150 && angle < 210) preCheck = true; + var angle = ad.Target.GetAngleTo(ad.Attacker.Coordinate); + if (angle.InDegrees >= 150 && angle.InDegrees < 210) preCheck = true; } else preCheck = true; @@ -5606,25 +5607,6 @@ public void CancelAllConcentrationEffects(bool leaveSelf) /// The base maximum speed of this living /// protected short m_maxSpeedBase; - /// - /// Holds the Living's Coordinate inside the current Region - /// - protected Point3D m_groundTarget; - - /// - /// Gets the current direction the Object is facing - /// - public override ushort Heading - { - get { return base.Heading; } - set - { - ushort oldHeading = base.Heading; - base.Heading = value; - if (base.Heading != oldHeading) - UpdateTickSpeed(); - } - } private bool m_fixedSpeed = false; @@ -5637,21 +5619,11 @@ public virtual bool FixedSpeed set { m_fixedSpeed = value; } } - /// - /// Gets or sets the current speed of this living - /// - public virtual short CurrentSpeed - { - get - { - return m_currentSpeed; - } - set - { - m_currentSpeed = value; - UpdateTickSpeed(); - } - } + public virtual short CurrentSpeed + { + get => Motion.Speed; + set => Motion = Geometry.Motion.Create(Position, Motion.Destination, value); + } /// /// Gets the maxspeed of this living @@ -5690,28 +5662,25 @@ public virtual GameObject TargetObject m_targetObjectWeakReference.Target = value; } } + + public virtual void TurnTo(Coordinate coordinate, bool sendUpdate = true) + => Orientation = Coordinate.GetOrientationTo(coordinate); + public virtual bool IsSitting { get { return false; } set { } } - /// - /// Gets the Living's ground-target Coordinate inside the current Region - /// - public virtual Point3D GroundTarget - { - get { return m_groundTarget; } - } - /// - /// Sets the Living's ground-target Coordinates inside the current Region - /// - public virtual void SetGroundTarget(int groundX, int groundY, int groundZ) - { - m_groundTarget.X = groundX; - m_groundTarget.Y = groundY; - m_groundTarget.Z = groundZ; - } + [Obsolete("Use GroundTargetPosition instead!")] + public virtual Point3D GroundTarget + => GroundTargetPosition.Coordinate.ToPoint3D(); + + [Obsolete("Use GroundTargetPosition_set instead!")] + public virtual void SetGroundTarget(int groundX, int groundY, int groundZ) + => GroundTargetPosition = Position.Create(Position.RegionID, groundX, groundY, groundZ); + + public virtual Position GroundTargetPosition { get; set; } = Position.Nowhere; /// /// Gets or Sets the current level of the Object @@ -5753,39 +5722,6 @@ public virtual int CalculateSkillLevel(Skill skill) #endregion #region Movement - /// - /// The tick speed in X direction. - /// - public double TickSpeedX { get; protected set; } - - /// - /// The tick speed in Y direction. - /// - public double TickSpeedY { get; protected set; } - - /// - /// The tick speed in Z direction. - /// - public double TickSpeedZ { get; protected set; } - - /// - /// Updates tick speed for this living. - /// - protected virtual void UpdateTickSpeed() - { - int speed = CurrentSpeed; - - if (speed == 0) - SetTickSpeed(0, 0, 0); - else - { - // Living will move in the direction it is currently heading. - - double heading = Heading * HEADING_TO_RADIAN; - SetTickSpeed(-Math.Sin(heading), Math.Cos(heading), 0, speed); - } - } - public virtual void UpdateHealthManaEndu() { if (IsAlive) @@ -5801,121 +5737,48 @@ public virtual void UpdateHealthManaEndu() } } - /// - /// Set the tick speed, that is the distance covered in one tick. - /// - /// - /// - /// - protected void SetTickSpeed(double dx, double dy, double dz) - { - TickSpeedX = dx; - TickSpeedY = dy; - TickSpeedZ = dz; - } - - /// - /// Set the tick speed, that is the distance covered in one tick. - /// - /// - /// - /// - /// - protected void SetTickSpeed(double dx, double dy, double dz, int speed) - { - double tickSpeed = speed * 0.001; - SetTickSpeed(dx * tickSpeed, dy * tickSpeed, dz * tickSpeed); - } + public int MovementStartTick + => Motion.StartTimeInMilliSeconds; - /// - /// The tick at which the movement started. - /// - public int MovementStartTick { get; set; } + public virtual bool IsMoving => CurrentSpeed != 0; - /// - /// Elapsed ticks since movement started. - /// - protected int MovementElapsedTicks - { - get { return Environment.TickCount - MovementStartTick; } - } + public override Position Position + { + get => Motion.CurrentPosition; + set => Motion = Motion.Create(value, Motion.Destination, Motion.Speed); + } - /// - /// True if the living is moving, else false. - /// - public virtual bool IsMoving - { - get { return m_currentSpeed != 0; } - } + protected virtual Motion Motion { get; set; } = new Motion(); - /// - /// The current X position of this living. - /// - public override int X - { - get - { - return (IsMoving) - ? (int)(base.X + MovementElapsedTicks * TickSpeedX) - : base.X; - } - set - { - base.X = value; - } - } + [Obsolete("Use .Position.X instead!")] + public override int X + { + set => Position = Motion.Start.With(x: value); + } - /// - /// The current Y position of this living. - /// - public override int Y - { - get - { - return (IsMoving) - ? (int)(base.Y + MovementElapsedTicks * TickSpeedY) - : base.Y; - } - set - { - base.Y = value; - } - } + [Obsolete("Use .Position.Y instead!")] + public override int Y + { + set => Position = Motion.Start.With(y: value); + } - /// - /// The current Z position of this living. - /// - public override int Z - { - get - { - return (IsMoving) - ? (int)(base.Z + MovementElapsedTicks * TickSpeedZ) - : base.Z; - } - set - { - base.Z = value; - } - } + [Obsolete("Use .Position.Z instead!")] + public override int Z + { + set => Position = Motion.Start.With(z: value); + } - /// - /// Moves the item from one spot to another spot, possible even - /// over region boundaries - /// - /// new regionid - /// new x - /// new y - /// new z - /// new heading - /// true if moved - public override bool MoveTo(ushort regionID, int x, int y, int z, ushort heading) - { - if (regionID != CurrentRegionID) - CancelAllConcentrationEffects(); + public override Angle Orientation + { + get => Position.Orientation; + set => Position = Motion.Start.With(orientation: value); + } - return base.MoveTo(regionID, x, y, z, heading); - } + public override bool MoveTo(Position position) + { + if (position.RegionID != CurrentRegionID) CancelAllConcentrationEffects(); + return base.MoveTo(position); + } #endregion #region Stealth /// @@ -6976,7 +6839,6 @@ public GameLiving() { m_guildName = string.Empty; m_targetObjectWeakReference = new WeakRef(null); - m_groundTarget = new Point3D(0, 0, 0); //Set all combat properties m_activeWeaponSlot = eActiveWeaponSlot.Standard; diff --git a/GameServer/gameobjects/GameMerchant.cs b/GameServer/gameobjects/GameMerchant.cs index 465eefa1e5..c57b975668 100644 --- a/GameServer/gameobjects/GameMerchant.cs +++ b/GameServer/gameobjects/GameMerchant.cs @@ -292,12 +292,12 @@ public override void SaveIntoDatabase() merchant.Name = Name; merchant.Guild = GuildName; - merchant.X = X; - merchant.Y = Y; - merchant.Z = Z; - merchant.Heading = Heading; + merchant.X = Position.X; + merchant.Y = Position.Y; + merchant.Z = Position.Z; + merchant.Heading = Orientation.InHeading; + merchant.Region = Position.RegionID; merchant.Speed = MaxSpeedBase; - merchant.Region = CurrentRegionID; merchant.Realm = (byte)Realm; merchant.RoamingRange = RoamingRange; merchant.Model = Model; diff --git a/GameServer/gameobjects/GameMoney.cs b/GameServer/gameobjects/GameMoney.cs index 5d2283977a..bc2f965654 100644 --- a/GameServer/gameobjects/GameMoney.cs +++ b/GameServer/gameobjects/GameMoney.cs @@ -23,9 +23,6 @@ namespace DOL.GS { - /// - /// Zusammenfassung für GameLoot. - /// public class GameMoney: GameStaticItemTimed { /// @@ -71,11 +68,7 @@ public static bool IsItemMoney(string name) { /// the gameobject that dropped this bag public GameMoney(long copperValue, GameObject dropper):this(copperValue) { - X=dropper.X; - Y=dropper.Y; - Z=dropper.Z; - Heading = dropper.Heading; - CurrentRegion = dropper.CurrentRegion; + Position = dropper.Position; } /// /// Returns the number of mithril pieces in this bag diff --git a/GameServer/gameobjects/GameNPC.cs b/GameServer/gameobjects/GameNPC.cs index c5391f757f..7d1aa034d8 100644 --- a/GameServer/gameobjects/GameNPC.cs +++ b/GameServer/gameobjects/GameNPC.cs @@ -26,21 +26,17 @@ using DOL.AI.Brain; using DOL.Database; using DOL.Events; -using DOL.GS; using DOL.GS.Effects; using DOL.GS.Housing; -using DOL.GS.Keeps; using DOL.GS.Movement; using DOL.GS.PacketHandler; using DOL.GS.Quests; using DOL.GS.Spells; using DOL.GS.Styles; -using DOL.GS.Utils; using DOL.Language; using DOL.GS.ServerProperties; using DOL.GS.Finance; -using System.Threading.Tasks; -using System.Numerics; +using DOL.GS.Geometry; namespace DOL.GS { @@ -177,20 +173,14 @@ public override ushort Model } } - /// - /// Gets or sets the heading of this NPC - /// - public override ushort Heading + public override Angle Orientation { - get { return base.Heading; } + get { return base.Orientation; } set { if (IsTurningDisabled) return; - ushort oldHeading = base.Heading; - base.Heading = value; - if (base.Heading != oldHeading) - BroadcastUpdate(); + base.Orientation = value; } } @@ -703,14 +693,6 @@ public enum eFlags : uint /// Holds various flags of this npc /// protected eFlags m_flags; - /// - /// Spawn point - /// - protected Point3D m_spawnPoint; - /// - /// Spawn Heading - /// - protected ushort m_spawnHeading; /// @@ -724,10 +706,6 @@ public string PackageID set { m_packageID = value; } } - /// - /// The last time this NPC sent the 0x09 update packet - /// - protected volatile uint m_lastUpdateTickCount = uint.MinValue; /// /// The last time this NPC was actually updated to at least one player /// @@ -798,68 +776,35 @@ public virtual bool IsVisibleToPlayers get { return (uint)Environment.TickCount - m_lastVisibleToPlayerTick < 60000; } } - /// - /// Gets or sets the spawnposition of this npc - /// - public virtual Point3D SpawnPoint - { - get { return m_spawnPoint; } - set { m_spawnPoint = value; } - } + public Position SpawnPosition { get; set; } = Position.Nowhere; - /// - /// Gets or sets the spawnposition of this npc - /// - [Obsolete("Use GameNPC.SpawnPoint")] - public virtual int SpawnX - { - get { return m_spawnPoint.X; } - set { m_spawnPoint.X = value; } - } - /// - /// Gets or sets the spawnposition of this npc - /// - [Obsolete("Use GameNPC.SpawnPoint")] - public virtual int SpawnY - { - get { return m_spawnPoint.Y; } - set { m_spawnPoint.Y = value; } - } - /// - /// Gets or sets the spawnposition of this npc - /// - [Obsolete("Use GameNPC.SpawnPoint")] - public virtual int SpawnZ - { - get { return m_spawnPoint.Z; } - set { m_spawnPoint.Z = value; } - } + [Obsolete("Use SpawnPosition instead!")] + public Point3D SpawnPoint + { + get => SpawnPosition.Coordinate.ToPoint3D(); + set => SpawnPosition = Position.Create(CurrentRegionID, value.ToCoordinate(), SpawnPosition.Orientation.InHeading); + } - /// - /// Gets or sets the spawnheading of this npc - /// - public virtual ushort SpawnHeading - { - get { return m_spawnHeading; } - set { m_spawnHeading = value; } - } + [Obsolete("Use SpawnPosition.Heading instead!")] + public ushort SpawnHeading + { + get => SpawnPosition.Orientation.InHeading; + private set => SpawnPosition = Position.With(Angle.Heading(value)); + } - /// - /// Gets or sets the current speed of the npc - /// - public override short CurrentSpeed - { - set - { - SaveCurrentPosition(); + public short ZSpeedFactor + => (short)((Motion.Destination.Z - Motion.Start.Z) / Motion.FullDistance); - if (base.CurrentSpeed != value) - { - base.CurrentSpeed = value; - BroadcastUpdate(); - } - } - } + protected override Motion Motion + { + set + { + base.Motion = value; + BroadcastUpdate(); + } + } + + public Coordinate Destination => Motion.Destination; /// /// Stores the currentwaypoint that npc has to wander to @@ -879,91 +824,6 @@ public short PathingNormalSpeed /// protected short m_pathingNormalSpeed; - /// - /// Gets the current X of this living. Don't modify this property - /// to try to change position of the mob while active. Use the - /// MoveTo function instead - /// - public override int X - { - get - { - if (!IsMoving) - return base.X; - - if (TargetPosition.X != 0 || TargetPosition.Y != 0 || TargetPosition.Z != 0) - { - long expectedDistance = FastMath.Abs((long)TargetPosition.X - m_x); - - if (expectedDistance == 0) - return TargetPosition.X; - - long actualDistance = FastMath.Abs((long)(MovementElapsedTicks * TickSpeedX)); - - if (expectedDistance - actualDistance < 0) - return TargetPosition.X; - } - - return base.X; - } - } - - /// - /// Gets the current Y of this NPC. Don't modify this property - /// to try to change position of the mob while active. Use the - /// MoveTo function instead - /// - public override int Y - { - get - { - if (!IsMoving) - return base.Y; - - if (TargetPosition.X != 0 || TargetPosition.Y != 0 || TargetPosition.Z != 0) - { - long expectedDistance = FastMath.Abs((long)TargetPosition.Y - m_y); - - if (expectedDistance == 0) - return TargetPosition.Y; - - long actualDistance = FastMath.Abs((long)(MovementElapsedTicks * TickSpeedY)); - - if (expectedDistance - actualDistance < 0) - return TargetPosition.Y; - } - return base.Y; - } - } - - /// - /// Gets the current Z of this NPC. Don't modify this property - /// to try to change position of the mob while active. Use the - /// MoveTo function instead - /// - public override int Z - { - get - { - if (!IsMoving) - return base.Z; - - if (TargetPosition.X != 0 || TargetPosition.Y != 0 || TargetPosition.Z != 0) - { - long expectedDistance = FastMath.Abs((long)TargetPosition.Z - m_z); - - if (expectedDistance == 0) - return TargetPosition.Z; - - long actualDistance = FastMath.Abs((long)(MovementElapsedTicks * TickSpeedZ)); - - if (expectedDistance - actualDistance < 0) - return TargetPosition.Z; - } - return base.Z; - } - } - protected int m_maxdistance; /// /// The Mob's max distance from its spawn before return automatically @@ -1011,7 +871,7 @@ public bool IsOutOfTetherRange { if (TetherRange > 0) { - if (this.IsWithinRadius(this.SpawnPoint, TetherRange)) + if (Coordinate.DistanceTo(SpawnPosition) <= TetherRange) return false; else return true; @@ -1088,25 +948,6 @@ public string PathID set { m_pathID = value; } } - private IPoint3D m_targetPosition = new Point3D(0, 0, 0); - - /// - /// The target position. - /// - public virtual IPoint3D TargetPosition - { - get - { - return m_targetPosition; - } - - protected set - { - SaveCurrentPosition(); - m_targetPosition = value; - } - } - /// /// The target object. /// @@ -1129,102 +970,39 @@ public override GameObject TargetObject } } - /// - /// Updates the tick speed for this living. - /// - protected override void UpdateTickSpeed() - { - if (!IsMoving) - { - SetTickSpeed(0, 0, 0); - return; - } - - if (TargetPosition.X != 0 || TargetPosition.Y != 0 || TargetPosition.Z != 0) - { - double dist = this.GetDistanceTo(new Point3D(TargetPosition.X, TargetPosition.Y, TargetPosition.Z)); - - if (dist <= 0) - { - SetTickSpeed(0, 0, 0); - return; - } - - double dx = (double)(TargetPosition.X - m_x) / dist; - double dy = (double)(TargetPosition.Y - m_y) / dist; - double dz = (double)(TargetPosition.Z - m_z) / dist; - - SetTickSpeed(dx, dy, dz, CurrentSpeed); - return; - } - - base.UpdateTickSpeed(); - } - - /// - /// True if the mob is at its target position, else false. - /// - public bool IsAtTargetPosition - { - get - { - return (X == TargetPosition.X && Y == TargetPosition.Y && Z == TargetPosition.Z); - } - } + public bool IsAtTargetLocation + => Motion.Destination.Equals(Coordinate); - /// - /// Turns the npc towards a specific spot - /// - /// Target X - /// Target Y - public virtual void TurnTo(int tx, int ty) - { - TurnTo(tx, ty, true); - } + public override void TurnTo(Coordinate coordinate, bool sendUpdate = true) + { + if (IsStunned || IsMezzed) return; - /// - /// Turns the npc towards a specific spot - /// optionally sends update to client - /// - /// Target X - /// Target Y - public virtual void TurnTo(int tx, int ty, bool sendUpdate) - { - if (IsStunned || IsMezzed) return; + Notify(GameNPCEvent.TurnTo, this, new TurnToEventArgs(coordinate.X, coordinate.Y)); - Notify(GameNPCEvent.TurnTo, this, new TurnToEventArgs(tx, ty)); + if (sendUpdate) Orientation = Coordinate.GetOrientationTo(coordinate); + else base.Orientation = Coordinate.GetOrientationTo(coordinate); + } - if (sendUpdate) - Heading = GetHeading(new Point2D(tx, ty)); - else - base.Heading = GetHeading(new Point2D(tx, ty)); - } + [Obsolete("Use TurnTo(Coordinate[,bool]) instead.")] + public virtual void TurnTo(int tx, int ty, bool sendUpdate = true) + => TurnTo(Coordinate.Create(x: tx, y: ty ), sendUpdate); - /// - /// Turns the npc towards a specific heading - /// - /// the new heading - public virtual void TurnTo(ushort heading) - { - TurnTo(heading, true); - } + [Obsolete("Use .TurnTo(Angle[,bool]) instead!")] + public virtual void TurnTo(ushort heading, bool sendUpdate = true) + => TurnTo(Angle.Heading(heading), sendUpdate); - /// - /// Turns the npc towards a specific heading - /// optionally sends update to client - /// - /// the new heading - public virtual void TurnTo(ushort heading, bool sendUpdate) - { - if (IsStunned || IsMezzed) return; + public virtual void TurnTo(Angle newOrientation, bool sendUpdate = true) + { + if (IsStunned || IsMezzed) return; - Notify(GameNPCEvent.TurnToHeading, this, new TurnToHeadingEventArgs(heading)); + Notify(GameNPCEvent.TurnToHeading, this, new TurnToHeadingEventArgs(newOrientation.InHeading)); - if (sendUpdate) - if (Heading != heading) Heading = heading; - else - if (base.Heading != heading) base.Heading = heading; - } + if (sendUpdate) + { + if (Orientation != newOrientation) Orientation = newOrientation; + else if (base.Orientation != newOrientation) base.Orientation = newOrientation; + } + } /// /// Turns the NPC towards a specific gameObject @@ -1247,7 +1025,7 @@ public virtual void TurnTo(GameObject target, bool sendUpdate) if (target == null || target.CurrentRegion != CurrentRegion) return; - TurnTo(target.X, target.Y, sendUpdate); + TurnTo(target.Coordinate, sendUpdate); } /// @@ -1286,15 +1064,8 @@ public virtual void TurnTo(GameObject target, int duration) /// protected class RestoreHeadingAction : RegionAction { - /// - /// The NPCs old heading - /// - protected readonly ushort m_oldHeading; - - /// - /// The NPCs old position - /// - protected readonly Point3D m_oldPosition; + private readonly Angle oldOrientation; + protected readonly Coordinate m_oldPosition; /// /// Creates a new TurnBackAction @@ -1303,13 +1074,10 @@ protected class RestoreHeadingAction : RegionAction public RestoreHeadingAction(GameNPC actionSource) : base(actionSource) { - m_oldHeading = actionSource.Heading; - m_oldPosition = new Point3D(actionSource); + oldOrientation = actionSource.Orientation; + m_oldPosition = actionSource.Coordinate; } - /// - /// Called on every timer tick - /// protected override void OnTick() { GameNPC npc = (GameNPC)m_actionSource; @@ -1321,20 +1089,12 @@ protected override void OnTick() if (npc.AttackState) return; if (npc.IsMoving) return; if (npc.Equals(m_oldPosition)) return; - if (npc.Heading == m_oldHeading) return; // already set? oO + if (npc.Orientation == oldOrientation) return; // already set? oO - npc.TurnTo(m_oldHeading); + npc.TurnTo(oldOrientation); } } - /// - /// Gets the last time this mob was updated - /// - public uint LastUpdateTickCount - { - get { return m_lastUpdateTickCount; } - } - /// /// Gets the last this this NPC was actually update to at least one player. /// @@ -1393,101 +1153,62 @@ public virtual void CancelWalkToTimer() } } - /// - /// Ticks required to arrive at a given spot. - /// - /// - /// - /// + [Obsolete("This is going to be removed.")] public virtual int GetTicksToArriveAt(IPoint3D target, int speed) { - return GetDistanceTo(target) * 1000 / speed; + return (int)Coordinate.DistanceTo(target.ToCoordinate()) * 1000 / speed; } - /// - /// Make the current (calculated) position permanent. - /// - private void SaveCurrentPosition() - { - SavePosition(this); - } + /// + /// Make the current (calculated) position permanent. + /// + private void SaveCurrentPosition() + => Position = Position; - /// - /// Make the target position permanent. - /// - private void SavePosition(IPoint3D target) - { - X = target.X; - Y = target.Y; - Z = target.Z; + [Obsolete("Use .SaveCurrentPosition() instead!")] + private void SavePosition(IPoint3D target) + => Position = Position.Create(CurrentRegionID, target.ToCoordinate(), Orientation); - MovementStartTick = Environment.TickCount; - } + [Obsolete("Use WalkTo(Coordinate, short) instead!")] + public virtual void WalkTo(int targetX, int targetY, int targetZ, short speed) + => WalkTo(Coordinate.Create(x: targetX, y: targetY, z: targetZ ), speed); - /// - /// Walk to a certain spot at a given speed. - /// - /// - /// - /// - /// - public virtual void WalkTo(int targetX, int targetY, int targetZ, short speed) - { - WalkTo(new Point3D(targetX, targetY, targetZ), speed); - } + [Obsolete("Use WalkTo(Coordinate, short) instead!")] + public virtual void WalkTo(IPoint3D target, short speed) + => WalkTo(target.ToCoordinate(), speed); - /// - /// Walk to a certain spot at a given speed. - /// - /// - /// - public virtual void WalkTo(IPoint3D target, short speed) + public virtual void WalkTo(Coordinate destination, short speed) { - if (IsTurningDisabled) - return; + if (IsTurningDisabled) return; - if (speed > MaxSpeed) - speed = MaxSpeed; + if (speed > MaxSpeed) speed = MaxSpeed; - if (speed <= 0) - return; + if (speed <= 0) return; - TargetPosition = target; // this also saves the current position + Motion = Geometry.Motion.Create(Position, destination, speed); - if (IsWithinRadius(TargetPosition, CONST_WALKTOTOLERANCE)) + if ((int)Motion.RemainingDistance == 0) { - // No need to start walking. - Notify(GameNPCEvent.ArriveAtTarget, this); return; } CancelWalkToTimer(); - m_Heading = GetHeading(TargetPosition); - m_currentSpeed = speed; + var notifyDestination = TargetObject != null ? TargetObject.Coordinate : Coordinate.Nowhere; + Notify(GameNPCEvent.WalkTo, this, new WalkToEventArgs(notifyDestination, speed)); - UpdateTickSpeed(); - Notify(GameNPCEvent.WalkTo, this, new WalkToEventArgs(TargetPosition, speed)); - - StartArriveAtTargetAction(GetTicksToArriveAt(TargetPosition, speed)); - BroadcastUpdate(); + StartArriveAtTargetAction((int)(Motion.RemainingDistance * 1000 / speed)); } public PathCalculator PathCalculator { get; protected set; } - /// - /// Finds a valid path to the destination (or picks the direct path otherwise). Uses WalkTo for each of the pathing nodes. - /// - /// - /// - /// true if a path was found - public bool PathTo(IPoint3D dest, short? speed = null) - { - var walkSpeed = speed ?? MaxSpeed; - if (!PathCalculator.ShouldPath(this, new Vector3(dest.X, dest.Y, dest.Z))) + + public void PathTo(Coordinate destination, short speed) + { + if (!PathCalculator.ShouldPath(this, destination)) { - WalkTo(dest, walkSpeed); - return false; + WalkTo(destination, speed); + return; } // Initialize pathing if possible and required @@ -1495,40 +1216,35 @@ public bool PathTo(IPoint3D dest, short? speed = null) { if (!PathCalculator.IsSupported(this)) { - WalkTo(dest, walkSpeed); - return false; + WalkTo(destination, speed); + return; } // TODO: Only make this check once on spawn since it internally calls .CurrentZone + hashtable lookup? PathCalculator = new PathCalculator(this); } // Pick the next pathing node, and walk towards it - Vector3? nextNode = null; - bool didFindPath = false; - bool shouldUseAirPath = true; + var nextMotionTarget = Coordinate.Nowhere; + if (PathCalculator != null) { - var res = PathCalculator.CalculateNextTarget(new Vector3(dest.X, dest.Y, dest.Z)); - nextNode = res.Item1; - var noPathReason = res.Item2; - shouldUseAirPath = noPathReason == NoPathReason.RECAST_FOUND_NO_PATH; - didFindPath = PathCalculator.DidFindPath; + nextMotionTarget = PathCalculator.CalculateNextLineSegment(destination); } // Directly walk towards the target (or call the customly provided action) - if (!nextNode.HasValue) + if (nextMotionTarget.Equals(Coordinate.Nowhere)) { - WalkTo(dest, walkSpeed); - return false; + WalkTo(destination, speed); + return; } // Do the actual pathing bit: Walk towards the next pathing node - WalkTo(nextNode.Value, walkSpeed, npc => npc.PathTo(dest, speed)); - return true; + WalkTo(nextMotionTarget, speed, npc => npc.PathTo(destination, speed)); + return; } - private void WalkTo(Vector3 node, short speed, Action goToNextNodeCallback) - { + private void WalkTo(Coordinate destination, short speed, Action goToNextNodeCallback) + { if (IsTurningDisabled) return; @@ -1538,9 +1254,9 @@ private void WalkTo(Vector3 node, short speed, Action goToNextNodeCallb if (speed <= 0) return; - TargetPosition = new Point3D(node.X, node.Y, node.Z); // this also saves the current position + Motion = Geometry.Motion.Create(Position, destination,speed); - if (IsWithinRadius(TargetPosition, 5)) + if ((int)Motion.RemainingDistance == 0) { goToNextNodeCallback(this); return; @@ -1548,12 +1264,7 @@ private void WalkTo(Vector3 node, short speed, Action goToNextNodeCallb CancelWalkToTimer(); - m_Heading = GetHeading(TargetPosition); - m_currentSpeed = speed; - - UpdateTickSpeed(); - StartArriveAtTargetAction(GetTicksToArriveAt(TargetPosition, speed), goToNextNodeCallback); - BroadcastUpdate(); + StartArriveAtTargetAction((int)(Motion.RemainingDistance * 1000 / speed), goToNextNodeCallback); } @@ -1600,28 +1311,16 @@ public virtual void WalkToSpawn(short speed) IsReturningHome = true; IsReturningToSpawnPoint = true; - PathTo(SpawnPoint, speed); + PathTo(SpawnPosition.Coordinate, speed); } - /// - /// This function is used to start the mob walking. It will - /// walk in the heading direction until the StopMovement function - /// is called - /// - /// walk speed + [Obsolete("This is going to be removed.")] public virtual void Walk(short speed) { Notify(GameNPCEvent.Walk, this, new WalkEventArgs(speed)); CancelWalkToTimer(); - SaveCurrentPosition(); - TargetPosition.Clear(); - - m_currentSpeed = speed; - - MovementStartTick = Environment.TickCount; - UpdateTickSpeed(); - BroadcastUpdate(); + Motion = Geometry.Motion.Create(Position, Coordinate.Nowhere, speed); } /// @@ -1643,22 +1342,14 @@ public virtual void StopMoving() CurrentSpeed = 0; } - /// - /// Stops the movement of the mob and forcibly moves it to the - /// given target position. - /// + [Obsolete("This is going to be removed.")] public virtual void StopMovingAt(IPoint3D target) { CancelWalkToSpawn(); - if (IsMoving) - { - m_currentSpeed = 0; - UpdateTickSpeed(); - } + if (IsMoving) CurrentSpeed = 0; SavePosition(target); - BroadcastUpdate(); } public const int STICKMINIMUMRANGE = 100; @@ -1718,8 +1409,8 @@ public virtual void FollowTargetInRange() else if (m_attackers.Count == 0 && this.Spells.Count > 0 && this.TargetObject != null && GameServer.ServerRules.IsAllowedToAttack(this, (this.TargetObject as GameLiving), true)) { if (TargetObject.Realm == 0 || Realm == 0) - m_lastAttackTickPvE = m_CurrentRegion.Time; - else m_lastAttackTickPvP = m_CurrentRegion.Time; + m_lastAttackTickPvE = CurrentRegion.Time; + else m_lastAttackTickPvP = CurrentRegion.Time; if (this.CurrentRegion.Time - LastAttackedByEnemyTick > 10 * 1000) { // Aredhel: Erm, checking for spells in a follow method, what did we create @@ -1764,13 +1455,8 @@ protected virtual int FollowTimerCallback(RegionTimer callingTimer) } //Calculate the difference between our position and the players position - float diffx = (long)followTarget.X - X; - float diffy = (long)followTarget.Y - Y; - float diffz = (long)followTarget.Z - Z; - - //SH: Removed Z checks when one of the two Z values is zero(on ground) - //Tolakram: a Z of 0 does not indicate on the ground. Z varies based on terrain Removed 0 Z check - float distance = (float)Math.Sqrt(diffx * diffx + diffy * diffy + diffz * diffz); + var diffVec = followTarget.Coordinate - Coordinate; + var distance = diffVec.Length; //if distance is greater then the max follow distance, stop following and return home if ((int)distance > m_followMaxDist) @@ -1780,7 +1466,6 @@ protected virtual int FollowTimerCallback(RegionTimer callingTimer) this.WalkToSpawn(); return 0; } - int newX, newY, newZ; if (this.Brain is StandardMobBrain) { @@ -1806,12 +1491,10 @@ protected virtual int FollowTimerCallback(RegionTimer callingTimer) } //If we're part of a formation, we can get out early. - newX = followTarget.X; - newY = followTarget.Y; - newZ = followTarget.Z; - if (brain.CheckFormation(ref newX, ref newY, ref newZ)) + var formationCoordinate = brain.GetFormationCoordinate(followTarget.Coordinate); + if (formationCoordinate != Coordinate.Nowhere) { - WalkTo(newX, newY, (ushort)newZ, MaxSpeed); + WalkTo(formationCoordinate, MaxSpeed); return ServerProperties.Properties.GAMENPC_FOLLOWCHECK_TIME; } } @@ -1837,23 +1520,21 @@ protected virtual int FollowTimerCallback(RegionTimer callingTimer) } // follow on distance - diffx = (diffx / distance) * m_followMinDist; - diffy = (diffy / distance) * m_followMinDist; - diffz = (diffz / distance) * m_followMinDist; + var distanceFactor = m_followMinDist / distance; + var followOffset = diffVec * distanceFactor; //Subtract the offset from the target's position to get //our target position - newX = (int)(followTarget.X - diffx); - newY = (int)(followTarget.Y - diffy); - newZ = (int)(followTarget.Z - diffz); + var destination = followTarget.Coordinate - followOffset; if (InCombat || Brain is BomberBrain) { - PathTo(new Point3D(newX, newY, (ushort)newZ), MaxSpeed); + PathTo(destination, MaxSpeed); } else { - PathTo(new Point3D(newX, newY, (ushort)newZ), (short)GetDistance(new Point2D(newX, newY))); + var speed = (short)Coordinate.DistanceTo(destination, ignoreZ: true); + PathTo(destination, speed); } return ServerProperties.Properties.GAMENPC_FOLLOWCHECK_TIME; } @@ -1931,7 +1612,7 @@ public void MoveOnPath(short speed) PathingNormalSpeed = speed; - if (this.IsWithinRadius(CurrentWayPoint, 100)) + if (Coordinate.DistanceTo(CurrentWayPoint.Coordinate) < 100) { // reaching a waypoint can start an ambient sentence FireAmbientSentence(eAmbientTrigger.moving); @@ -1950,7 +1631,7 @@ public void MoveOnPath(short speed) if (CurrentWayPoint != null) { GameEventMgr.AddHandler(this, GameNPCEvent.ArriveAtTarget, new DOLEventHandler(OnArriveAtWaypoint)); - WalkTo(CurrentWayPoint, Math.Min(speed, (short)CurrentWayPoint.MaxSpeed)); + WalkTo(CurrentWayPoint.Coordinate, Math.Min(speed, (short)CurrentWayPoint.MaxSpeed)); m_IsMovingOnPath = true; Notify(GameNPCEvent.PathMoveStarts, this); } @@ -2052,7 +1733,7 @@ protected override void OnTick() if (npc.CurrentWayPoint != null) { - npc.WalkTo(npc.CurrentWayPoint, (short)Math.Min(npc.PathingNormalSpeed, npc.CurrentWayPoint.MaxSpeed)); + npc.WalkTo(npc.CurrentWayPoint.Coordinate, (short)Math.Min(npc.PathingNormalSpeed, npc.CurrentWayPoint.MaxSpeed)); } else { @@ -2145,13 +1826,8 @@ public override void LoadFromDatabase(DataObject obj) GuildName = dbMob.Guild; ExamineArticle = dbMob.ExamineArticle; MessageArticle = dbMob.MessageArticle; - m_x = dbMob.X; - m_y = dbMob.Y; - m_z = dbMob.Z; - m_Heading = (ushort)(dbMob.Heading & 0xFFF); + Position = Position.Create(regionID: dbMob.Region, x: dbMob.X, y: dbMob.Y, z: dbMob.Z, heading: (ushort)(dbMob.Heading & 0xFFF) ); m_maxSpeedBase = (short)dbMob.Speed; - m_currentSpeed = 0; - CurrentRegionID = dbMob.Region; Realm = (eRealm)dbMob.Realm; Model = dbMob.Model; Size = dbMob.Size; @@ -2324,12 +2000,12 @@ public override void SaveIntoDatabase() mob.Guild = GuildName; mob.ExamineArticle = ExamineArticle; mob.MessageArticle = MessageArticle; - mob.X = X; - mob.Y = Y; - mob.Z = Z; - mob.Heading = Heading; + mob.X = Position.X; + mob.Y = Position.Y; + mob.Z = Position.Z; + mob.Heading = Orientation.InHeading; mob.Speed = MaxSpeedBase; - mob.Region = CurrentRegionID; + mob.Region = Position.RegionID; mob.Realm = (byte)Realm; mob.Model = Model; mob.Size = Size; @@ -2967,7 +2643,7 @@ public virtual bool RiderMount(GamePlayer rider, bool forced) if (exists != -1) return false; - rider.MoveTo(CurrentRegionID, X, Y, Z, Heading); + rider.MoveTo(Position); Notify(GameNPCEvent.RiderMount, this, new RiderMountEventArgs(rider, this)); int slot = GetFreeArrayLocation(); @@ -3119,17 +2795,6 @@ public GamePlayer[] CurrentRiders #endregion #region Add/Remove/Create/Remove/Update - - /// - /// Broadcasts the NPC Update to all players around - /// - public override void BroadcastUpdate() - { - base.BroadcastUpdate(); - - m_lastUpdateTickCount = (uint)Environment.TickCount; - } - /// /// callback that npc was updated to the world /// so it must be visible to at least one player @@ -3169,10 +2834,8 @@ public override bool AddToWorld() if (anyPlayer) m_lastVisibleToPlayerTick = (uint)Environment.TickCount; - m_spawnPoint.X = X; - m_spawnPoint.Y = Y; - m_spawnPoint.Z = Z; - m_spawnHeading = Heading; + + SpawnPosition = Position; lock (BrainSync) { ABrain brain = Brain; @@ -3232,10 +2895,7 @@ public override bool AddToWorld() m_teleporterIndicator.Flags ^= eFlags.CANTTARGET; m_teleporterIndicator.Flags ^= eFlags.DONTSHOWNAME; m_teleporterIndicator.Flags ^= eFlags.FLYING; - m_teleporterIndicator.X = X; - m_teleporterIndicator.Y = Y; - m_teleporterIndicator.Z = Z + 1; - m_teleporterIndicator.CurrentRegionID = CurrentRegionID; + m_teleporterIndicator.Position = Position + Vector.Create(z: 1); } m_teleporterIndicator.AddToWorld(); @@ -3263,10 +2923,7 @@ public virtual bool Spawn() Health = MaxHealth; Mana = MaxMana; Endurance = MaxEndurance; - X = SpawnPoint.X; - Y = SpawnPoint.Y; - Z = SpawnPoint.Z; - Heading = SpawnHeading; + Position = SpawnPosition; return AddToWorld(); } @@ -3320,23 +2977,17 @@ public override bool RemoveFromWorld() return true; } - /// - /// Move an NPC within the same region without removing from world - /// - /// - /// - /// - /// - /// - /// Move regardless of combat check - /// true if npc was moved - public virtual bool MoveInRegion(ushort regionID, int x, int y, int z, ushort heading, bool forceMove) - { + [Obsolete("Use MoveWithoutRemovingFromWorld(Position,bool) instead!")] + public virtual bool MoveInRegion(ushort regionID, int x, int y, int z, ushort heading, bool forceMove) + => MoveWithoutRemovingFromWorld(Position.Create(regionID, x, y, z, heading), forceMove); + + public virtual bool MoveWithoutRemovingFromWorld(Position destination, bool forceMove) + { if (m_ObjectState != eObjectState.Active) return false; // pets can't be moved across regions - if (regionID != CurrentRegionID) + if (destination.RegionID != CurrentRegionID) return false; if (forceMove == false) @@ -3352,14 +3003,14 @@ public virtual bool MoveInRegion(ushort regionID, int x, int y, int z, ushort he return false; } - Region rgn = WorldMgr.GetRegion(regionID); + Region rgn = WorldMgr.GetRegion(destination.RegionID); - if (rgn == null || rgn.GetZone(x, y) == null) + if (rgn == null || rgn.GetZone(destination.Coordinate) == null) return false; // For a pet move simple erase the pet from all clients and redraw in the new location - Notify(GameObjectEvent.MoveTo, this, new MoveToEventArgs(regionID, x, y, z, heading)); + Notify(GameObjectEvent.MoveTo, this, new MoveToEventArgs(destination.RegionID, destination.X, destination.Y, destination.Z, destination.Orientation.InHeading)); if (ObjectState == eObjectState.Active) { @@ -3369,10 +3020,7 @@ public virtual bool MoveInRegion(ushort regionID, int x, int y, int z, ushort he } } - m_x = x; - m_y = y; - m_z = z; - m_Heading = heading; + Position = destination; foreach (GamePlayer player in GetPlayersInRadius(WorldMgr.VISIBILITY_DISTANCE)) { @@ -3389,25 +3037,21 @@ public virtual bool MoveInRegion(ushort regionID, int x, int y, int z, ushort he return true; } - /// - /// Gets or Sets the current Region of the Object - /// - public override Region CurrentRegion - { - get { return base.CurrentRegion; } - set + public override Position Position + { + set { - Region oldRegion = CurrentRegion; - base.CurrentRegion = value; - Region newRegion = CurrentRegion; - if (oldRegion != newRegion && newRegion != null) + var oldRegionID = Position.RegionID; + base.Position = value; + var newRegion = value.RegionID; + if (oldRegionID != newRegion && newRegion != 0) { if (m_followTimer != null) m_followTimer.Stop(); m_followTimer = new RegionTimer(this); m_followTimer.Callback = new RegionTimerCallback(FollowTimerCallback); } } - } + } /// /// Marks this object as deleted! @@ -4080,8 +3724,7 @@ public virtual void ContinueStartAttack(GameObject target) if (AttackState) { // if we're moving we need to lock down the current position - if (IsMoving) - SaveCurrentPosition(); + if (IsMoving) SaveCurrentPosition(); if (ActiveWeaponSlot == eActiveWeaponSlot.Distance) { @@ -4154,9 +3797,9 @@ public void NPCStopRangedAttackCheckLOS(GamePlayer player, ushort response, usho public void SetLastMeleeAttackTick() { if (TargetObject.Realm == 0 || Realm == 0) - m_lastAttackTickPvE = m_CurrentRegion.Time; + m_lastAttackTickPvE = CurrentRegion.Time; else - m_lastAttackTickPvP = m_CurrentRegion.Time; + m_lastAttackTickPvP = CurrentRegion.Time; } private void StartMeleeAttackTimer() @@ -4838,11 +4481,7 @@ public virtual void DropLoot(GameObject killer) } else { - loot.X = X; - loot.Y = Y; - loot.Z = Z; - loot.Heading = Heading; - loot.CurrentRegion = CurrentRegion; + loot.Position = Position; (loot as WorldInventoryItem).Item.IsCrafted = false; (loot as WorldInventoryItem).Item.Creator = Name; } @@ -4860,11 +4499,7 @@ public virtual void DropLoot(GameObject killer) invitem = GameInventoryItem.Create(lootTemplate); loot = new WorldInventoryItem(invitem); - loot.X = X; - loot.Y = Y; - loot.Z = Z; - loot.Heading = Heading; - loot.CurrentRegion = CurrentRegion; + loot.Position = Position; (loot as WorldInventoryItem).Item.IsCrafted = false; (loot as WorldInventoryItem).Item.Creator = Name; @@ -5691,7 +5326,7 @@ public override void Notify(DOLEvent e, object sender, EventArgs args) { if (IsReturningToSpawnPoint) { - TurnTo(SpawnHeading); + TurnTo(SpawnPosition.Orientation); IsReturningToSpawnPoint = false; } } @@ -5744,7 +5379,7 @@ public void FireAmbientSentence(eAmbientTrigger trigger, GameLiving living = nul // broadcasted , yelled or talked ? if (chosen.Voice.StartsWith("b")) { - foreach (GamePlayer player in CurrentRegion.GetPlayersInRadius(X, Y, Z, 25000, false, false)) + foreach (GamePlayer player in CurrentRegion.GetPlayersInRadius(Coordinate, 25000, false, false)) { player.Out.SendMessage(text, eChatType.CT_Broadcast, eChatLoc.CL_ChatWindow); } @@ -5896,7 +5531,6 @@ public GameNPC Copy(GameNPC copyTarget) copyTarget.CanUseLefthandedWeapon = CanUseLefthandedWeapon; copyTarget.Charisma = Charisma; copyTarget.Constitution = Constitution; - copyTarget.CurrentRegion = CurrentRegion; copyTarget.Dexterity = Dexterity; copyTarget.Empathy = Empathy; copyTarget.Endurance = Endurance; @@ -5907,7 +5541,6 @@ public GameNPC Copy(GameNPC copyTarget) copyTarget.GuildName = GuildName; copyTarget.ExamineArticle = ExamineArticle; copyTarget.MessageArticle = MessageArticle; - copyTarget.Heading = Heading; copyTarget.Intelligence = Intelligence; copyTarget.IsCloakHoodUp = IsCloakHoodUp; copyTarget.IsCloakInvisible = IsCloakInvisible; @@ -5935,9 +5568,7 @@ public GameNPC Copy(GameNPC copyTarget) copyTarget.Strength = Strength; copyTarget.TetherRange = TetherRange; copyTarget.MaxDistance = MaxDistance; - copyTarget.X = X; - copyTarget.Y = Y; - copyTarget.Z = Z; + copyTarget.Position = Position; copyTarget.OwnerID = OwnerID; copyTarget.PackageID = PackageID; @@ -6021,7 +5652,6 @@ public GameNPC(ABrain defaultBrain) : base() m_followTarget = new WeakRef(null); m_size = 50; //Default size - TargetPosition = new Point3D(); m_followMinDist = 100; m_followMaxDist = 3000; m_flags = 0; @@ -6029,9 +5659,6 @@ public GameNPC(ABrain defaultBrain) : base() m_roamingRange = 0; // default to non roaming - tolakram m_ownerID = ""; - if (m_spawnPoint == null) - m_spawnPoint = new Point3D(); - //m_factionName = ""; LinkedFactions = new ArrayList(1); if (m_ownBrain == null) diff --git a/GameServer/gameobjects/GameObject.cs b/GameServer/gameobjects/GameObject.cs index 8f8848f369..2ebbc3eb4c 100644 --- a/GameServer/gameobjects/GameObject.cs +++ b/GameServer/gameobjects/GameObject.cs @@ -20,7 +20,6 @@ using System.Linq; using System.Collections; using System.Collections.Generic; -using System.Reflection; using System.Text; using DOL.Database; @@ -29,9 +28,8 @@ using DOL.GS.Quests; using DOL.GS.Housing; using DOL.GS.PacketHandler; -using DOL.GS.Utils; - -using log4net; +using DOL.GS.Geometry; +using DOL.GS.Keeps; namespace DOL.GS { @@ -39,7 +37,7 @@ namespace DOL.GS /// This class holds all information that /// EVERY object in the game world needs! /// - public abstract class GameObject : Point3D + public abstract class GameObject { /// /// Defines a logger for this class. @@ -97,16 +95,6 @@ public virtual eObjectState ObjectState #region Position - /// - /// The Object's current Region - /// - protected Region m_CurrentRegion; - - /// - /// The direction the Object is facing - /// - protected ushort m_Heading; - /// /// Holds the realm of this object /// @@ -121,13 +109,14 @@ public virtual eRealm Realm set { m_Realm = value; } } - /// - /// Gets or Sets the current Region of the Object - /// public virtual Region CurrentRegion { - get { return m_CurrentRegion; } - set { m_CurrentRegion = value; } + get => Position.Region; + set + { + if(value == null) Position = Position.With(regionID: 0); + Position = Position.With(regionID: value.ID); + } } protected string m_ownerID; @@ -144,19 +133,6 @@ public virtual string OwnerID } } - - /// - /// Get's or sets the current Region by the ID - /// - public virtual ushort CurrentRegionID - { - get { return m_CurrentRegion == null ? (ushort)0 : m_CurrentRegion.ID; } - set - { - CurrentRegion = WorldMgr.GetRegion(value); - } - } - /// /// Gets the current Zone of the Object /// @@ -164,59 +140,75 @@ public Zone CurrentZone { get { - if (m_CurrentRegion != null) + if (CurrentRegion != null) { - return m_CurrentRegion.GetZone(X, Y); + return CurrentRegion.GetZone(Coordinate); } return null; } } - /// - /// Gets the current direction the Object is facing - /// - public virtual ushort Heading - { - get { return m_Heading; } - set { m_Heading = (ushort)(value & 0xFFF); } - } + public virtual Position Position { get; set; } - /// - /// Returns the angle towards a target spot in degrees, clockwise - /// - /// target x - /// target y - /// the angle towards the spot - public float GetAngle( IPoint2D point ) - { - float headingDifference = ( GetHeading( point ) & 0xFFF ) - ( this.Heading & 0xFFF ); + public Coordinate Coordinate => Position.Coordinate; - if (headingDifference < 0) - headingDifference += 4096.0f; + [Obsolete("Use .Position.X instead!")] + public virtual int X + { + get => Position.X; + set => Position = Position.With(x: value); + } - return (headingDifference * 360.0f / 4096.0f); - } + [Obsolete("Use .Position.Y instead!")] + public virtual int Y + { + get => Position.Y; + set => Position = Position.With(y: value); + } - /// - /// Get distance to a point - /// - /// - /// If either Z-value is zero, the z-axis is ignored - /// - /// Target point - /// Distance or int.MaxValue if distance cannot be calculated - public override int GetDistanceTo( IPoint3D point ) + [Obsolete("Use .Position.Z instead!")] + public virtual int Z { - GameObject obj = point as GameObject; + get => Position.Z; + set => Position = Position.With(z: value); + } - if ( obj == null || this.CurrentRegionID == obj.CurrentRegionID ) - { - return base.GetDistanceTo( point ); - } - else - { - return int.MaxValue; - } + public virtual Angle Orientation + { + get => Position.Orientation; + set => Position = Position.With(value); + } + + [Obsolete("Use .Orientation.Heading instead!")] + public virtual ushort Heading + { + get => Orientation.InHeading; + set => Orientation = Angle.Heading(value); + } + + public virtual ushort CurrentRegionID + { + get => Position.RegionID; + set => Position = Position.With(regionID: value); + } + + [Obsolete("Use .GetAngleTo(Coordinate) instead!")] + public float GetAngle(IPoint2D point) + => GetAngleTo(Coordinate.Create(point.X, point.Y)).InDegrees; + + public Angle GetAngleTo(Coordinate coordinate) + => Coordinate.GetOrientationTo(coordinate) - Orientation; + + public int GetDistanceTo(GameObject obj, double zfactor = 1) + => GetDistanceTo(obj.Position, zfactor); + + [Obsolete("Use .GetDistanceTo(Position,double) instead!")] + public virtual int GetDistanceTo(IPoint3D point, double zfactor = 1) + { + var obj = point as GameObject; + var regionID = Position.RegionID; + if(obj != null) regionID = obj.Position.RegionID; + return GetDistanceTo(Position.Create(regionID, point.ToCoordinate()),zfactor); } /// @@ -225,40 +217,28 @@ public override int GetDistanceTo( IPoint3D point ) /// /// If either Z-value is zero, the z-axis is ignored /// - /// Target point - /// Z-axis factor - use values between 0 and 1 to decrease the influence of Z-axis - /// Adjusted distance or int.MaxValue if distance cannot be calculated - public override int GetDistanceTo( IPoint3D point, double zfactor ) + public virtual int GetDistanceTo(Position position, double zfactor) { - GameObject obj = point as GameObject; + if (Position.RegionID != position.RegionID) return int.MaxValue; - if ( obj == null || this.CurrentRegionID == obj.CurrentRegionID ) - { - return base.GetDistanceTo( point, zfactor ); - } - else - { - return int.MaxValue; - } + var offset = position.Coordinate - Coordinate; + var dz = offset.Z * zfactor; + + return (int)(offset.Length2D + Math.Sqrt(dz*dz)); } - /// - /// Checks if an object is within a given radius, optionally ignoring z values - /// - /// Target object - /// Radius - /// Ignore Z values - /// False if the object is null, in a different region, or outside the radius; otherwise true - public bool IsWithinRadius(GameObject obj, int radius, bool ignoreZ = false) - { - if (obj == null) - return false; + public bool IsWithinRadius(GameObject obj, int radius, bool ignoreZ = false) + { + if (obj == null) return false; - if (this.CurrentRegionID != obj.CurrentRegionID) - return false; + if (this.CurrentRegionID != obj.CurrentRegionID) return false; - return base.IsWithinRadius(obj, radius, ignoreZ); - } + double distance; + if (ignoreZ) distance = Coordinate.DistanceTo(obj.Coordinate, ignoreZ: true); + else distance = Coordinate.DistanceTo(obj.Coordinate); + + return distance < radius; + } /// /// determines wether a target object is front @@ -272,9 +252,9 @@ public virtual bool IsObjectInFront(GameObject target, double viewangle, bool ra { if (target == null) return false; - float angle = this.GetAngle(target); - if (angle >= 360 - viewangle / 2 || angle < viewangle / 2) - return true; + var angle = GetAngleTo(target.Coordinate); + var isInFront = angle.InDegrees >= 360 - viewangle / 2 || angle.InDegrees < viewangle / 2; + if (isInFront) return true; // if target is closer than 32 units it is considered always in view // tested and works this way for normal evade, parry, block (in 1.69) if (rangeCheck) @@ -283,9 +263,37 @@ public virtual bool IsObjectInFront(GameObject target, double viewangle, bool ra return false; } - /// - /// Checks if object is underwater - /// + private static ((int X, int Y) BottomLeft, (int X, int Y) TopRight)[] hardcodedUnderWaterAreas = new[] + { + // Mount Collory + ((479000,664000),(488000,670000)), + ((472000,656000),(488000,664000)), + ((468500,624000),(488000,654000)), + ((431000,659000),(466000,683000)), + ((431000,646000),(460000,659001)), + ((431000,624000),(455000,646001)), + ((431000,671000),(471000,683000)), + // Breifine + ((456000,558000),(479000,618000)), + // Cruachan Gorge + ((360000,586000),(424000,618000)), + ((360000,563000),(424000,578000)), + // Emain Macha + ((428000,505000),(444000,555000)), + // Hadrian's Wall + ((603000,500000),(620000,553000)), + // Snowdonia + ((592000,633000),(617000,678000)), + ((581000,662000),(617000,678000)), + // Sauvage Forrest + ((626000,584000),(681000,615000)), + // Uppland + ((610000,297000),(652000,353000)), + // Yggdra + ((671000,408000),(693000,421000)), + ((674000,364000),(716000,394000)) + }; + public virtual bool IsUnderwater { get @@ -295,36 +303,19 @@ public virtual bool IsUnderwater // Special land areas below the waterlevel in NF if (CurrentRegion.ID == 163) { - // Mount Collory - if ((Y > 664000) && (Y < 670000) && (X > 479000) && (X < 488000)) return false; - if ((Y > 656000) && (Y < 664000) && (X > 472000) && (X < 488000)) return false; - if ((Y > 624000) && (Y < 654000) && (X > 468500) && (X < 488000)) return false; - if ((Y > 659000) && (Y < 683000) && (X > 431000) && (X < 466000)) return false; - if ((Y > 646000) && (Y < 659001) && (X > 431000) && (X < 460000)) return false; - if ((Y > 624000) && (Y < 646001) && (X > 431000) && (X < 455000)) return false; - if ((Y > 671000) && (Y < 683000) && (X > 431000) && (X < 471000)) return false; - // Breifine - if ((Y > 558000) && (Y < 618000) && (X > 456000) && (X < 479000)) return false; - // Cruachan Gorge - if ((Y > 586000) && (Y < 618000) && (X > 360000) && (X < 424000)) return false; - if ((Y > 563000) && (Y < 578000) && (X > 360000) && (X < 424000)) return false; - // Emain Macha - if ((Y > 505000) && (Y < 555000) && (X > 428000) && (X < 444000)) return false; - // Hadrian's Wall - if ((Y > 500000) && (Y < 553000) && (X > 603000) && (X < 620000)) return false; - // Snowdonia - if ((Y > 633000) && (Y < 678000) && (X > 592000) && (X < 617000)) return false; - if ((Y > 662000) && (Y < 678000) && (X > 581000) && (X < 617000)) return false; - // Sauvage Forrest - if ((Y > 584000) && (Y < 615000) && (X > 626000) && (X < 681000)) return false; - // Uppland - if ((Y > 297000) && (Y < 353000) && (X > 610000) && (X < 652000)) return false; - // Yggdra - if ((Y > 408000) && (Y < 421000) && (X > 671000) && (X < 693000)) return false; - if ((Y > 364000) && (Y < 394000) && (X > 674000) && (X < 716000)) return false; + foreach(var area in hardcodedUnderWaterAreas) + { + if(Coordinate.X > area.BottomLeft.X + && Coordinate.Y > area.BottomLeft.Y + && Coordinate.X < area.TopRight.X + && Coordinate.Y > area.TopRight.Y) + { + return false; + } + } } - return Z < CurrentZone.Waterlevel; + return Position.Z < CurrentZone.Waterlevel; } } @@ -336,7 +327,7 @@ public virtual IList CurrentAreas get { if (CurrentZone != null) - return CurrentZone.GetAreasOfSpot(this); + return CurrentZone.GetAreasOfSpot(Coordinate); return new List(); } set { } @@ -750,24 +741,12 @@ public virtual void DeleteFromDatabase() #region Add-/Remove-/Create-/Move- - /// - /// Creates this object in the gameworld - /// - /// region target - /// x target - /// y target - /// z target - /// heading - /// true if created successfully + [Obsolete("This is going to be removed.")] public virtual bool Create(ushort regionID, int x, int y, int z, ushort heading) { if (m_ObjectState == eObjectState.Active) return false; - CurrentRegionID = regionID; - m_x = x; - m_y = y; - m_z = z; - m_Heading = heading; + Position = Position.Create(regionID, x, y, z, heading); return AddToWorld(); } @@ -781,11 +760,14 @@ public virtual bool AddToWorld() Zone currentZone = CurrentZone; // CurrentZone checks for null Region. // Should it be the case, currentZone will be null as well. + if(this is GameKeepDoor && currentZone == null) Console.WriteLine($"Current Zone does not exist"); if (currentZone == null || m_ObjectState == eObjectState.Active) return false; - if (!m_CurrentRegion.AddObject(this)) + if (!CurrentRegion.AddObject(this)) + { return false; + } Notify(GameObjectEvent.AddToWorld, this); ObjectState = eObjectState.Active; @@ -810,54 +792,38 @@ public virtual bool AddToWorld() /// public virtual bool RemoveFromWorld() { - if (m_CurrentRegion == null || ObjectState != eObjectState.Active) + if (CurrentRegion == null || ObjectState != eObjectState.Active) return false; Notify(GameObjectEvent.RemoveFromWorld, this); ObjectState = eObjectState.Inactive; - m_CurrentRegion.RemoveObject(this); + CurrentRegion.RemoveObject(this); return true; } - /// - /// Move this object to a GameLocation - /// - /// - /// + [Obsolete("Use MoveTo(Position) instead!")] public virtual bool MoveTo(GameLocation loc) - { - return MoveTo(loc.RegionID, loc.X, loc.Y, loc.Z, loc.Heading); - } + => MoveTo(loc.Position); - /// - /// Moves the item from one spot to another spot, possible even - /// over region boundaries - /// - /// new regionid - /// new x - /// new y - /// new z - /// new heading - /// true if moved - public virtual bool MoveTo(ushort regionID, int x, int y, int z, ushort heading) + [Obsolete("Use MoveTo(Position) instead!")] + public virtual bool MoveTo(ushort regionID, int x, int y, int z, ushort heading) + => MoveTo(Position.Create(regionID, x, y, z, heading)); + + public virtual bool MoveTo(Position position) { if (m_ObjectState != eObjectState.Active) return false; - Region rgn = WorldMgr.GetRegion(regionID); + Region rgn = WorldMgr.GetRegion(position.RegionID); if (rgn == null) return false; - if (rgn.GetZone(x, y) == null) + if (rgn.GetZone(position.Coordinate) == null) return false; - Notify(GameObjectEvent.MoveTo, this, new MoveToEventArgs(regionID, x, y, z, heading)); + Notify(GameObjectEvent.MoveTo, this, new MoveToEventArgs(position.RegionID, position.X, position.Y, position.Z, position.Orientation.InHeading)); if (!RemoveFromWorld()) return false; - m_x = x; - m_y = y; - m_z = z; - m_Heading = heading; - CurrentRegionID = regionID; + Position = position; return AddToWorld(); } @@ -1208,7 +1174,7 @@ public IEnumerable GetPlayersInRadius(bool useCache, ushort radiusToCheck, bool if (CurrentRegion != null) { //Eden - avoid server freeze - if (CurrentRegion.GetZone(X, Y) == null) + if (CurrentZone == null) { if (this is GamePlayer && (this as GamePlayer).Client.Account.PrivLevel < 3 && !(this as GamePlayer).TempProperties.getProperty("isbeingbanned", false)) { @@ -1219,7 +1185,7 @@ public IEnumerable GetPlayersInRadius(bool useCache, ushort radiusToCheck, bool } else { - return CurrentRegion.GetPlayersInRadius(X, Y, Z, radiusToCheck, withDistance, ignoreZ); + return CurrentRegion.GetPlayersInRadius(Coordinate, radiusToCheck, withDistance, ignoreZ); } } return new Region.EmptyEnumerator(); @@ -1382,7 +1348,7 @@ public IEnumerable GetNPCsInRadius(bool useCache, ushort radiusToCheck, bool wit if (CurrentRegion != null) { //Eden - avoid server freeze - if (CurrentRegion.GetZone(X, Y) == null) + if (CurrentZone == null) { if (this is GamePlayer && !(this as GamePlayer).TempProperties.getProperty("isbeingbanned", false)) { @@ -1393,7 +1359,7 @@ public IEnumerable GetNPCsInRadius(bool useCache, ushort radiusToCheck, bool wit } else { - IEnumerable result = CurrentRegion.GetNPCsInRadius(X, Y, Z, radiusToCheck, withDistance, ignoreZ); + IEnumerable result = CurrentRegion.GetNPCsInRadius(Coordinate, radiusToCheck, withDistance, ignoreZ); return result; } } @@ -1425,7 +1391,7 @@ public IEnumerable GetItemsInRadius(ushort radiusToCheck, bool withDistance) if (CurrentRegion != null) { //Eden - avoid server freeze - if (CurrentRegion.GetZone(X, Y) == null) + if (CurrentZone == null) { if (this is GamePlayer && !(this as GamePlayer).TempProperties.getProperty("isbeingbanned", false)) { @@ -1436,7 +1402,7 @@ public IEnumerable GetItemsInRadius(ushort radiusToCheck, bool withDistance) } else { - return CurrentRegion.GetItemsInRadius(X, Y, Z, radiusToCheck, withDistance); + return CurrentRegion.GetItemsInRadius(Coordinate, radiusToCheck, withDistance); } } return new Region.EmptyEnumerator(); @@ -1464,7 +1430,7 @@ public IEnumerable GetDoorsInRadius(ushort radiusToCheck, bool withDistance) if (CurrentRegion != null) { //Eden : avoid server freeze - if (CurrentRegion.GetZone(X, Y) == null) + if (CurrentZone == null) { if (this is GamePlayer && !(this as GamePlayer).TempProperties.getProperty("isbeingbanned", false)) { @@ -1475,7 +1441,7 @@ public IEnumerable GetDoorsInRadius(ushort radiusToCheck, bool withDistance) } else { - return CurrentRegion.GetDoorsInRadius(X, Y, Z, radiusToCheck, withDistance); + return CurrentRegion.GetDoorsInRadius(Coordinate, radiusToCheck, withDistance); } } return new Region.EmptyEnumerator(); @@ -1589,7 +1555,7 @@ public override string ToString() .Append(" oid=").Append(ObjectID.ToString()) .Append(" state=").Append(ObjectState.ToString()) .Append(" reg=").Append(reg == null ? "null" : reg.ID.ToString()) - .Append(" loc=").Append(X.ToString()).Append(',').Append(Y.ToString()).Append(',').Append(Z.ToString()) + .Append(" loc=").Append(Coordinate) .ToString(); } @@ -1616,7 +1582,7 @@ public virtual void BroadcastUpdate() { if (player == null) continue; - + player.Out.SendObjectUpdate(this); } } @@ -1652,5 +1618,28 @@ public static string ObjectHasOwner() else return m_boat_ownerid; } - } + + [Obsolete("Use .Position.Coordinate.GetOrientationTo(Coordinate).InHeading instead!")] + public ushort GetHeading(Point2D p) + { + return Position.Coordinate.GetOrientationTo(Coordinate.Create(p.X, p.Y)).InHeading; + } + + [Obsolete("Use .Coordinate.DistanceTo(Coordinate) instead!")] + public bool IsWithinRadius(Point3D p, int radius, bool ignoreZ = false) + { + return Coordinate.DistanceTo(Coordinate.Create(p.X, p.Y, p.Z)) <= radius; + } + + [Obsolete("Use Vector addition instead!")] + public Point2D GetPointFromHeading(ushort heading, int distance) + { + return (Coordinate + Vector.Create(Angle.Heading(heading), distance)).ToPoint3D(); + } + + public int GetDistance(GameObject obj2, double zFactor = 1) + { + return GetDistanceTo(obj2.Position, zFactor); + } + } } \ No newline at end of file diff --git a/GameServer/gameobjects/GamePlayer.cs b/GameServer/gameobjects/GamePlayer.cs index b775dc400c..a07bf64cc5 100644 --- a/GameServer/gameobjects/GamePlayer.cs +++ b/GameServer/gameobjects/GamePlayer.cs @@ -30,6 +30,7 @@ using DOL.Events; using DOL.GS.Effects; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.Housing; using DOL.GS.Keeps; using DOL.GS.PacketHandler; @@ -458,61 +459,69 @@ public bool UsedLevelCommand set { if (DBCharacter != null) DBCharacter.UsedLevelCommand = value; } } - /// - /// Gets or sets the BindHouseRegion for this player - /// (delegate to property in DBCharacter) - /// - public int BindHouseRegion - { - get { return DBCharacter != null ? DBCharacter.BindHouseRegion : 0; } - set { if (DBCharacter != null) DBCharacter.BindHouseRegion = value; } - } + public Position BindHousePosition + { + get + { + if (DBCharacter == null) return Position.Zero; + + return Position.Create( + (ushort)DBCharacter.BindHouseRegion, + DBCharacter.BindHouseXpos, + DBCharacter.BindHouseYpos, + DBCharacter.BindHouseZpos, + (ushort)DBCharacter.BindHouseHeading); + } + set + { + DBCharacter.BindHouseRegion = value.RegionID; + DBCharacter.BindHouseXpos = value.X; + DBCharacter.BindHouseYpos = value.Y; + DBCharacter.BindHouseZpos = value.Z; + DBCharacter.BindHouseHeading = value.Orientation.InHeading; + } + } - /// - /// Gets or sets the BindHouseXpos for this player - /// (delegate to property in DBCharacter) - /// - public int BindHouseXpos - { - get { return DBCharacter != null ? DBCharacter.BindHouseXpos : 0; } - set { if (DBCharacter != null) DBCharacter.BindHouseXpos = value; } - } + [Obsolete("Use BindHousePosition instead!")] + public int BindHouseRegion + { + get => BindHousePosition.RegionID; + set => BindHousePosition.With(regionID: (ushort)value); + } - /// - /// Gets or sets the BindHouseYpos for this player - /// (delegate to property in DBCharacter) - /// - public int BindHouseYpos - { - get { return DBCharacter != null ? DBCharacter.BindHouseYpos : 0; } - set { if (DBCharacter != null) DBCharacter.BindHouseYpos = value; } - } + [Obsolete("Use BindHousePosition instead!")] + public int BindHouseXpos + { + get => BindHousePosition.X; + set => BindHousePosition.With(x: value); + } - /// - /// Gets or sets BindHouseZpos for this player - /// (delegate to property in DBCharacter) - /// - public int BindHouseZpos - { - get { return DBCharacter != null ? DBCharacter.BindHouseZpos : 0; } - set { if (DBCharacter != null) DBCharacter.BindHouseZpos = value; } - } - - /// - /// Gets or sets the BindHouseHeading for this player - /// (delegate to property in DBCharacter) - /// - public int BindHouseHeading - { - get { return DBCharacter != null ? DBCharacter.BindHouseHeading : 0; } - set { if (DBCharacter != null) DBCharacter.BindHouseHeading = value; } - } - - /// - /// Gets or sets the CustomisationStep for this player - /// (delegate to property in DBCharacter) - /// - public byte CustomisationStep + [Obsolete("Use BindHousePosition instead!")] + public int BindHouseYpos + { + get => BindHousePosition.Y; + set => BindHousePosition.With(y: value); + } + + [Obsolete("Use BindHousePosition instead!")] + public int BindHouseZpos + { + get => BindHousePosition.Z; + set => BindHousePosition.With(z: value); + } + + [Obsolete("Use BindHousePosition instead!")] + public int BindHouseHeading + { + get => BindHousePosition.Orientation.InHeading; + set => BindHousePosition.With(Angle.Heading(value)); + } + + /// + /// Gets or sets the CustomisationStep for this player + /// (delegate to property in DBCharacter) + /// + public byte CustomisationStep { get { return DBCharacter != null ? DBCharacter.CustomisationStep : (byte)0; } set { if (DBCharacter != null) DBCharacter.CustomisationStep = value; } @@ -548,50 +557,55 @@ public bool ShowXFireInfo set { if (DBCharacter != null) DBCharacter.ShowXFireInfo = value; } } - /// - /// Gets or sets the BindRegion for this player - /// (delegate to property in DBCharacter) - /// + public Position BindPosition + { + get + { + if(DBCharacter == null) return Position.Zero; + + return DBCharacter.GetBindPosition(); + } + set + { + if (DBCharacter == null) return; + + DBCharacter.BindRegion = value.RegionID; + DBCharacter.BindXpos = value.X; + DBCharacter.BindYpos = value.Y; + DBCharacter.BindZpos = value.Z; + DBCharacter.BindHeading = value.Orientation.InHeading; + } + } + + [Obsolete("Use BindPosition instead!")] public int BindRegion { get { return DBCharacter != null ? DBCharacter.BindRegion : 0; } set { if (DBCharacter != null) DBCharacter.BindRegion = value; } } - /// - /// Gets or sets the BindXpos for this player - /// (delegate to property in DBCharacter) - /// + [Obsolete("Use BindPosition instead!")] public int BindXpos { get { return DBCharacter != null ? DBCharacter.BindXpos : 0; } set { if (DBCharacter != null) DBCharacter.BindXpos = value; } } - /// - /// Gets or sets the BindYpos for this player - /// (delegate to property in DBCharacter) - /// + [Obsolete("Use BindPosition instead!")] public int BindYpos { get { return DBCharacter != null ? DBCharacter.BindYpos : 0; } set { if (DBCharacter != null) DBCharacter.BindYpos = value; } } - /// - /// Gets or sets the BindZpos for this player - /// (delegate to property in DBCharacter) - /// + [Obsolete("Use BindPosition instead!")] public int BindZpos { get { return DBCharacter != null ? DBCharacter.BindZpos : 0; } set { if (DBCharacter != null) DBCharacter.BindZpos = value; } } - /// - /// Gets or sets the BindHeading for this player - /// (delegate to property in DBCharacter) - /// + [Obsolete("Use BindPosition instead!")] public int BindHeading { get { return DBCharacter != null ? DBCharacter.BindHeading : 0; } @@ -837,7 +851,7 @@ public void OnLinkdeath() private void CheckIfNearEnemyKeepAndAddToRvRLinkDeathListIfNecessary() { - AbstractGameKeep keep = GameServer.KeepManager.GetKeepCloseToSpot(this.CurrentRegionID, this, WorldMgr.VISIBILITY_DISTANCE); + AbstractGameKeep keep = GameServer.KeepManager.GetKeepCloseToSpot(Position, WorldMgr.VISIBILITY_DISTANCE); if(keep != null && this.Client.Account.PrivLevel == 1 && GameServer.KeepManager.IsEnemy(keep, this)) { if(WorldMgr.RvRLinkDeadPlayers.ContainsKey(this.m_InternalID)) @@ -908,11 +922,7 @@ protected virtual void CleanupOnDisconnect() // DamienOphyr: Overwrite current position with Bind position in database, MoveTo() is inoperant if (CurrentRegion.IsInstance) { - DBCharacter.Region = BindRegion; - DBCharacter.Xpos = BindXpos; - DBCharacter.Ypos = BindYpos; - DBCharacter.Zpos = BindZpos; - DBCharacter.Direction = BindHeading; + Position = BindPosition; } //check for battleground caps @@ -1172,11 +1182,7 @@ public virtual void Bind(bool forced) if (forced) { - BindRegion = CurrentRegionID; - BindHeading = Heading; - BindXpos = X; - BindYpos = Y; - BindZpos = Z; + BindPosition = Position; if (DBCharacter != null) GameServer.Database.SaveObject(DBCharacter); return; @@ -1196,8 +1202,9 @@ public virtual void Bind(bool forced) Out.SendMessage(LanguageMgr.GetTranslation(Client.Account.Language, "GamePlayer.Bind.MustWait", (1 + (BindAllowInterval - changeTime) / 1000)), eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } - - string description = string.Format("in {0}", this.GetBindSpotDescription()); + + var spotDescription = WorldMgr.GetRegion(BindPosition.RegionID).GetTranslatedSpotDescription(Client, BindPosition.Coordinate); + string description = string.Format("in {0}", spotDescription); Out.SendMessage(LanguageMgr.GetTranslation(Client.Account.Language, "GamePlayer.Bind.LastBindPoint", description), eChatType.CT_System, eChatLoc.CL_SystemWindow); bool bound = false; @@ -1206,11 +1213,7 @@ public virtual void Bind(bool forced) if (bindarea != null) { bound = true; - BindRegion = CurrentRegionID; - BindHeading = Heading; - BindXpos = X; - BindYpos = Y; - BindZpos = Z; + BindPosition = Position; if (DBCharacter != null) GameServer.Database.SaveObject(DBCharacter); } @@ -1240,15 +1243,7 @@ public virtual void Bind(bool forced) else { bound = true; - double angle = house.Heading * ((Math.PI * 2) / 360); // angle*2pi/360; - int outsideX = (int)(house.X + (0 * Math.Cos(angle) + 500 * Math.Sin(angle))); - int outsideY = (int)(house.Y - (500 * Math.Cos(angle) - 0 * Math.Sin(angle))); - ushort outsideHeading = (ushort)((house.Heading < 180 ? house.Heading + 180 : house.Heading - 180) / 0.08789); - BindHouseRegion = CurrentRegionID; - BindHouseHeading = outsideHeading; - BindHouseXpos = outsideX; - BindHouseYpos = outsideY; - BindHouseZpos = house.Z; + BindHousePosition = house.OutdoorJumpPosition; if (DBCharacter != null) GameServer.Database.SaveObject(DBCharacter); } @@ -1459,53 +1454,36 @@ public virtual void Release(eReleaseType releaseCommand, bool forced) m_releaseType = releaseCommand; } - int relX = 0, relY = 0, relZ = 0; - ushort relRegion = 0, relHeading = 0; + var releasePosition = Position.Zero; switch (m_releaseType) { case eReleaseType.Duel: { - relRegion = (ushort)character.Region; - relX = character.Xpos; - relY = character.Ypos; - relZ = character.Zpos; - relHeading = 2048; + releasePosition = character.GetPosition().With(Angle.Degrees(180)); break; } case eReleaseType.House: { - relRegion = (ushort)BindHouseRegion; - relX = BindHouseXpos; - relY = BindHouseYpos; - relZ = BindHouseZpos; - relHeading = (ushort)BindHouseHeading; + releasePosition = BindHousePosition; break; } - case eReleaseType.City: { if (Realm == eRealm.Hibernia) { - relRegion = 201; // Tir Na Nog - relX = 8192 + 15780; - relY = 8192 + 22727; - relZ = 7060; + // Tir Na Nog + releasePosition = Position.Create(regionID: 201, x: 192 + 15780, y: 8192 + 22727, z: 7060, heading: 2048); } else if (Realm == eRealm.Midgard) { - relRegion = 101; // Jordheim - relX = 8192 + 24664; - relY = 8192 + 21402; - relZ = 8759; + // Jordheim + releasePosition = Position.Create(regionID: 101, x: 8192 + 24664, y: 8192 + 21402, z: 8759, heading: 2048); } else { - relRegion = 10; // City of Camelot - relX = 8192 + 26315; - relY = 8192 + 21177; - relZ = 8256; + // City of Camelot + releasePosition = Position.Create(regionID: 10, x: 8192 + 26315, y: 8192 + 21177, z: 8256, heading: 2048); } - relHeading = 2048; break; } case eReleaseType.RvR: @@ -1514,18 +1492,14 @@ public virtual void Release(eReleaseType releaseCommand, bool forced) { if (keep.IsPortalKeep && keep.OriginalRealm == Realm) { - relRegion = keep.CurrentRegion.ID; - relX = keep.X; - relY = keep.Y; - relZ = keep.Z; + releasePosition = Position.Create(keep.CurrentRegion.ID, keep.X, keep.Y, keep.Z); } } //if we aren't releasing anywhere, release to the border keeps - if (relX == 0) + if (releasePosition.Coordinate == Coordinate.Zero) { - relRegion = CurrentRegion.ID; - GameServer.KeepManager.GetBorderKeepLocation(((byte)Realm * 2) / 1, out relX, out relY, out relZ, out relHeading); + releasePosition = GameServer.KeepManager.GetBorderKeepPosition(((byte)Realm * 2) / 1); } break; } @@ -1534,32 +1508,26 @@ public virtual void Release(eReleaseType releaseCommand, bool forced) if (!ServerProperties.Properties.DISABLE_TUTORIAL) { //Tutorial - if (BindRegion == 27) + if (BindPosition.RegionID == 27) { switch (Realm) { case eRealm.Albion: { - relRegion = 1; // Cotswold - relX = 8192 + 553251; - relY = 8192 + 502936; - relZ = 2280; + // Cotswold + releasePosition = Position.Create(regionID: 1, x: 8192 + 553251, y: 8192 + 502936, z: 2280); break; } case eRealm.Midgard: { - relRegion = 100; // Mularn - relX = 8192 + 795621; - relY = 8192 + 719590; - relZ = 4680; + // Mularn + releasePosition = Position.Create(regionID: 100, x: 8192 + 795621, y: 8192 + 719590, z: 4680); break; } case eRealm.Hibernia: { - relRegion = 200; // MagMell - relX = 8192 + 338652; - relY = 8192 + 482335; - relZ = 5200; + // MagMell + releasePosition = Position.Create(regionID: 200, x: 8192 + 338652, y: 8192 + 482335, z: 5200); break; } } @@ -1594,10 +1562,7 @@ public virtual void Release(eReleaseType releaseCommand, bool forced) { if (keep.DBKeep.BaseLevel > 50 && keep.Realm == Realm) { - relRegion = (ushort)keep.Region; - relX = keep.X; - relY = keep.Y; - relZ = keep.Z; + releasePosition = Position.Create((ushort)keep.Region, x: keep.X, y: keep.Y, z: keep.Z); break; } } @@ -1606,24 +1571,23 @@ public virtual void Release(eReleaseType releaseCommand, bool forced) //nf case 163: { - if (BindRegion != 163) + if (BindPosition.RegionID != 163) { - relRegion = 163; switch (Realm) { case eRealm.Albion: { - GameServer.KeepManager.GetBorderKeepLocation(1, out relX, out relY, out relZ, out relHeading); + releasePosition = GameServer.KeepManager.GetBorderKeepPosition(1); break; } case eRealm.Midgard: { - GameServer.KeepManager.GetBorderKeepLocation(3, out relX, out relY, out relZ, out relHeading); + releasePosition = GameServer.KeepManager.GetBorderKeepPosition(3); break; } case eRealm.Hibernia: { - GameServer.KeepManager.GetBorderKeepLocation(5, out relX, out relY, out relZ, out relHeading); + releasePosition = GameServer.KeepManager.GetBorderKeepPosition(5); break; } } @@ -1631,11 +1595,7 @@ public virtual void Release(eReleaseType releaseCommand, bool forced) } else { - relRegion = (ushort)BindRegion; - relX = BindXpos; - relY = BindYpos; - relZ = BindZpos; - relHeading = (ushort)BindHeading; + releasePosition = BindPosition; } break; }/* @@ -1646,11 +1606,7 @@ public virtual void Release(eReleaseType releaseCommand, bool forced) }*/ default: { - relRegion = (ushort)BindRegion; - relX = BindXpos; - relY = BindYpos; - relZ = BindZpos; - relHeading = (ushort)BindHeading; + releasePosition = BindPosition; break; } } @@ -1723,7 +1679,7 @@ public virtual void Release(eReleaseType releaseCommand, bool forced) StartEnduranceRegeneration(); Region region = null; - if ((region = WorldMgr.GetRegion((ushort)BindRegion)) != null && region.GetZone(BindXpos, BindYpos) != null) + if ((region = WorldMgr.GetRegion(BindPosition.RegionID)) != null && region.GetZone(BindPosition.Coordinate) != null) { Out.SendMessage(LanguageMgr.GetTranslation(Client.Account.Language, "GamePlayer.Release.SurroundingChange"), eChatType.CT_YouDied, eChatLoc.CL_SystemWindow); } @@ -1738,7 +1694,7 @@ public virtual void Release(eReleaseType releaseCommand, bool forced) //Call MoveTo after new GameGravestone(this... //or the GraveStone will be located at the player's bindpoint - MoveTo(relRegion, relX, relY, relZ, relHeading); + MoveTo(releasePosition); //It is enough if we revive the player on this client only here //because for other players the player will be removed in the MoveTo //method and added back again (if in view) with full health ... so no @@ -1758,20 +1714,6 @@ public virtual void Release(eReleaseType releaseCommand, bool forced) } TempProperties.removeProperty(DEATH_CONSTITUTION_LOSS_PROPERTY); - - //Reset last valide position array to prevent /stuck avec /release - lock (m_lastUniqueLocations) - { - for (int i = 0; i < m_lastUniqueLocations.Length; i++) - { - GameLocation loc = m_lastUniqueLocations[i]; - loc.X = X; - loc.Y = Y; - loc.Z = Z; - loc.Heading = Heading; - loc.RegionID = CurrentRegionID; - } - } } /// @@ -7325,7 +7267,7 @@ public override int AttackRange case 2: range *= 1.15; break; //doesn't exist on live case 3: range *= 1.25; break; //Flight +25% } - if (livingTarget != null) range += Math.Min((Z - livingTarget.Z) / 2.0, 500); + if (livingTarget != null) range += Math.Min((Position.Z - livingTarget.Position.Z) / 2.0, 500); if (range < 32) range = 32; return (int)(range); @@ -9880,7 +9822,7 @@ public override bool RemoveFromWorld() if (ObjectState == eObjectState.Active) { DismountSteed(true); - if (CurrentRegion.GetZone(X, Y) == null) + if (CurrentZone == null) { if (this is GamePlayer && this.Client.Account.PrivLevel < 3 && !(this as GamePlayer).TempProperties.getProperty("isbeingbanned", false)) { @@ -9950,21 +9892,11 @@ public override void Delete() /// public const string DEBUG_MODE_PROPERTY = "Player.DebugMode"; - /// - /// This function moves a player to a specific region and - /// specific coordinates. - /// - /// RegionID to move to - /// X target coordinate - /// Y target coordinate - /// Z target coordinate (0 to put player on floor) - /// Target heading - /// true if move succeeded, false if failed - public override bool MoveTo(ushort regionID, int x, int y, int z, ushort heading) + public override bool MoveTo(Position position) { //if we are jumping somewhere away from our house not using house.Exit //we need to make the server know we have left the house - if ((CurrentHouse != null || InHouse) && CurrentHouse.RegionID != regionID) + if ((CurrentHouse != null || InHouse) && CurrentHouse.RegionID != position.RegionID) { InHouse = false; CurrentHouse = null; @@ -9973,13 +9905,13 @@ public override bool MoveTo(ushort regionID, int x, int y, int z, ushort heading if (IsOnHorse) IsOnHorse = false; //Get the destination region based on the ID - Region rgn = WorldMgr.GetRegion(regionID); + Region rgn = WorldMgr.GetRegion(position.RegionID); //If the region doesn't exist, return false or if they aren't allowed to zone here if (rgn == null || !GameServer.ServerRules.IsAllowedToZone(this, rgn)) return false; //If the x,y inside this region doesn't point to a zone //return false - if (rgn.GetZone(x, y) == null) + if (rgn.GetZone(position.Coordinate) == null) return false; Diving(waterBreath.Normal); @@ -9987,7 +9919,9 @@ public override bool MoveTo(ushort regionID, int x, int y, int z, ushort heading if (SiegeWeapon != null) SiegeWeapon.ReleaseControl(); - if (regionID != CurrentRegionID) + var positionBeforePort = Position; + + if (position.RegionID != positionBeforePort.RegionID) { GameEventMgr.Notify(GamePlayerEvent.RegionChanging, this); if (!RemoveFromWorld()) @@ -10018,8 +9952,6 @@ public override bool MoveTo(ushort regionID, int x, int y, int z, ushort heading IsJumping = true; } bool hasPetToMove = false; - //Remove the last update tick property, to prevent speedhack messages during zoning and teleporting! - LastPositionUpdateTick = 0; if (ControlledBrain != null && ControlledBrain.WalkState != eWalkState.Stay) { @@ -10031,21 +9963,13 @@ public override bool MoveTo(ushort regionID, int x, int y, int z, ushort heading //Set the new destination //Current Speed = 0 when moved ... else X,Y,Z continue to be modified CurrentSpeed = 0; - MovementStartTick = Environment.TickCount; - Point3D originalPoint = new Point3D(X, Y, Z); - X = x; - Y = y; - Z = z; - Heading = heading; + Position = position; //Remove the last update tick property, to prevent speedhack messages during zoning and teleporting! TempProperties.removeProperty(PlayerPositionUpdateHandler.LASTMOVEMENTTICK); //If the destination is in another region - if (regionID != CurrentRegionID) + if (position.RegionID != positionBeforePort.RegionID) { - //Set our new region - CurrentRegionID = regionID; - //Send the region update packet, the rest will be handled //by the packethandlers Out.SendRegionChanged(); @@ -10056,7 +9980,7 @@ public override bool MoveTo(ushort regionID, int x, int y, int z, ushort heading Out.SendPlayerJump(false); // are we jumping far enough to force a complete refresh? - if (GetDistanceTo(originalPoint) > WorldMgr.REFRESH_DISTANCE) + if (Coordinate.DistanceTo(positionBeforePort) > WorldMgr.REFRESH_DISTANCE) { RefreshWorld(); } @@ -10081,17 +10005,16 @@ public override bool MoveTo(ushort regionID, int x, int y, int z, ushort heading if (hasPetToMove) { - Point2D point = GetPointFromHeading(Heading, 64); - if (ControlledBody is GameNPC petBody) { - petBody.MoveInRegion(CurrentRegionID, point.X, point.Y, this.Z + 10, (ushort)((this.Heading + 2048) % 4096), false); + var destination = Position.TurnedAround() + Vector.Create(Orientation, length: 64, z: 10); + petBody.MoveWithoutRemovingFromWorld(destination, false); if (petBody.ControlledNpcList != null) foreach (IControlledBrain icb in petBody.ControlledNpcList) if (icb != null && icb.Body is GameNPC petBody2 - && originalPoint.IsWithinRadius(petBody2, 500)) - petBody2.MoveInRegion(CurrentRegionID, point.X, point.Y, this.Z + 10, (ushort)((this.Heading + 2048) % 4096), false); + && petBody2.Coordinate.DistanceTo(positionBeforePort) < 500) + petBody2.MoveWithoutRemovingFromWorld(destination, false); } } } @@ -10131,11 +10054,11 @@ public virtual void RefreshWorld() //Eden - Move to bind, and check if the loc is allowed public virtual bool MoveToBind() { - Region rgn = WorldMgr.GetRegion((ushort)BindRegion); - if (rgn == null || rgn.GetZone(BindXpos, BindYpos) == null) + Region rgn = WorldMgr.GetRegion(BindPosition.RegionID); + if (rgn == null || rgn.GetZone(BindPosition.Coordinate) == null) { if (log.IsErrorEnabled) - log.Error("Player: " + Name + " unknown bind point : (R/X/Y) " + BindRegion + "/" + BindXpos + "/" + BindYpos); + log.Error("Player: " + Name + " unknown bind point : (R/X/Y) " + BindPosition.RegionID + "/" + BindPosition.X + "/" + BindPosition.Y); //Kick the player, avoid server freeze Client.Out.SendPlayerQuit(true); SaveIntoDatabase(); @@ -10149,7 +10072,7 @@ public virtual bool MoveToBind() b.Account = Client.Account.Name; b.DateBan = DateTime.Now; b.Type = "B"; - b.Reason = "X/Y/Zone : " + X + "/" + Y + "/" + CurrentRegion.ID; + b.Reason = "X/Y/RegionID : " + Position.X + "/" + Position.Y + "/" + Position.RegionID; GameServer.Database.AddObject(b); GameServer.Database.SaveObject(b); string message = "Unknown bind point, your account is banned, contact a GM."; @@ -10160,7 +10083,7 @@ public virtual bool MoveToBind() } if (GameServer.ServerRules.IsAllowedToMoveToBind(this)) - return MoveTo((ushort)BindRegion, BindXpos, BindYpos, BindZpos, (ushort)BindHeading); + return MoveTo(BindPosition); return false; } @@ -10356,41 +10279,14 @@ public long AreaUpdateTick set { m_areaUpdateTick = value; } } - /// - /// Gets the current position of this player - /// - public override int X - { - set - { - base.X = value; - if (DBCharacter != null) DBCharacter.Xpos = base.X; - } - } - - /// - /// Gets the current position of this player - /// - public override int Y - { - set - { - base.Y = value; - if (DBCharacter != null) DBCharacter.Ypos = base.Y; - } - } - - /// - /// Gets the current position of this player - /// - public override int Z - { - set - { - base.Z = value; - if (DBCharacter != null) DBCharacter.Zpos = base.Z; - } - } + public override Position Position + { + set + { + base.Position = value; + if(DBCharacter != null) DBCharacter.SetPosition(value); + } + } /// /// Gets or sets the current speed of this player @@ -10433,28 +10329,7 @@ public Zone LastPositionUpdateZone set { m_lastPositionUpdateZone = value; } } - - private int m_lastPositionUpdateTick = 0; - - /// - /// The environment tick count when this players position was last updated - /// - public int LastPositionUpdateTick - { - get { return m_lastPositionUpdateTick; } - set { m_lastPositionUpdateTick = value; } - } - - private Point3D m_lastPositionUpdatePoint = new Point3D(0, 0, 0); - - /// - /// The last recorded position of this player - /// - public Point3D LastPositionUpdatePoint - { - get { return m_lastPositionUpdatePoint; } - set { m_lastPositionUpdatePoint = value; } - } + public Coordinate LastUpdateCoordinate => Motion.Start.Coordinate; /// /// Holds the players max Z for fall damage @@ -10483,15 +10358,12 @@ public override eRealm Realm } } - /// - /// Gets or sets the heading of this player - /// - public override ushort Heading + public override Angle Orientation { set { - base.Heading = value; - if (DBCharacter != null) DBCharacter.Direction = value; + base.Orientation = value; + if (DBCharacter != null) DBCharacter.Direction = value.InHeading; if (AttackState && ActiveWeaponSlot != eActiveWeaponSlot.Distance) { @@ -10981,29 +10853,17 @@ public virtual void Sit(bool sit) UpdatePlayerStatus(); } - /// - /// Sets the Living's ground-target Coordinates inside the current Region - /// - public override void SetGroundTarget(int groundX, int groundY, int groundZ) - { - base.SetGroundTarget(groundX, groundY, groundZ); - Out.SendMessage(String.Format("You ground-target {0},{1},{2}", groundX, groundY, groundZ), eChatType.CT_System, eChatLoc.CL_SystemWindow); - if (SiegeWeapon != null) - SiegeWeapon.SetGroundTarget(groundX, groundY, groundZ); - } - - /// - /// Holds unique locations array - /// - protected readonly GameLocation[] m_lastUniqueLocations; + public override Position GroundTargetPosition + { + set + { + base.GroundTargetPosition = value; + Out.SendMessage(String.Format("You ground-target {0},{1},{2}", value.X, value.Y, value.Z), eChatType.CT_System, eChatLoc.CL_SystemWindow); + if (SiegeWeapon != null) SiegeWeapon.GroundTargetPosition = value; + } + } - /// - /// Gets unique locations array - /// - public GameLocation[] LastUniqueLocations - { - get { return m_lastUniqueLocations; } - } + public Position[] LastUniquePositions { get; } = new Position[4]; /// /// Updates Health, Mana, Sitting, Endurance, Concentration and Alive status to client @@ -11726,14 +11586,7 @@ public virtual WorldInventoryItem CreateItemOnTheGround(InventoryItem item) else { gameItem = new WorldInventoryItem(item); - - Point2D itemloc = this.GetPointFromHeading(this.Heading, 30); - gameItem.X = itemloc.X; - gameItem.Y = itemloc.Y; - gameItem.Z = Z; - gameItem.Heading = Heading; - gameItem.CurrentRegionID = CurrentRegionID; - + gameItem.Position = Position + Vector.Create(Orientation, length: 30); gameItem.AddOwner(this); gameItem.AddToWorld(); } @@ -11769,8 +11622,8 @@ public virtual bool PickupObject(GameObject floorObject, bool checkRange) { log.DebugFormat("Pickup error: {0} object x{1}, y{2}, z{3}, r{4} - player x{5}, y{6}, z{7}, r{8}", Name, - floorObject.X, floorObject.Y, floorObject.Z, floorObject.CurrentRegionID, - X, Y, Z, CurrentRegionID); + floorObject.Position.X, floorObject.Position.Y, floorObject.Position.Z, floorObject.Position.RegionID, + Position.X, Position.Y, Position.Z, Position.RegionID); } catch { @@ -12439,26 +12292,20 @@ public override void LoadFromDatabase(DataObject obj) #endregion #region setting world-init-position (delegate to PlayerCharacter dont make sense) - m_x = DBCharacter.Xpos; - m_y = DBCharacter.Ypos; - m_z = DBCharacter.Zpos; - m_Heading = (ushort)DBCharacter.Direction; + Position = DBCharacter.GetPosition(); //important, use CurrentRegion property //instead because it sets the Region too CurrentRegionID = (ushort)DBCharacter.Region; - if (CurrentRegion == null || CurrentRegion.GetZone(m_x, m_y) == null) + if (CurrentRegion == null || CurrentRegion.GetZone(Coordinate) == null) { - log.WarnFormat("Invalid region/zone on char load ({0}): x={1} y={2} z={3} reg={4}; moving to bind point.", DBCharacter.Name, X, Y, Z, DBCharacter.Region); - m_x = DBCharacter.BindXpos; - m_y = DBCharacter.BindYpos; - m_z = DBCharacter.BindZpos; - m_Heading = (ushort)DBCharacter.BindHeading; - CurrentRegionID = (ushort)DBCharacter.BindRegion; + log.WarnFormat("Invalid region/zone on char load ({0}): x={1} y={2} z={3} reg={4}; moving to bind point." + , DBCharacter.Name, Coordinate.X, Coordinate.Y, Coordinate.Z, DBCharacter.Region); + Position = DBCharacter.GetBindPosition(); } - for (int i = 0; i < m_lastUniqueLocations.Length; i++) + for (int i = 0; i < LastUniquePositions.Length; i++) { - m_lastUniqueLocations[i] = new GameLocation(null, CurrentRegionID, m_x, m_y, m_z); + LastUniquePositions[i] = Position; } #endregion @@ -12474,7 +12321,7 @@ public override void LoadFromDatabase(DataObject obj) SetCharacterClass(CharacterClass.GetClass(DBCharacter.Class)); - m_currentSpeed = 0; + CurrentSpeed = 0; if (MaxSpeedBase == 0) MaxSpeedBase = PLAYER_BASE_SPEED; @@ -12590,14 +12437,9 @@ public override void SaveIntoDatabase() DBCharacter.ActiveWeaponSlot = (byte)((byte)ActiveWeaponSlot | (byte)ActiveQuiverSlot); if (m_stuckFlag) { - lock (m_lastUniqueLocations) + lock (LastUniquePositions) { - GameLocation loc = m_lastUniqueLocations[m_lastUniqueLocations.Length - 1]; - DBCharacter.Xpos = loc.X; - DBCharacter.Ypos = loc.Y; - DBCharacter.Zpos = loc.Z; - DBCharacter.Region = loc.RegionID; - DBCharacter.Direction = loc.Heading; + DBCharacter.SetPosition(LastUniquePositions[LastUniquePositions.Length - 1]); } } GameServer.Database.SaveObject(DBCharacter); @@ -13012,17 +12854,17 @@ protected override void OnTick() fieldOfListen += (npc.Level - player.Level) * 3; } - double angle = npc.GetAngle( player ); + var angle = npc.GetAngleTo(player.Coordinate); //player in front fieldOfView /= 2.0; - bool canSeePlayer = (angle >= 360 - fieldOfView || angle < fieldOfView); + bool canSeePlayer = (angle.InDegrees >= 360 - fieldOfView || angle.InDegrees < fieldOfView); //If npc can not see nor hear the player, continue the loop fieldOfListen /= 2.0; if (canSeePlayer == false && - !(angle >= (45 + 60) - fieldOfListen && angle < (45 + 60) + fieldOfListen) && - !(angle >= (360 - 45 - 60) - fieldOfListen && angle < (360 - 45 - 60) + fieldOfListen)) + !(angle.InDegrees >= (45 + 60) - fieldOfListen && angle.InDegrees < (45 + 60) + fieldOfListen) && + !(angle.InDegrees >= (360 - 45 - 60) - fieldOfListen && angle.InDegrees < (360 - 45 - 60) + fieldOfListen)) continue; double chanceMod = 1.0; @@ -15625,7 +15467,6 @@ public GamePlayer(GameClient client, DOLCharacters dbChar) m_debuffBonus = new PropertyIndexer((int)eProperty.MaxProperty); m_buff4Bonus = new PropertyIndexer((int)eProperty.MaxProperty); m_itemBonus = new PropertyIndexer((int)eProperty.MaxProperty); - m_lastUniqueLocations = new GameLocation[4]; m_canFly = false; CreateInventory(); diff --git a/GameServer/gameobjects/GameSiegeWeapon.cs b/GameServer/gameobjects/GameSiegeWeapon.cs index 96a2a9cb03..b817e0bafe 100644 --- a/GameServer/gameobjects/GameSiegeWeapon.cs +++ b/GameServer/gameobjects/GameSiegeWeapon.cs @@ -24,13 +24,11 @@ using DOL.Database; using DOL.Events; using DOL.GS.Keeps; +using DOL.GS.Geometry; namespace DOL.GS { #region GameSiegeweapon - /// - /// Description résumée de GameSiegeWeapon. - /// public class GameSiegeWeapon : GameMovingObject { public GameSiegeWeapon() @@ -184,6 +182,17 @@ public string ItemId get { return m_itemId; } set { m_itemId = value; } } + + public Coordinate AimCoordinate + { + get + { + var targetPosition = Position.Zero; + if(TargetObject != null) targetPosition = TargetObject.Position; + else if(GroundTargetPosition != Position.Nowhere) targetPosition = GroundTargetPosition; + return targetPosition.Coordinate; + } + } #endregion #region public methode public void TakeControl(GamePlayer player) @@ -235,10 +244,10 @@ public void Aim() if (Owner.TargetObject == null) return; if (!GameServer.ServerRules.IsAllowedToAttack(Owner, ((GameLiving)Owner.TargetObject), true)) return; CurrentState &= ~eState.Aimed; - SetGroundTarget(Owner.TargetObject.X, Owner.TargetObject.Y, Owner.TargetObject.Z); + GroundTargetPosition = Owner.TargetObject.Position; TargetObject = Owner.TargetObject; SiegeWeaponTimer.CurrentAction = SiegeTimer.eAction.Aiming; - Heading = GetHeading( GroundTarget ); + TurnTo(GroundTargetPosition.Coordinate); PreAction(); if (Owner != null) { @@ -262,8 +271,8 @@ public void Move() { if (!CanUse()) return; if (!m_enableToMove) return; - if (Owner == null || Owner.GroundTarget == null) return; - if ( !this.IsWithinRadius( Owner.GroundTarget, 1000 ) ) + if (Owner == null || Owner.GroundTargetPosition == Position.Nowhere) return; + if (Coordinate.DistanceTo(Owner.GroundTargetPosition) > 1000) { Owner.Out.SendMessage("Ground target is too far away to move to!", eChatType.CT_System, eChatLoc.CL_SystemWindow); @@ -277,7 +286,7 @@ public void Move() } //let's check if we are trying to move too close to a door, if we are, don't move - foreach (IDoor door in Owner.CurrentRegion.GetDoorsInRadius(Owner.GroundTarget.X, Owner.GroundTarget.Y, Owner.GroundTarget.Z, (ushort)(AttackRange - 50), false)) + foreach (IDoor door in Owner.CurrentRegion.GetDoorsInRadius(Owner.GroundTargetPosition.Coordinate, (ushort)(AttackRange - 50), false)) { if (door is GameKeepDoor) { @@ -288,7 +297,7 @@ public void Move() //unarmed siege weapon CurrentState &= ~eState.Armed; - WalkTo(Owner.GroundTarget, 100); + WalkTo(Owner.GroundTargetPosition.Coordinate, 100); } public void StopMove() @@ -329,10 +338,9 @@ public void Fire() } return; } - if (TargetObject != null) - SetGroundTarget(TargetObject.X, TargetObject.Y, TargetObject.Z); - if (GroundTarget == null) - return; + if (TargetObject != null) GroundTargetPosition = TargetObject.Position; + + if (GroundTargetPosition == Position.Nowhere) return; new RegionTimer(this, new RegionTimerCallback(MakeDelayedDamage), GetActionDelay(SiegeTimer.eAction.Fire)); BroadcastFireAnimation(GetActionDelay(SiegeTimer.eAction.Fire)); if (Owner != null) diff --git a/GameServer/gameobjects/GameStaticItem.cs b/GameServer/gameobjects/GameStaticItem.cs index 1b94ce3c18..746bcf2d58 100644 --- a/GameServer/gameobjects/GameStaticItem.cs +++ b/GameServer/gameobjects/GameStaticItem.cs @@ -20,6 +20,7 @@ using System.Collections; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.Language; namespace DOL.GS @@ -195,29 +196,25 @@ public override void LoadFromDatabase(DataObject obj) base.LoadFromDatabase(obj); m_loadedFromScript = false; - CurrentRegionID = item.Region; TranslationId = item.TranslationId; Name = item.Name; ExamineArticle = item.ExamineArticle; Model = item.Model; Emblem = item.Emblem; Realm = (eRealm)item.Realm; - Heading = item.Heading; - X = item.X; - Y = item.Y; - Z = item.Z; + Position = Position.Create(item.Region, item.X, item.Y, item.Z, item.Heading); RespawnInterval = item.RespawnInterval; } - /// - /// Gets or sets the heading of this item - /// - public override ushort Heading + /// + /// Gets or sets the heading of this item + /// + public override Angle Orientation { - get { return base.Heading; } + get => base.Orientation; set { - base.Heading = value; + base.Orientation = value; if (ObjectState == eObjectState.Active) { foreach (GamePlayer player in GetPlayersInRadius(WorldMgr.VISIBILITY_DISTANCE)) @@ -282,11 +279,11 @@ public override void SaveIntoDatabase() obj.Model = Model; obj.Emblem = Emblem; obj.Realm = (byte)Realm; - obj.Heading = Heading; - obj.Region = CurrentRegionID; - obj.X = X; - obj.Y = Y; - obj.Z = Z; + obj.Heading = Orientation.InHeading; + obj.Region = Position.RegionID; + obj.X = Position.X; + obj.Y = Position.Y; + obj.Z = Position.Z; obj.ClassType = this.GetType().ToString(); obj.RespawnInterval = RespawnInterval; diff --git a/GameServer/gameobjects/GameTeleporter.cs b/GameServer/gameobjects/GameTeleporter.cs index 6c805de1a7..abcc6b3f02 100644 --- a/GameServer/gameobjects/GameTeleporter.cs +++ b/GameServer/gameobjects/GameTeleporter.cs @@ -29,6 +29,7 @@ using DOL.GS.Spells; using log4net; using System.Reflection; +using DOL.GS.Geometry; namespace DOL.GS { @@ -142,15 +143,15 @@ protected virtual bool GetTeleportLocation(GamePlayer player, string text) } else { - IGameLocation location = house.OutdoorJumpPoint; + var position = house.OutdoorJumpPosition; Teleport teleport = new Teleport(); teleport.TeleportID = "personal"; teleport.Realm = (int)DestinationRealm; - teleport.RegionID = location.RegionID; - teleport.X = location.X; - teleport.Y = location.Y; - teleport.Z = location.Z; - teleport.Heading = location.Heading; + teleport.RegionID = position.RegionID; + teleport.X = position.X; + teleport.Y = position.Y; + teleport.Z = position.Z; + teleport.Heading = position.Orientation.InHeading; OnDestinationPicked(player, teleport); return true; } @@ -161,16 +162,14 @@ protected virtual bool GetTeleportLocation(GamePlayer player, string text) if (text.ToLower() == "hearth") { // Check if player has set a house bind - if (!(player.BindHouseRegion > 0)) + if (!(player.BindHousePosition.RegionID > 0)) { SayTo(player, "Sorry, you haven't set any house bind point yet."); return false; } // Check if the house at the player's house bind location still exists - ArrayList houses = (ArrayList)HouseMgr.GetHousesCloseToSpot((ushort)player. - BindHouseRegion, player.BindHouseXpos, player. - BindHouseYpos, 700); + ArrayList houses = (ArrayList)HouseMgr.GetHousesCloseToSpot(player.BindHousePosition, radius: 700); if (houses.Count == 0) { SayTo(player, "I'm afraid I can't teleport you to your hearth since the house at your " + @@ -210,11 +209,11 @@ protected virtual bool GetTeleportLocation(GamePlayer player, string text) Teleport teleport = new Teleport(); teleport.TeleportID = "hearth"; teleport.Realm = (int)DestinationRealm; - teleport.RegionID = player.BindHouseRegion; - teleport.X = player.BindHouseXpos; - teleport.Y = player.BindHouseYpos; - teleport.Z = player.BindHouseZpos; - teleport.Heading = player.BindHouseHeading; + teleport.RegionID = player.BindHousePosition.RegionID; + teleport.X = player.BindHousePosition.X; + teleport.Y = player.BindHousePosition.Y; + teleport.Z = player.BindHousePosition.Z; + teleport.Heading = player.BindHousePosition.Orientation.InHeading; OnDestinationPicked(player, teleport); return true; } @@ -229,15 +228,15 @@ protected virtual bool GetTeleportLocation(GamePlayer player, string text) } else { - IGameLocation location = house.OutdoorJumpPoint; + var position = house.OutdoorJumpPosition; Teleport teleport = new Teleport(); teleport.TeleportID = "guild house"; teleport.Realm = (int)DestinationRealm; - teleport.RegionID = location.RegionID; - teleport.X = location.X; - teleport.Y = location.Y; - teleport.Z = location.Z; - teleport.Heading = location.Heading; + teleport.RegionID = position.RegionID; + teleport.X = position.X; + teleport.Y = position.Y; + teleport.Z = position.Z; + teleport.Heading = position.Orientation.InHeading; OnDestinationPicked(player, teleport); return true; } @@ -331,9 +330,8 @@ protected virtual void OnTeleport(GamePlayer player, Teleport destination) if (player.InCombat == false && GameRelic.IsPlayerCarryingRelic(player) == false) { player.LeaveHouse(); - GameLocation currentLocation = new GameLocation("TeleportStart", player.CurrentRegionID, player.X, player.Y, player.Z); - player.MoveTo((ushort)destination.RegionID, destination.X, destination.Y, destination.Z, (ushort)destination.Heading); - GameServer.ServerRules.OnPlayerTeleport(player, currentLocation, destination); + player.MoveTo(destination.GetPosition()); + GameServer.ServerRules.OnPlayerTeleport(player, destination); } } } diff --git a/GameServer/gameobjects/InventoryItem/GameInventorySiegeBallista.cs b/GameServer/gameobjects/InventoryItem/GameInventorySiegeBallista.cs index 66ce52a34e..0a385e39ce 100644 --- a/GameServer/gameobjects/InventoryItem/GameInventorySiegeBallista.cs +++ b/GameServer/gameobjects/InventoryItem/GameInventorySiegeBallista.cs @@ -72,10 +72,7 @@ public override bool Use(GamePlayer player) bal.Level = Convert.ToByte(Level); bal.Name = Name; bal.Model = (ushort) Model; - bal.X = player.X; - bal.Y = player.Y; - bal.Z = player.Z; - bal.CurrentRegion = player.CurrentRegion; + bal.Position = player.Position; bal.Realm = player.Realm; bal.AddToWorld(); diff --git a/GameServer/gameobjects/InventoryItem/GameInventorySiegeCatapult.cs b/GameServer/gameobjects/InventoryItem/GameInventorySiegeCatapult.cs index fdaae23f87..8f2a6fcfd1 100644 --- a/GameServer/gameobjects/InventoryItem/GameInventorySiegeCatapult.cs +++ b/GameServer/gameobjects/InventoryItem/GameInventorySiegeCatapult.cs @@ -72,10 +72,7 @@ public override bool Use(GamePlayer player) cat.Level = Convert.ToByte(Level); cat.Name = Name; cat.Model = (ushort) Model; - cat.X = player.X; - cat.Y = player.Y; - cat.Z = player.Z; - cat.CurrentRegion = player.CurrentRegion; + cat.Position = player.Position; cat.Realm = player.Realm; cat.AddToWorld(); diff --git a/GameServer/gameobjects/InventoryItem/GameInventorySiegeRam.cs b/GameServer/gameobjects/InventoryItem/GameInventorySiegeRam.cs index 469ecee0a0..59bc1c0c01 100644 --- a/GameServer/gameobjects/InventoryItem/GameInventorySiegeRam.cs +++ b/GameServer/gameobjects/InventoryItem/GameInventorySiegeRam.cs @@ -72,10 +72,7 @@ public override bool Use(GamePlayer player) ram.Level = Convert.ToByte(Level); ram.Name = Name; ram.Model = (ushort) Model; - ram.X = player.X; - ram.Y = player.Y; - ram.Z = player.Z; - ram.CurrentRegion = player.CurrentRegion; + ram.Position = player.Position; ram.Realm = player.Realm; ram.AddToWorld(); diff --git a/GameServer/gameobjects/InventoryItem/GameInventorySiegeTrebuchet.cs b/GameServer/gameobjects/InventoryItem/GameInventorySiegeTrebuchet.cs index f783191cfc..927357b647 100644 --- a/GameServer/gameobjects/InventoryItem/GameInventorySiegeTrebuchet.cs +++ b/GameServer/gameobjects/InventoryItem/GameInventorySiegeTrebuchet.cs @@ -72,10 +72,7 @@ public override bool Use(GamePlayer player) bal.Level = Convert.ToByte(Level); bal.Name = Name; bal.Model = (ushort) Model; - bal.X = player.X; - bal.Y = player.Y; - bal.Z = player.Z; - bal.CurrentRegion = player.CurrentRegion; + bal.Position = player.Position; bal.Realm = player.Realm; bal.AddToWorld(); diff --git a/GameServer/gameobjects/SiegeWeapon/gamesiegecatapult.cs b/GameServer/gameobjects/SiegeWeapon/gamesiegecatapult.cs index dec645907f..197496aaf3 100644 --- a/GameServer/gameobjects/SiegeWeapon/gamesiegecatapult.cs +++ b/GameServer/gameobjects/SiegeWeapon/gamesiegecatapult.cs @@ -18,6 +18,7 @@ */ using System; using System.Collections; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; namespace DOL.GS @@ -65,14 +66,14 @@ protected IList SelectTargets() { ArrayList list = new ArrayList(20); - foreach (GamePlayer player in WorldMgr.GetPlayersCloseToSpot(this.CurrentRegionID, GroundTarget.X, GroundTarget.Y, GroundTarget.Z, (ushort)150)) + foreach (GamePlayer player in WorldMgr.GetPlayersCloseToSpot(GroundTargetPosition, (ushort)150)) { if (GameServer.ServerRules.IsAllowedToAttack(Owner, player, true)) { list.Add(player); } } - foreach (GameNPC npc in WorldMgr.GetNPCsCloseToSpot(this.CurrentRegionID, GroundTarget.X, GroundTarget.Y, GroundTarget.Z, (ushort)150)) + foreach (GameNPC npc in WorldMgr.GetNPCsCloseToSpot(GroundTargetPosition, (ushort)150)) { if (GameServer.ServerRules.IsAllowedToAttack(Owner, npc, true)) { @@ -93,7 +94,7 @@ public override void DoDamage() //todo remove ammo + spell in db and uncomment //m_spellHandler.StartSpell(player); base.DoDamage();//anim mut be called after damage - if (GroundTarget == null) return; + if (GroundTargetPosition == Position.Nowhere) return; IList targets = SelectTargets(); foreach (GameLiving living in targets) diff --git a/GameServer/gameobjects/SiegeWeapon/gamesiegecauldron.cs b/GameServer/gameobjects/SiegeWeapon/gamesiegecauldron.cs index 44853e917f..02d0b65ba6 100644 --- a/GameServer/gameobjects/SiegeWeapon/gamesiegecauldron.cs +++ b/GameServer/gameobjects/SiegeWeapon/gamesiegecauldron.cs @@ -22,6 +22,7 @@ using DOL.GS.PacketHandler; using DOL.GS.Spells; using DOL.GS.Keeps; +using DOL.GS.Geometry; namespace DOL.GS { @@ -42,7 +43,7 @@ public GameSiegeCauldron() Effect = 0x8A1; Model = 0xA2F; CurrentState = eState.Aimed; - SetGroundTarget(X, Y, Z - 100); + GroundTargetPosition = Position - Vector.Create(z: 100); ActionDelay = new int[] { 0, //none @@ -55,7 +56,7 @@ public GameSiegeCauldron() public override bool AddToWorld() { - SetGroundTarget(X, Y, Component.Keep.Z); + GroundTargetPosition = Position.With(z: Component.Keep.Z); return base.AddToWorld(); } diff --git a/GameServer/gameutils/DoorMgr.cs b/GameServer/gameutils/DoorMgr.cs index e26c1baf8a..e589923da9 100644 --- a/GameServer/gameutils/DoorMgr.cs +++ b/GameServer/gameutils/DoorMgr.cs @@ -25,6 +25,7 @@ using DOL.GS.Keeps; using log4net; +using DOL.GS.Geometry; namespace DOL.GS { @@ -67,7 +68,7 @@ public static bool LoadDoor(DBDoor door) if (currentZone == null) return false; //check if the door is a keep door - foreach (AbstractArea area in currentZone.GetAreasOfSpot(door.X, door.Y, door.Z)) + foreach (AbstractArea area in currentZone.GetAreasOfSpot(Coordinate.Create(door.X, door.Y, door.Z))) { if (area is KeepArea) { diff --git a/GameServer/gameutils/GamePlayerUtils.cs b/GameServer/gameutils/GamePlayerUtils.cs index d42879a310..552be2f502 100644 --- a/GameServer/gameutils/GamePlayerUtils.cs +++ b/GameServer/gameutils/GamePlayerUtils.cs @@ -23,6 +23,7 @@ using DOL.Language; using DOL.Database; +using DOL.GS.Geometry; namespace DOL.GS { @@ -31,36 +32,23 @@ namespace DOL.GS /// public static class GamePlayerUtils { - #region Spot and Area Description / Translation - /// - /// Get Spot Description Checking Any Area with Description or Zone Description - /// - /// - /// - /// - public static string GetSpotDescription(this Region reg, IPoint3D spot) - { - return reg.GetSpotDescription(spot.X, spot.Y, spot.Z); - } - - /// - /// Get Spot Description Checking Any Area with Description or Zone Description - /// - /// - /// - /// - /// - /// + #region Spot and Area Description / Translation + [Obsolete("This is going to be removed.")] + public static string GetSpotDescription(this Region reg, IPoint3D spot) + => reg.GetSpotDescription(spot.X, spot.Y, spot.Z); + + [Obsolete("This is going to be removed.")] public static string GetSpotDescription(this Region reg, int x, int y, int z) { + var coordinate = Coordinate.Create(x,y,z); if (reg != null) { - var area = reg.GetAreasOfSpot(x, y, z).OfType().FirstOrDefault(a => a.DisplayMessage && !string.IsNullOrEmpty(a.Description)); + var area = reg.GetAreasOfSpot(coordinate).OfType().FirstOrDefault(a => a.DisplayMessage && !string.IsNullOrEmpty(a.Description)); if (area != null) return area.Description; - var zone = reg.GetZone(x, y); + var zone = reg.GetZone(coordinate); if (zone != null) return zone.Description; @@ -71,32 +59,19 @@ public static string GetSpotDescription(this Region reg, int x, int y, int z) return string.Empty; } - /// - /// Get Spot Description Checking Any Area with Description or Zone Description and Try Translating it - /// - /// - /// - /// - /// - public static string GetTranslatedSpotDescription(this Region reg, GameClient client, IPoint3D spot) - { - return reg.GetTranslatedSpotDescription(client, spot.X, spot.Y, spot.Z); - } - - /// - /// Get Spot Description Checking Any Area with Description or Zone Description and Try Translating it - /// - /// - /// - /// - /// - /// - /// - public static string GetTranslatedSpotDescription(this Region reg, GameClient client, int x, int y, int z) + [Obsolete("This is going to be removed.")] + public static string GetTranslatedSpotDescription(this Region reg, GameClient client, IPoint3D spot) + => reg.GetTranslatedSpotDescription(client, spot.X, spot.Y, spot.Z); + + [Obsolete("This is going to be removed.")] + public static string GetTranslatedSpotDescription(this Region reg, GameClient client, int x, int y, int z) + => GetTranslatedSpotDescription(reg, client, Coordinate.Create(x, y, z)); + + public static string GetTranslatedSpotDescription(this Region reg, GameClient client, Coordinate coordinate) { if (reg != null) { - var area = reg.GetAreasOfSpot(x, y, z).OfType().FirstOrDefault(a => a.DisplayMessage); + var area = reg.GetAreasOfSpot(coordinate).OfType().FirstOrDefault(a => a.DisplayMessage); // Try Translate Area First if (area != null) @@ -109,7 +84,7 @@ public static string GetTranslatedSpotDescription(this Region reg, GameClient cl return area.Description; } - var zone = reg.GetZone(x, y); + var zone = reg.GetZone(coordinate); // Try Translate Zone if (zone != null) @@ -126,64 +101,34 @@ public static string GetTranslatedSpotDescription(this Region reg, GameClient cl return string.Empty; } - - /// - /// Get Player Spot Description Checking Any Area with Description or Zone Description and Try Translating it - /// - /// - /// + + [Obsolete("This is going to be removed.")] public static string GetTranslatedSpotDescription(this GamePlayer player) { return player.GetTranslatedSpotDescription(player.CurrentRegion, player.X, player.Y, player.Z); } - - /// - /// Get Player Spot Description Checking Any Area with Description or Zone Description and Try Translating it - /// - /// - /// - /// - /// - /// - /// + + [Obsolete("This is going to be removed.")] public static string GetTranslatedSpotDescription(this GamePlayer player, Region region, int x, int y, int z) { return player.Client.GetTranslatedSpotDescription(region, x, y, z); } - - /// - /// Get Client Spot Description Checking Any Area with Description or Zone Description and Try Translating it - /// - /// - /// - /// - /// - /// - /// + + [Obsolete("This is going to be removed.")] public static string GetTranslatedSpotDescription(this GameClient client, Region region, int x, int y, int z) { return region.GetTranslatedSpotDescription(client, x, y, z); } - - /// - /// Get Player Spot Description Checking Any Area with Description or Zone Description - /// - /// - /// + + [Obsolete("This is going to be removed.")] public static string GetSpotDescription(this GamePlayer player) { return player.GetTranslatedSpotDescription(); } - - /// - /// Get Player's Bind Spot Description Checking Any Area with Description or Zone Description - /// - /// - /// - public static string GetBindSpotDescription(this GamePlayer player) - { - return player.GetTranslatedSpotDescription(WorldMgr.GetRegion((ushort)player.BindRegion), player.BindXpos, player.BindYpos, player.BindZpos); - } + + [Obsolete("This is going to be removed.")] + public static string GetBindSpotDescription(this GamePlayer player) + => WorldMgr.GetRegion((ushort)player.BindPosition.RegionID).GetTranslatedSpotDescription(player.Client,player.BindPosition.Coordinate); #endregion #region player skills / bonuses diff --git a/GameServer/gameutils/GuildBanner.cs b/GameServer/gameutils/GuildBanner.cs index 1b08a97c69..2a51cf2dc2 100644 --- a/GameServer/gameutils/GuildBanner.cs +++ b/GameServer/gameutils/GuildBanner.cs @@ -7,6 +7,7 @@ using DOL.Database; using log4net; using DOL.GS.Effects; +using DOL.GS.Geometry; namespace DOL.GS { @@ -190,12 +191,8 @@ protected void PlayerDied(DOLEvent e, object sender, EventArgs args) m_player.Guild.SendMessageToGuildMembers(m_player.Name + " has dropped the guild banner!", eChatType.CT_Guild, eChatLoc.CL_SystemWindow); gameItem = new WorldInventoryItem(m_item); - Point2D point = m_player.GetPointFromHeading(m_player.Heading, 30); - gameItem.X = point.X; - gameItem.Y = point.Y; - gameItem.Z = m_player.Z; - gameItem.Heading = m_player.Heading; - gameItem.CurrentRegionID = m_player.CurrentRegionID; + var point = m_player.Position + Vector.Create(m_player.Orientation, length: 30); + gameItem.Position = point; gameItem.AddOwner(m_player); if (playerKiller != null) diff --git a/GameServer/gameutils/IDoor.cs b/GameServer/gameutils/IDoor.cs index f60435c73c..f35a3dcb32 100644 --- a/GameServer/gameutils/IDoor.cs +++ b/GameServer/gameutils/IDoor.cs @@ -18,24 +18,22 @@ */ using DOL.Database; +using DOL.GS.Geometry; namespace DOL.GS { - /// - /// The state a door can take - /// public enum eDoorState { Open, Closed } - /// - /// IDoor is interface for door and keepdoor - /// - public interface IDoor : IPoint3D + + public interface IDoor { string Name {get;} uint Flag {get;} + Coordinate Coordinate { get; } + Angle Orientation { get; } ushort Heading {get;} ushort ZoneID { get; } eRealm Realm {get;} diff --git a/GameServer/gameutils/InventoryLogging.cs b/GameServer/gameutils/InventoryLogging.cs index 0336002338..be09462aeb 100644 --- a/GameServer/gameutils/InventoryLogging.cs +++ b/GameServer/gameutils/InventoryLogging.cs @@ -53,7 +53,7 @@ public static class InventoryLogging }; public static Func GetGameObjectString = obj => - obj == null ? "(null)" : ("(" + obj.Name + ";" + obj.GetType() + ";" + obj.X + ";" + obj.Y + ";" + obj.Z + ";" + obj.CurrentRegionID + ")"); + obj == null ? "(null)" : ("(" + obj.Name + ";" + obj.GetType() + ";" + obj.Coordinate + ";" + obj.Position.RegionID + ")"); public static Func GetItemString = (item, count) => item == null ? "(null)" : ("(" + count + ";" + item.Name + ";" + item.Id_nb + ")"); diff --git a/GameServer/gameutils/LosCheckMgr.cs b/GameServer/gameutils/LosCheckMgr.cs index 5c1ffc3924..2b2fb03736 100644 --- a/GameServer/gameutils/LosCheckMgr.cs +++ b/GameServer/gameutils/LosCheckMgr.cs @@ -822,11 +822,11 @@ private void UpdateVincinityLosCache(GameObject source, GameObject target, bool if((isObjectFromPlayer(target) || isObjectFromPlayer(source)) && isObjectFromPlayer(contamined)) { // Update using PvP cache Timeout - if(LOSMGR_PET_CONTAMINATION_RADIUS > 0 && source.GetDistanceTo(contamined, LOSMGR_CONTAMINATION_ZFACTOR) <= LOSMGR_PET_CONTAMINATION_RADIUS) + if(LOSMGR_PET_CONTAMINATION_RADIUS > 0 && source.GetDistanceTo(contamined.Position, LOSMGR_CONTAMINATION_ZFACTOR) <= LOSMGR_PET_CONTAMINATION_RADIUS) { // FIXME debug if(LOSMGR_DEBUG_LEVEL >= LOSMGR_DEBUG_DEBUG) - log.Warn("LOSMGR_D : Contamination Los Check (Pet PvP) of "+source.Name+" and "+target.Name+" Contaminated "+contamined.Name+", range : "+source.GetDistanceTo(contamined, LOSMGR_CONTAMINATION_ZFACTOR)); + log.Warn("LOSMGR_D : Contamination Los Check (Pet PvP) of "+source.Name+" and "+target.Name+" Contaminated "+contamined.Name+", range : "+source.GetDistanceTo(contamined.Position, LOSMGR_CONTAMINATION_ZFACTOR)); UpdateLosCacheItem(source, target, losOK, LOSMGR_PLAYER_VS_PLAYER_CACHE_TIMEOUT, time); } @@ -838,11 +838,11 @@ private void UpdateVincinityLosCache(GameObject source, GameObject target, bool if(contamined is GameKeepGuard) { // Update using PvE cache Timeout - if(LOSMGR_GUARD_CONTAMINATION_RADIUS > 0 && source.GetDistanceTo(contamined, LOSMGR_CONTAMINATION_ZFACTOR) <= LOSMGR_GUARD_CONTAMINATION_RADIUS) + if(LOSMGR_GUARD_CONTAMINATION_RADIUS > 0 && source.GetDistanceTo(contamined.Position, LOSMGR_CONTAMINATION_ZFACTOR) <= LOSMGR_GUARD_CONTAMINATION_RADIUS) { // FIXME debug if(LOSMGR_DEBUG_LEVEL >= LOSMGR_DEBUG_DEBUG) - log.Warn("LOSMGR_D : Contamination Los Check (Grd PvE) of "+source.Name+" and "+target.Name+" Contaminated "+contamined.Name+", range : "+source.GetDistanceTo(contamined, LOSMGR_CONTAMINATION_ZFACTOR)); + log.Warn("LOSMGR_D : Contamination Los Check (Grd PvE) of "+source.Name+" and "+target.Name+" Contaminated "+contamined.Name+", range : "+source.GetDistanceTo(contamined.Position, LOSMGR_CONTAMINATION_ZFACTOR)); UpdateLosCacheItem(source, target, losOK, LOSMGR_PLAYER_VS_ENVIRONMENT_CACHE_TIMEOUT, time); } @@ -854,11 +854,11 @@ private void UpdateVincinityLosCache(GameObject source, GameObject target, bool if((isObjectFromPlayer(target) || isObjectFromPlayer(source)) || isObjectFromPlayer(contamined)) { // Update using PvE cache Timeout - if(LOSMGR_NPC_CONTAMINATION_RADIUS > 0 && source.GetDistanceTo(contamined, LOSMGR_CONTAMINATION_ZFACTOR) <= LOSMGR_NPC_CONTAMINATION_RADIUS) + if(LOSMGR_NPC_CONTAMINATION_RADIUS > 0 && source.GetDistanceTo(contamined.Position, LOSMGR_CONTAMINATION_ZFACTOR) <= LOSMGR_NPC_CONTAMINATION_RADIUS) { // FIXME debug if(LOSMGR_DEBUG_LEVEL >= LOSMGR_DEBUG_DEBUG) - log.Warn("LOSMGR_D : Contamination Los Check (Mob PvE) of "+source.Name+" and "+target.Name+" Contaminated "+contamined.Name+", range : "+source.GetDistanceTo(contamined, LOSMGR_CONTAMINATION_ZFACTOR)); + log.Warn("LOSMGR_D : Contamination Los Check (Mob PvE) of "+source.Name+" and "+target.Name+" Contaminated "+contamined.Name+", range : "+source.GetDistanceTo(contamined.Position, LOSMGR_CONTAMINATION_ZFACTOR)); UpdateLosCacheItem(source, target, losOK, LOSMGR_PLAYER_VS_ENVIRONMENT_CACHE_TIMEOUT, time); } @@ -868,11 +868,11 @@ private void UpdateVincinityLosCache(GameObject source, GameObject target, bool // else it's EvE radius - if(source.GetDistanceTo(contamined, LOSMGR_CONTAMINATION_ZFACTOR) <= LOSMGR_MAX_CONTAMINATION_RADIUS) + if(source.GetDistanceTo(contamined.Position, LOSMGR_CONTAMINATION_ZFACTOR) <= LOSMGR_MAX_CONTAMINATION_RADIUS) { // FIXME debug if(LOSMGR_DEBUG_LEVEL >= LOSMGR_DEBUG_DEBUG) - log.Warn("LOSMGR_D : Contamination Los Check (Mob EvE) of "+source.Name+" and "+target.Name+" Contaminated "+contamined.Name+", range : "+source.GetDistanceTo(contamined, LOSMGR_CONTAMINATION_ZFACTOR)); + log.Warn("LOSMGR_D : Contamination Los Check (Mob EvE) of "+source.Name+" and "+target.Name+" Contaminated "+contamined.Name+", range : "+source.GetDistanceTo(contamined.Position, LOSMGR_CONTAMINATION_ZFACTOR)); UpdateLosCacheItem(source, target, losOK, LOSMGR_ENVIRONMENT_VS_ENVIRONMENT_CACHE_TIMEOUT, time); } @@ -887,11 +887,11 @@ private void UpdateVincinityLosCache(GameObject source, GameObject target, bool // P v P if(target is GamePlayer || source is GamePlayer) { - if(LOSMGR_PLAYER_CONTAMINATION_RADIUS > 0 && source.GetDistanceTo(contamined, LOSMGR_CONTAMINATION_ZFACTOR) <= LOSMGR_PLAYER_CONTAMINATION_RADIUS) + if(LOSMGR_PLAYER_CONTAMINATION_RADIUS > 0 && source.GetDistanceTo(contamined.Position, LOSMGR_CONTAMINATION_ZFACTOR) <= LOSMGR_PLAYER_CONTAMINATION_RADIUS) { // FIXME debug if(LOSMGR_DEBUG_LEVEL >= LOSMGR_DEBUG_DEBUG) - log.Warn("LOSMGR_D : Contamination Los Check (Pl PvP) of "+source.Name+" and "+target.Name+" Contaminated "+contamined.Name+", range : "+source.GetDistanceTo(contamined, LOSMGR_CONTAMINATION_ZFACTOR)); + log.Warn("LOSMGR_D : Contamination Los Check (Pl PvP) of "+source.Name+" and "+target.Name+" Contaminated "+contamined.Name+", range : "+source.GetDistanceTo(contamined.Position, LOSMGR_CONTAMINATION_ZFACTOR)); UpdateLosCacheItem(source, target, losOK, LOSMGR_PLAYER_VS_PLAYER_CACHE_TIMEOUT, time); } @@ -902,11 +902,11 @@ private void UpdateVincinityLosCache(GameObject source, GameObject target, bool // Player to Pet if(isObjectFromPlayer(target) || isObjectFromPlayer(source)) { - if(LOSMGR_PET_CONTAMINATION_RADIUS > 0 && source.GetDistanceTo(contamined, LOSMGR_CONTAMINATION_ZFACTOR) <= LOSMGR_PET_CONTAMINATION_RADIUS) + if(LOSMGR_PET_CONTAMINATION_RADIUS > 0 && source.GetDistanceTo(contamined.Position, LOSMGR_CONTAMINATION_ZFACTOR) <= LOSMGR_PET_CONTAMINATION_RADIUS) { // FIXME debug if(LOSMGR_DEBUG_LEVEL >= LOSMGR_DEBUG_DEBUG) - log.Warn("LOSMGR_D : Contamination Los Check (Pl PvPets) of "+source.Name+" and "+target.Name+" Contaminated "+contamined.Name+", range : "+source.GetDistanceTo(contamined, LOSMGR_CONTAMINATION_ZFACTOR)); + log.Warn("LOSMGR_D : Contamination Los Check (Pl PvPets) of "+source.Name+" and "+target.Name+" Contaminated "+contamined.Name+", range : "+source.GetDistanceTo(contamined.Position, LOSMGR_CONTAMINATION_ZFACTOR)); UpdateLosCacheItem(source, target, losOK, LOSMGR_PLAYER_VS_PLAYER_CACHE_TIMEOUT, time); } @@ -914,11 +914,11 @@ private void UpdateVincinityLosCache(GameObject source, GameObject target, bool continue; } - if(source.GetDistanceTo(contamined, LOSMGR_CONTAMINATION_ZFACTOR) <= LOSMGR_NPC_CONTAMINATION_RADIUS) + if(source.GetDistanceTo(contamined.Position, LOSMGR_CONTAMINATION_ZFACTOR) <= LOSMGR_NPC_CONTAMINATION_RADIUS) { // FIXME debug if(LOSMGR_DEBUG_LEVEL >= LOSMGR_DEBUG_DEBUG) - log.Warn("LOSMGR_D : Contamination Los Check (Pl PvE) of "+source.Name+" and "+target.Name+" Contaminated "+contamined.Name+", range : "+source.GetDistanceTo(contamined, LOSMGR_CONTAMINATION_ZFACTOR)); + log.Warn("LOSMGR_D : Contamination Los Check (Pl PvE) of "+source.Name+" and "+target.Name+" Contaminated "+contamined.Name+", range : "+source.GetDistanceTo(contamined.Position, LOSMGR_CONTAMINATION_ZFACTOR)); // else we're in PvE, a player can't be in EvE UpdateLosCacheItem(source, target, losOK, LOSMGR_PLAYER_VS_ENVIRONMENT_CACHE_TIMEOUT, time); diff --git a/GameServer/gameutils/MovementMgr.cs b/GameServer/gameutils/MovementMgr.cs index 0294d3452a..9e7b6cb405 100644 --- a/GameServer/gameutils/MovementMgr.cs +++ b/GameServer/gameutils/MovementMgr.cs @@ -156,21 +156,20 @@ public static PathPoint LoadPath(string pathID) PathPoint prev = null; PathPoint first = null; - foreach (DBPathPoint pp in pathPoints.Values) + foreach (DBPathPoint dbPathPoint in pathPoints.Values) { - PathPoint p = new PathPoint(pp.X, pp.Y, pp.Z, pp.MaxSpeed, pathType); - p.WaitTime = pp.WaitTime; + var pathPoint = new PathPoint(dbPathPoint, pathType); if (first == null) { - first = p; + first = pathPoint; } - p.Prev = prev; + pathPoint.Prev = prev; if (prev != null) { - prev.Next = p; + prev.Next = pathPoint; } - prev = p; + prev = pathPoint; } return first; @@ -211,11 +210,10 @@ public static void SavePath(string pathID, PathPoint path) int i = 1; do { - DBPathPoint dbpp = new DBPathPoint(path.X, path.Y, path.Z, path.MaxSpeed); - dbpp.Step = i++; - dbpp.PathID = pathID; - dbpp.WaitTime = path.WaitTime; - GameServer.Database.AddObject(dbpp); + var dbPathPoint = path.GenerateDbEntry(); + dbPathPoint.Step = i++; + dbPathPoint.PathID = pathID; + GameServer.Database.AddObject(dbPathPoint); path = path.Next; } while (path != null && path != root); diff --git a/GameServer/gameutils/PathPoint.cs b/GameServer/gameutils/PathPoint.cs index 50309026ed..057c24bcba 100644 --- a/GameServer/gameutils/PathPoint.cs +++ b/GameServer/gameutils/PathPoint.cs @@ -18,85 +18,68 @@ */ using System; using DOL.Database; +using DOL.GS.Geometry; namespace DOL.GS.Movement { - /// - /// represents a point in a way path - /// - public class PathPoint : Point3D - { - protected int m_maxspeed; - protected PathPoint m_next = null; - protected PathPoint m_prev = null; - protected ePathType m_type; - protected bool m_flag; - protected int m_waitTime = 0; + public class PathPoint + { + public Coordinate Coordinate { get; set; } - public PathPoint(PathPoint pp) : this(pp, pp.MaxSpeed,pp.Type) {} + [Obsolete("Use .Coordinate instead!")] + public int X { get => Coordinate.X; set => Coordinate.With(x: value); } + [Obsolete("Use .Coordinate instead!")] + public int Y { get => Coordinate.Y; set => Coordinate.With(y: value); } + [Obsolete("Use .Coordinate instead!")] + public int Z { get => Coordinate.Z; set => Coordinate.With(z: value); } - public PathPoint(Point3D p, int maxspeed, ePathType type) : this(p.X, p.Y, p.Z, maxspeed, type) {} + [Obsolete("This is going to be removed.")] + public PathPoint(PathPoint pp) : this(pp.Coordinate, pp.MaxSpeed, pp.Type) { } - public PathPoint(int x, int y, int z, int maxspeed, ePathType type) : base(x, y, z) - { - m_maxspeed = maxspeed; - m_type = type; - m_flag = false; - m_waitTime = 0; - } + public PathPoint(Coordinate coordinate, int maxspeed, ePathType type) + { + Coordinate = coordinate; + MaxSpeed = maxspeed; + Type = type; + } - /// - /// Speed allowed after that waypoint in forward direction - /// - public int MaxSpeed - { - get { return m_maxspeed; } - set { m_maxspeed = value; } - } + public PathPoint(int x, int y, int z, int maxspeed, ePathType type) + : this(Coordinate.Create(x, y, z), maxspeed, type) { } - /// - /// next waypoint in path - /// - public PathPoint Next - { - get { return m_next; } - set { m_next = value; } - } + public PathPoint(DBPathPoint dbEntry, ePathType type) + { + Coordinate = Coordinate.Create(dbEntry.X, dbEntry.Y, dbEntry.Z); + MaxSpeed = dbEntry.MaxSpeed; + WaitTime = dbEntry.WaitTime; + Type = type; + } - /// - /// previous waypoint in path - /// - public PathPoint Prev - { - get { return m_prev; } - set { m_prev = value; } - } + public Angle AngleToNextPathPoint + => Coordinate.GetOrientationTo(Next.Coordinate); - /// - /// flag toggle when go through pathpoint - /// - public bool FiredFlag - { - get { return m_flag; } - set { m_flag = value; } - } + public int MaxSpeed { get; set; } - /// - /// path type - /// - public ePathType Type - { - get { return m_type; } - set { m_type = value; } - } + public PathPoint Prev { get; set; } + public PathPoint Next { get; set; } - /// - /// path type - /// - public int WaitTime - { - get { return m_waitTime; } - set { m_waitTime = value; } - } - } + /// + /// flag toggle when go through pathpoint + /// + public bool FiredFlag { get; set; } = false; + + public ePathType Type { get; set; } + + public int WaitTime { get; set; } = 0; + + public DBPathPoint GenerateDbEntry() + { + var dbPathPoint = new DBPathPoint(); + dbPathPoint.X = Coordinate.X; + dbPathPoint.Y = Coordinate.Y; + dbPathPoint.Z = Coordinate.Z; + dbPathPoint.MaxSpeed = MaxSpeed; + dbPathPoint.WaitTime = WaitTime; + return dbPathPoint; + } + } } diff --git a/GameServer/gameutils/RegionTimersResync.cs b/GameServer/gameutils/RegionTimersResync.cs index 15989ec85b..1022e6811f 100644 --- a/GameServer/gameutils/RegionTimersResync.cs +++ b/GameServer/gameutils/RegionTimersResync.cs @@ -204,14 +204,16 @@ private static void Resynch(object nullValue) } catch(Exception e) { - log.Error("Can't restart Brain in RegionTimerResynch, NPC Name = "+npc.Name+" X="+npc.X+"/Y="+npc.Y+"/Z="+npc.Z+"/R="+npc.CurrentRegion.ID+" "+e); + log.Error("Can't restart Brain in RegionTimerResynch, NPC Name = "+npc.Name + +" X="+npc.Position.X+"/Y="+npc.Position.Y+"/Z="+npc.Position.Z+"/R="+npc.Position.RegionID+" "+e); try { npc.Die(null); } catch(Exception ee) { - log.Error("Can't restart Brain and Kill NPC in RegionTimerResynch, NPC Name = "+npc.Name+" X="+npc.X+"/Y="+npc.Y+"/Z="+npc.Z+"/R="+npc.CurrentRegion.ID+" "+ee); + log.Error("Can't restart Brain and Kill NPC in RegionTimerResynch, NPC Name = "+npc.Name + +" X="+npc.Position.X+"/Y="+npc.Position.Y+"/Z="+npc.Position.Z+"/R="+npc.Position.RegionID+" "+ee); } } } diff --git a/GameServer/gameutils/Util.cs b/GameServer/gameutils/Util.cs index 1ce59fd035..c366aa327d 100644 --- a/GameServer/gameutils/Util.cs +++ b/GameServer/gameutils/Util.cs @@ -28,6 +28,7 @@ using DOL.GS.Utils; using Microsoft.Diagnostics.Runtime; +using DOL.GS.Geometry; namespace DOL.GS { @@ -414,29 +415,13 @@ public static string FormatTime(long seconds) return str.ToString(); } - /// - /// [Ganrod] Nidel: Check if between two values are near with tolerance. - /// - /// - /// - /// - /// + [Obsolete("This is going to be removed.")] public static bool IsNearValue(int valueToHave, int compareToCompare, ushort tolerance) { return FastMath.Abs(valueToHave - compareToCompare) <= FastMath.Abs(tolerance); } - /// - /// [Ganrod] Nidel: Check if between two distances are near with tolerance. - /// - /// X coord value to have - /// Y coord value to have - /// Z coord value to have - /// X coord value to compare - /// Y coord value to compare - /// Z coord value to compare - /// Tolerance distance between two coords - /// + [Obsolete("This is going to be removed.")] public static bool IsNearDistance(int xH, int yH, int zH, int xC, int yC, int zC, ushort tolerance) { return IsNearValue(xH, xC, tolerance) && IsNearValue(yH, yC, tolerance) && IsNearValue(zH, zC, tolerance); diff --git a/GameServer/gameutils/WarMapMgr.cs b/GameServer/gameutils/WarMapMgr.cs index c8ac7ae5ae..a693b6f162 100644 --- a/GameServer/gameutils/WarMapMgr.cs +++ b/GameServer/gameutils/WarMapMgr.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using DOL.GS; using log4net; +using DOL.GS.Geometry; namespace DOL.GS { @@ -56,8 +57,8 @@ public static bool AddFight(byte zoneid, int x, int y, byte realm1, byte realm2) long time = NFTime; Fight fight = new Fight(); fight.Zone = zoneid; - fight.X = (byte)((x - zone.XOffset) >> 14); - fight.Y = (byte)((y - zone.YOffset) >> 14); + fight.X = (byte)((x - zone.Offset.X) >> 14); + fight.Y = (byte)((y - zone.Offset.Y) >> 14); fight.Realm1 = realm1; fight.Realm2 = realm2; lock (m_fights) @@ -68,7 +69,15 @@ public static bool AddFight(byte zoneid, int x, int y, byte realm1, byte realm2) return true; } + [Obsolete("Use .AddGroup(Position,string,byte) instead!")] public static bool AddGroup(byte zoneid, int x, int y, string name, byte realm) + { + var zone = WorldMgr.GetZone(zoneid); + if (zone == null) return false; + return AddGroup(Position.Create(zone.ZoneRegion.ID, x, y), name, realm); + } + + public static bool AddGroup(Position position, string name, byte realm) { if (!ServerProperties.Properties.ENABLE_WARMAPMGR) return false; @@ -76,18 +85,20 @@ public static bool AddGroup(byte zoneid, int x, int y, string name, byte realm) lock (m_groups) { if (m_groups.ContainsKey(name)) return false; - m_groups.Add(name, new Dictionary()); - Zone zone = WorldMgr.GetZone(zoneid); + m_groups.Add(name, new Dictionary()); + var region = WorldMgr.GetRegion(position.RegionID); + var zone = region.GetZone(position.Coordinate); if (zone == null) return false; long time = NFTime; Group group = new Group(); - group.Zone = zoneid; - group.X = (byte)((x - zone.XOffset) >> 14); - group.Y = (byte)((y - zone.YOffset) >> 14); + group.Zone = (byte)zone.ID; + var groupPosition = position - zone.Offset; + group.X = (byte)(groupPosition.X >> 14); + group.Y = (byte)((groupPosition.Y) >> 14); group.Realm = realm; while (m_groups[name].ContainsKey(time)) time++; m_groups[name].Add(time, group); - } + } return true; } diff --git a/GameServer/housing/House.cs b/GameServer/housing/House.cs index afd7fc5ef0..bb32287477 100644 --- a/GameServer/housing/House.cs +++ b/GameServer/housing/House.cs @@ -23,19 +23,20 @@ using System.Reflection; using DOL.Database; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.Language; using log4net; namespace DOL.GS.Housing { - public class House : Point3D, IGameLocation + public class House { /// /// Defines a logger for this class. /// private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private readonly DBHouse _databaseItem; + private readonly DBHouse dbHouse; private readonly Dictionary _housePermissions; private readonly Dictionary _housepointItems; private readonly Dictionary _indoorItems; @@ -47,20 +48,20 @@ public class House : Point3D, IGameLocation public int HouseNumber { - get { return _databaseItem.HouseNumber; } - set { _databaseItem.HouseNumber = value; } + get { return dbHouse.HouseNumber; } + set { dbHouse.HouseNumber = value; } } public string OwnerID { - get { return _databaseItem.OwnerID; } - set { _databaseItem.OwnerID = value; } + get { return dbHouse.OwnerID; } + set { dbHouse.OwnerID = value; } } public int Model { - get { return _databaseItem.Model; } - set { _databaseItem.Model = value; } + get { return dbHouse.Model; } + set { dbHouse.Model = value; } } public eRealm Realm @@ -79,122 +80,122 @@ public eRealm Realm public int Emblem { - get { return _databaseItem.Emblem; } - set { _databaseItem.Emblem = value; } + get { return dbHouse.Emblem; } + set { dbHouse.Emblem = value; } } public int PorchRoofColor { - get { return _databaseItem.PorchRoofColor; } - set { _databaseItem.PorchRoofColor = value; } + get { return dbHouse.PorchRoofColor; } + set { dbHouse.PorchRoofColor = value; } } public int PorchMaterial { - get { return _databaseItem.PorchMaterial; } - set { _databaseItem.PorchMaterial = value; } + get { return dbHouse.PorchMaterial; } + set { dbHouse.PorchMaterial = value; } } public bool Porch { - get { return _databaseItem.Porch; } - set { _databaseItem.Porch = value; } + get { return dbHouse.Porch; } + set { dbHouse.Porch = value; } } public bool IndoorGuildBanner { - get { return _databaseItem.IndoorGuildBanner; } - set { _databaseItem.IndoorGuildBanner = value; } + get { return dbHouse.IndoorGuildBanner; } + set { dbHouse.IndoorGuildBanner = value; } } public bool IndoorGuildShield { - get { return _databaseItem.IndoorGuildShield; } - set { _databaseItem.IndoorGuildShield = value; } + get { return dbHouse.IndoorGuildShield; } + set { dbHouse.IndoorGuildShield = value; } } public bool OutdoorGuildBanner { - get { return _databaseItem.OutdoorGuildBanner; } - set { _databaseItem.OutdoorGuildBanner = value; } + get { return dbHouse.OutdoorGuildBanner; } + set { dbHouse.OutdoorGuildBanner = value; } } public bool OutdoorGuildShield { - get { return _databaseItem.OutdoorGuildShield; } - set { _databaseItem.OutdoorGuildShield = value; } + get { return dbHouse.OutdoorGuildShield; } + set { dbHouse.OutdoorGuildShield = value; } } public int RoofMaterial { - get { return _databaseItem.RoofMaterial; } - set { _databaseItem.RoofMaterial = value; } + get { return dbHouse.RoofMaterial; } + set { dbHouse.RoofMaterial = value; } } public int DoorMaterial { - get { return _databaseItem.DoorMaterial; } - set { _databaseItem.DoorMaterial = value; } + get { return dbHouse.DoorMaterial; } + set { dbHouse.DoorMaterial = value; } } public int WallMaterial { - get { return _databaseItem.WallMaterial; } - set { _databaseItem.WallMaterial = value; } + get { return dbHouse.WallMaterial; } + set { dbHouse.WallMaterial = value; } } public int TrussMaterial { - get { return _databaseItem.TrussMaterial; } - set { _databaseItem.TrussMaterial = value; } + get { return dbHouse.TrussMaterial; } + set { dbHouse.TrussMaterial = value; } } public int WindowMaterial { - get { return _databaseItem.WindowMaterial; } - set { _databaseItem.WindowMaterial = value; } + get { return dbHouse.WindowMaterial; } + set { dbHouse.WindowMaterial = value; } } public int Rug1Color { - get { return _databaseItem.Rug1Color; } - set { _databaseItem.Rug1Color = value; } + get { return dbHouse.Rug1Color; } + set { dbHouse.Rug1Color = value; } } public int Rug2Color { - get { return _databaseItem.Rug2Color; } - set { _databaseItem.Rug2Color = value; } + get { return dbHouse.Rug2Color; } + set { dbHouse.Rug2Color = value; } } public int Rug3Color { - get { return _databaseItem.Rug3Color; } - set { _databaseItem.Rug3Color = value; } + get { return dbHouse.Rug3Color; } + set { dbHouse.Rug3Color = value; } } public int Rug4Color { - get { return _databaseItem.Rug4Color; } - set { _databaseItem.Rug4Color = value; } + get { return dbHouse.Rug4Color; } + set { dbHouse.Rug4Color = value; } } public DateTime LastPaid { - get { return _databaseItem.LastPaid; } - set { _databaseItem.LastPaid = value; } + get { return dbHouse.LastPaid; } + set { dbHouse.LastPaid = value; } } public long KeptMoney { - get { return _databaseItem.KeptMoney; } - set { _databaseItem.KeptMoney = value; } + get { return dbHouse.KeptMoney; } + set { dbHouse.KeptMoney = value; } } public bool NoPurge { - get { return _databaseItem.NoPurge; } - set { _databaseItem.NoPurge = value; } + get { return dbHouse.NoPurge; } + set { dbHouse.NoPurge = value; } } public int UniqueID { get; set; } @@ -216,7 +217,7 @@ public IDictionary HousepointItems public DBHouse DatabaseItem { - get { return _databaseItem; } + get { return dbHouse; } } public IEnumerable> HousePermissions @@ -244,7 +245,7 @@ public bool IsOccupied { get { - foreach (GamePlayer player in WorldMgr.GetPlayersCloseToSpot(RegionID, X, Y, 25000, WorldMgr.VISIBILITY_DISTANCE)) + foreach (GamePlayer player in WorldMgr.GetPlayersCloseToSpot(Position.With(z: 25000), WorldMgr.VISIBILITY_DISTANCE)) { if (player.CurrentHouse == this && player.InHouse) { @@ -256,47 +257,70 @@ public bool IsOccupied } } - public override int X - { - get { return _databaseItem.X; } - set { _databaseItem.X = value; } - } - - public override int Y - { - get { return _databaseItem.Y; } - set { _databaseItem.Y = value; } - } - - public override int Z - { - get { return _databaseItem.Z; } - set { _databaseItem.Z = value; } - } - - public ushort RegionID - { - get { return _databaseItem.RegionID; } - set { _databaseItem.RegionID = value; } - } - - public ushort Heading - { - get { return (ushort) _databaseItem.Heading; } - set { _databaseItem.Heading = value; } - } + public Position Position + { + get => Position.Create(dbHouse.RegionID, dbHouse.X, dbHouse.Y, dbHouse.Z, (ushort)(dbHouse.Heading/180.0*2048)); + set + { + dbHouse.X = value.X; + dbHouse.Y = value.Y; + dbHouse.Z = value.Z; + dbHouse.Heading = value.Orientation.InDegrees; + dbHouse.RegionID = value.RegionID; + } + } + + [Obsolete("Use .Position instead!")] + public int X + { + get => Position.X; + set => Position = Position.With(x: value); + } + + [Obsolete("Use .Position instead!")] + public int Y + { + get => Position.Y; + set => Position = Position.With(y: value); + } + + [Obsolete("Use .Position instead!")] + public int Z + { + get => Position.Z; + set => Position = Position.With(z: value); + } + + [Obsolete("Use either .Orientation (in degrees) or .Position.Heading instead!")] + public ushort Heading + { + get => (ushort)dbHouse.Heading; + set => dbHouse.Heading = value; + } + + ///House orientation in degrees. + public ushort Orientation + { + get => (ushort)dbHouse.Heading; + } + + public ushort RegionID + { + get => Position.RegionID; + set => Position = Position.With(regionID: value); + } public string Name { - get { return _databaseItem.Name; } - set { _databaseItem.Name = value; } + get { return dbHouse.Name; } + set { dbHouse.Name = value; } } #endregion public House(DBHouse house) { - _databaseItem = house; + dbHouse = house; _permissionLevels = new Dictionary(); _indoorItems = new Dictionary(); _outdoorItems = new Dictionary(); @@ -309,28 +333,19 @@ public House(DBHouse house) log.DebugFormat("House destructor called for House #{0} in region {1}", HouseNumber, RegionID); } - /// - /// The spot you are teleported to when you exit this house. - /// - public GameLocation OutdoorJumpPoint - { - get - { - double angle = Heading*((Math.PI*2)/360); // angle*2pi/360; - var x = (int) (X + (0*Math.Cos(angle) + 500*Math.Sin(angle))); - var y = (int) (Y - (500*Math.Cos(angle) - 0*Math.Sin(angle))); - var heading = (ushort) ((Heading < 180 ? Heading + 180 : Heading - 180)/0.08789); + [Obsolete("Use OutdoorJumpPosition instead!")] + public GameLocation OutdoorJumpPoint + => new GameLocation(OutdoorJumpPosition); - return new GameLocation("Housing", RegionID, x, y, Z, heading); - } - } + public Position OutdoorJumpPosition + => (Position + Vector.Create(Position.Orientation + Angle.Degrees(180), length: 500)).TurnedAround(); /// /// Sends a update of the house and the garden to all players in range /// public void SendUpdate() { - foreach (GamePlayer player in WorldMgr.GetPlayersCloseToSpot(this, HousingConstants.HouseViewingDistance)) + foreach (GamePlayer player in WorldMgr.GetPlayersCloseToSpot(Position, HousingConstants.HouseViewingDistance)) { player.Out.SendHouse(this); player.Out.SendGarden(this); @@ -351,7 +366,7 @@ public void Enter(GamePlayer player) IList list = GetAllPlayersInHouse(); if (list.Count == 0) { - foreach (GamePlayer pl in WorldMgr.GetPlayersCloseToSpot(this, HousingConstants.HouseViewingDistance)) + foreach (GamePlayer pl in WorldMgr.GetPlayersCloseToSpot(Position, HousingConstants.HouseViewingDistance)) { pl.Out.SendHouseOccupied(this, true); } @@ -364,63 +379,61 @@ public void Enter(GamePlayer player) player.InHouse = true; player.CurrentHouse = this; - ushort heading = 0; + switch (Model) + { + //thx to sp4m + default: + player.MoveTo(Position.With(z: 25022, heading: 0)); + break; - switch (Model) - { - //thx to sp4m - default: - player.MoveTo(RegionID, X, Y, 25022, heading); - break; + case 1: + player.MoveTo(Position.With(z: 25025, heading: 0) + Vector.Create(x: 80, y: 100)); + break; - case 1: - player.MoveTo(RegionID, X + 80, Y + 100, ((25025)), heading); - break; + case 2: + player.MoveTo(Position.With(z: 24910, heading: 0) + Vector.Create(x: -260, y: 100)); + break; - case 2: - player.MoveTo(RegionID, X - 260, Y + 100, ((24910)), heading); - break; - - case 3: - player.MoveTo(RegionID, X - 200, Y + 100, ((24800)), heading); - break; + case 3: + player.MoveTo(Position.With(z: 24800, heading: 0) + Vector.Create(x: -200, y: 100)); + break; - case 4: - player.MoveTo(RegionID, X - 350, Y - 30, ((24660)), heading); - break; + case 4: + player.MoveTo(Position.With(z: 24660, heading: 0) + Vector.Create(x: -350, y: -30)); + break; - case 5: - player.MoveTo(RegionID, X + 230, Y - 480, ((25100)), heading); - break; + case 5: + player.MoveTo(Position.With(z: 25100, heading: 0) + Vector.Create(x: 230, y: -480)); + break; - case 6: - player.MoveTo(RegionID, X - 80, Y - 660, ((24700)), heading); - break; + case 6: + player.MoveTo(Position.With(z: 24700, heading: 0) + Vector.Create(x: -80, y: -660)); + break; - case 7: - player.MoveTo(RegionID, X - 80, Y - 660, ((24700)), heading); - break; + case 7: + player.MoveTo(Position.With(z: 24700, heading: 0) + Vector.Create(x: -80, y: -660)); + break; - case 8: - player.MoveTo(RegionID, X - 90, Y - 625, ((24670)), heading); - break; + case 8: + player.MoveTo(Position.With(z: 24670, heading: 0) + Vector.Create(x: -90, y: -625)); + break; - case 9: - player.MoveTo(RegionID, X + 400, Y - 160, ((25150)), heading); - break; + case 9: + player.MoveTo(Position.With(z: 25150, heading: 0) + Vector.Create(x: 400, y: -160)); + break; - case 10: - player.MoveTo(RegionID, X + 400, Y - 80, ((25060)), heading); - break; + case 10: + player.MoveTo(Position.With(z: 25060, heading: 0) + Vector.Create(x: 400, y: -80)); + break; - case 11: - player.MoveTo(RegionID, X + 400, Y - 60, ((24900)), heading); - break; + case 11: + player.MoveTo(Position.With(z: 24900, heading: 0) + Vector.Create(x: 400, y: -60)); + break; - case 12: - player.MoveTo(RegionID, X, Y - 620, ((24595)), heading); - break; - } + case 12: + player.MoveTo(Position.With(z: 24595, heading: 0) + Vector.Create(y: -620)); + break; + } ChatUtil.SendSystemMessage(player, "House.Enter.EnteredHouse", HouseNumber); } @@ -432,7 +445,7 @@ public void Enter(GamePlayer player) /// text or not public void Exit(GamePlayer player, bool silent) { - player.MoveTo(OutdoorJumpPoint); + player.MoveTo(OutdoorJumpPosition); if (!silent) { @@ -444,7 +457,7 @@ public void Exit(GamePlayer player, bool silent) IList list = GetAllPlayersInHouse(); if (list.Count == 0) { - foreach (GamePlayer pl in WorldMgr.GetPlayersCloseToSpot(this, HousingConstants.HouseViewingDistance)) + foreach (GamePlayer pl in WorldMgr.GetPlayersCloseToSpot(Position, HousingConstants.HouseViewingDistance)) { pl.Out.SendHouseOccupied(this, false); } @@ -552,7 +565,7 @@ public int GetGuildEmblemFlags() public IList GetAllPlayersInHouse() { var ret = new List(); - foreach (GamePlayer player in WorldMgr.GetPlayersCloseToSpot(RegionID, X, Y, 25000, WorldMgr.VISIBILITY_DISTANCE)) + foreach (GamePlayer player in WorldMgr.GetPlayersCloseToSpot(Position.With(z: 25000), WorldMgr.VISIBILITY_DISTANCE)) { if (player.CurrentHouse == this && player.InHouse) { @@ -622,20 +635,27 @@ public static void LoadHookpointOffsets() } } + [Obsolete("Use GetHookPointCoordinate(uint) instead!")] public Point3D GetHookpointLocation(uint n) - { - if (n > HousingConstants.MaxHookpointLocations) - return null; + { + var loc = GetHookPointCoordinate(n); + if(loc == Coordinate.Nowhere) return null; + else return loc.ToPoint3D(); + } - int[] hookpointsCoords = HousingConstants.RelativeHookpointsCoords[Model][n]; + public Coordinate GetHookPointCoordinate(uint number) + { + if (number > HousingConstants.MaxHookpointLocations) return Coordinate.Nowhere; - if (hookpointsCoords == null) - return null; + int[] hookpointsCoords = HousingConstants.RelativeHookpointsCoords[Model][number]; - return new Point3D(X + hookpointsCoords[0], Y + hookpointsCoords[1], 25000 + hookpointsCoords[2]); - } + if (hookpointsCoords == null) return Coordinate.Nowhere; + + var hookPointOffset = Vector.Create(x: hookpointsCoords[0], y: hookpointsCoords[1], z: hookpointsCoords[2]); + return Position.Coordinate.With(z: 25000) + hookPointOffset; + } - private int GetHookpointPosition(int objX, int objY, int objZ) + private int GetHookpointPosition(Coordinate loc) { int position = -1; @@ -643,8 +663,8 @@ private int GetHookpointPosition(int objX, int objY, int objZ) { if (HousingConstants.RelativeHookpointsCoords[Model][i] != null) { - if (HousingConstants.RelativeHookpointsCoords[Model][i][0] + X == objX && - HousingConstants.RelativeHookpointsCoords[Model][i][1] + Y == objY) + if (HousingConstants.RelativeHookpointsCoords[Model][i][0] + Position.X == loc.X && + HousingConstants.RelativeHookpointsCoords[Model][i][1] + Position.Y == loc.Y) { position = i; } @@ -664,7 +684,7 @@ private ushort GetHookpointHeading(uint n) if (hookpointsCoords == null) return 0; - return (ushort) (Heading + hookpointsCoords[3]); + return (ushort) (Orientation + hookpointsCoords[3]); } /// @@ -682,13 +702,9 @@ public bool FillHookpoint(uint position, string templateID, ushort heading, int return false; //get location from slot - IPoint3D location = GetHookpointLocation(position); - if (location == null) - return false; + var coordinate = GetHookPointCoordinate(position); + if (coordinate == Coordinate.Nowhere) return false; - int x = location.X; - int y = location.Y; - int z = location.Z; GameObject hookpointObject = null; switch ((eObjectType)item.Object_Type) @@ -702,7 +718,7 @@ public bool FillHookpoint(uint position, string templateID, ushort heading, int } case eObjectType.HouseNPC: { - hookpointObject = GameServer.ServerRules.PlaceHousingNPC(this, item, location, GetHookpointHeading(position)); + hookpointObject = GameServer.ServerRules.PlaceHousingNPC(this, item, coordinate, GetHookpointHeading(position)); break; } case eObjectType.HouseBindstone: @@ -711,11 +727,7 @@ public bool FillHookpoint(uint position, string templateID, ushort heading, int hookpointObject.CurrentHouse = this; hookpointObject.InHouse = true; hookpointObject.OwnerID = templateID; - hookpointObject.X = x; - hookpointObject.Y = y; - hookpointObject.Z = z; - hookpointObject.Heading = heading; - hookpointObject.CurrentRegionID = RegionID; + hookpointObject.Position = Position.Create(RegionID, coordinate, heading); hookpointObject.Name = item.Name; hookpointObject.Model = (ushort) item.Model; hookpointObject.AddToWorld(); @@ -725,7 +737,7 @@ public bool FillHookpoint(uint position, string templateID, ushort heading, int } case eObjectType.HouseInteriorObject: { - hookpointObject = GameServer.ServerRules.PlaceHousingInteriorItem(this, item, location, heading); + hookpointObject = GameServer.ServerRules.PlaceHousingInteriorItem(this, item, coordinate, heading); break; } } @@ -747,7 +759,7 @@ public void EmptyHookpoint(GamePlayer player, GameObject obj, bool addToInventor return; } - int position = GetHookpointPosition(obj.X, obj.Y, obj.Z); + int position = GetHookpointPosition(obj.Coordinate); if (position < 0) { @@ -875,21 +887,14 @@ public bool AddConsignment(long startValue) var zaddition = (int) consignmentCoords[2]; var realm = (int) consignmentCoords[3]; - double angle = Heading*((Math.PI*2)/360); // angle*2pi/360; - var heading = (ushort) ((Heading < 180 ? Heading + 180 : Heading - 180)/0.08789); - var tX = (int) ((X + (500*Math.Sin(angle))) - Math.Sin(angle - multi)*range); - var tY = (int) ((Y - (500*Math.Cos(angle))) + Math.Cos(angle - multi)*range); + var merchantPosition = OutdoorJumpPosition + Vector.Create(Position.Orientation - Angle.Radians(multi), length: range, z: zaddition); GameConsignmentMerchant con = GameServer.ServerRules.CreateHousingConsignmentMerchant(this); - con.CurrentRegionID = RegionID; - con.X = tX; - con.Y = tY; - con.Z = Z + zaddition; + con.Position = merchantPosition; con.Level = 50; con.Realm = (eRealm) realm; con.HouseNumber = (ushort)HouseNumber; - con.Heading = heading; con.Model = 144; con.Flags |= GameNPC.eFlags.PEACE; @@ -1054,7 +1059,7 @@ public void Edit(GamePlayer player, List changes) } // save the house - GameServer.Database.SaveObject(_databaseItem); + GameServer.Database.SaveObject(dbHouse); SendUpdate(); } @@ -1284,15 +1289,15 @@ public bool HasOwnerPermissions(GamePlayer player) return true; // check by character name/account if not guild house - if (!_databaseItem.GuildHouse) + if (!dbHouse.GuildHouse) { // check if character is explicit owner - if (_databaseItem.OwnerID == player.ObjectId) + if (dbHouse.OwnerID == player.ObjectId) return true; // check account-wide if not a guild house IEnumerable charsOnAccount = from chr in player.Client.Account.Characters - where chr.ObjectId == _databaseItem.OwnerID + where chr.ObjectId == dbHouse.OwnerID select chr; if (charsOnAccount.Count() > 0) @@ -1467,7 +1472,7 @@ public bool CanUseTools(GamePlayer player) /// public void SaveIntoDatabase() { - GameServer.Database.SaveObject(_databaseItem); + GameServer.Database.SaveObject(dbHouse); } /// diff --git a/GameServer/housing/HouseMgr.cs b/GameServer/housing/HouseMgr.cs index b4fbb15aae..a3de1ec26e 100644 --- a/GameServer/housing/HouseMgr.cs +++ b/GameServer/housing/HouseMgr.cs @@ -30,6 +30,7 @@ using DOL.Language; using log4net; +using DOL.GS.Geometry; namespace DOL.GS.Housing { @@ -447,7 +448,7 @@ public static void RemoveHouse(House house) } // remove the house for all nearby players - foreach (GamePlayer player in WorldMgr.GetPlayersCloseToSpot(house, WorldMgr.OBJ_UPDATE_DISTANCE)) + foreach (GamePlayer player in WorldMgr.GetPlayersCloseToSpot(house.Position, WorldMgr.OBJ_UPDATE_DISTANCE)) { player.Out.SendRemoveHouse(house); player.Out.SendGarden(house); @@ -835,27 +836,26 @@ public static void BuyHousingItem(GamePlayer player, ushort slot, byte count, eM GameServer.ServerRules.BuyHousingItem(player, slot, count, merchantType); } - - /// - /// This function gets the house close to spot - /// - /// array of house - public static IEnumerable GetHousesCloseToSpot(ushort regionid, int x, int y, int radius) - { - var myhouses = new ArrayList(); - int radiussqrt = radius * radius; - foreach (House house in GetHouses(regionid).Values) - { - int xdiff = house.X - x; - int ydiff = house.Y - y; - int range = xdiff * xdiff + ydiff * ydiff; - if (range < 0) - range *= -1; - if (range > radiussqrt) - continue; - myhouses.Add(house); - } - return myhouses; - } + [Obsolete("Use .GetHousesCloseToSpot(Position) instead!")] + public static IEnumerable GetHousesCloseToSpot(ushort regionid, int x, int y, int radius) + => GetHousesCloseToSpot(Position.Create(x: x, y: y, regionID: regionid), radius); + + public static IEnumerable GetHousesCloseToSpot(Position position, int radius) + { + var myhouses = new ArrayList(); + int radiussqrt = radius * radius; + foreach (House house in GetHouses(position.RegionID).Values) + { + int xdiff = house.Position.X - position.X; + int ydiff = house.Position.Y - position.Y; + int range = xdiff * xdiff + ydiff * ydiff; + if (range < 0) + range *= -1; + if (range > radiussqrt) + continue; + myhouses.Add(house); + } + return myhouses; + } } } \ No newline at end of file diff --git a/GameServer/housing/HousingConstants.cs b/GameServer/housing/HousingConstants.cs index d6ada3397a..9471433146 100644 --- a/GameServer/housing/HousingConstants.cs +++ b/GameServer/housing/HousingConstants.cs @@ -96,6 +96,23 @@ public static class HousingConstants new[] {-0.58f, 638, 100, 3} // model 12 }; + public static readonly float[][] ConsignmentPositions = new[] + { + null, + new[] {0.55f, 630, 40, 1}, // model 1 + new[] {0.55f, 630, 40, 1}, // model 2 + new[] {-0.55f, 613, 100, 1}, // model 3 + new[] {0.53f, 620, 100, 1}, // model 4 + new[] {-0.47f, 755, 40, 2}, // model 5 + new[] {-0.5f, 630, 40, 2}, // model 6 + new[] {0.48f, 695, 100, 2}, // model 7 + new[] {-0.505f, 680, 100, 2}, // model 8 + new[] {0.475f, 693, 40, 3}, // model 9 + new[] {0.47f, 688, 40, 3}, // model 10 + new[] {-0.65f, 603, 100, 3}, // model 11 + new[] {-0.58f, 638, 100, 3} // model 12 + }; + /// /// Housing hookpoint coordinates offset relative to a house. /// diff --git a/GameServer/housing/LotMarker.cs b/GameServer/housing/LotMarker.cs index af93130226..ee59369bf5 100644 --- a/GameServer/housing/LotMarker.cs +++ b/GameServer/housing/LotMarker.cs @@ -20,6 +20,7 @@ using System.Collections; using DOL.Database; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; namespace DOL.GS.Housing @@ -255,11 +256,7 @@ public static void SpawnLotMarker(DBHouse house) { var obj = new GameLotMarker { - X = house.X, - Y = house.Y, - Z = house.Z, - CurrentRegionID = house.RegionID, - Heading = (ushort) house.Heading, + Position = Position.Create(house.RegionID, house.X, house.Y, house.Z, (ushort)house.Heading), Name = "Lot Marker", Model = 1308, DatabaseItem = house diff --git a/GameServer/keeps/AbstractGameKeep.cs b/GameServer/keeps/AbstractGameKeep.cs index bd7e65d170..13a5d359c5 100644 --- a/GameServer/keeps/AbstractGameKeep.cs +++ b/GameServer/keeps/AbstractGameKeep.cs @@ -27,6 +27,7 @@ using DOL.GS.PacketHandler; using log4net; +using DOL.GS.Geometry; namespace DOL.GS.Keeps { @@ -195,7 +196,7 @@ public Zone CurrentZone { if (CurrentRegion != null) { - return CurrentRegion.GetZone(X, Y); + return CurrentRegion.GetZone(Position.Coordinate); } return null; } @@ -349,49 +350,47 @@ public virtual string Name set { DBKeep.Name = value; } } - /// - /// The Keep Region ID linked to the DBKeep - /// + public Position Position + { + get => DBKeep.GetPosition(); + set => DBKeep.SetPosition(value); + } + public ushort Region { - get { return DBKeep.Region; } - set { DBKeep.Region = value; } + get => Position.RegionID; + set => Position = Position.With(regionID: value); } - /// - /// The Keep X linked to the DBKeep - /// public int X { - get { return DBKeep.X; } - set { DBKeep.X = value; } + get => Position.X; + set => Position = Position.With(x: value); } - /// - /// The Keep Y linked to the DBKeep - /// public int Y { - get { return DBKeep.Y; } - set { DBKeep.Y = value; } + get => Position.Y; + set => Position = Position.With(y: value); } - /// - /// The Keep Z linked to the DBKeep - /// public int Z { - get { return DBKeep.Z; } - set { DBKeep.Z = value; } + get => Position.Z; + set => Position = Position.With(z: value); } - /// - /// The Keep Heading linked to the DBKeep - /// + [Obsolete("Use .Orientation instead!")] public ushort Heading { - get { return DBKeep.Heading; } - set { DBKeep.Heading = value; } + get => (ushort)Position.Orientation.InDegrees; + set => Position = Position.With(orientation: Angle.Degrees(value)); + } + + public Angle Orientation + { + get => Position.Orientation; + set => Position = Position.With(orientation: value); } /// @@ -457,7 +456,7 @@ public virtual void Load(DBKeep keep) GameEventMgr.AddHandler(CurrentRegion, RegionEvent.PlayerEnter, new DOLEventHandler(SendKeepInit)); KeepArea area = null; //see if any keep areas for this keep have already been added via DBArea - foreach (AbstractArea a in CurrentRegion.GetAreasOfSpot(keep.X, keep.Y, keep.Z)) + foreach (AbstractArea a in CurrentRegion.GetAreasOfSpot(keep.GetPosition().Coordinate)) { if (a is KeepArea && a.Description == keep.Name) { @@ -504,17 +503,13 @@ public virtual void Remove(KeepArea area) { door.Delete(); GameDoor d = new GameDoor(); - d.CurrentRegionID = door.CurrentRegionID; d.DoorID = door.DoorID; - d.Heading = door.Heading; d.Level = door.Level; d.Model = door.Model; d.Name = "door"; d.Realm = door.Realm; d.State = eDoorState.Closed; - d.X = door.X; - d.Y = door.Y; - d.Z = door.Z; + d.Position = door.Position; DoorMgr.RegisterDoor(door); d.AddToWorld(); } @@ -660,7 +655,7 @@ public virtual bool CheckForClaim(GamePlayer player) int count = 0; foreach (GamePlayer p in player.Group.GetPlayersInTheGroup()) { - if (GameServer.KeepManager.GetKeepCloseToSpot(p.CurrentRegionID, p, WorldMgr.VISIBILITY_DISTANCE) == this) + if (GameServer.KeepManager.GetKeepCloseToSpot(p.Position, WorldMgr.VISIBILITY_DISTANCE) == this) count++; } @@ -939,10 +934,10 @@ public TimeSpan TotalChangeLevelTimeRemaining } } - /// - /// Starts the Change Level Timer - /// - public void StartChangeLevelTimer() + /// + /// Starts the Change Level Timer + /// + public void StartChangeLevelTimer() { int newinterval = CalculateTimeToUpgrade(); @@ -1168,16 +1163,15 @@ protected void ResetPlayersOfKeep() DBKeepHookPoint hp = DOLDB.SelectObject(DB.Column(nameof(DBKeepHookPoint.HookPointID)).IsEqualTo(97).And(DB.Column(nameof(DBKeepHookPoint.Height)).IsEqualTo(Height))); if (hp == null) return; - int z = component.Z + hp.Z; + int z = component.Position.Z + hp.Z; foreach (GamePlayer player in component.GetPlayersInRadius(WorldMgr.VISIBILITY_DISTANCE)) { - int d = hookpoint.GetDistance( player as IPoint2D ); + int d = (int)hookpoint.Position.Coordinate.DistanceTo(player.Coordinate, ignoreZ: true); if (d > distance) continue; - if (player.Z > z) - player.MoveTo(player.CurrentRegionID, player.X, player.Y, z, player.Heading); + if (player.Position.Z > z) player.MoveTo(player.Position.With(z: z)); } } diff --git a/GameServer/keeps/GameKeepComponent.cs b/GameServer/keeps/GameKeepComponent.cs index f9036e4f27..0162a78183 100644 --- a/GameServer/keeps/GameKeepComponent.cs +++ b/GameServer/keeps/GameKeepComponent.cs @@ -26,6 +26,7 @@ using DOL.GS.PacketHandler; using DOL.GS.ServerProperties; using log4net; +using DOL.GS.Geometry; namespace DOL.GS.Keeps { @@ -115,7 +116,13 @@ public bool Climbing /// public int ComponentHeading { get; set; } - protected int m_oldMaxHealth; + public Angle RelativeOrientationToKeep + { + get => Angle.Degrees(ComponentHeading * 90); + set => ComponentHeading = value.InDegrees / 90; + } + + protected int m_oldMaxHealth; public override byte Level => (byte)(Keep.BaseLevel-10 + (Keep.Level * 3)); @@ -150,7 +157,7 @@ public override IList GetExamineMessages(GamePlayer player) if (player.Client.Account.PrivLevel > 1) { - list.Add(Name + " with a Z of " + Z.ToString()); + list.Add($"{Name} with a Z of {Position.Z}"); } return list; @@ -203,19 +210,18 @@ public virtual void LoadFromDatabase(DBKeepComponent component, AbstractGameKeep Keep = keep; //this.DBKeepComponent = component; base.LoadFromDatabase(component); - //this x and y is for get object in radius - double angle = keep.Heading * ((Math.PI * 2) / 360); // angle*2pi/360; - X = (int)(keep.X + ((sbyte)component.X * 148 * Math.Cos(angle) + (sbyte)component.Y * 148 * Math.Sin(angle))); - Y = (int)(keep.Y - ((sbyte)component.Y * 148 * Math.Cos(angle) - (sbyte)component.X * 148 * Math.Sin(angle))); - Z = keep.Z; + //this x and y is for get object in radius + var angle = keep.Orientation; + var offset = Vector.Create(148 * (sbyte)component.X, -148 * (sbyte)component.Y, 0) + .RotatedClockwise(angle); + + //need check to be sure for heading + angle += Angle.Degrees(component.Heading * 90); + Position = keep.Position.With(angle) + offset; // and this one for packet sent ComponentX = component.X; ComponentY = component.Y; ComponentHeading = (ushort)component.Heading; - //need check to be sure for heading - angle = (component.Heading * 90 + keep.Heading); - if (angle > 360) angle -= 360; - Heading = (ushort)(angle / 0.08789); Name = keep.Name; Model = INVISIBLE_MODEL; Skin = component.Skin; @@ -223,7 +229,6 @@ public virtual void LoadFromDatabase(DBKeepComponent component, AbstractGameKeep Health = MaxHealth; // this.Health = component.Health; m_oldHealthPercent = HealthPercent; - CurrentRegion = myregion; ID = component.ID; SaveInDB = false; IsRaized = false; @@ -403,12 +408,12 @@ public virtual void FillPositions() if (guard.PatrolGroup != null) continue; if (guard.HookPoint != null) continue; - if (guard.Position == null) continue; - if (guard.Position.Height > guard.Component.Height) + if (guard.DbKeepPosition == null) continue; + if (guard.DbKeepPosition.Height > guard.Component.Height) guard.RemoveFromWorld(); else { - if (guard.Position.Height <= guard.Component.Height && + if (guard.DbKeepPosition.Height <= guard.Component.Height && guard.ObjectState != GameObject.eObjectState.Active && !guard.IsRespawning) guard.AddToWorld(); } @@ -416,12 +421,12 @@ public virtual void FillPositions() foreach (var banner in Keep.Banners.Values) { - if (banner.Position == null) continue; - if (banner.Position.Height > banner.Component.Height) + if (banner.DbKeepPosition == null) continue; + if (banner.DbKeepPosition.Height > banner.Component.Height) banner.RemoveFromWorld(); else { - if (banner.Position.Height <= banner.Component.Height && + if (banner.DbKeepPosition.Height <= banner.Component.Height && banner.ObjectState != GameObject.eObjectState.Active) banner.AddToWorld(); } @@ -555,8 +560,8 @@ public override void Die(GameObject killer) foreach (var guard in Keep.Guards.Values) { - guard.MoveTo(guard.CurrentRegionID, guard.X, guard.Y, Keep.Z, guard.Heading); - guard.SpawnPoint.Z = Keep.Z; + guard.MoveTo(guard.Position); + guard.SpawnPosition = guard.SpawnPosition.With(z: Keep.Z); } } } @@ -713,8 +718,8 @@ public override string ToString() .Append(" ComponentID=").Append(ID) .Append(" Skin=").Append(Skin) .Append(" Height=").Append(Height) - .Append(" Heading=").Append(Heading) - .Append(" nComponentX=").Append((sbyte)ComponentX) + .Append(" Heading=").Append(Orientation.InHeading) + .Append(" ComponentX=").Append((sbyte)ComponentX) .Append(" ComponentY=").Append((sbyte)ComponentY) .Append(" ComponentHeading=").Append(ComponentHeading) .ToString(); diff --git a/GameServer/keeps/Gameobjects/FrontiersPortalStone.cs b/GameServer/keeps/Gameobjects/FrontiersPortalStone.cs index 61b9c0febd..42369bb279 100644 --- a/GameServer/keeps/Gameobjects/FrontiersPortalStone.cs +++ b/GameServer/keeps/Gameobjects/FrontiersPortalStone.cs @@ -16,9 +16,11 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ +using System; using System.Collections; using DOL.Database; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; namespace DOL.GS.Keeps @@ -39,7 +41,7 @@ public GameKeepComponent Component } private DBKeepPosition m_position; - public DBKeepPosition Position + public DBKeepPosition DbKeepPosition { get { return m_position; } set { m_position = value; } @@ -64,7 +66,7 @@ public override eRealm Realm { if (m_component != null) return m_component.Keep.Realm; - if (m_CurrentRegion.ID == 163) + if (CurrentRegion.ID == 163) return CurrentZone.Realm; return base.Realm; } @@ -125,16 +127,14 @@ public override bool Interact(GamePlayer player) return true; } - public void GetTeleportLocation(out int x, out int y) - { - ushort originalHeading = m_Heading; - m_Heading = (ushort)Util.Random((m_Heading - 500), (m_Heading + 500)); - int distance = Util.Random(50, 150); - Point2D portloc = this.GetPointFromHeading( this.Heading, distance ); - x = portloc.X; - y = portloc.Y; - m_Heading = originalHeading; - } + [Obsolete("This is going to be removed.")] + public void GetTeleportLocation(out int x, out int y) + { + var angle = Orientation + Angle.Heading(Util.Random(- 500, 500)); + var portPosition = Position + Vector.Create(angle, length: Util.Random(50, 150)); + x = portPosition.X; + y = portPosition.Y; + } public class TeleporterEffect : GameNPC { @@ -157,11 +157,7 @@ public override bool AddToWorld() { if (!base.AddToWorld()) return false; TeleporterEffect mob = new TeleporterEffect(); - mob.CurrentRegion = this.CurrentRegion; - mob.X = this.X; - mob.Y = this.Y; - mob.Z = this.Z; - mob.Heading = this.Heading; + mob.Position = Position; mob.Health = mob.MaxHealth; mob.MaxSpeedBase = 0; if (mob.AddToWorld()) diff --git a/GameServer/keeps/Gameobjects/GameKeepBanner.cs b/GameServer/keeps/Gameobjects/GameKeepBanner.cs index eaf58fb1a8..9d16866158 100644 --- a/GameServer/keeps/Gameobjects/GameKeepBanner.cs +++ b/GameServer/keeps/Gameobjects/GameKeepBanner.cs @@ -18,6 +18,7 @@ */ using System; using DOL.Database; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; namespace DOL.GS.Keeps @@ -78,7 +79,7 @@ public GameKeepComponent Component } protected DBKeepPosition m_position; - public DBKeepPosition Position + public DBKeepPosition DbKeepPosition { get { return m_position; } set { m_position = value; } @@ -97,7 +98,7 @@ public void DeleteObject() } Component = null; - Position = null; + DbKeepPosition = null; base.Delete(); CurrentRegion = null; @@ -166,14 +167,14 @@ public virtual void LoadFromPosition(DBKeepPosition pos, GameKeepComponent compo if (component.Keep.Guild != null) { ChangeGuild(); - Z += 1500; + Position += Vector.Create(z: 1500); this.AddToWorld(); } } else { ChangeRealm(); - Z += 1000; // this works around an issue where all banners are at keep level instead of on top + Position += Vector.Create(z: 1000); // this works around an issue where all banners are at keep level instead of on top // with a z value > height of the keep the banners show correctly - tolakram this.AddToWorld(); } @@ -182,14 +183,14 @@ public virtual void LoadFromPosition(DBKeepPosition pos, GameKeepComponent compo log.Warn($"LoadFromPosition(): There is already a Banner with TemplateID {this.TemplateID} on KeepID {component.Keep.KeepID}, not adding Banner for KeepPosition_ID {pos.ObjectId} on KeepComponent_ID {component.InternalID}"); } + [Obsolete("This is going to be removed!")] public void MoveToPosition(DBKeepPosition position) { PositionMgr.LoadKeepItemPosition(position, this); int zAdd = 1000; - if (BannerType == eBannerType.Guild) - zAdd = 1500; + if (BannerType == eBannerType.Guild) zAdd = 1500; - this.MoveTo(this.CurrentRegionID, this.X, this.Y, this.Z + zAdd, this.Heading); + this.MoveTo(Position + Vector.Create(z: zAdd)); } public void ChangeRealm() diff --git a/GameServer/keeps/Gameobjects/GameKeepDoor.cs b/GameServer/keeps/Gameobjects/GameKeepDoor.cs index 64cfa5fbba..1291584062 100644 --- a/GameServer/keeps/Gameobjects/GameKeepDoor.cs +++ b/GameServer/keeps/Gameobjects/GameKeepDoor.cs @@ -18,22 +18,19 @@ */ using System; using System.Collections; -using System.Reflection; using DOL.Database; -using DOL.Events; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using DOL.GS.ServerProperties; -using log4net; - namespace DOL.GS.Keeps { - /// - /// keep door in world - /// - public class GameKeepDoor : GameLiving, IDoor, IKeepItem + /// + /// keep door in world + /// + public class GameKeepDoor : GameLiving, IDoor, IKeepItem { private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); @@ -272,7 +269,7 @@ public GameKeepComponent Component } protected DBKeepPosition m_position; - public DBKeepPosition Position + public DBKeepPosition DbKeepPosition { get { return m_position; } set { m_position = value; } @@ -405,7 +402,7 @@ public override bool Interact(GamePlayer player) if (!GameServer.KeepManager.IsEnemy(this, player) || player.Client.Account.PrivLevel != 1) { - int keepz = Z, distance = 0; + int keepz = Position.Z, distance = 0; //calculate distance //normal door @@ -427,7 +424,7 @@ public override bool Interact(GamePlayer player) { if (DoorID == 1) { - keepz = Z + 83; + keepz = Position.Z + 83; } else { @@ -459,19 +456,17 @@ public override bool Interact(GamePlayer player) break; } if (DoorIndex == 1 && keepdistance < gatedistance) - keepz = Z + 92;//checked in game with lvl 1 keep + keepz = Position.Z + 92;//checked in game with lvl 1 keep } } - Point2D keepPoint; + Position keepPoint; //calculate x y - if (IsObjectInFront(player, 180, false)) - keepPoint = GetPointFromHeading( this.Heading, -distance ); - else - keepPoint = GetPointFromHeading( this.Heading, distance ); + if (IsObjectInFront(player, 180, false)) keepPoint = Position + Vector.Create(Orientation, -distance); + else keepPoint = Position + Vector.Create(Orientation, distance); //move player - player.MoveTo(CurrentRegionID, keepPoint.X, keepPoint.Y, keepz, player.Heading); + player.MoveTo(keepPoint.With(z: keepz).With(player.Orientation)); } return base.Interact(player); } @@ -576,7 +571,7 @@ public void DeleteObject() } Component = null; - Position = null; + DbKeepPosition = null; base.Delete(); CurrentRegion = null; } @@ -617,10 +612,7 @@ public override void LoadFromDatabase(DataObject obj) if (curZone == null) return; this.CurrentRegion = curZone.ZoneRegion; m_name = door.Name; - m_Heading = (ushort)door.Heading; - m_x = door.X; - m_y = door.Y; - m_z = door.Z; + Position = Position.Create(regionID:CurrentRegion.ID, x: door.X, y: door.Y, z: door.Z, heading: (ushort)door.Heading ); m_level = 0; m_model = 0xFFFF; m_doorID = door.InternalID; @@ -707,7 +699,7 @@ public int GenerateDoorID() int componentID = m_component.ID; //index not sure yet - int doorIndex = this.Position.TemplateType; + int doorIndex = this.DbKeepPosition.TemplateType; int id = 0; //add door type id += doortype * 100000000; diff --git a/GameServer/keeps/Gameobjects/GameRelicDoor.cs b/GameServer/keeps/Gameobjects/GameRelicDoor.cs index 2b246fc837..9256bef155 100644 --- a/GameServer/keeps/Gameobjects/GameRelicDoor.cs +++ b/GameServer/keeps/Gameobjects/GameRelicDoor.cs @@ -16,16 +16,12 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ -using System; using System.Collections; -using System.Reflection; using DOL.Database; -using DOL.Events; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; -using log4net; - namespace DOL.GS.Keeps { @@ -153,15 +149,13 @@ public override bool Interact(GamePlayer player) if (GameServer.ServerRules.IsSameRealm(player, this, true) || player.Client.Account.PrivLevel != 1) { - Point2D point; + Position position; //calculate x y - if ( IsObjectInFront( player, 180, false ) ) - point = this.GetPointFromHeading( this.Heading, -500 ); - else - point = this.GetPointFromHeading( this.Heading, 500 ); + if ( IsObjectInFront( player, 180, false ) ) position = Position + Vector.Create(Position.Orientation, length: -500); + else position = Position + Vector.Create(Position.Orientation, length: 500); //move player - player.MoveTo(CurrentRegionID, point.X, point.Y, player.Z, player.Heading); + player.MoveTo(position); } return base.Interact(player); } @@ -244,10 +238,7 @@ public override void LoadFromDatabase(DataObject obj) if (curZone == null) return; this.CurrentRegion = curZone.ZoneRegion; m_name = door.Name; - m_Heading = (ushort)door.Heading; - m_x = door.X; - m_y = door.Y; - m_z = door.Z; + Position = Position.Create(regionID: CurrentRegion.ID, x: door.X, y: door.Y, z: door.Z, heading: (ushort)door.Heading ); m_level = 0; m_model = 0xFFFF; m_doorID = door.InternalID; diff --git a/GameServer/keeps/Gameobjects/Guards/GameKeepGuard.cs b/GameServer/keeps/Gameobjects/Guards/GameKeepGuard.cs index 1ddfbce6d6..f434aab12c 100644 --- a/GameServer/keeps/Gameobjects/Guards/GameKeepGuard.cs +++ b/GameServer/keeps/Gameobjects/Guards/GameKeepGuard.cs @@ -25,6 +25,7 @@ using DOL.Language; using DOL.GS.ServerProperties; using System.Collections.Generic; +using DOL.GS.Geometry; namespace DOL.GS.Keeps { @@ -57,7 +58,7 @@ public GameKeepComponent Component } private DBKeepPosition m_position; - public DBKeepPosition Position + public DBKeepPosition DbKeepPosition { get { return m_position; } set { m_position = value; } @@ -416,7 +417,7 @@ public void GuardStopAttackCheckLOS(GamePlayer player, ushort response, ushort t { StopAttack(); - if (TargetObject != null && TargetPosition is GameLiving) + if (TargetObject != null && TargetObject is GameLiving) { (this.Brain as KeepGuardBrain).RemoveFromAggroList(TargetObject as GameLiving); } @@ -730,7 +731,8 @@ public override bool AddToWorld() { CurrentWayPoint = guard.CurrentWayPoint; m_changingPositions = true; - MoveTo(guard.CurrentRegionID, guard.X - Util.Random(200, 350), guard.Y - Util.Random(200, 350), guard.Z, guard.Heading); + var offset = Vector.Create(x: Util.Random(200, 350), y: Util.Random(200, 350)); + MoveTo(guard.Position - offset); m_changingPositions = false; foundGuard = true; break; @@ -892,7 +894,7 @@ public void DeleteObject() if (Component.Keep.Guards.ContainsKey(skey)) Component.Keep.Guards.Remove(skey); else if (log.IsWarnEnabled) - log.Warn($"Can't find {Position.ClassType} with dataObjectId {m_dataObjectID} in Component InternalID {Component.InternalID} Guard list."); + log.Warn($"Can't find {DbKeepPosition.ClassType} with dataObjectId {m_dataObjectID} in Component InternalID {Component.InternalID} Guard list."); } else if (log.IsWarnEnabled) log.Warn($"Keep is null on delete of guard {Name} with dataObjectId {m_dataObjectID}"); @@ -907,7 +909,7 @@ public void DeleteObject() if (Inventory != null) Inventory.ClearInventory(); Inventory = null; - Position = null; + DbKeepPosition = null; TempProperties.removeAllProperties(); base.Delete(); @@ -958,8 +960,7 @@ public void LoadFromPosition(DBKeepPosition pos, GameKeepComponent component) public void MoveToPosition(DBKeepPosition position) { PositionMgr.LoadGuardPosition(position, this); - if (!InCombat) - MoveTo(CurrentRegionID, X, Y, Z, Heading); + if (!InCombat) MoveTo(Position); } #endregion @@ -1005,12 +1006,15 @@ public void ChangeGuild() /// /// Adding special handling for walking to a point for patrol guards to be in a formation /// - public override void WalkTo(int tx, int ty, int tz, short speed) + public override void WalkTo(Coordinate destination, short speed) { int offX = 0; int offY = 0; if (IsMovingOnPath && PatrolGroup != null) - PatrolGroup.GetMovementOffset(this, out offX, out offY); - base.WalkTo(tx - offX, ty - offY, tz, speed); + { + PatrolGroup.GetMovementOffset(this, out offX, out offY); + } + var offset = Vector.Create(x: offX, y: offY ); + base.WalkTo(destination - offset, speed); } public override void WalkToSpawn() diff --git a/GameServer/keeps/Gameobjects/Guards/Patrol.cs b/GameServer/keeps/Gameobjects/Guards/Patrol.cs index 09bbecaf82..5e8711d729 100644 --- a/GameServer/keeps/Gameobjects/Guards/Patrol.cs +++ b/GameServer/keeps/Gameobjects/Guards/Patrol.cs @@ -7,6 +7,7 @@ using DOL.GS.Movement; using DOL.Events; using DOL.Database; +using DOL.GS.Geometry; namespace DOL.GS.Keeps { @@ -175,38 +176,23 @@ public void ChangePatrolLevel() CreatePatrolGuard(PatrolGuards.Count); } - int x = 0; - int y = 0; - - List guardsToKeep = new List(); - + var position = Position.Zero; + var guardsToKeep = new List(); for (int i = 0; i < PatrolGuards.Count; i++) { - GameKeepGuard guard = PatrolGuards[i] as GameKeepGuard; - - // Console.WriteLine(PatrolID + " loading guard " + guard.Name); + var guard = PatrolGuards[i] as GameKeepGuard; if (i < guardsToPatrol) { // we need to reposition the patrol at their spawn point plus variation - if (x == 0) - { - x = guard.SpawnPoint.X; - y = guard.SpawnPoint.Y; - } - else - { - x += Util.Random(250, 350); - y += Util.Random(250, 350); - } + if (position == Position.Zero) position = guard.SpawnPosition; + else position += Vector.Create(x: Util.Random(250, 350), y: Util.Random(250, 350)); if (guard.IsAlive) { + if (guard.IsMovingOnPath) guard.StopMovingOnPath(); - if (guard.IsMovingOnPath) - guard.StopMovingOnPath(); - - guard.MoveTo(guard.CurrentRegionID, x, y, guard.SpawnPoint.Z, guard.SpawnHeading); + guard.MoveTo(position); } guardsToKeep.Add(guard); diff --git a/GameServer/keeps/Gameobjects/IKeepItem.cs b/GameServer/keeps/Gameobjects/IKeepItem.cs index f224a38045..c951e22717 100644 --- a/GameServer/keeps/Gameobjects/IKeepItem.cs +++ b/GameServer/keeps/Gameobjects/IKeepItem.cs @@ -16,15 +16,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ -using System; -using System.Collections; using DOL.Database; - +using DOL.GS.Geometry; namespace DOL.GS.Keeps { public interface IKeepItem { + Position Position { get; set; } ushort CurrentRegionID { get;set;} int X { get;set;} int Y { get;set;} @@ -32,7 +31,7 @@ public interface IKeepItem ushort Heading { get;set;} string TemplateID { get;} GameKeepComponent Component { get; set;} - DBKeepPosition Position { get;set;} + DBKeepPosition DbKeepPosition { get;set;} void LoadFromPosition(DBKeepPosition position, GameKeepComponent component); void MoveToPosition(DBKeepPosition position); } diff --git a/GameServer/keeps/HookPointInventory.cs b/GameServer/keeps/HookPointInventory.cs index a227f05f13..1381272bf1 100644 --- a/GameServer/keeps/HookPointInventory.cs +++ b/GameServer/keeps/HookPointInventory.cs @@ -270,15 +270,11 @@ public void Invoke(GamePlayer player, int payType, GameKeepHookPoint hookpoint, if (hookPointObj == null) return; //use default value so no need to load //hookPointObj.LoadFromDatabase(this.ObjectTemplate); - hookPointObj.CurrentRegion = player.CurrentRegion; hookPointObj.Realm = hookpoint.Component.Keep.Realm; if (hookPointObj is GameSiegeWeapon) ((GameSiegeWeapon)hookPointObj).EnableToMove = false; - hookPointObj.X = hookpoint.X; - hookPointObj.Y = hookpoint.Y; - hookPointObj.Z = hookpoint.Z; - hookPointObj.Heading = hookpoint.Heading; + hookPointObj.Position = hookpoint.Position; if (hookPointObj is GameSiegeWeapon) (hookPointObj as GameSiegeWeapon).HookPoint = hookpoint; @@ -318,16 +314,12 @@ public static void Invoke(GameKeepHookPoint hookpoint, string objectType) //use default value so no need to load //hookPointObj.LoadFromDatabase(this.ObjectTemplate); - hookPointObj.CurrentRegion = hookpoint.Component.CurrentRegion; hookPointObj.Realm = hookpoint.Component.Keep.Realm; if (hookPointObj is GameSiegeWeapon) ((GameSiegeWeapon)hookPointObj).EnableToMove = false; - hookPointObj.X = hookpoint.X; - hookPointObj.Y = hookpoint.Y; - hookPointObj.Z = hookpoint.Z; - hookPointObj.Heading = hookpoint.Heading; + hookPointObj.Position = hookpoint.Position; if (hookPointObj is GameSiegeWeapon) (hookPointObj as GameSiegeWeapon).HookPoint = hookpoint; diff --git a/GameServer/keeps/IGameKeep.cs b/GameServer/keeps/IGameKeep.cs index ef1b9ee163..21f6a4861b 100644 --- a/GameServer/keeps/IGameKeep.cs +++ b/GameServer/keeps/IGameKeep.cs @@ -20,7 +20,7 @@ using System.Collections; using System.Collections.Generic; using DOL.Database; - +using DOL.GS.Geometry; namespace DOL.GS.Keeps { @@ -33,14 +33,15 @@ public interface IGameKeep void LoadFromDatabase(DataObject keep); void SaveIntoDatabase(); - - + ushort KeepID { get; } - + + Position Position {get;} int X { get; } int Y { get; } int Z { get; } ushort Heading { get; } + Angle Orientation { get; } Region CurrentRegion { get; } Guild Guild { get; } diff --git a/GameServer/keeps/IKeepManager.cs b/GameServer/keeps/IKeepManager.cs index dc351bf04b..57e5f0b9f6 100644 --- a/GameServer/keeps/IKeepManager.cs +++ b/GameServer/keeps/IKeepManager.cs @@ -22,6 +22,7 @@ using System.Linq; using System.Reflection; using DOL.Database; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; @@ -55,14 +56,19 @@ public interface IKeepManager bool IsNewKeepComponent(int skin); void RegisterKeep(int keepID, AbstractGameKeep keep); AbstractGameKeep GetKeepByID(int id); + [Obsolete("This is going to be removed.")] IEnumerable GetKeepsCloseToSpot(ushort regionid, IPoint3D point3d, int radius); + [Obsolete("This is going to be removed.")] + ICollection GetKeepsCloseToSpot(ushort regionid, int x, int y, int z, int radius); + [Obsolete("Use .GetKeepCloseToSpot(Position, int) instead!")] AbstractGameKeep GetKeepCloseToSpot(ushort regionid, IPoint3D point3d, int radius); + [Obsolete("Use .GetKeepCloseToSpot(Position, int) instead!")] + AbstractGameKeep GetKeepCloseToSpot(ushort regionid, int x, int y, int z, int radius); + AbstractGameKeep GetKeepCloseToSpot(Position position, int radius); ICollection GetKeepsByRealmMap(int map); AbstractGameKeep GetBGPK(GamePlayer player); ICollection GetFrontierKeeps(); ICollection GetKeepsOfRegion(ushort region); - ICollection GetKeepsCloseToSpot(ushort regionid, int x, int y, int z, int radius); - AbstractGameKeep GetKeepCloseToSpot(ushort regionid, int x, int y, int z, int radius); int GetTowerCountByRealm(eRealm realm); Dictionary GetTowerCountAllRealm(); Dictionary GetTowerCountFromZones(List zones); @@ -75,6 +81,8 @@ public interface IKeepManager bool IsEnemy(GameKeepDoor checker, GamePlayer target); bool IsEnemy(GameKeepComponent checker, GamePlayer target); byte GetHeightFromLevel(byte level); + Position GetBorderKeepPosition(int keepid); + [Obsolete("Use GetBorderKeepPosition(int) instead!")] void GetBorderKeepLocation(int keepid, out int x, out int y, out int z, out ushort heading); int GetRealmKeepBonusLevel(eRealm realm); int GetRealmTowerBonusLevel(eRealm realm); diff --git a/GameServer/keeps/KeepArea.cs b/GameServer/keeps/KeepArea.cs index 71f7c45f68..4e7780e4d7 100644 --- a/GameServer/keeps/KeepArea.cs +++ b/GameServer/keeps/KeepArea.cs @@ -78,7 +78,7 @@ public override void LoadFromDatabase(DBArea area) { base.LoadFromDatabase(area); GameServer.KeepManager.Log.Debug("KeepArea " + area.Description + " LoadFromDatabase called"); - GameServer.KeepManager.Log.Debug("X: " + area.X + "(" + m_X + ") Y: " + area.Y + "(" + m_Y + ") Region:" + area.Region + " Radius: " + m_Radius); + GameServer.KeepManager.Log.Debug("X: " + area.X + "(" + X + ") Y: " + area.Y + "(" + Y + ") Region:" + area.Region + " Radius: " + m_Radius); } } } diff --git a/GameServer/keeps/KeepHookPoint.cs b/GameServer/keeps/KeepHookPoint.cs index f61953f617..fb873459b1 100644 --- a/GameServer/keeps/KeepHookPoint.cs +++ b/GameServer/keeps/KeepHookPoint.cs @@ -21,54 +21,36 @@ using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; namespace DOL.GS.Keeps { /// /// A keepComponent /// - public class GameKeepHookPoint : Point3D + public class GameKeepHookPoint { public GameKeepHookPoint(int id, GameKeepComponent component) { m_index = id; m_component = component; m_hookpointTimer = new HookpointTimer(this, this.Component); - this.X = component.X; - this.Y = component.Y; - this.Z = component.Z; - this.Heading = component.Heading; + Position = component.Position; } public GameKeepHookPoint(DBKeepHookPoint dbhookPoint, GameKeepComponent component) { - double angle = component.Keep.Heading * ((Math.PI * 2) / 360); // angle*2pi/360; - switch (component.ComponentHeading) - { - case 0: - X = (int)(component.X + Math.Cos(angle) * dbhookPoint.X + Math.Sin(angle) * dbhookPoint.Y); - Y = (int)(component.Y - Math.Cos(angle) * dbhookPoint.Y + Math.Sin(angle) * dbhookPoint.X); - break; - case 1: - X = (int)(component.X + Math.Cos(angle) * dbhookPoint.Y - Math.Sin(angle) * dbhookPoint.X); - Y = (int)(component.Y + Math.Cos(angle) * dbhookPoint.X + Math.Sin(angle) * dbhookPoint.Y); - break; - case 2: - X = (int)(component.X - Math.Cos(angle) * dbhookPoint.X - Math.Sin(angle) * dbhookPoint.Y); - Y = (int)(component.Y + Math.Cos(angle) * dbhookPoint.Y - Math.Sin(angle) * dbhookPoint.X); - break; - case 3: - X = (int)(component.X - Math.Cos(angle) * dbhookPoint.Y + Math.Sin(angle) * dbhookPoint.X); - Y = (int)(component.Y - Math.Cos(angle) * dbhookPoint.X - Math.Sin(angle) * dbhookPoint.Y); - break; - } - this.Z = component.Z + dbhookPoint.Z; - this.Heading = (ushort)(component.Heading + dbhookPoint.Heading); - this.m_index = dbhookPoint.HookPointID; - this.Component = component; + var angle = component.Keep.Orientation + component.RelativeOrientationToKeep; + var offset = Vector.Create(dbhookPoint.X, -dbhookPoint.Y, dbhookPoint.Z).RotatedClockwise(angle); + Position = component.Position + offset; + Position = Position.With(component.Orientation + Angle.Heading(dbhookPoint.Heading)); + m_index = dbhookPoint.HookPointID; + Component = component; m_hookpointTimer = new HookpointTimer(this, this.Component); } + public Position Position { get; private init; } + #region properties // id <0x20=red,>0x20 - blue,>0x40 - green and yellow: 0x41(ballista),0x61(trebuchet),0x81(cauldron) @@ -91,12 +73,6 @@ public bool IsFree get { return (m_object == null); } } - private ushort m_heading; - public ushort Heading - { - get { return m_heading; } - set { m_heading = value; } - } private GameLiving m_object; public GameLiving Object diff --git a/GameServer/keeps/KeepManager.cs b/GameServer/keeps/KeepManager.cs index 6d76459895..25c15cc47b 100644 --- a/GameServer/keeps/KeepManager.cs +++ b/GameServer/keeps/KeepManager.cs @@ -22,6 +22,7 @@ using System.Linq; using System.Reflection; using DOL.Database; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; @@ -289,29 +290,13 @@ public virtual AbstractGameKeep GetKeepByID(int id) return m_keepList[id] as AbstractGameKeep; } - /// - /// get list of keep close to spot - /// - /// - /// - /// - /// + [Obsolete("Use .GetKeepCloseToSpot(Position, int) instead!")] public virtual IEnumerable GetKeepsCloseToSpot(ushort regionid, IPoint3D point3d, int radius) - { - return GetKeepsCloseToSpot(regionid, point3d.X, point3d.Y, point3d.Z, radius); - } + => GetKeepsCloseToSpot(regionid, point3d.X, point3d.Y, point3d.Z, radius); - /// - /// get the keep with minimum distance close to spot - /// - /// - /// - /// - /// - public virtual AbstractGameKeep GetKeepCloseToSpot(ushort regionid, IPoint3D point3d, int radius) - { - return GetKeepCloseToSpot(regionid, point3d.X, point3d.Y, point3d.Z, radius); - } + [Obsolete("Use .GetKeepCloseToSpot(Position, int) instead!")] + public virtual AbstractGameKeep GetKeepCloseToSpot(ushort regionid, IPoint3D point3d, int radius) + => GetKeepCloseToSpot(Position.Create(regionid, point3d.ToCoordinate()), radius); /// /// Gets all keeps by a realm map /rw @@ -441,16 +426,10 @@ public virtual ICollection GetKeepsCloseToSpot(ushort regionid return closeKeeps; } - /// - /// get the keep with minimum distance close to spot - /// - /// - /// - /// - /// - /// - /// public virtual AbstractGameKeep GetKeepCloseToSpot(ushort regionid, int x, int y, int z, int radius) + => GetKeepCloseToSpot(Position.Create(regionid,x,y), radius); + + public virtual AbstractGameKeep GetKeepCloseToSpot(Position position, int radius) { AbstractGameKeep closestKeep = null; @@ -461,11 +440,11 @@ public virtual AbstractGameKeep GetKeepCloseToSpot(ushort regionid, int x, int y foreach (AbstractGameKeep keep in m_keepList.Values) { - if (keep == null || keep.DBKeep == null || keep.DBKeep.Region != regionid) + if (keep == null || keep.DBKeep == null || keep.DBKeep.Region != position.RegionID) continue; - long xdiff = keep.DBKeep.X - x; - long ydiff = keep.DBKeep.Y - y; + long xdiff = keep.DBKeep.X - position.X; + long ydiff = keep.DBKeep.Y - position.Y; long range = xdiff * xdiff + ydiff * ydiff; if (range > radiussqrt) @@ -698,68 +677,33 @@ public virtual byte GetHeightFromLevel(byte level) return 0; } - public virtual void GetBorderKeepLocation(int keepid, out int x, out int y, out int z, out ushort heading) + public virtual void GetBorderKeepLocation(int keepid, out int x, out int y, out int z, out ushort heading) + { + var result = GetBorderKeepPosition(keepid); + x = result.X; + y = result.Y; + z = result.Z; + heading = result.Orientation.InHeading; + } + + public virtual Position GetBorderKeepPosition(int keepid) { - x = 0; - y = 0; - z = 0; - heading = 0; + var newFrontierRegionID = (ushort)163; switch (keepid) { //sauvage - case 1: - { - x = 653811; - y = 616998; - z = 9560; - heading = 2040; - break; - } + case 1: return Position.Create(newFrontierRegionID, x: 653811, y: 616998, z: 9560, heading: 2040); //snowdonia - case 2: - { - x = 616149; - y = 679042; - z = 9560; - heading = 1611; - break; - } + case 2: return Position.Create(newFrontierRegionID, x: 616149, y: 679042, z: 9560, heading: 1611); //svas - case 3: - { - x = 651460; - y = 313758; - z = 9432; - heading = 1004; - break; - } + case 3: return Position.Create(newFrontierRegionID, x: 651460, y: 313758, z: 9432, heading: 1004); //vind - case 4: - { - x = 715179; - y = 365101; - z = 9432; - heading = 314; - break; - } + case 4: return Position.Create(newFrontierRegionID, x: 715179, y: 365101, z: 9432, heading: 314); //ligen - case 5: - { - x = 396519; - y = 618017; - z = 9838; - heading = 2159; - break; - } + case 5: return Position.Create(newFrontierRegionID, x: 396519, y: 618017, z: 9838, heading: 2159); //cain - case 6: - { - x = 432841; - y = 680032; - z = 9747; - heading = 2585; - break; - } + case 6: return Position.Create(newFrontierRegionID, x: 432841, y: 680032, z: 9747, heading: 2585); + default: return Position.Zero; } } @@ -838,9 +782,8 @@ public virtual void ExitBattleground(GamePlayer player) if (location != "") { - Teleport t = DOLDB.SelectObject(DB.Column(nameof(Teleport.TeleportID)).IsEqualTo(location)); - if (t != null) - player.MoveTo((ushort)t.RegionID, t.X, t.Y, t.Z, (ushort)t.Heading); + var t = DOLDB.SelectObject(DB.Column(nameof(Teleport.TeleportID)).IsEqualTo(location)); + if (t != null) player.MoveTo(t.GetPosition()); } } } diff --git a/GameServer/keeps/Managers/Position Manager.cs b/GameServer/keeps/Managers/Position Manager.cs index a4ca6ca91f..f6b3a796da 100644 --- a/GameServer/keeps/Managers/Position Manager.cs +++ b/GameServer/keeps/Managers/Position Manager.cs @@ -26,6 +26,7 @@ using DOL.GS.Movement; using DOL.GS.PacketHandler; using System.Collections.Generic; +using DOL.GS.Geometry; namespace DOL.GS.Keeps { @@ -82,134 +83,24 @@ public static void LoadGuardPosition(DBKeepPosition pos, GameKeepGuard guard) { LoadKeepItemPosition(pos, guard); - guard.SpawnPoint.X = guard.X; - guard.SpawnPoint.Y = guard.Y; - guard.SpawnPoint.Z = guard.Z; - guard.SpawnHeading = guard.Heading; + guard.SpawnPosition = guard.Position; } - public static void LoadKeepItemPosition(DBKeepPosition pos, IKeepItem item) - { - item.CurrentRegionID = item.Component.CurrentRegionID; - int x, y; - LoadXY(item.Component, pos.XOff, pos.YOff, out x, out y); - item.X = x; - item.Y = y; - - item.Z = item.Component.Keep.Z + pos.ZOff; - - item.Heading = (ushort)(item.Component.Heading + pos.HOff); - - item.Position = pos; - } - - /// - /// Calculates X and Y based on component rotation and offset - /// - /// The assigned component object - /// The argument X - /// The argument Y - /// The result X - /// The result Y - public static void LoadXY(GameKeepComponent component, int inX, int inY, out int outX, out int outY) - { - double angle = component.Keep.Heading * ((Math.PI * 2) / 360); // angle*2pi/360; - double C = Math.Cos(angle); - double S = Math.Sin(angle); - switch (component.ComponentHeading) - { - case 0: - { - outX = (int)(component.X + C * inX + S * inY); - outY = (int)(component.Y - C * inY + S * inX); - break; - } - case 1: - { - outX = (int)(component.X + C * inY - S * inX); - outY = (int)(component.Y + C * inX + S * inY); - break; - } - case 2: - { - outX = (int)(component.X - C * inX - S * inY); - outY = (int)(component.Y + C * inY - S * inX); - break; - } - case 3: - { - outX = (int)(component.X - C * inY + S * inX); - outY = (int)(component.Y - C * inX - S * inY); - break; - } - default: - { - outX = 0; - outY = 0; - break; - } - } - } - - /// - /// Saves X and Y offsets - /// - /// The assigned component object - /// The argument X - /// The argument Y - /// The result X - /// The result Y - public static void SaveXY(GameKeepComponent component, int inX, int inY, out int outX, out int outY) - { - double angle = component.Keep.Heading * ((Math.PI * 2) / 360); // angle*2pi/360; - int gx = inX - component.X; - int gy = inY - component.Y; - double C = Math.Cos(angle); - double S = Math.Sin(angle); - switch (component.ComponentHeading) - { - case 0: - { - outX = (int)(gx * C + gy * S); - outY = (int)(gx * S - gy * C); - break; - } - case 1: - { - outX = (int)(gy * C - gx * S); - outY = (int)(gx * C + gy * S); - break; - } - case 2: - { - outX = (int)((gx * C + gy * S) / (-C * C - S * S)); - outY = (int)(gy * C - gx * S); - break; - } - case 3: - { - outX = (int)(gx * S - gy * C); - outY = (int)((gx * C + gy * S) / (-C * C - S * S)); - break; - } - default: - { - outX = 0; - outY = 0; - break; - } - } - } + public static void LoadKeepItemPosition(DBKeepPosition pos, IKeepItem item) + { + var keepPositionOffset = Vector.Create(pos.XOff, -pos.YOff, pos.ZOff).RotatedClockwise(item.Component.Orientation); + var orientation = item.Component.Orientation + Angle.Heading(pos.HOff); + item.Position = (item.Component.Position + keepPositionOffset).With(orientation); + item.DbKeepPosition = pos; + } + + public static Vector SaveXY(GameKeepComponent component, Coordinate keepPointCoordinate) + { + var angle = component.Keep.Orientation + component.RelativeOrientationToKeep; + var vector = keepPointCoordinate - component.Coordinate; + return vector.RotatedClockwise(angle - Angle.Degrees(90)); + } - /// - /// Creates a position - /// - /// - /// - /// - /// - /// - /// public static DBKeepPosition CreatePosition(Type type, int height, GamePlayer player, string guardID, GameKeepComponent component) { DBKeepPosition pos = CreatePosition(guardID, component, player); @@ -249,15 +140,13 @@ public static DBKeepPosition CreatePosition(string templateID, GameKeepComponent pos.ComponentSkin = component.Skin; pos.ComponentRotation = component.ComponentHeading; pos.TemplateID = templateID; - int x, y; - - SaveXY(component, player.X, player.Y, out x, out y); - pos.XOff = x; - pos.YOff = y; - pos.ZOff = player.Z - component.Z; + var keepPositionOffset = SaveXY(component, player.Coordinate); + pos.XOff = keepPositionOffset.X; + pos.YOff = keepPositionOffset.Y; + pos.ZOff = keepPositionOffset.Z; - pos.HOff = player.Heading - component.Heading; + pos.HOff = (player.Orientation - component.Orientation).InHeading; return pos; } @@ -343,27 +232,22 @@ public static PathPoint LoadPatrolPath(string pathID, GameKeepComponent componen PathPoint first = null; for (int i = 0; i < sorted.Count; i++) { - DBPathPoint pp = (DBPathPoint)sorted.GetByIndex(i); - PathPoint p = new PathPoint(pp.X, pp.Y, pp.Z, pp.MaxSpeed, pathType); - - int x, y; - LoadXY(component, pp.X, pp.Y, out x, out y); - p.X = x; - p.Y = y; - p.Z = component.Keep.Z + p.Z; - - p.WaitTime = pp.WaitTime; + var dbPathPoint = (DBPathPoint)sorted.GetByIndex(i); + var pathPoint = new PathPoint(dbPathPoint, pathType); + var relativeOffset = Vector.Create(pathPoint.Coordinate.X, -pathPoint.Coordinate.Y, pathPoint.Coordinate.Z) + .RotatedClockwise(component.Orientation); + pathPoint.Coordinate = component.Coordinate + relativeOffset; if (first == null) { - first = p; + first = pathPoint; } - p.Prev = prev; + pathPoint.Prev = prev; if (prev != null) { - prev.Next = p; + prev.Next = pathPoint; } - prev = p; + prev = pathPoint; } return first; } @@ -391,17 +275,15 @@ public static void SavePatrolPath(string pathID, PathPoint path, GameKeepCompone int i = 1; do { - DBPathPoint dbpp = new DBPathPoint(path.X, path.Y, path.Z, path.MaxSpeed); - int x, y; - SaveXY(component, dbpp.X, dbpp.Y, out x, out y); - dbpp.X = x; - dbpp.Y = y; - dbpp.Z = dbpp.Z - component.Z; - - dbpp.Step = i++; - dbpp.PathID = pathID; - dbpp.WaitTime = path.WaitTime; - GameServer.Database.AddObject(dbpp); + var dbPathPoint = path.GenerateDbEntry(); + var offset = SaveXY(component, Coordinate.Create(dbPathPoint.X, dbPathPoint.Y)); + dbPathPoint.X = offset.X; + dbPathPoint.Y = offset.Y; + dbPathPoint.Z = offset.Z; + dbPathPoint.Step = i++; + dbPathPoint.PathID = pathID; + + GameServer.Database.AddObject(dbPathPoint); path = path.Next; } while (path != null && path != root); } @@ -440,15 +322,13 @@ public static void CreateDoor(int doorID, GamePlayer player) pos.ComponentSkin = component.Skin; pos.ComponentRotation = component.ComponentHeading; pos.TemplateID = Guid.NewGuid().ToString(); - int x, y; - - SaveXY(component, player.X, player.Y, out x, out y); - pos.XOff = x; - pos.YOff = y; - pos.ZOff = player.Z - component.Z; + var keepPositionOffset = SaveXY(component, player.Coordinate); + pos.XOff = keepPositionOffset.X; + pos.YOff = keepPositionOffset.Y; + pos.ZOff = keepPositionOffset.Z; - pos.HOff = player.Heading - component.Heading; + pos.HOff = (player.Orientation - component.Orientation).InHeading; GameServer.Database.AddObject(pos); diff --git a/GameServer/keeps/Relics/GameRelic.cs b/GameServer/keeps/Relics/GameRelic.cs index 4c7047419c..942f6a8d68 100644 --- a/GameServer/keeps/Relics/GameRelic.cs +++ b/GameServer/keeps/Relics/GameRelic.cs @@ -7,6 +7,7 @@ using DOL.GS.PacketHandler; using DOL.Database; using log4net; +using DOL.GS.Geometry; namespace DOL.GS { @@ -177,12 +178,8 @@ public virtual void RelicPadTakesOver(GameRelicPad pad, bool returning) Realm = pad.Realm; LastRealm = pad.Realm; pad.MountRelic(this, returning); - CurrentRegionID = pad.CurrentRegionID; + Position = pad.Position; PlayerLoosesRelic(true); - X = pad.X; - Y = pad.Y; - Z = pad.Z; - Heading = pad.Heading; SaveIntoDatabase(); AddToWorld(); } @@ -194,11 +191,7 @@ protected virtual void Update() { if (m_item == null || m_currentCarrier == null) return; - CurrentRegionID = m_currentCarrier.CurrentRegionID; - X = m_currentCarrier.X; - Y = m_currentCarrier.Y; - Z = m_currentCarrier.Z; - Heading = m_currentCarrier.Heading; + Position = m_currentCarrier.Position; } @@ -227,7 +220,7 @@ protected virtual void PlayerTakesRelic(GamePlayer player) if (IsMounted) { - AbstractGameKeep keep = GameServer.KeepManager.GetKeepCloseToSpot(m_currentRelicPad.CurrentRegionID, m_currentRelicPad, WorldMgr.VISIBILITY_DISTANCE); + AbstractGameKeep keep = GameServer.KeepManager.GetKeepCloseToSpot(m_currentRelicPad.Position, WorldMgr.VISIBILITY_DISTANCE); log.DebugFormat("keep {0}", keep); @@ -493,11 +486,7 @@ public override void LoadFromDatabase(DataObject obj) { InternalID = obj.ObjectId; m_dbRelic = obj as DBRelic; - CurrentRegionID = (ushort)m_dbRelic.Region; - X = m_dbRelic.X; - Y = m_dbRelic.Y; - Z = m_dbRelic.Z; - Heading = (ushort)m_dbRelic.Heading; + Position = Position.Create((ushort)m_dbRelic.Region, m_dbRelic.X, m_dbRelic.Y, m_dbRelic.Z, (ushort)m_dbRelic.Heading); m_relicType = (eRelicType)m_dbRelic.relicType; Realm = (eRealm)m_dbRelic.Realm; m_originalRealm = (eRealm)m_dbRelic.OriginalRealm; @@ -541,12 +530,12 @@ public override void SaveIntoDatabase() m_dbRelic.Realm = (int)Realm; m_dbRelic.OriginalRealm = (int)OriginalRealm; m_dbRelic.LastRealm = (int)m_lastRealm; - m_dbRelic.Heading = (int)Heading; - m_dbRelic.Region = (int)CurrentRegionID; + m_dbRelic.Heading = Orientation.InHeading; + m_dbRelic.Region = Position.RegionID; m_dbRelic.relicType = (int)RelicType; - m_dbRelic.X = X; - m_dbRelic.Y = Y; - m_dbRelic.Z = Z; + m_dbRelic.X = Position.X; + m_dbRelic.Y = Position.Y; + m_dbRelic.Z = Position.Z; if (InternalID == null) { diff --git a/GameServer/keeps/Relics/GameRelicPad.cs b/GameServer/keeps/Relics/GameRelicPad.cs index 656be45ee1..c0ad351a4e 100644 --- a/GameServer/keeps/Relics/GameRelicPad.cs +++ b/GameServer/keeps/Relics/GameRelicPad.cs @@ -224,7 +224,7 @@ public class PadArea : Area.Circle GameRelicPad m_parent; public PadArea(GameRelicPad parentPad) - : base("", parentPad.X, parentPad.Y, parentPad.Z, PAD_AREA_RADIUS) + : base("", parentPad.Coordinate, PAD_AREA_RADIUS) { m_parent = parentPad; } diff --git a/GameServer/language/LanguageMgr.cs b/GameServer/language/LanguageMgr.cs index ac8b1d2cf1..2ce68011cc 100644 --- a/GameServer/language/LanguageMgr.cs +++ b/GameServer/language/LanguageMgr.cs @@ -26,6 +26,7 @@ using DOL.Database; using DOL.GS; +using DOL.GS.Geometry; using log4net; namespace DOL.Language @@ -448,6 +449,23 @@ private static ArrayList ReadLanguageDirectory(string path, string language) #endregion Initialization + public static string GetCardinalDirection(string languageID, Angle direction) + { + var clockwiseDirectionIndexBeginningFromSouth = ((direction.InHeading + 256) % 4096) / 512; + switch (clockwiseDirectionIndexBeginningFromSouth) + { + case 0: return LanguageMgr.GetTranslation(languageID, "Scripts.Players.Yell.South"); + case 1: return LanguageMgr.GetTranslation(languageID, "Scripts.Players.Yell.SouthWest"); + case 2: return LanguageMgr.GetTranslation(languageID, "Scripts.Players.Yell.West"); + case 3: return LanguageMgr.GetTranslation(languageID, "Scripts.Players.Yell.NorthWest"); + case 4: return LanguageMgr.GetTranslation(languageID, "Scripts.Players.Yell.North"); + case 5: return LanguageMgr.GetTranslation(languageID, "Scripts.Players.Yell.NorthEast"); + case 6: return LanguageMgr.GetTranslation(languageID, "Scripts.Players.Yell.East"); + case 7: return LanguageMgr.GetTranslation(languageID, "Scripts.Players.Yell.SouthEast"); + } + return ""; + } + #region GetLanguageDataObject public static LanguageDataObject GetLanguageDataObject(string language, string translationId, LanguageDataObject.eTranslationIdentifier translationIdentifier) { diff --git a/GameServer/managers/worldmanager/RegionWeather.cs b/GameServer/managers/worldmanager/RegionWeather.cs index ced9afe48d..9594c6ba19 100644 --- a/GameServer/managers/worldmanager/RegionWeather.cs +++ b/GameServer/managers/worldmanager/RegionWeather.cs @@ -89,8 +89,8 @@ public sealed class RegionWeather public RegionWeather(Region Region) { this.Region = Region; - WeatherMinPosition = (uint)Math.Max(0, Region.Zones.Min(z => z.XOffset)); - WeatherMaxPosition = (uint)Math.Max(0, Region.Zones.Max(z => z.XOffset + z.Width)); + WeatherMinPosition = (uint)Math.Max(0, Region.Zones.Min(z => z.Offset.X)); + WeatherMaxPosition = (uint)Math.Max(0, Region.Zones.Max(z => z.Offset.X + z.Width)); } /// diff --git a/GameServer/managers/worldmanager/WeatherManager.cs b/GameServer/managers/worldmanager/WeatherManager.cs index efe66af0a0..702535cc6c 100644 --- a/GameServer/managers/worldmanager/WeatherManager.cs +++ b/GameServer/managers/worldmanager/WeatherManager.cs @@ -220,7 +220,7 @@ private void StopWeather(RegionWeather weather) { SendWeatherUpdate(weather, player); - if (player.X > weatherCurrentPosition - weather.Width && player.X < weatherCurrentPosition) + if (player.Position.X > weatherCurrentPosition - weather.Width && player.Position.X < weatherCurrentPosition) player.Out.SendMessage("The sky clears up again as the storm clouds disperse!", eChatType.CT_Important, eChatLoc.CL_SystemWindow); } } diff --git a/GameServer/minotaurrelics/MinotaurRelic.cs b/GameServer/minotaurrelics/MinotaurRelic.cs index 22a90cad87..e2e406dc03 100644 --- a/GameServer/minotaurrelics/MinotaurRelic.cs +++ b/GameServer/minotaurrelics/MinotaurRelic.cs @@ -24,6 +24,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Effects; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using DOL.GS.Spells; @@ -47,11 +48,6 @@ public MinotaurRelic(DBMinotaurRelic obj) DBMinotaurRelic m_dbRelic; Timer timer = null; public RegionTimer respawntimer = null; - protected int m_spawny; - protected int m_spawnx; - protected int m_spawnz; - protected int m_spawnheading; - protected int m_spawnregion; protected int m_relicSpellID; protected Spell m_relicSpell; protected string m_relicTarget; @@ -126,35 +122,7 @@ public string RelicTarget set { m_relicTarget = value; } } - public int SpawnX - { - get { return m_spawnx; } - set { m_spawnx = value; } - } - - public int SpawnY - { - get { return m_spawny; } - set { m_spawny = value; } - } - - public int SpawnZ - { - get { return m_spawnz; } - set { m_spawnz = value; } - } - - public int SpawnHeading - { - get { return m_spawnheading; } - set { m_spawnheading = value; } - } - - public int SpawnRegion - { - get { return m_spawnregion; } - set { m_spawnregion = value; } - } + public Position SpawnPosition { get; set; } public int Effect { @@ -174,18 +142,9 @@ public override void LoadFromDatabase(DataObject obj) m_dbRelic = obj as DBMinotaurRelic; RelicID = m_dbRelic.RelicID; - Heading = (ushort)m_dbRelic.SpawnHeading; - CurrentRegionID = (ushort)m_dbRelic.SpawnRegion; - X = m_dbRelic.SpawnX; - Y = m_dbRelic.SpawnY; - Z = m_dbRelic.SpawnZ; - - SpawnHeading = m_dbRelic.SpawnHeading; - SpawnRegion = m_dbRelic.SpawnRegion; + SpawnPosition = Position.Create((ushort)m_dbRelic.SpawnRegion, m_dbRelic.SpawnX, m_dbRelic.SpawnY, m_dbRelic.SpawnZ, (ushort)m_dbRelic.SpawnHeading); + Position = SpawnPosition; Effect = m_dbRelic.Effect; - SpawnX = m_dbRelic.SpawnX; - SpawnY = m_dbRelic.SpawnY; - SpawnZ = m_dbRelic.SpawnZ; RelicSpellID = m_dbRelic.relicSpell; RelicSpell = SkillBase.GetSpellByID(m_dbRelic.relicSpell); @@ -209,11 +168,11 @@ public override void LoadFromDatabase(DataObject obj) /// public override void SaveIntoDatabase() { - m_dbRelic.SpawnHeading = Heading; - m_dbRelic.SpawnRegion = CurrentRegionID; - m_dbRelic.SpawnX = X; - m_dbRelic.SpawnY = Y; - m_dbRelic.SpawnZ = Z; + m_dbRelic.SpawnHeading = Orientation.InHeading; + m_dbRelic.SpawnRegion = Position.RegionID; + m_dbRelic.SpawnX = Position.X; + m_dbRelic.SpawnY = Position.Y; + m_dbRelic.SpawnZ = Position.Z; m_dbRelic.Effect = Effect; @@ -512,11 +471,7 @@ protected override int RespawnTimerCallback(RegionTimer respawnTimer) } if (ObjectState == eObjectState.Active) return 0; - X = SpawnX; - Y = SpawnY; - Z = SpawnZ; - Heading = (ushort)SpawnHeading; - CurrentRegionID = (ushort)SpawnRegion; + Position = SpawnPosition; XP = MinotaurRelicManager.MAX_RELIC_EXP; AddToWorld(); return 0; @@ -530,11 +485,7 @@ public virtual void ManualRespawn() respawntimer = null; } if (ObjectState == eObjectState.Active) return; - X = SpawnX; - Y = SpawnY; - Z = SpawnZ; - Heading = (ushort)SpawnHeading; - CurrentRegionID = (ushort)SpawnRegion; + Position = SpawnPosition; XP = MinotaurRelicManager.MAX_RELIC_EXP; AddToWorld(); } @@ -546,16 +497,12 @@ public virtual void ManualRespawn() protected virtual void Update(GameLiving living) { if (living == null) return; - CurrentRegionID = living.CurrentRegionID; - X = living.X; - Y = living.Y; - Z = living.Z; - Heading = living.Heading; + Position = living.Position; foreach (GameClient clt in WorldMgr.GetClientsOfRegion(CurrentRegionID)) { if (clt == null || clt.Player == null) continue; if (XP > 0) - clt.Player.Out.SendMinotaurRelicMapUpdate((byte)RelicID, CurrentRegionID, X, Y, Z); + clt.Player.Out.SendMinotaurRelicMapUpdate((byte)RelicID, Position); else clt.Player.Out.SendMinotaurRelicMapRemove((byte)RelicID); } @@ -635,7 +582,7 @@ public override bool AddToWorld() { if (SpawnLocked) { - if (X == SpawnX && Y == SpawnY) + if (Position.Coordinate == SpawnPosition.Coordinate) { if (ProtectorClassType != string.Empty) { diff --git a/GameServer/minotaurrelics/MinotaurRelicManager.cs b/GameServer/minotaurrelics/MinotaurRelicManager.cs index e488dc029c..8fda2a3989 100644 --- a/GameServer/minotaurrelics/MinotaurRelicManager.cs +++ b/GameServer/minotaurrelics/MinotaurRelicManager.cs @@ -140,7 +140,7 @@ private static void MapUpdate(object nullValue) { foreach(MinotaurRelic relic in relics[clt.Player.CurrentRegionID]) { - clt.Player.Out.SendMinotaurRelicMapUpdate((byte)relic.RelicID, relic.CurrentRegionID, relic.X, relic.Y, relic.Z); + clt.Player.Out.SendMinotaurRelicMapUpdate((byte)relic.RelicID, relic.Position); } } } diff --git a/GameServer/minotaurrelics/Protectors/ArrektosProtector.cs b/GameServer/minotaurrelics/Protectors/ArrektosProtector.cs index 3634bbcd51..dd1c936e5a 100644 --- a/GameServer/minotaurrelics/Protectors/ArrektosProtector.cs +++ b/GameServer/minotaurrelics/Protectors/ArrektosProtector.cs @@ -40,6 +40,7 @@ using System.Collections.Generic; using System.Text; using DOL.GS.Effects; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using DOL.GS.Spells; @@ -54,13 +55,7 @@ public override bool AddToWorld() { //foreman fogo doesn't leave the room. TetherRange = 1000; - - X = 49293; - Y = 42208; - Z = 27562; - Heading = 2057; - CurrentRegionID = 245; - + Position = Position.Create(regionID: 245, x: 49293, y: 42208, z: 27562,heading: 2057); Flags = 0; Level = 56; diff --git a/GameServer/minotaurrelics/Protectors/BaseProtector.cs b/GameServer/minotaurrelics/Protectors/BaseProtector.cs index 4ce91fc37a..e64c2ba30f 100644 --- a/GameServer/minotaurrelics/Protectors/BaseProtector.cs +++ b/GameServer/minotaurrelics/Protectors/BaseProtector.cs @@ -69,11 +69,7 @@ public static bool LockRelic() LockedEffect = new GameNPC(); LockedEffect.Model = 1583; LockedEffect.Name = "LOCKED_RELIC"; - LockedEffect.X = Relic.X; - LockedEffect.Y = Relic.Y; - LockedEffect.Z = Relic.Z; - LockedEffect.Heading = Relic.Heading; - LockedEffect.CurrentRegionID = Relic.CurrentRegionID; + LockedEffect.Position = Relic.Position; LockedEffect.Flags = GameNPC.eFlags.CANTTARGET; LockedEffect.AddToWorld(); diff --git a/GameServer/packets/Client/168/DialogResponseHandler.cs b/GameServer/packets/Client/168/DialogResponseHandler.cs index 76482a8482..ab0392f919 100644 --- a/GameServer/packets/Client/168/DialogResponseHandler.cs +++ b/GameServer/packets/Client/168/DialogResponseHandler.cs @@ -255,7 +255,7 @@ protected override void OnTick() return; } - AbstractGameKeep keep = GameServer.KeepManager.GetKeepCloseToSpot(player.CurrentRegionID, player, WorldMgr.VISIBILITY_DISTANCE); + AbstractGameKeep keep = GameServer.KeepManager.GetKeepCloseToSpot(player.Position, WorldMgr.VISIBILITY_DISTANCE); if (keep == null) { player.Out.SendMessage("You have to be near the keep to claim it.", eChatType.CT_System, diff --git a/GameServer/packets/Client/168/DoorRequestHandler.cs b/GameServer/packets/Client/168/DoorRequestHandler.cs index 7edb15dea3..d9e75dfbd4 100644 --- a/GameServer/packets/Client/168/DoorRequestHandler.cs +++ b/GameServer/packets/Client/168/DoorRequestHandler.cs @@ -23,6 +23,7 @@ using DOL.GS.Keeps; using DOL.GS.ServerProperties; using DOL.Language; +using DOL.GS.Geometry; namespace DOL.GS.PacketHandler.Client.v168 { @@ -190,10 +191,10 @@ public void AddingDoor(GamePlayer player, byte response) door.MaxHealth = 2545; door.Health = 2545; door.Locked = 0; - door.X = player.X; - door.Y = player.Y; - door.Z = player.Z; - door.Heading = player.Heading; + door.X = player.Position.X; + door.Y = player.Position.Y; + door.Z = player.Position.Z; + door.Heading = player.Orientation.InHeading; GameServer.Database.AddObject(door); player.Out.SendMessage("Added door " + m_handlerDoorID + " to the database!", eChatType.CT_Important, @@ -261,7 +262,7 @@ protected override void OnTick() } else { - if (player.IsWithinRadius(mydoor, m_radius)) + if (player.Coordinate.DistanceTo(mydoor.Coordinate) < m_radius) { if (m_doorState == 0x01) mydoor.Open(player); @@ -297,11 +298,8 @@ protected override void OnTick() //else basic quick hack var door = new GameDoor(); door.DoorID = m_doorId; - door.X = player.X; - door.Y = player.Y; - door.Z = player.Z; + door.Position = player.Position.With(door.Orientation); door.Realm = eRealm.Door; - door.CurrentRegion = player.CurrentRegion; door.Open(player); } } diff --git a/GameServer/packets/Client/168/HouseEnterLeaveRequestHandler.cs b/GameServer/packets/Client/168/HouseEnterLeaveRequestHandler.cs index 01119a443c..87cf00b21d 100644 --- a/GameServer/packets/Client/168/HouseEnterLeaveRequestHandler.cs +++ b/GameServer/packets/Client/168/HouseEnterLeaveRequestHandler.cs @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ +using DOL.GS.Geometry; using DOL.GS.Housing; namespace DOL.GS.PacketHandler.Client.v168 @@ -78,7 +79,8 @@ protected override void OnTick() break; case 1: - if (!player.IsWithinRadius(_house, WorldMgr.VISIBILITY_DISTANCE) || (player.CurrentRegionID != _house.RegionID)) + if (player.Coordinate.DistanceTo(_house.Position) > WorldMgr.VISIBILITY_DISTANCE + || (player.CurrentRegionID != _house.RegionID)) { ChatUtil.SendSystemMessage(player, string.Format("You are too far away to enter house {0}.", _house.HouseNumber)); return; diff --git a/GameServer/packets/Client/168/HousingPlaceItemHandler.cs b/GameServer/packets/Client/168/HousingPlaceItemHandler.cs index e3cf0e46dc..0670222c0e 100644 --- a/GameServer/packets/Client/168/HousingPlaceItemHandler.cs +++ b/GameServer/packets/Client/168/HousingPlaceItemHandler.cs @@ -20,6 +20,7 @@ using System.Collections.Generic; using System.Reflection; using DOL.Database; +using DOL.GS.Geometry; using DOL.GS.Housing; using DOL.GS.ServerProperties; using DOL.GS.Utils; @@ -42,7 +43,7 @@ public void HandlePacket(GameClient client, GSPacketIn packet) { int unknow1 = packet.ReadByte(); // 1=Money 0=Item (?) int slot = packet.ReadByte(); // Item/money slot - ushort housenumber = packet.ReadShort(); // N° of house + ushort housenumber = packet.ReadShort(); int unknow2 = (byte)packet.ReadByte(); _position = (byte)packet.ReadByte(); int method = packet.ReadByte(); // 2=Wall 3=Floor @@ -329,7 +330,7 @@ public void HandlePacket(GameClient client, GSPacketIn packet) ChatUtil.SendSystemMessage(client, "Scripts.Player.Housing.GardenItemPlacedName", orgitem.Name); // update all nearby players - foreach (GamePlayer player in WorldMgr.GetPlayersCloseToSpot(house.RegionID, house, WorldMgr.OBJ_UPDATE_DISTANCE)) + foreach (GamePlayer player in WorldMgr.GetPlayersCloseToSpot(house.Position, WorldMgr.OBJ_UPDATE_DISTANCE)) { player.Out.SendGarden(house); } @@ -393,7 +394,7 @@ public void HandlePacket(GameClient client, GSPacketIn packet) }; // figure out proper rotation for item - int properRotation = client.Player.Heading / 10; + int properRotation = client.Player.Orientation.InHeading / 10; properRotation = properRotation.Clamp(0, 360); if (method == 2 && IsSuitableForWall(orgitem)) @@ -554,7 +555,7 @@ public void HandlePacket(GameClient client, GSPacketIn packet) } // if the hookpoint doesn't exist, prompt player to Log it in the database for us - if (house.GetHookpointLocation((uint)_position) == null) + if (house.GetHookPointCoordinate((uint)_position) == Coordinate.Nowhere) { client.Out.SendInventorySlotsUpdate(new[] { slot }); @@ -574,7 +575,7 @@ public void HandlePacket(GameClient client, GSPacketIn packet) } } } - else if (house.GetHookpointLocation((uint)_position) != null) + else if (house.GetHookPointCoordinate((uint)_position) != Coordinate.Nowhere) { var point = new DBHouseHookpointItem { @@ -597,7 +598,7 @@ public void HandlePacket(GameClient client, GSPacketIn packet) if (house.HousepointItems.ContainsKey(point.HookpointID) == false) { house.HousepointItems.Add(point.HookpointID, point); - house.FillHookpoint((uint)_position, orgitem.Id_nb, client.Player.Heading, 0); + house.FillHookpoint((uint)_position, orgitem.Id_nb, client.Player.Orientation.InHeading, 0); } else { @@ -697,7 +698,7 @@ public void HandlePacket(GameClient client, GSPacketIn packet) } // if hookpoint doesn't exist, prompt player to Log it in the database for us - if (house.GetHookpointLocation((uint)_position) == null) + if (house.GetHookPointCoordinate((uint)_position) == Coordinate.Nowhere) { client.Out.SendInventorySlotsUpdate(new[] { slot }); @@ -744,7 +745,7 @@ public void HandlePacket(GameClient client, GSPacketIn packet) // create the new vault and attach it to the house var houseVault = new GameHouseVault(orgitem.Template, vaultIndex); - houseVault.Attach(house, (uint)_position, (ushort)((client.Player.Heading + 2048) % 4096)); + houseVault.Attach(house, (uint)_position, (client.Player.Orientation + Angle.Degrees(180)).InHeading); // remove the original item from the player's inventory client.Player.Inventory.RemoveItem(orgitem); @@ -883,14 +884,15 @@ private void LogLocation(GamePlayer player, byte response) if (player.CurrentHouse == null) return; + var offset = player.Coordinate - player.CurrentHouse.Position.Coordinate; var a = new HouseHookpointOffset { HouseModel = player.CurrentHouse.Model, HookpointID = _position, - X = player.X - player.CurrentHouse.X, - Y = player.Y - player.CurrentHouse.Y, - Z = player.Z - 25000, - Heading = player.Heading - player.CurrentHouse.Heading + X = offset.X, + Y = offset.Y, + Z = player.Position.Z - 25000, + Heading = player.Orientation.InHeading - player.CurrentHouse.Position.Orientation.InHeading }; if (GameServer.Database.AddObject(a) && House.AddNewOffset(a)) diff --git a/GameServer/packets/Client/168/PlayerGroundTargetHandler.cs b/GameServer/packets/Client/168/PlayerGroundTargetHandler.cs index 61092e6a1d..4467180d36 100644 --- a/GameServer/packets/Client/168/PlayerGroundTargetHandler.cs +++ b/GameServer/packets/Client/168/PlayerGroundTargetHandler.cs @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ +using DOL.GS.Geometry; + namespace DOL.GS.PacketHandler.Client.v168 { [PacketHandlerAttribute(PacketHandlerType.TCP, eClientPackets.PlayerGroundTarget, "Handles Player Ground Target Settings", eClientStatus.PlayerInGame)] @@ -77,7 +79,7 @@ protected override void OnTick() { var player = (GamePlayer) m_actionSource; player.GroundTargetInView = ((m_flag & 0x100) != 0); - player.SetGroundTarget(m_x, m_y, (ushort) m_z); + player.GroundTargetPosition = Position.Create(player.Position.RegionID, m_x, m_y, (ushort) m_z); if (!player.GroundTargetInView) player.Out.SendMessage("Your ground target is not visible!", eChatType.CT_System, eChatLoc.CL_SystemWindow); @@ -96,7 +98,7 @@ protected override void OnTick() if (player.Steed.OwnerID == player.InternalID) { player.Out.SendMessage("You usher your boat forward.", eChatType.CT_System, eChatLoc.CL_SystemWindow); - player.Steed.WalkTo(player.GroundTarget, player.Steed.MaxSpeed); + player.Steed.WalkTo(player.GroundTargetPosition.Coordinate, player.Steed.MaxSpeed); return; } } @@ -107,7 +109,7 @@ protected override void OnTick() eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } - player.Steed.WalkTo(player.GroundTarget, player.Steed.MaxSpeed); + player.Steed.WalkTo(player.GroundTargetPosition.Coordinate, player.Steed.MaxSpeed); return; } } diff --git a/GameServer/packets/Client/168/PlayerHeadingUpdateHandler.cs b/GameServer/packets/Client/168/PlayerHeadingUpdateHandler.cs index 8c9ece9440..af0e58f4b3 100644 --- a/GameServer/packets/Client/168/PlayerHeadingUpdateHandler.cs +++ b/GameServer/packets/Client/168/PlayerHeadingUpdateHandler.cs @@ -20,6 +20,7 @@ using System.Collections; using System.Reflection; using DOL.GS; +using DOL.GS.Geometry; using log4net; namespace DOL.GS.PacketHandler.Client.v168 @@ -55,7 +56,7 @@ public void HandlePacket(GameClient client, GSPacketIn packet) var steedSlot = (byte) packet.ReadByte(); var ridingFlag = (byte)packet.ReadByte(); - client.Player.Heading = (ushort)(head & 0xFFF); + client.Player.Orientation = Angle.Heading(head); // client.Player.PetInView = ((flags & 0x04) != 0); // TODO client.Player.GroundTargetInView = ((flags & 0x08) != 0); client.Player.TargetInView = ((flags & 0x10) != 0); @@ -65,7 +66,7 @@ public void HandlePacket(GameClient client, GSPacketIn packet) state = 5; // set dead state else if (client.Player.Steed != null && client.Player.Steed.ObjectState == GameObject.eObjectState.Active) { - client.Player.Heading = client.Player.Steed.Heading; + client.Player.Orientation = client.Player.Steed.Orientation; state = 6; // Set ride state steedSlot = (byte)client.Player.Steed.RiderSlot(client.Player); // there rider slot this player head = (ushort)client.Player.Steed.ObjectID; // heading = steed ID diff --git a/GameServer/packets/Client/168/PlayerInitRequestHandler.cs b/GameServer/packets/Client/168/PlayerInitRequestHandler.cs index 7b5d3c6040..5a251d8efa 100644 --- a/GameServer/packets/Client/168/PlayerInitRequestHandler.cs +++ b/GameServer/packets/Client/168/PlayerInitRequestHandler.cs @@ -213,9 +213,7 @@ private static void CheckBGLevelCapForPlayerAndMoveIfNecessary(GamePlayer player { player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "PlayerInitRequestHandler.LevelCap"), eChatType.CT_YouWereHit, eChatLoc.CL_SystemWindow); - player.MoveTo((ushort) player.BindRegion, player.BindXpos, - player.BindYpos, player.BindZpos, - (ushort) player.BindHeading); + player.MoveTo(player.BindPosition); break; } } @@ -235,7 +233,7 @@ private static void CheckIfPlayerLogsNearEnemyKeepAndMoveIfNecessary(GamePlayer int gracePeriodInMinutes = 0; Int32.TryParse(Properties.RVR_LINK_DEATH_RELOG_GRACE_PERIOD, out gracePeriodInMinutes); - AbstractGameKeep keep = GameServer.KeepManager.GetKeepCloseToSpot(player.CurrentRegionID, player, WorldMgr.VISIBILITY_DISTANCE); + AbstractGameKeep keep = GameServer.KeepManager.GetKeepCloseToSpot(player.Position, WorldMgr.VISIBILITY_DISTANCE); if (keep != null && player.Client.Account.PrivLevel == 1 && GameServer.KeepManager.IsEnemy(keep, player)) { if (WorldMgr.RvRLinkDeadPlayers.ContainsKey(player.InternalID)) @@ -266,9 +264,7 @@ private static void SendMessageAndMoveToSafeLocation(GamePlayer player) { player.Out.SendMessage(LanguageMgr.GetTranslation(player.Client.Account.Language, "PlayerInitRequestHandler.SaferLocation"), eChatType.CT_System, eChatLoc.CL_SystemWindow); - player.MoveTo((ushort) player.BindRegion, player.BindXpos, - player.BindYpos, player.BindZpos, - (ushort) player.BindHeading); + player.MoveTo(player.BindPosition); } private static void SendHouseRentRemindersToPlayer(GamePlayer player) diff --git a/GameServer/packets/Client/168/PlayerPositionUpdateHandler.cs b/GameServer/packets/Client/168/PlayerPositionUpdateHandler.cs index 6b2a538d2c..e21d532b20 100644 --- a/GameServer/packets/Client/168/PlayerPositionUpdateHandler.cs +++ b/GameServer/packets/Client/168/PlayerPositionUpdateHandler.cs @@ -29,6 +29,7 @@ using DOL.GS; using DOL.GS.PacketHandler; using log4net; +using DOL.GS.Geometry; namespace DOL.GS.PacketHandler.Client.v168 { @@ -92,6 +93,10 @@ public void HandlePacket(GameClient client, GSPacketIn packet) ushort yOffsetInZone = packet.ReadShort(); ushort currentZoneID = packet.ReadShort(); + var headingflag = packet.ReadShort(); + var flyingflag = packet.ReadShort(); + var flags = (byte)packet.ReadByte(); + //Dinberg - Instance considerations. //Now this gets complicated, so listen up! We have told the client a lie when it comes to the zoneID. @@ -128,18 +133,14 @@ public void HandlePacket(GameClient client, GSPacketIn packet) // move to bind if player fell through the floor if (realZ == 0) { - client.Player.MoveTo( - (ushort)client.Player.BindRegion, - client.Player.BindXpos, - client.Player.BindYpos, - (ushort)client.Player.BindZpos, - (ushort)client.Player.BindHeading - ); + client.Player.MoveTo(client.Player.BindPosition); return; } - int realX = newZone.XOffset + xOffsetInZone; - int realY = newZone.YOffset + yOffsetInZone; + var newCoordinate = Coordinate.Create( + x: newZone.Offset.X + xOffsetInZone, + y: newZone.Offset.Y + yOffsetInZone, + z: realZ); bool zoneChange = newZone != client.Player.LastPositionUpdateZone; if (zoneChange) @@ -181,17 +182,17 @@ public void HandlePacket(GameClient client, GSPacketIn packet) int coordsPerSec = 0; int jumpDetect = 0; - int timediff = Environment.TickCount - client.Player.LastPositionUpdateTick; + int timediff = Environment.TickCount - client.Player.MovementStartTick; int distance = 0; if (timediff > 0) { - distance = client.Player.LastPositionUpdatePoint.GetDistanceTo(new Point3D(realX, realY, realZ)); + distance = (int)client.Player.LastUpdateCoordinate.DistanceTo(newCoordinate); coordsPerSec = distance * 1000 / timediff; - if (distance < 100 && client.Player.LastPositionUpdatePoint.Z > 0) + if (distance < 100 && client.Player.LastUpdateCoordinate.Z > 0) { - jumpDetect = realZ - client.Player.LastPositionUpdatePoint.Z; + jumpDetect = realZ - client.Player.LastUpdateCoordinate.Z; } } @@ -208,11 +209,6 @@ public void HandlePacket(GameClient client, GSPacketIn packet) #endif #endregion DEBUG - client.Player.LastPositionUpdateTick = Environment.TickCount; - client.Player.LastPositionUpdatePoint.X = realX; - client.Player.LastPositionUpdatePoint.Y = realY; - client.Player.LastPositionUpdatePoint.Z = realZ; - int tolerance = ServerProperties.Properties.CPS_TOLERANCE; if (client.Player.Steed != null && client.Player.Steed.MaxSpeed > 0) @@ -313,25 +309,16 @@ public void HandlePacket(GameClient client, GSPacketIn packet) client.Player.TempProperties.setProperty(LASTCPSTICK, environmentTick); } - var headingflag = packet.ReadShort(); - var flyingflag = packet.ReadShort(); - var flags = (byte)packet.ReadByte(); - - client.Player.Heading = (ushort)(headingflag & 0xFFF); - if (client.Player.X != realX || client.Player.Y != realY) + if (client.Player.Coordinate.X != newCoordinate.X || client.Player.Coordinate.Y != newCoordinate.Y) + { client.Player.TempProperties.setProperty(LASTMOVEMENTTICK, client.Player.CurrentRegion.Time); - client.Player.X = realX; - client.Player.Y = realY; - client.Player.Z = realZ; + } + client.Player.Position = Position.Create(client.Player.Position.RegionID, coordinate: newCoordinate, heading: (ushort)(headingflag & 0xFFF)); // update client zone information for waterlevel and diving if (zoneChange) client.Out.SendPlayerPositionAndObjectID(); - // used to predict current position, should be before - // any calculation (like fall damage) - client.Player.MovementStartTick = Environment.TickCount; - // Begin ---------- New Area System ----------- if (client.Player.CurrentRegion.Time > client.Player.AreaUpdateTick) // check if update is needed { @@ -340,7 +327,7 @@ public void HandlePacket(GameClient client, GSPacketIn packet) // Because we may be in an instance we need to do the area check from the current region // rather than relying on the zone which is in the skinned region. - Tolakram - var newAreas = client.Player.CurrentRegion.GetAreasOfZone(newZone, client.Player); + var newAreas = client.Player.CurrentRegion.GetAreasOfZone(newZone, client.Player.Coordinate); // Check for left areas if (oldAreas != null) @@ -521,21 +508,17 @@ public void HandlePacket(GameClient client, GSPacketIn packet) client.Player.TempProperties.setProperty(SHLASTFLY, SHlastFly); client.Player.TempProperties.setProperty(SHLASTSTATUS, SHlastStatus); client.Player.TempProperties.setProperty(SHSPEEDCOUNTER, SHcount); - lock (client.Player.LastUniqueLocations) + lock (client.Player.LastUniquePositions) { - GameLocation[] locations = client.Player.LastUniqueLocations; - GameLocation loc = locations[0]; - if (loc.X != realX || loc.Y != realY || loc.Z != realZ || loc.RegionID != client.Player.CurrentRegionID) - { - loc = locations[locations.Length - 1]; - Array.Copy(locations, 0, locations, 1, locations.Length - 1); - locations[0] = loc; - loc.X = realX; - loc.Y = realY; - loc.Z = realZ; - loc.Heading = client.Player.Heading; - loc.RegionID = client.Player.CurrentRegionID; - } + var positions = client.Player.LastUniquePositions; + var pos = positions[0]; + var newPosition = client.Player.Position.With(coordinate: newCoordinate); + if (pos.Coordinate != newPosition.Coordinate) + { + pos = positions[positions.Length - 1]; + Array.Copy(positions, 0, positions, 1, positions.Length - 1); + positions[0] = newPosition; + } } //**************// @@ -566,24 +549,24 @@ public void HandlePacket(GameClient client, GSPacketIn packet) fallDamage = client.Player.CalcFallDamage(fallPercent); } - client.Player.MaxLastZ = client.Player.Z; + client.Player.MaxLastZ = client.Player.Position.Z; } else { // always set Z if on the ground if (flyingflag == 0) - client.Player.MaxLastZ = client.Player.Z; + client.Player.MaxLastZ = client.Player.Position.Z; // set Z if in air and higher than old Z - else if (maxLastZ < client.Player.Z) - client.Player.MaxLastZ = client.Player.Z; + else if (maxLastZ < client.Player.Position.Z) + client.Player.MaxLastZ = client.Player.Position.Z; } } //**************// //Riding is set here! if (client.Player.Steed != null && client.Player.Steed.ObjectState == GameObject.eObjectState.Active) - client.Player.Heading = client.Player.Steed.Heading; + client.Player.Orientation = client.Player.Steed.Orientation; var outpak = new GSUDPPacketOut(client.Out.GetPacketCode(eServerPackets.PlayerPosition)); outpak.WriteShort((ushort)client.SessionID); @@ -615,9 +598,10 @@ public void HandlePacket(GameClient client, GSPacketIn packet) } outpak.WriteShort(content); } - outpak.WriteShort((ushort)client.Player.Z); - outpak.WriteShort((ushort)(client.Player.X - client.Player.CurrentZone.XOffset)); - outpak.WriteShort((ushort)(client.Player.Y - client.Player.CurrentZone.YOffset)); + var zoneCoord = client.Player.Coordinate - client.Player.CurrentZone.Offset; + outpak.WriteShort((ushort)zoneCoord.Z); + outpak.WriteShort((ushort)zoneCoord.X); + outpak.WriteShort((ushort)zoneCoord.Y); // Write Zone outpak.WriteShort(client.Player.CurrentZone.ZoneSkinID); @@ -630,7 +614,7 @@ public void HandlePacket(GameClient client, GSPacketIn packet) else { // Set Player always on ground, this is an "anti lag" packet - ushort contenthead = (ushort)(client.Player.Heading + (true ? 0x1000 : 0)); + ushort contenthead = (ushort)(client.Player.Orientation.InHeading + (true ? 0x1000 : 0)); outpak.WriteShort(contenthead); outpak.WriteShort(0); // No Fall Speed. } @@ -681,16 +665,16 @@ public void HandlePacket(GameClient client, GSPacketIn packet) if (client.Player.IsStealthed) playerAction |= 0x02; ushort playerState = 0; - outpak1124.WriteFloatLowEndian(client.Player.X); - outpak1124.WriteFloatLowEndian(client.Player.Y); - outpak1124.WriteFloatLowEndian(client.Player.Z); + outpak1124.WriteFloatLowEndian(client.Player.Position.X); + outpak1124.WriteFloatLowEndian(client.Player.Position.Y); + outpak1124.WriteFloatLowEndian(client.Player.Position.Z); outpak1124.WriteFloatLowEndian(client.Player.CurrentSpeed); outpak1124.WriteFloatLowEndian(fallSpeed); outpak1124.WriteShort((ushort)client.SessionID); outpak1124.WriteShort(currentZoneID); outpak1124.WriteShort(playerState); outpak1124.WriteShort((ushort)(client.Player.Steed?.RiderSlot(client.Player) ?? 0)); // fall damage flag coming in, steed seat position going out - outpak1124.WriteShort(client.Player.Heading); + outpak1124.WriteShort(client.Player.Orientation.InHeading); outpak1124.WriteByte(playerAction); outpak1124.WriteByte((byte)(client.Player.RPFlag ? 1 : 0)); outpak1124.WriteByte(0); @@ -864,30 +848,30 @@ private void _HandlePacket1124(GameClient client, GSPacketIn packet) client.Player.LastPositionUpdateZone = newZone; } + var newPosition = Position.Create( + regionID: newZone.ZoneRegion.ID, + x: (int)newPlayerX, + y: (int)newPlayerY, + z: (int)newPlayerZ, + heading: (ushort)(newHeading & 0xFFF) + ); + int coordsPerSec = 0; int jumpDetect = 0; - int timediff = Environment.TickCount - client.Player.LastPositionUpdateTick; + int timediff = Environment.TickCount - client.Player.MovementStartTick; int distance = 0; if (timediff > 0) { - distance = client.Player.LastPositionUpdatePoint.GetDistanceTo(new Point3D(newPlayerX, newPlayerY, newPlayerZ)); + distance = (int)client.Player.LastUpdateCoordinate.DistanceTo(newPosition.Coordinate); coordsPerSec = distance * 1000 / timediff; - if (distance < 100 && client.Player.LastPositionUpdatePoint.Z > 0) + if (distance < 100 && client.Player.LastUpdateCoordinate.Z > 0) { - jumpDetect = (int)newPlayerZ - client.Player.LastPositionUpdatePoint.Z; + jumpDetect = (int)newPlayerZ - client.Player.LastUpdateCoordinate.Z; } } - client.Player.LastPositionUpdateTick = Environment.TickCount; - client.Player.LastPositionUpdatePoint.X = (int)newPlayerX; - client.Player.LastPositionUpdatePoint.Y = (int)newPlayerY; - client.Player.LastPositionUpdatePoint.Z = (int)newPlayerZ; - client.Player.X = (int)newPlayerX; - client.Player.Y = (int)newPlayerY; - client.Player.Z = (int)newPlayerZ; - int tolerance = ServerProperties.Properties.CPS_TOLERANCE; if (client.Player.Steed != null && client.Player.Steed.MaxSpeed > 0) @@ -993,19 +977,12 @@ private void _HandlePacket1124(GameClient client, GSPacketIn packet) } //client.Player.Heading = (ushort)(newHeading & 0xFFF); //patch 0024 expermental - if (client.Player.X != newPlayerX || client.Player.Y != newPlayerY) + if (client.Player.Position.X != newPosition.X || client.Player.Position.Y != newPosition.Y) { client.Player.TempProperties.setProperty(LASTMOVEMENTTICK, client.Player.CurrentRegion.Time); } - client.Player.X = (int)newPlayerX; - client.Player.Y = (int)newPlayerY; - client.Player.Z = (int)newPlayerZ; - client.Player.Heading = (ushort)(newHeading & 0xFFF); - - // used to predict current position, should be before - // any calculation (like fall damage) - client.Player.MovementStartTick = Environment.TickCount; // experimental 0024 + client.Player.Position = newPosition; // Begin ---------- New Area System ----------- if (client.Player.CurrentRegion.Time > client.Player.AreaUpdateTick) // check if update is needed @@ -1015,7 +992,7 @@ private void _HandlePacket1124(GameClient client, GSPacketIn packet) // Because we may be in an instance we need to do the area check from the current region // rather than relying on the zone which is in the skinned region. - Tolakram - var newAreas = client.Player.CurrentRegion.GetAreasOfZone(newZone, client.Player); + var newAreas = client.Player.CurrentRegion.GetAreasOfZone(newZone, client.Player.Coordinate); // Check for left areas if (oldAreas != null) @@ -1095,20 +1072,15 @@ private void _HandlePacket1124(GameClient client, GSPacketIn packet) return; } } - lock (client.Player.LastUniqueLocations) + lock (client.Player.LastUniquePositions) { - GameLocation[] locations = client.Player.LastUniqueLocations; - GameLocation loc = locations[0]; - if (loc.X != (int)newPlayerX || loc.Y != (int)newPlayerY || loc.Z != (int)newPlayerZ || loc.RegionID != client.Player.CurrentRegionID) + var positions = client.Player.LastUniquePositions; + var pos = positions[0]; + if (pos.Coordinate != newPosition.Coordinate) { - loc = locations[locations.Length - 1]; - Array.Copy(locations, 0, locations, 1, locations.Length - 1); - locations[0] = loc; - loc.X = (int)newPlayerX; - loc.Y = (int)newPlayerY; - loc.Z = (int)newPlayerZ; - loc.Heading = client.Player.Heading; - loc.RegionID = client.Player.CurrentRegionID; + pos = positions[positions.Length - 1]; + Array.Copy(positions, 0, positions, 1, positions.Length - 1); + positions[0] = newPosition; } } @@ -1136,10 +1108,10 @@ private void _HandlePacket1124(GameClient client, GSPacketIn packet) client.Player.CalcFallDamage(fallPercent); } - client.Player.MaxLastZ = client.Player.Z; + client.Player.MaxLastZ = client.Player.Position.Z; } - else if (maxLastZ < client.Player.Z || client.Player.IsRiding || newPlayerZSpeed > -150) // is riding, for dragonflys - client.Player.MaxLastZ = client.Player.Z; + else if (maxLastZ < client.Player.Position.Z || client.Player.IsRiding || newPlayerZSpeed > -150) // is riding, for dragonflys + client.Player.MaxLastZ = client.Player.Position.Z; } catch { @@ -1151,7 +1123,7 @@ private void _HandlePacket1124(GameClient client, GSPacketIn packet) if (client.Player.Steed != null && client.Player.Steed.ObjectState == GameObject.eObjectState.Active) { - client.Player.Heading = client.Player.Steed.Heading; + client.Player.Orientation = client.Player.Steed.Orientation; newHeading = (ushort)client.Player.Steed.ObjectID; } else if ((playerState >> 10) == 4) // patch 0062 fix bug on release preventing players from receiving res sickness @@ -1209,9 +1181,9 @@ private void _HandlePacket1124(GameClient client, GSPacketIn packet) outpak190.WriteShort((ushort)client.SessionID); outpak190.WriteShort((ushort)(client.Player.CurrentSpeed & 0x1FF)); outpak190.WriteShort((ushort)newPlayerZ); - var xoff = (ushort)(newPlayerX - (client.Player.CurrentZone?.XOffset ?? 0)); + var xoff = (ushort)(newPlayerX - (client.Player.CurrentZone?.Offset.X ?? 0)); outpak190.WriteShort(xoff); - var yoff = (ushort)(newPlayerY - (client.Player.CurrentZone?.YOffset ?? 0)); + var yoff = (ushort)(newPlayerY - (client.Player.CurrentZone?.Offset.Y ?? 0)); outpak190.WriteShort(yoff); outpak190.WriteShort(currentZoneID); outpak190.WriteShort(newHeading); diff --git a/GameServer/packets/Client/168/RegionChangeRequestHandler.cs b/GameServer/packets/Client/168/RegionChangeRequestHandler.cs index 805dc9b3fd..70779edce9 100644 --- a/GameServer/packets/Client/168/RegionChangeRequestHandler.cs +++ b/GameServer/packets/Client/168/RegionChangeRequestHandler.cs @@ -26,6 +26,7 @@ using DOL.GS.ServerRules; using log4net; +using DOL.GS.Geometry; namespace DOL.GS.PacketHandler.Client.v168 { @@ -73,8 +74,8 @@ public void HandlePacket(GameClient client, GSPacketIn packet) ChatUtil.SendDebugMessage(client, $"Invalid Jump (ZonePoint table): [{jumpSpotId}]{((zonePoint == null) ? ". Entry missing!" : ". TargetRegion is 0!")}"); zonePoint = new ZonePoint(); zonePoint.Id = jumpSpotId; - string zonePointLocation = $"Region {player.CurrentRegionID} and coordinates ({player.X},{player.Y},{player.Z})"; - Log.Error($"ZonePoint {jumpSpotId} at {zonePointLocation} on client {client.Version} missing. Either ZonePoint missing or RegionChangeRequestHandler needs to be updated."); + string zonePointToText = $"Region {player.CurrentRegionID} and coordinates ({player.Coordinate})"; + Log.Error($"ZonePoint {jumpSpotId} at {zonePointToText} on client {client.Version} missing. Either ZonePoint missing or RegionChangeRequestHandler needs to be updated."); } if (client.Account.PrivLevel > 1) @@ -240,7 +241,7 @@ protected override void OnTick() } //move the player - player.MoveTo(m_zonePoint.TargetRegion, m_zonePoint.TargetX, m_zonePoint.TargetY, m_zonePoint.TargetZ, m_zonePoint.TargetHeading); + player.MoveTo(m_zonePoint.GetTargetPosition()); } } } diff --git a/GameServer/packets/Client/168/UseSkillHandler.cs b/GameServer/packets/Client/168/UseSkillHandler.cs index 47ad1e3fb6..e997ce1ad1 100644 --- a/GameServer/packets/Client/168/UseSkillHandler.cs +++ b/GameServer/packets/Client/168/UseSkillHandler.cs @@ -20,6 +20,7 @@ using System.Collections; using System.Collections.Generic; using System.Reflection; +using DOL.GS.Geometry; using DOL.GS.Styles; using log4net; @@ -35,13 +36,15 @@ public class UseSkillHandler : IPacketHandler public void HandlePacket(GameClient client, GSPacketIn packet) { + var player = client.Player; if (client.Version >= GameClient.eClientVersion.Version1124) { - client.Player.X = (int)packet.ReadFloatLowEndian(); - client.Player.Y = (int)packet.ReadFloatLowEndian(); - client.Player.Z = (int)packet.ReadFloatLowEndian(); - client.Player.CurrentSpeed = (short)packet.ReadFloatLowEndian(); - client.Player.Heading = packet.ReadShort(); + var x = (int)packet.ReadFloatLowEndian(); + var y = (int)packet.ReadFloatLowEndian(); + var z = (int)packet.ReadFloatLowEndian(); + player.CurrentSpeed = (short)packet.ReadFloatLowEndian(); + var heading = packet.ReadShort(); + player.Position = Position.Create(player.Position.RegionID, x, y, z, heading); } int flagSpeedData = packet.ReadShort(); int index = packet.ReadByte(); diff --git a/GameServer/packets/Client/168/UseSlotHandler.cs b/GameServer/packets/Client/168/UseSlotHandler.cs index bc931a1c4a..f7ff7f6d00 100644 --- a/GameServer/packets/Client/168/UseSlotHandler.cs +++ b/GameServer/packets/Client/168/UseSlotHandler.cs @@ -17,6 +17,8 @@ * */ +using DOL.GS.Geometry; + namespace DOL.GS.PacketHandler.Client.v168 { /// @@ -27,19 +29,21 @@ public class UseSlotHandler : IPacketHandler { public void HandlePacket(GameClient client, GSPacketIn packet) { + var player = client.Player; if (client.Version >= GameClient.eClientVersion.Version1124) { - client.Player.X = (int)packet.ReadFloatLowEndian(); - client.Player.Y = (int)packet.ReadFloatLowEndian(); - client.Player.Z = (int)packet.ReadFloatLowEndian(); - client.Player.CurrentSpeed = (short)packet.ReadFloatLowEndian(); - client.Player.Heading = packet.ReadShort(); + var x = (int)packet.ReadFloatLowEndian(); + var y = (int)packet.ReadFloatLowEndian(); + var z = (int)packet.ReadFloatLowEndian(); + player.CurrentSpeed = (short)packet.ReadFloatLowEndian(); + var heading = packet.ReadShort(); + player.Position = Position.Create(player.Position.RegionID, x, y, z, heading); } int flagSpeedData = packet.ReadShort(); int slot = packet.ReadByte(); int type = packet.ReadByte(); - new UseSlotAction(client.Player, flagSpeedData, slot, type).Start(1); + new UseSlotAction(player, flagSpeedData, slot, type).Start(1); } /// diff --git a/GameServer/packets/Client/168/UseSpellHandler.cs b/GameServer/packets/Client/168/UseSpellHandler.cs index eaf994413b..7378ea30f5 100644 --- a/GameServer/packets/Client/168/UseSpellHandler.cs +++ b/GameServer/packets/Client/168/UseSpellHandler.cs @@ -20,6 +20,7 @@ using System.Collections; using System.Collections.Generic; using System.Reflection; +using DOL.GS.Geometry; using log4net; namespace DOL.GS.PacketHandler.Client.v168 @@ -42,11 +43,13 @@ public void HandlePacket(GameClient client, GSPacketIn packet) int spellLineIndex; if (client.Version >= GameClient.eClientVersion.Version1124) { - client.Player.X = (int)packet.ReadFloatLowEndian(); - client.Player.Y = (int)packet.ReadFloatLowEndian(); - client.Player.Z = (int)packet.ReadFloatLowEndian(); - client.Player.CurrentSpeed = (short)packet.ReadFloatLowEndian(); - client.Player.Heading = packet.ReadShort(); + var x = (int)packet.ReadFloatLowEndian(); + var y = (int)packet.ReadFloatLowEndian(); + var z = (int)packet.ReadFloatLowEndian(); + var speed = (short)packet.ReadFloatLowEndian(); + var heading = packet.ReadShort(); + client.Player.Position = Position.Create(client.Player.CurrentRegionID, x, y, z, heading); + client.Player.CurrentSpeed = speed; flagSpeedData = packet.ReadShort(); // target visible ? 0xA000 : 0x0000 spellLevel = packet.ReadByte(); spellLineIndex = packet.ReadByte(); @@ -71,17 +74,20 @@ public void HandlePacket(GameClient client, GSPacketIn packet) } else { - client.Player.X = newZone.XOffset + xOffsetInZone; - client.Player.Y = newZone.YOffset + yOffsetInZone; - client.Player.Z = realZ; - client.Player.MovementStartTick = Environment.TickCount; + client.Player.Position = Position.Create( + client.Player.CurrentRegionID, + newZone.Offset.X + xOffsetInZone, + newZone.Offset.Y + yOffsetInZone, + realZ, + client.Player.Orientation + ); } } spellLevel = packet.ReadByte(); spellLineIndex = packet.ReadByte(); - client.Player.Heading = (ushort)(heading & 0xfff); + client.Player.Orientation = Angle.Heading(heading); } new UseSpellAction(client.Player, flagSpeedData, spellLevel, spellLineIndex).Start(1); diff --git a/GameServer/packets/Client/168/warmapshowrequesthandler.cs b/GameServer/packets/Client/168/warmapshowrequesthandler.cs index 8a931b176f..f1564a4735 100644 --- a/GameServer/packets/Client/168/warmapshowrequesthandler.cs +++ b/GameServer/packets/Client/168/warmapshowrequesthandler.cs @@ -18,7 +18,7 @@ */ using System; using System.Collections; - +using DOL.GS.Geometry; using DOL.GS.Keeps; namespace DOL.GS.PacketHandler.Client.v168 @@ -128,54 +128,43 @@ public void HandlePacket(GameClient client, GSPacketIn packet) } } - int x = 0; - int y = 0; - int z = 0; - ushort heading = 0; + var portPosition = Position.Zero; switch (keepId) { - //sauvage - case 1: - //snowdonia - case 2: - //svas - case 3: - //vind - case 4: - //ligen - case 5: - //cain - case 6: + + case 1: //sauvage + case 2: //snowdonia + case 3: //svas + case 4: //vind + case 5: //ligen + case 6: //cain { - GameServer.KeepManager.GetBorderKeepLocation(keepId, out x, out y, out z, out heading); + portPosition = GameServer.KeepManager.GetBorderKeepPosition(keepId); break; } default: { if (keep != null && keep is GameKeep) { - FrontiersPortalStone stone = keep.TeleportStone; + var stone = keep.TeleportStone; if (stone != null) { - heading = stone.Heading; - z = stone.Z; - stone.GetTeleportLocation(out x, out y); + var distance = Util.Random(50, 150); + var direction = stone.Orientation + Angle.Heading(Util.Random(- 500, 500)); + portPosition = stone.Position + Vector.Create(direction, distance); } else { - x = keep.X; - y = keep.Y; - z = keep.Z+150; - heading = keep.Heading; + portPosition = Position.Create(regionID: 163, keep.X, keep.Y, keep.Z+150, keep.Orientation); } } break; } } - if (x != 0) + if (portPosition != Position.Zero) { - client.Player.MoveTo(163, x, y, z, heading); + client.Player.MoveTo(portPosition); } break; diff --git a/GameServer/packets/Server/IPacketLib.cs b/GameServer/packets/Server/IPacketLib.cs index f28b4a664d..cc81c92c35 100644 --- a/GameServer/packets/Server/IPacketLib.cs +++ b/GameServer/packets/Server/IPacketLib.cs @@ -22,6 +22,7 @@ using DOL.AI.Brain; using DOL.Database; +using DOL.GS.Geometry; using DOL.GS.Housing; using DOL.GS.Keeps; using DOL.GS.Profession; @@ -750,7 +751,9 @@ void SendDialogBox(eDialogCode code, ushort data1, ushort data2, ushort data3, u void SendConcentrationList(); void SendUpdateCraftingSkills(); void SendChangeTarget(GameObject newTarget); + [Obsolete("Use .SendChangeGroundTarget(Point3D) instead!")] void SendChangeGroundTarget(Point3D newTarget); + void SendChangeGroundTarget(Coordinate groundTarget); void SendPetWindow(GameLiving pet, ePetWindowAction windowAction, eAggressionState aggroState, eWalkState walkState); void SendPlaySound(eSoundType soundType, ushort soundID); void SendNPCsQuestEffect(GameNPC npc, eQuestIndicator indicator); @@ -762,6 +765,8 @@ void SendDialogBox(eDialogCode code, ushort data1, ushort data2, ushort data3, u void SendSiegeWeaponCloseInterface(); void SendSiegeWeaponInterface(GameSiegeWeapon siegeWeapon, int time); void SendLivingDataUpdate(GameLiving living, bool updateStrings); + void SendSoundEffect(ushort soundId, Position position, ushort radius); + [Obsolete("Use .SendSoundEffect(ushort,Position,ushort) instead!")] void SendSoundEffect(ushort soundId, ushort zoneId, ushort x, ushort y, ushort z, ushort radius); //keep void SendKeepInfo(IGameKeep keep); @@ -812,7 +817,9 @@ void SendDialogBox(eDialogCode code, ushort data1, ushort data2, ushort data3, u void SendVampireEffect(GameLiving living, bool show); void SendXFireInfo(byte flag); void SendMinotaurRelicMapRemove(byte id); + [Obsolete("Use .SendMinotaurRelicMapUpdate(byte, Position) instead!")] void SendMinotaurRelicMapUpdate(byte id, ushort region, int x, int y, int z); + void SendMinotaurRelicMapUpdate(byte id, Position position); void SendMinotaurRelicWindow(GamePlayer player, int spell, bool flag); void SendMinotaurRelicBarUpdate(GamePlayer player, int xp); diff --git a/GameServer/packets/Server/PacketLib1104.cs b/GameServer/packets/Server/PacketLib1104.cs index 1b9e5b3f62..9c9e4064f9 100644 --- a/GameServer/packets/Server/PacketLib1104.cs +++ b/GameServer/packets/Server/PacketLib1104.cs @@ -24,7 +24,7 @@ using DOL.Database; using log4net; - +using DOL.GS.Geometry; namespace DOL.GS.PacketHandler { @@ -145,7 +145,7 @@ public override void SendCharacterOverview(eRealm realm) Region region = WorldMgr.GetRegion((ushort)c.Region); if (region != null) { - locationDescription = m_gameClient.GetTranslatedSpotDescription(region, c.Xpos, c.Ypos, c.Zpos); + locationDescription = GamePlayerUtils.GetTranslatedSpotDescription(region, m_gameClient, c.GetPosition().Coordinate); } pak.FillString(locationDescription, 24); diff --git a/GameServer/packets/Server/PacketLib1110.cs b/GameServer/packets/Server/PacketLib1110.cs index 69797ba0ea..422174729b 100644 --- a/GameServer/packets/Server/PacketLib1110.cs +++ b/GameServer/packets/Server/PacketLib1110.cs @@ -27,6 +27,7 @@ using log4net; using DOL.GS.Spells; using DOL.GS.Delve; +using DOL.GS.Geometry; namespace DOL.GS.PacketHandler { @@ -163,21 +164,10 @@ public override void SendSiegeWeaponAnimation(GameSiegeWeapon siegeWeapon) using (var pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.SiegeWeaponAnimation))) { pak.WriteInt((uint)siegeWeapon.ObjectID); - pak.WriteInt( - (uint) - (siegeWeapon.TargetObject == null - ? (siegeWeapon.GroundTarget == null ? 0 : siegeWeapon.GroundTarget.X) - : siegeWeapon.TargetObject.X)); - pak.WriteInt( - (uint) - (siegeWeapon.TargetObject == null - ? (siegeWeapon.GroundTarget == null ? 0 : siegeWeapon.GroundTarget.Y) - : siegeWeapon.TargetObject.Y)); - pak.WriteInt( - (uint) - (siegeWeapon.TargetObject == null - ? (siegeWeapon.GroundTarget == null ? 0 : siegeWeapon.GroundTarget.Z) - : siegeWeapon.TargetObject.Z)); + var aimCoordinate = siegeWeapon.AimCoordinate; + pak.WriteInt((uint)aimCoordinate.X); + pak.WriteInt((uint)aimCoordinate.Y); + pak.WriteInt((uint)aimCoordinate.Z); pak.WriteInt((uint)(siegeWeapon.TargetObject == null ? 0 : siegeWeapon.TargetObject.ObjectID)); pak.WriteShort(siegeWeapon.Effect); pak.WriteShort((ushort)(siegeWeapon.SiegeWeaponTimer.TimeUntilElapsed)); // timer is no longer ( value / 100 ) @@ -198,10 +188,12 @@ public override void SendSiegeWeaponFireAnimation(GameSiegeWeapon siegeWeapon, i return; using (var pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.SiegeWeaponAnimation))) { + var targetPosition = siegeWeapon.TargetObject.Position; + if(targetPosition == Position.Nowhere) targetPosition = siegeWeapon.GroundTargetPosition; pak.WriteInt((uint) siegeWeapon.ObjectID); - pak.WriteInt((uint) (siegeWeapon.TargetObject == null ? siegeWeapon.GroundTarget.X : siegeWeapon.TargetObject.X)); - pak.WriteInt((uint) (siegeWeapon.TargetObject == null ? siegeWeapon.GroundTarget.Y : siegeWeapon.TargetObject.Y)); - pak.WriteInt((uint) (siegeWeapon.TargetObject == null ? siegeWeapon.GroundTarget.Z + 50 : siegeWeapon.TargetObject.Z + 50)); + pak.WriteInt((uint) (targetPosition.X)); + pak.WriteInt((uint) (targetPosition.Y)); + pak.WriteInt((uint) (targetPosition.Z + 50)); pak.WriteInt((uint) (siegeWeapon.TargetObject == null ? 0 : siegeWeapon.TargetObject.ObjectID)); pak.WriteShort(siegeWeapon.Effect); pak.WriteShort((ushort) (timer)); // timer is no longer ( value / 100 ) diff --git a/GameServer/packets/Server/PacketLib1112.cs b/GameServer/packets/Server/PacketLib1112.cs index 1c86df6275..7dc35136bb 100644 --- a/GameServer/packets/Server/PacketLib1112.cs +++ b/GameServer/packets/Server/PacketLib1112.cs @@ -566,7 +566,7 @@ public override void SendPlayerForgedPosition(GamePlayer player) // Write Speed if (player.Steed != null && player.Steed.ObjectState == GameObject.eObjectState.Active) { - player.Heading = player.Steed.Heading; + player.Orientation = player.Steed.Orientation; pak.WriteShort(0x1800); } else @@ -610,13 +610,10 @@ public override void SendPlayerForgedPosition(GamePlayer player) pak.WriteShort(content); } - // Get Off Corrd - int offX = player.X - player.CurrentZone.XOffset; - int offY = player.Y - player.CurrentZone.YOffset; - - pak.WriteShort((ushort)player.Z); - pak.WriteShort((ushort)offX); - pak.WriteShort((ushort)offY); + var zoneCoordinate = player.Coordinate - player.CurrentZone.Offset; + pak.WriteShort((ushort)zoneCoordinate.Z); + pak.WriteShort((ushort)zoneCoordinate.X); + pak.WriteShort((ushort)zoneCoordinate.Y); // Write Zone pak.WriteShort(player.CurrentZone.ZoneSkinID); @@ -630,7 +627,7 @@ public override void SendPlayerForgedPosition(GamePlayer player) else { // Set Player always on ground, this is an "anti lag" packet - ushort contenthead = (ushort)(player.Heading + (true ? 0x1000 : 0)); + ushort contenthead = (ushort)(player.Orientation.InHeading + (true ? 0x1000 : 0)); pak.WriteShort(contenthead); // No Fall Speed. pak.WriteShort(0); diff --git a/GameServer/packets/Server/PacketLib1115.cs b/GameServer/packets/Server/PacketLib1115.cs index 0a470715d9..004197ff10 100644 --- a/GameServer/packets/Server/PacketLib1115.cs +++ b/GameServer/packets/Server/PacketLib1115.cs @@ -135,11 +135,11 @@ public override void SendKeepInfo(IGameKeep keep) using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.KeepInfo))) { - pak.WriteShort((ushort)keep.KeepID); + pak.WriteShort(keep.KeepID); pak.WriteShort(0); pak.WriteInt((uint)keep.X); pak.WriteInt((uint)keep.Y); - pak.WriteShort((ushort)keep.Heading); + pak.WriteShort((ushort)keep.Orientation.InDegrees); pak.WriteByte((byte)keep.Realm); pak.WriteByte((byte)keep.Level);//level pak.WriteShort(0);//unk diff --git a/GameServer/packets/Server/PacketLib1124.cs b/GameServer/packets/Server/PacketLib1124.cs index 889cc56989..38f387c07d 100644 --- a/GameServer/packets/Server/PacketLib1124.cs +++ b/GameServer/packets/Server/PacketLib1124.cs @@ -38,7 +38,7 @@ using DOL.GS.Styles; using log4net; - +using DOL.GS.Geometry; namespace DOL.GS.PacketHandler { @@ -64,11 +64,11 @@ public override void SendKeepInfo(IGameKeep keep) using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.KeepInfo))) { - pak.WriteShort((ushort)keep.KeepID); + pak.WriteShort(keep.KeepID); pak.WriteShort(0); pak.WriteInt((uint)keep.X); pak.WriteInt((uint)keep.Y); - pak.WriteShort((ushort)keep.Heading); + pak.WriteShort((ushort)keep.Orientation.InDegrees); pak.WriteByte((byte)keep.Realm); pak.WriteByte((byte)keep.Level);//level pak.WriteShort(0);//unk @@ -175,17 +175,17 @@ public override void SendNPCCreate(GameNPC npc) ushort speedZ = 0; if (npc == null) return; - if (!npc.IsAtTargetPosition) + if (!npc.IsAtTargetLocation) { speed = npc.CurrentSpeed; - speedZ = (ushort)npc.TickSpeedZ; + speedZ = (ushort)npc.ZSpeedFactor; } pak.WriteShort((ushort)npc.ObjectID); pak.WriteShort((ushort)(speed)); - pak.WriteShort(npc.Heading); - pak.WriteShort((ushort)npc.Z); - pak.WriteInt((uint)npc.X); - pak.WriteInt((uint)npc.Y); + pak.WriteShort(npc.Orientation.InHeading); + pak.WriteShort((ushort)npc.Position.Z); + pak.WriteInt((uint)npc.Position.X); + pak.WriteInt((uint)npc.Position.Y); pak.WriteShort(speedZ); pak.WriteShort(npc.Model); pak.WriteByte(npc.Size); @@ -319,12 +319,12 @@ public override void SendPlayerCreate(GamePlayer playerToCreate) using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.PlayerCreate172))) { - pak.WriteFloatLowEndian(playerToCreate.X); - pak.WriteFloatLowEndian(playerToCreate.Y); - pak.WriteFloatLowEndian(playerToCreate.Z); + pak.WriteFloatLowEndian(playerToCreate.Position.X); + pak.WriteFloatLowEndian(playerToCreate.Position.Y); + pak.WriteFloatLowEndian(playerToCreate.Position.Z); pak.WriteShort((ushort)playerToCreate.Client.SessionID); pak.WriteShort((ushort)playerToCreate.ObjectID); - pak.WriteShort(playerToCreate.Heading); + pak.WriteShort(playerToCreate.Orientation.InHeading); pak.WriteShort(playerToCreate.Model); pak.WriteByte(playerToCreate.GetDisplayLevel(m_gameClient.Player)); @@ -403,11 +403,11 @@ public override void SendPlayerPositionAndObjectID() using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.PositionAndObjectID))) { - pak.WriteFloatLowEndian(m_gameClient.Player.X); - pak.WriteFloatLowEndian(m_gameClient.Player.Y); - pak.WriteFloatLowEndian(m_gameClient.Player.Z); + pak.WriteFloatLowEndian(m_gameClient.Player.Position.X); + pak.WriteFloatLowEndian(m_gameClient.Player.Position.Y); + pak.WriteFloatLowEndian(m_gameClient.Player.Position.Z); pak.WriteShort((ushort)m_gameClient.Player.ObjectID); //This is the player's objectid not Sessionid!!! - pak.WriteShort(m_gameClient.Player.Heading); + pak.WriteShort(m_gameClient.Player.Orientation.InHeading); int flags = 0; Zone zone = m_gameClient.Player.CurrentZone; @@ -418,8 +418,8 @@ public override void SendPlayerPositionAndObjectID() if (zone.IsDungeon) { - pak.WriteShort((ushort)(zone.XOffset / 0x2000)); - pak.WriteShort((ushort)(zone.YOffset / 0x2000)); + pak.WriteShort((ushort)(zone.Offset.X / 0x2000)); + pak.WriteShort((ushort)(zone.Offset.Y / 0x2000)); } else { @@ -634,21 +634,10 @@ public override void SendSiegeWeaponAnimation(GameSiegeWeapon siegeWeapon) using (var pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.SiegeWeaponAnimation))) { pak.WriteInt((uint)siegeWeapon.ObjectID); - pak.WriteInt( - (uint) - (siegeWeapon.TargetObject == null - ? (siegeWeapon.GroundTarget == null ? 0 : siegeWeapon.GroundTarget.X) - : siegeWeapon.TargetObject.X)); - pak.WriteInt( - (uint) - (siegeWeapon.TargetObject == null - ? (siegeWeapon.GroundTarget == null ? 0 : siegeWeapon.GroundTarget.Y) - : siegeWeapon.TargetObject.Y)); - pak.WriteInt( - (uint) - (siegeWeapon.TargetObject == null - ? (siegeWeapon.GroundTarget == null ? 0 : siegeWeapon.GroundTarget.Z) - : siegeWeapon.TargetObject.Z)); + var aimCoordinate = siegeWeapon.AimCoordinate; + pak.WriteInt((uint)aimCoordinate.X); + pak.WriteInt((uint)aimCoordinate.Y); + pak.WriteInt((uint)aimCoordinate.Z); pak.WriteInt((uint)(siegeWeapon.TargetObject == null ? 0 : siegeWeapon.TargetObject.ObjectID)); pak.WriteShort(siegeWeapon.Effect); pak.WriteShort((ushort)(siegeWeapon.SiegeWeaponTimer.TimeUntilElapsed)); @@ -835,13 +824,14 @@ protected override void WriteGroupMemberMapUpdate(GSTCPPacketOut pak, GameLiving if (living.CurrentSpeed != 0) { Zone zone = living.CurrentZone; + var zoneCoordinate = living.Coordinate - zone.Offset; if (zone == null) return; pak.WriteByte((byte)(0x40 | living.GroupIndex)); //Dinberg - ZoneSkinID for group members aswell. pak.WriteShort(zone.ZoneSkinID); - pak.WriteShort((ushort)(living.X - zone.XOffset)); - pak.WriteShort((ushort)(living.Y - zone.YOffset)); + pak.WriteShort((ushort)(zoneCoordinate.X)); + pak.WriteShort((ushort)(zoneCoordinate.Y)); } } diff --git a/GameServer/packets/Server/PacketLib1125.cs b/GameServer/packets/Server/PacketLib1125.cs index e9701f7a30..30f6a2d7f1 100644 --- a/GameServer/packets/Server/PacketLib1125.cs +++ b/GameServer/packets/Server/PacketLib1125.cs @@ -19,6 +19,7 @@ using DOL.Database; using DOL.GS.Effects; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.Housing; using DOL.GS.Profession; using DOL.GS.Spells; @@ -205,7 +206,7 @@ public override void SendCharacterOverview(eRealm realm) Region region = WorldMgr.GetRegion((ushort)c.Region); if (region != null) { - locationDescription = region.GetTranslatedSpotDescription(m_gameClient, c.Xpos, c.Ypos, c.Zpos); + locationDescription = region.GetTranslatedSpotDescription(m_gameClient, c.GetPosition().Coordinate); } if (locationDescription.Length > 23) // location name over 23 chars has to be truncated eg. "The Great Pyramid of Stygia" { diff --git a/GameServer/packets/Server/PacketLib1126.cs b/GameServer/packets/Server/PacketLib1126.cs index 9e21d4f43c..38147e3e0f 100644 --- a/GameServer/packets/Server/PacketLib1126.cs +++ b/GameServer/packets/Server/PacketLib1126.cs @@ -17,6 +17,7 @@ * */ using DOL.Database; +using DOL.GS.Geometry; using log4net; using System; using System.Collections.Generic; @@ -181,7 +182,7 @@ public override void SendCharacterOverview(eRealm realm) string locationDescription = string.Empty; Region region = WorldMgr.GetRegion((ushort)c.Region); if (region != null) - locationDescription = m_gameClient.GetTranslatedSpotDescription(region, c.Xpos, c.Ypos, c.Zpos); + locationDescription = GamePlayerUtils.GetTranslatedSpotDescription(region, m_gameClient, c.GetPosition().Coordinate); string classname = ""; if (c.Class != 0) classname = ((eCharacterClass)c.Class).ToString(); diff --git a/GameServer/packets/Server/PacketLib168.cs b/GameServer/packets/Server/PacketLib168.cs index 85804a26c9..ca7bfdc870 100644 --- a/GameServer/packets/Server/PacketLib168.cs +++ b/GameServer/packets/Server/PacketLib168.cs @@ -41,6 +41,7 @@ using DOL.GS.Finance; using DOL.GS.Profession; using DOL.GS.Behaviour; +using DOL.GS.Geometry; namespace DOL.GS.PacketHandler { @@ -237,7 +238,8 @@ public virtual void SendCharacterOverview(eRealm realm) Region reg = WorldMgr.GetRegion((ushort) characters[j].Region); if (reg != null) { - var description = m_gameClient.GetTranslatedSpotDescription(reg, characters[j].Xpos, characters[j].Ypos, characters[j].Zpos); + var coordinate = characters[j].GetPosition().Coordinate; + var description = GamePlayerUtils.GetTranslatedSpotDescription(reg, m_gameClient, coordinate); pak.FillString(description, 24); } else @@ -538,10 +540,10 @@ public virtual void SendPlayerPositionAndObjectID() using (var pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.PositionAndObjectID))) { pak.WriteShort((ushort) m_gameClient.Player.ObjectID); //This is the player's objectid not Sessionid!!! - pak.WriteShort((ushort) m_gameClient.Player.Z); - pak.WriteInt((uint) m_gameClient.Player.X); - pak.WriteInt((uint) m_gameClient.Player.Y); - pak.WriteShort(m_gameClient.Player.Heading); + pak.WriteShort((ushort) m_gameClient.Player.Position.Z); + pak.WriteInt((uint) m_gameClient.Player.Position.X); + pak.WriteInt((uint) m_gameClient.Player.Position.Y); + pak.WriteShort(m_gameClient.Player.Orientation.InHeading); int flags = 0; if (m_gameClient.Player.CurrentZone.IsDivingEnabled) @@ -560,11 +562,11 @@ public virtual void SendPlayerJump(bool headingOnly) using (var pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.CharacterJump))) { - pak.WriteInt((uint) (headingOnly ? 0 : m_gameClient.Player.X)); - pak.WriteInt((uint) (headingOnly ? 0 : m_gameClient.Player.Y)); + pak.WriteInt((uint) (headingOnly ? 0 : m_gameClient.Player.Position.X)); + pak.WriteInt((uint) (headingOnly ? 0 : m_gameClient.Player.Position.Y)); pak.WriteShort((ushort) m_gameClient.Player.ObjectID); - pak.WriteShort((ushort) (headingOnly ? 0 : m_gameClient.Player.Z)); - pak.WriteShort(m_gameClient.Player.Heading); + pak.WriteShort((ushort) (headingOnly ? 0 : m_gameClient.Player.Position.Z)); + pak.WriteShort(m_gameClient.Player.Orientation.InHeading); if (m_gameClient.Player.InHouse == false || m_gameClient.Player.CurrentHouse == null) { pak.WriteShort(0); @@ -662,6 +664,12 @@ public virtual void SendMessage(string msg, eChatType type, eChatLoc loc) } } + protected ushort GetXOffsetInZone(GamePlayer player) + => (ushort)(player.Coordinate.X - player.CurrentZone.Offset.X); + + protected ushort GetYOffsetInZone(GamePlayer player) + => (ushort)(player.Coordinate.Y - player.CurrentZone.Offset.Y); + public virtual void SendPlayerCreate(GamePlayer playerToCreate) { if (playerToCreate == null) @@ -693,14 +701,14 @@ public virtual void SendPlayerCreate(GamePlayer playerToCreate) pak.WriteShort((ushort) playerToCreate.ObjectID); //pak.WriteInt(playerToCreate.X); //pak.WriteInt(playerToCreate.Y); - pak.WriteShort((ushort) playerRegion.GetXOffInZone(playerToCreate.X, playerToCreate.Y)); - pak.WriteShort((ushort) playerRegion.GetYOffInZone(playerToCreate.X, playerToCreate.Y)); + pak.WriteShort(GetXOffsetInZone(playerToCreate)); + pak.WriteShort(GetYOffsetInZone(playerToCreate)); //Dinberg:Instances - changing to ZoneSkinID for instance zones. pak.WriteByte((byte) playerZone.ZoneSkinID); pak.WriteByte(0); - pak.WriteShort((ushort) playerToCreate.Z); - pak.WriteShort(playerToCreate.Heading); + pak.WriteShort((ushort) playerToCreate.Position.Z); + pak.WriteShort(playerToCreate.Orientation.InHeading); pak.WriteShort(playerToCreate.Model); //DOLConsole.WriteLine("send created player "+target.Player.Name+" to "+client.Player.Name+" alive="+target.Player.Alive); pak.WriteByte((byte) (playerToCreate.IsAlive ? 0x1 : 0x0)); @@ -763,11 +771,8 @@ public virtual void SendObjectUpdate(GameObject obj) return; } - var xOffsetInZone = (ushort) (obj.X - z.XOffset); - var yOffsetInZone = (ushort) (obj.Y - z.YOffset); - ushort xOffsetInTargetZone = 0; - ushort yOffsetInTargetZone = 0; - ushort zOffsetInTargetZone = 0; + var currentZoneCoord = obj.Coordinate - z.Offset; + var targetZoneCoord = Coordinate.Zero; int speed = 0; ushort targetZone = 0; @@ -799,17 +804,19 @@ public virtual void SendObjectUpdate(GameObject obj) flags |= 0x20; } - if (npc.IsMoving && !npc.IsAtTargetPosition) + if (npc.IsMoving && !npc.IsAtTargetLocation) { speed = npc.CurrentSpeed; - if (npc.TargetPosition.X != 0 || npc.TargetPosition.Y != 0 || npc.TargetPosition.Z != 0) + if (npc.Destination != Coordinate.Nowhere && npc.Destination != npc.Coordinate) { - Zone tz = npc.CurrentRegion.GetZone(npc.TargetPosition.X, npc.TargetPosition.Y); + Zone tz = npc.CurrentRegion.GetZone(npc.Destination); if (tz != null) { - xOffsetInTargetZone = (ushort) (npc.TargetPosition.X - tz.XOffset); - yOffsetInTargetZone = (ushort) (npc.TargetPosition.Y - tz.YOffset); - zOffsetInTargetZone = (ushort) (npc.TargetPosition.Z); + targetZoneCoord = npc.Destination - tz.Offset; + + var overshootVector = targetZoneCoord - currentZoneCoord; + overshootVector = overshootVector * (100/overshootVector.Length); + targetZoneCoord += overshootVector; //Dinberg:Instances - zoneSkinID for object positioning clientside. targetZone = tz.ZoneSkinID; } @@ -834,20 +841,13 @@ public virtual void SendObjectUpdate(GameObject obj) { pak.WriteShort((ushort) speed); - if (obj is GameNPC) - { - pak.WriteShort((ushort)(obj.Heading & 0xFFF)); - } - else - { - pak.WriteShort(obj.Heading); - } - pak.WriteShort(xOffsetInZone); - pak.WriteShort(xOffsetInTargetZone); - pak.WriteShort(yOffsetInZone); - pak.WriteShort(yOffsetInTargetZone); - pak.WriteShort((ushort) obj.Z); - pak.WriteShort(zOffsetInTargetZone); + pak.WriteShort(obj.Orientation.InHeading); + pak.WriteShort((ushort)currentZoneCoord.X); + pak.WriteShort((ushort)targetZoneCoord.X); + pak.WriteShort((ushort)currentZoneCoord.Y); + pak.WriteShort((ushort)targetZoneCoord.Y); + pak.WriteShort((ushort)currentZoneCoord.Z); + pak.WriteShort((ushort)targetZoneCoord.Z); pak.WriteShort((ushort) obj.ObjectID); pak.WriteShort((ushort) targetOID); //health @@ -928,10 +928,10 @@ public virtual void SendObjectCreate(GameObject obj) if (obj is GameStaticItem) pak.WriteShort((ushort) (obj as GameStaticItem).Emblem); else pak.WriteShort(0); - pak.WriteShort(obj.Heading); - pak.WriteShort((ushort) obj.Z); - pak.WriteInt((uint) obj.X); - pak.WriteInt((uint) obj.Y); + pak.WriteShort(obj.Orientation.InHeading); + pak.WriteShort((ushort) obj.Position.Z); + pak.WriteInt((uint) obj.Position.X); + pak.WriteInt((uint) obj.Position.Y); int flag = ((byte) obj.Realm & 3) << 4; ushort model = obj.Model; if (obj.IsUnderwater) @@ -1050,17 +1050,17 @@ public virtual void SendNPCCreate(GameNPC npc) { int speed = 0; ushort speedZ = 0; - if (npc.IsMoving && !npc.IsAtTargetPosition) + if (npc.IsMoving && !npc.IsAtTargetLocation) { speed = npc.CurrentSpeed; - speedZ = (ushort) npc.TickSpeedZ; + speedZ = (ushort)npc.ZSpeedFactor; } pak.WriteShort((ushort) npc.ObjectID); pak.WriteShort((ushort) speed); - pak.WriteShort(npc.Heading); - pak.WriteShort((ushort) npc.Z); - pak.WriteInt((uint) npc.X); - pak.WriteInt((uint) npc.Y); + pak.WriteShort(npc.Orientation.InHeading); + pak.WriteShort((ushort) npc.Position.Z); + pak.WriteInt((uint) npc.Position.X); + pak.WriteInt((uint) npc.Position.Y); pak.WriteShort(speedZ); pak.WriteShort(npc.Model); pak.WriteByte(npc.Size); @@ -2537,7 +2537,7 @@ public virtual void SendPlayerForgedPosition(GamePlayer player) // Write Speed if (player.Steed != null && player.Steed.ObjectState == GameObject.eObjectState.Active) { - player.Heading = player.Steed.Heading; + player.Orientation = player.Steed.Orientation; pak.WriteShort(0x1800); } else @@ -2582,12 +2582,11 @@ public virtual void SendPlayerForgedPosition(GamePlayer player) } // Get Off Corrd - int offX = player.X - player.CurrentZone.XOffset; - int offY = player.Y - player.CurrentZone.YOffset; + var zoneCoord = player.Coordinate - player.CurrentZone.Offset; - pak.WriteShort((ushort)player.Z); - pak.WriteShort((ushort)offX); - pak.WriteShort((ushort)offY); + pak.WriteShort((ushort)zoneCoord.Z); + pak.WriteShort((ushort)zoneCoord.X); + pak.WriteShort((ushort)zoneCoord.Y); // Write Zone pak.WriteByte((byte)player.CurrentZone.ZoneSkinID); @@ -2602,7 +2601,7 @@ public virtual void SendPlayerForgedPosition(GamePlayer player) else { // Set Player always on ground, this is an "anti lag" packet - ushort contenthead = (ushort)(player.Heading + (true ? 0x1000 : 0)); + ushort contenthead = (ushort)(player.Orientation.InHeading + (true ? 0x1000 : 0)); pak.WriteShort(contenthead); // No Fall Speed. pak.WriteShort(0); @@ -3561,16 +3560,21 @@ public void SendChangeTarget(GameObject newTarget) } } - public void SendChangeGroundTarget(Point3D newTarget) - { - using (var pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.ChangeGroundTarget))) - { - pak.WriteInt((uint) (newTarget == null ? 0 : newTarget.X)); - pak.WriteInt((uint) (newTarget == null ? 0 : newTarget.Y)); - pak.WriteInt((uint) (newTarget == null ? 0 : newTarget.Z)); - SendTCP(pak); - } - } + [Obsolete("Use .SendChangeGroundTarget(Coordinate) instead!")] + public void SendChangeGroundTarget(Point3D newTarget) + => SendChangeGroundTarget(newTarget.ToCoordinate()); + + public void SendChangeGroundTarget(Coordinate newTarget) + { + using (var pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.ChangeGroundTarget))) + { + var gtLoc = newTarget == Coordinate.Nowhere ? Coordinate.Zero : newTarget; + pak.WriteInt((uint)(gtLoc.X)); + pak.WriteInt((uint)(gtLoc.Y)); + pak.WriteInt((uint)(gtLoc.Z)); + SendTCP(pak); + } + } public virtual void SendPetWindow(GameLiving pet, ePetWindowAction windowAction, eAggressionState aggroState, eWalkState walkState) @@ -3689,10 +3693,10 @@ public virtual void SendHouse(House house) using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.HouseCreate))) { pak.WriteShort((ushort) house.HouseNumber); - pak.WriteShort((ushort) house.Z); - pak.WriteInt((uint) house.X); - pak.WriteInt((uint) house.Y); - pak.WriteShort((ushort) house.Heading); + pak.WriteShort((ushort) house.Position.Z); + pak.WriteInt((uint) house.Position.X); + pak.WriteInt((uint) house.Position.Y); + pak.WriteShort((ushort) house.Orientation); pak.WriteShort((ushort) house.PorchRoofColor); pak.WriteShort((ushort) house.GetPorchAndGuildEmblemFlags()); pak.WriteShort((ushort) house.Emblem); @@ -3725,9 +3729,9 @@ public virtual void SendRemoveHouse(House house) using (var pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.HouseCreate))) { pak.WriteShort((ushort) house.HouseNumber); - pak.WriteShort((ushort) house.Z); - pak.WriteInt((uint) house.X); - pak.WriteInt((uint) house.Y); + pak.WriteShort((ushort) house.Position.Z); + pak.WriteInt((uint) house.Position.X); + pak.WriteInt((uint) house.Position.Y); pak.Fill(0x00, 15); pak.WriteByte(0x03); pak.WritePascalString(""); @@ -3816,9 +3820,9 @@ public virtual void SendEnterHouse(House house) { pak.WriteShort((ushort) house.HouseNumber); pak.WriteShort(25000); //constant! - pak.WriteInt((uint) house.X); - pak.WriteInt((uint) house.Y); - pak.WriteShort((ushort) house.Heading); //useless/ignored by client. + pak.WriteInt((uint) house.Position.X); + pak.WriteInt((uint) house.Position.Y); + pak.WriteShort((ushort) house.Orientation); //useless/ignored by client. pak.WriteByte(0x00); pak.WriteByte((byte) house.GetGuildEmblemFlags()); //emblem style pak.WriteShort((ushort) house.Emblem); //emblem @@ -3986,10 +3990,10 @@ public virtual void SendMovingObjectCreate(GameMovingObject obj) { pak.WriteShort((ushort) obj.ObjectID); pak.WriteShort(0); - pak.WriteShort(obj.Heading); - pak.WriteShort((ushort) obj.Z); - pak.WriteInt((uint) obj.X); - pak.WriteInt((uint) obj.Y); + pak.WriteShort(obj.Orientation.InHeading); + pak.WriteShort((ushort) obj.Position.Z); + pak.WriteInt((uint) obj.Position.X); + pak.WriteInt((uint) obj.Position.Y); pak.WriteShort(obj.Model); int flag = (obj.Type() | ((byte)obj.Realm == 3 ? 0x40 : (byte)obj.Realm << 4) | obj.GetDisplayLevel(m_gameClient.Player) << 9); pak.WriteShort((ushort) flag); //(0x0002-for Ship,0x7D42-for catapult,0x9602,0x9612,0x9622-for ballista) @@ -4088,21 +4092,10 @@ public virtual void SendSiegeWeaponAnimation(GameSiegeWeapon siegeWeapon) using (var pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.SiegeWeaponAnimation))) { pak.WriteInt((uint) siegeWeapon.ObjectID); - pak.WriteInt( - (uint) - (siegeWeapon.TargetObject == null - ? (siegeWeapon.GroundTarget == null ? 0 : siegeWeapon.GroundTarget.X) - : siegeWeapon.TargetObject.X)); - pak.WriteInt( - (uint) - (siegeWeapon.TargetObject == null - ? (siegeWeapon.GroundTarget == null ? 0 : siegeWeapon.GroundTarget.Y) - : siegeWeapon.TargetObject.Y)); - pak.WriteInt( - (uint) - (siegeWeapon.TargetObject == null - ? (siegeWeapon.GroundTarget == null ? 0 : siegeWeapon.GroundTarget.Z) - : siegeWeapon.TargetObject.Z)); + var aimCoordinate = siegeWeapon.AimCoordinate; + pak.WriteInt((uint)aimCoordinate.X); + pak.WriteInt((uint)aimCoordinate.Y); + pak.WriteInt((uint)aimCoordinate.Z); pak.WriteInt((uint) (siegeWeapon.TargetObject == null ? 0 : siegeWeapon.TargetObject.ObjectID)); pak.WriteShort(siegeWeapon.Effect); pak.WriteShort((ushort) (siegeWeapon.SiegeWeaponTimer.TimeUntilElapsed/100)); @@ -4119,9 +4112,9 @@ public virtual void SendSiegeWeaponFireAnimation(GameSiegeWeapon siegeWeapon, in using (var pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.SiegeWeaponAnimation))) { pak.WriteInt((uint) siegeWeapon.ObjectID); - pak.WriteInt((uint) (siegeWeapon.TargetObject == null ? 0 : siegeWeapon.TargetObject.X)); - pak.WriteInt((uint) (siegeWeapon.TargetObject == null ? 0 : siegeWeapon.TargetObject.Y)); - pak.WriteInt((uint) (siegeWeapon.TargetObject == null ? 0 : siegeWeapon.TargetObject.Z + 50)); + pak.WriteInt((uint) (siegeWeapon.TargetObject == null ? 0 : siegeWeapon.TargetObject.Position.X)); + pak.WriteInt((uint) (siegeWeapon.TargetObject == null ? 0 : siegeWeapon.TargetObject.Position.Y)); + pak.WriteInt((uint) (siegeWeapon.TargetObject == null ? 0 : siegeWeapon.TargetObject.Position.Z + 50)); pak.WriteInt((uint) (siegeWeapon.TargetObject == null ? 0 : siegeWeapon.TargetObject.ObjectID)); pak.WriteShort(siegeWeapon.Effect); pak.WriteShort((ushort) (timer/100)); @@ -4160,6 +4153,18 @@ public virtual void SendLivingDataUpdate(GameLiving living, bool updateStrings) } } + public virtual void SendSoundEffect(ushort soundId, Position pos, ushort radius) + { + var region = WorldMgr.GetRegion(pos.RegionID); + if(region == null) return; + + var zone = region.GetZone(pos.Coordinate); + if(zone == null) return; + + var zoneCoord = pos - zone.Offset; + SendSoundEffect(soundId, zone.ID, (ushort)zoneCoord.X, (ushort)zoneCoord.Y, (ushort)zoneCoord.Z, radius); + } + public virtual void SendSoundEffect(ushort soundId, ushort zoneId, ushort x, ushort y, ushort z, ushort radius) { using (var pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.SoundEffect))) @@ -4387,7 +4392,10 @@ public virtual void SendMinotaurRelicMapRemove(byte id) { } - public virtual void SendMinotaurRelicMapUpdate(byte id, ushort region, int x, int y, int z) + public void SendMinotaurRelicMapUpdate(byte id, ushort region, int x, int y, int z) + => SendMinotaurRelicMapUpdate(id, Position.Create(region, x, y, z)); + + public virtual void SendMinotaurRelicMapUpdate(byte id, Position position) { } diff --git a/GameServer/packets/Server/PacketLib170.cs b/GameServer/packets/Server/PacketLib170.cs index af262483e1..361c5fca53 100644 --- a/GameServer/packets/Server/PacketLib170.cs +++ b/GameServer/packets/Server/PacketLib170.cs @@ -53,11 +53,11 @@ public override void SendKeepInfo(IGameKeep keep) using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.KeepInfo))) { - pak.WriteShort((ushort)keep.KeepID); + pak.WriteShort(keep.KeepID); pak.WriteShort(0);//zone id not sure pak.WriteInt((uint)keep.X); pak.WriteInt((uint)keep.Y); - pak.WriteShort((ushort)keep.Heading); + pak.WriteShort((ushort)keep.Orientation.InDegrees); pak.WriteByte((byte)keep.Realm); pak.WriteByte((byte)keep.Level);//level(not sure) pak.WriteShort(0);//unk diff --git a/GameServer/packets/Server/PacketLib171.cs b/GameServer/packets/Server/PacketLib171.cs index 3cf21e860d..d3c4c15eca 100644 --- a/GameServer/packets/Server/PacketLib171.cs +++ b/GameServer/packets/Server/PacketLib171.cs @@ -54,10 +54,10 @@ public override void SendPlayerPositionAndObjectID() using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.PositionAndObjectID))) { pak.WriteShort((ushort)m_gameClient.Player.ObjectID); //This is the player's objectid not Sessionid!!! - pak.WriteShort((ushort)m_gameClient.Player.Z); - pak.WriteInt((uint)m_gameClient.Player.X); - pak.WriteInt((uint)m_gameClient.Player.Y); - pak.WriteShort(m_gameClient.Player.Heading); + pak.WriteShort((ushort)m_gameClient.Player.Position.Z); + pak.WriteInt((uint)m_gameClient.Player.Position.X); + pak.WriteInt((uint)m_gameClient.Player.Position.Y); + pak.WriteShort(m_gameClient.Player.Orientation.InHeading); int flags = 0; if (m_gameClient.Player.CurrentZone.IsDivingEnabled) @@ -67,8 +67,8 @@ public override void SendPlayerPositionAndObjectID() pak.WriteByte(0x00); //TODO Unknown Zone zone = m_gameClient.Player.CurrentZone; if (zone == null) return; - pak.WriteShort((ushort)(zone.XOffset / 0x2000)); - pak.WriteShort((ushort)(zone.YOffset / 0x2000)); + pak.WriteShort((ushort)(zone.Offset.X / 0x2000)); + pak.WriteShort((ushort)(zone.Offset.Y / 0x2000)); //Dinberg - Changing to allow instances... pak.WriteShort(m_gameClient.Player.CurrentRegion.Skin); pak.WriteShort(0x00); //TODO: unknown, new in 1.71 @@ -90,10 +90,10 @@ public override void SendObjectCreate(GameObject obj) if (obj is GameStaticItem) pak.WriteShort((ushort)(obj as GameStaticItem).Emblem); else pak.WriteShort(0); - pak.WriteShort(obj.Heading); - pak.WriteShort((ushort)obj.Z); - pak.WriteInt((uint)obj.X); - pak.WriteInt((uint)obj.Y); + pak.WriteShort(obj.Orientation.InHeading); + pak.WriteShort((ushort)obj.Position.Z); + pak.WriteInt((uint)obj.Position.X); + pak.WriteInt((uint)obj.Position.Y); int flag = ((byte)obj.Realm & 3) << 4; ushort model = obj.Model; if (obj.IsUnderwater) @@ -172,17 +172,17 @@ public override void SendNPCCreate(GameNPC npc) ushort speedZ = 0; if (npc == null) return; - if (!npc.IsAtTargetPosition) + if (!npc.IsAtTargetLocation) { speed = npc.CurrentSpeed; - speedZ = (ushort)npc.TickSpeedZ; + speedZ = (ushort)npc.ZSpeedFactor; } pak.WriteShort((ushort)npc.ObjectID); pak.WriteShort((ushort)(speed)); - pak.WriteShort(npc.Heading); - pak.WriteShort((ushort)npc.Z); - pak.WriteInt((uint)npc.X); - pak.WriteInt((uint)npc.Y); + pak.WriteShort(npc.Orientation.InHeading); + pak.WriteShort((ushort)npc.Position.Z); + pak.WriteInt((uint)npc.Position.X); + pak.WriteInt((uint)npc.Position.Y); pak.WriteShort(speedZ); pak.WriteShort(npc.Model); pak.WriteByte(npc.Size); diff --git a/GameServer/packets/Server/PacketLib172.cs b/GameServer/packets/Server/PacketLib172.cs index a4885dd735..4e4434482c 100644 --- a/GameServer/packets/Server/PacketLib172.cs +++ b/GameServer/packets/Server/PacketLib172.cs @@ -69,12 +69,12 @@ public override void SendPlayerCreate(GamePlayer playerToCreate) pak.WriteShort((ushort)playerToCreate.Client.SessionID); pak.WriteShort((ushort)playerToCreate.ObjectID); pak.WriteShort(playerToCreate.Model); - pak.WriteShort((ushort)playerToCreate.Z); + pak.WriteShort((ushort)playerToCreate.Position.Z); //Dinberg:Instances - Zoneskin ID for clientside positioning 'bluff'. pak.WriteShort(playerZone.ZoneSkinID); - pak.WriteShort((ushort)playerRegion.GetXOffInZone(playerToCreate.X, playerToCreate.Y)); - pak.WriteShort((ushort)playerRegion.GetYOffInZone(playerToCreate.X, playerToCreate.Y)); - pak.WriteShort(playerToCreate.Heading); + pak.WriteShort(GetXOffsetInZone(playerToCreate)); + pak.WriteShort(GetYOffsetInZone(playerToCreate)); + pak.WriteShort(playerToCreate.Orientation.InHeading); pak.WriteByte(playerToCreate.GetFaceAttribute(eCharFacePart.EyeSize)); //1-4 = Eye Size / 5-8 = Nose Size pak.WriteByte(playerToCreate.GetFaceAttribute(eCharFacePart.LipSize)); //1-4 = Ear size / 5-8 = Kin size @@ -124,7 +124,7 @@ public override void SendPlayerForgedPosition(GamePlayer player) // Write Speed if (player.Steed != null && player.Steed.ObjectState == GameObject.eObjectState.Active) { - player.Heading = player.Steed.Heading; + player.Orientation = player.Steed.Orientation; pak.WriteShort(0x1800); } else @@ -168,13 +168,10 @@ public override void SendPlayerForgedPosition(GamePlayer player) pak.WriteShort(content); } - // Get Off Corrd - int offX = player.X - player.CurrentZone.XOffset; - int offY = player.Y - player.CurrentZone.YOffset; - - pak.WriteShort((ushort)player.Z); - pak.WriteShort((ushort)offX); - pak.WriteShort((ushort)offY); + var zoneCoord = player.Coordinate - player.CurrentZone.Offset; + pak.WriteShort((ushort)zoneCoord.Z); + pak.WriteShort((ushort)zoneCoord.X); + pak.WriteShort((ushort)zoneCoord.Y); // Write Zone pak.WriteShort(player.CurrentZone.ZoneSkinID); @@ -188,7 +185,7 @@ public override void SendPlayerForgedPosition(GamePlayer player) else { // Set Player always on ground, this is an "anti lag" packet - ushort contenthead = (ushort)(player.Heading + (true ? 0x1000 : 0)); + ushort contenthead = (ushort)(player.Orientation.InHeading + (true ? 0x1000 : 0)); pak.WriteShort(contenthead); // No Fall Speed. pak.WriteShort(0); diff --git a/GameServer/packets/Server/PacketLib173.cs b/GameServer/packets/Server/PacketLib173.cs index c6df686ba1..bcdebe1361 100644 --- a/GameServer/packets/Server/PacketLib173.cs +++ b/GameServer/packets/Server/PacketLib173.cs @@ -31,6 +31,7 @@ using DOL.GS.Spells; using DOL.GS.Styles; using log4net; +using DOL.GS.Geometry; namespace DOL.GS.PacketHandler { @@ -299,7 +300,8 @@ public override void SendCharacterOverview(eRealm realm) Region reg = WorldMgr.GetRegion((ushort)characters[j].Region); if (reg != null) { - var description = m_gameClient.GetTranslatedSpotDescription(reg, characters[j].Xpos, characters[j].Ypos, characters[j].Zpos); + var coordinate = characters[j].GetPosition().Coordinate; + var description = GamePlayerUtils.GetTranslatedSpotDescription(reg, m_gameClient, coordinate); pak.FillString(description, 24); } else @@ -446,13 +448,13 @@ public override void SendKeepInfo(IGameKeep keep) using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.KeepInfo))) { - pak.WriteShort((ushort)keep.KeepID); + pak.WriteShort(keep.KeepID); pak.WriteShort(0); pak.WriteInt((uint)keep.X); pak.WriteInt((uint)keep.Y); - pak.WriteShort((ushort)keep.Heading); + pak.WriteShort((ushort)keep.Orientation.InDegrees); pak.WriteByte((byte)keep.Realm); - pak.WriteByte((byte)keep.Level);//level + pak.WriteByte(keep.Level);//level pak.WriteShort(0);//unk pak.WriteByte(0x52);//model pak.WriteByte(0);//unk diff --git a/GameServer/packets/Server/PacketLib174.cs b/GameServer/packets/Server/PacketLib174.cs index da2cc3c376..1c64126b71 100644 --- a/GameServer/packets/Server/PacketLib174.cs +++ b/GameServer/packets/Server/PacketLib174.cs @@ -29,6 +29,7 @@ using DOL.GS.Spells; using DOL.GS.Styles; using log4net; +using DOL.GS.Geometry; namespace DOL.GS.PacketHandler { @@ -117,7 +118,8 @@ public override void SendCharacterOverview(eRealm realm) Region reg = WorldMgr.GetRegion((ushort)characters[j].Region); if (reg != null) { - var description = m_gameClient.GetTranslatedSpotDescription(reg, characters[j].Xpos, characters[j].Ypos, characters[j].Zpos); + var coordinate = characters[j].GetPosition().Coordinate; + var description = GamePlayerUtils.GetTranslatedSpotDescription(reg, m_gameClient, coordinate); pak.FillString(description, 24); } else @@ -283,12 +285,12 @@ public override void SendPlayerCreate(GamePlayer playerToCreate) pak.WriteShort((ushort)playerToCreate.Client.SessionID); pak.WriteShort((ushort)playerToCreate.ObjectID); pak.WriteShort(playerToCreate.Model); - pak.WriteShort((ushort)playerToCreate.Z); + pak.WriteShort((ushort)playerToCreate.Position.Z); //Dinberg:Instances - zoneSkinID for object positioning clientside (as zones are hardcoded). pak.WriteShort(playerZone.ZoneSkinID); - pak.WriteShort((ushort)playerRegion.GetXOffInZone(playerToCreate.X, playerToCreate.Y)); - pak.WriteShort((ushort)playerRegion.GetYOffInZone(playerToCreate.X, playerToCreate.Y)); - pak.WriteShort(playerToCreate.Heading); + pak.WriteShort(GetXOffsetInZone(playerToCreate)); + pak.WriteShort(GetYOffsetInZone(playerToCreate)); + pak.WriteShort(playerToCreate.Orientation.InHeading); pak.WriteByte(playerToCreate.GetFaceAttribute(eCharFacePart.EyeSize)); //1-4 = Eye Size / 5-8 = Nose Size pak.WriteByte(playerToCreate.GetFaceAttribute(eCharFacePart.LipSize)); //1-4 = Ear size / 5-8 = Kin size @@ -329,10 +331,10 @@ public override void SendPlayerPositionAndObjectID() using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.PositionAndObjectID))) { pak.WriteShort((ushort)m_gameClient.Player.ObjectID); //This is the player's objectid not Sessionid!!! - pak.WriteShort((ushort)m_gameClient.Player.Z); - pak.WriteInt((uint)m_gameClient.Player.X); - pak.WriteInt((uint)m_gameClient.Player.Y); - pak.WriteShort(m_gameClient.Player.Heading); + pak.WriteShort((ushort)m_gameClient.Player.Position.Z); + pak.WriteInt((uint)m_gameClient.Player.Position.X); + pak.WriteInt((uint)m_gameClient.Player.Position.Y); + pak.WriteShort(m_gameClient.Player.Orientation.InHeading); int flags = 0; Zone zone = m_gameClient.Player.CurrentZone; @@ -347,8 +349,8 @@ public override void SendPlayerPositionAndObjectID() if (zone.IsDungeon) { - pak.WriteShort((ushort)(zone.XOffset / 0x2000)); - pak.WriteShort((ushort)(zone.YOffset / 0x2000)); + pak.WriteShort((ushort)(zone.Offset.X / 0x2000)); + pak.WriteShort((ushort)(zone.Offset.Y / 0x2000)); } else { @@ -380,8 +382,9 @@ protected virtual void WriteGroupMemberMapUpdate(GSTCPPacketOut pak, GameLiving pak.WriteByte((byte)(0x40 | living.GroupIndex)); //Dinberg - ZoneSkinID for group members aswell. pak.WriteShort(zone.ZoneSkinID); - pak.WriteShort((ushort)(living.X - zone.XOffset)); - pak.WriteShort((ushort)(living.Y - zone.YOffset)); + var zoneCoord = living.Coordinate - zone.Offset; + pak.WriteShort((ushort)(zoneCoord.X)); + pak.WriteShort((ushort)(zoneCoord.Y)); } } diff --git a/GameServer/packets/Server/PacketLib175.cs b/GameServer/packets/Server/PacketLib175.cs index e62811e708..62a11bf20c 100644 --- a/GameServer/packets/Server/PacketLib175.cs +++ b/GameServer/packets/Server/PacketLib175.cs @@ -473,12 +473,12 @@ public override void SendPlayerCreate(GamePlayer playerToCreate) pak.WriteShort((ushort)playerToCreate.Client.SessionID); pak.WriteShort((ushort)playerToCreate.ObjectID); pak.WriteShort(playerToCreate.Model); - pak.WriteShort((ushort)playerToCreate.Z); + pak.WriteShort((ushort)playerToCreate.Position.Z); //Dinberg:Instances - as with all objects, we need to use a zoneSkinID for clientside positioning. pak.WriteShort(playerZone.ZoneSkinID); - pak.WriteShort((ushort)playerRegion.GetXOffInZone(playerToCreate.X, playerToCreate.Y)); - pak.WriteShort((ushort)playerRegion.GetYOffInZone(playerToCreate.X, playerToCreate.Y)); - pak.WriteShort(playerToCreate.Heading); + pak.WriteShort(GetXOffsetInZone(playerToCreate)); + pak.WriteShort(GetYOffsetInZone(playerToCreate)); + pak.WriteShort(playerToCreate.Orientation.InHeading); pak.WriteByte(playerToCreate.GetFaceAttribute(eCharFacePart.EyeSize)); //1-4 = Eye Size / 5-8 = Nose Size pak.WriteByte(playerToCreate.GetFaceAttribute(eCharFacePart.LipSize)); //1-4 = Ear size / 5-8 = Kin size diff --git a/GameServer/packets/Server/PacketLib176.cs b/GameServer/packets/Server/PacketLib176.cs index 986d25976b..cc36b7e5bf 100644 --- a/GameServer/packets/Server/PacketLib176.cs +++ b/GameServer/packets/Server/PacketLib176.cs @@ -109,10 +109,10 @@ public override void SendObjectCreate(GameObject obj) else pak.WriteShort(0); - pak.WriteShort(obj.Heading); - pak.WriteShort((ushort)obj.Z); - pak.WriteInt((uint)obj.X); - pak.WriteInt((uint)obj.Y); + pak.WriteShort(obj.Orientation.InHeading); + pak.WriteShort((ushort)obj.Position.Z); + pak.WriteInt((uint)obj.Position.X); + pak.WriteInt((uint)obj.Position.Y); int flag = ((byte)obj.Realm & 3) << 4; ushort model = obj.Model; if (obj.IsUnderwater) @@ -370,10 +370,10 @@ public override void SendHouse(House house) using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.HouseCreate))) { pak.WriteShort((ushort)house.HouseNumber); - pak.WriteShort((ushort)house.Z); - pak.WriteInt((uint)house.X); - pak.WriteInt((uint)house.Y); - pak.WriteShort((ushort)house.Heading); + pak.WriteShort((ushort)house.Position.Z); + pak.WriteInt((uint)house.Position.X); + pak.WriteInt((uint)house.Position.Y); + pak.WriteShort((ushort)house.Orientation); pak.WriteShort((ushort)house.PorchRoofColor); pak.WriteShort((ushort)(house.GetPorchAndGuildEmblemFlags() | (house.Emblem & 0x010000) >> 13));//new Guild Emblem pak.WriteShort((ushort)house.Emblem); @@ -401,9 +401,9 @@ public override void SendEnterHouse(House house) pak.WriteShort((ushort)house.HouseNumber); pak.WriteShort((ushort)25000); //constant! - pak.WriteInt((uint)house.X); - pak.WriteInt((uint)house.Y); - pak.WriteShort((ushort)house.Heading); //useless/ignored by client. + pak.WriteInt((uint)house.Position.X); + pak.WriteInt((uint)house.Position.Y); + pak.WriteShort((ushort)house.Orientation); //useless/ignored by client. pak.WriteByte(0x00); pak.WriteByte((byte)(house.GetGuildEmblemFlags() | (house.Emblem & 0x010000) >> 14));//new Guild Emblem pak.WriteShort((ushort)house.Emblem); //emblem diff --git a/GameServer/packets/Server/PacketLib180.cs b/GameServer/packets/Server/PacketLib180.cs index 54dd47d49f..70c29463ab 100644 --- a/GameServer/packets/Server/PacketLib180.cs +++ b/GameServer/packets/Server/PacketLib180.cs @@ -157,12 +157,12 @@ public override void SendPlayerCreate(GamePlayer playerToCreate) pak.WriteShort((ushort)playerToCreate.Client.SessionID); pak.WriteShort((ushort)playerToCreate.ObjectID); pak.WriteShort(playerToCreate.Model); - pak.WriteShort((ushort)playerToCreate.Z); + pak.WriteShort((ushort)playerToCreate.Position.Z); //Dinberg:Instances - send out the 'fake' zone ID to the client for positioning purposes. pak.WriteShort(playerZone.ZoneSkinID); - pak.WriteShort((ushort)playerRegion.GetXOffInZone(playerToCreate.X, playerToCreate.Y)); - pak.WriteShort((ushort)playerRegion.GetYOffInZone(playerToCreate.X, playerToCreate.Y)); - pak.WriteShort(playerToCreate.Heading); + pak.WriteShort(GetXOffsetInZone(playerToCreate)); + pak.WriteShort(GetYOffsetInZone(playerToCreate)); + pak.WriteShort(playerToCreate.Orientation.InHeading); pak.WriteByte(playerToCreate.GetFaceAttribute(eCharFacePart.EyeSize)); //1-4 = Eye Size / 5-8 = Nose Size pak.WriteByte(playerToCreate.GetFaceAttribute(eCharFacePart.LipSize)); //1-4 = Ear size / 5-8 = Kin size diff --git a/GameServer/packets/Server/PacketLib186.cs b/GameServer/packets/Server/PacketLib186.cs index 5f5dc3e80d..2be20b5192 100644 --- a/GameServer/packets/Server/PacketLib186.cs +++ b/GameServer/packets/Server/PacketLib186.cs @@ -20,6 +20,7 @@ using log4net; using DOL.GS.Quests; using System.Reflection; +using DOL.GS.Geometry; namespace DOL.GS.PacketHandler { @@ -112,21 +113,21 @@ public override void SendMinotaurRelicMapRemove(byte id) SendTCP(pak); } } - - public override void SendMinotaurRelicMapUpdate(byte id, ushort region, int x, int y, int z) - { - using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.MinotaurRelicMapUpdate))) - { - pak.WriteIntLowEndian((uint)id); - pak.WriteIntLowEndian((uint)region); - pak.WriteIntLowEndian((uint)x); - pak.WriteIntLowEndian((uint)y); - pak.WriteIntLowEndian((uint)z); - - SendTCP(pak); - } - } + public override void SendMinotaurRelicMapUpdate(byte id, Position position) + { + using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.MinotaurRelicMapUpdate))) + { + + pak.WriteIntLowEndian((uint)id); + pak.WriteIntLowEndian((uint)position.RegionID); + pak.WriteIntLowEndian((uint)position.X); + pak.WriteIntLowEndian((uint)position.Y); + pak.WriteIntLowEndian((uint)position.Z); + + SendTCP(pak); + } + } public override void SendMinotaurRelicWindow(GamePlayer player, int effect, bool flag) { diff --git a/GameServer/packets/Server/PacketLib189.cs b/GameServer/packets/Server/PacketLib189.cs index 59e2a12dd5..12ac637d53 100644 --- a/GameServer/packets/Server/PacketLib189.cs +++ b/GameServer/packets/Server/PacketLib189.cs @@ -418,10 +418,10 @@ public override void SendHouse(House house) using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.HouseCreate))) { pak.WriteShort((ushort)house.HouseNumber); - pak.WriteShort((ushort)house.Z); - pak.WriteInt((uint)house.X); - pak.WriteInt((uint)house.Y); - pak.WriteShort((ushort)house.Heading); + pak.WriteShort((ushort)house.Position.Z); + pak.WriteInt((uint)house.Position.X); + pak.WriteInt((uint)house.Position.Y); + pak.WriteShort((ushort)house.Orientation); pak.WriteShort((ushort)house.PorchRoofColor); int flagPorchAndGuildEmblem = (house.Emblem & 0x010000) >> 13;//new Guild Emblem if (house.Porch) @@ -519,9 +519,9 @@ public override void SendEnterHouse(House house) { pak.WriteShort((ushort)house.HouseNumber); pak.WriteShort((ushort)25000); //constant! - pak.WriteInt((uint)house.X); - pak.WriteInt((uint)house.Y); - pak.WriteShort((ushort)house.Heading); //useless/ignored by client. + pak.WriteInt((uint)house.Position.X); + pak.WriteInt((uint)house.Position.Y); + pak.WriteShort((ushort)house.Orientation); //useless/ignored by client. pak.WriteByte(0x00); pak.WriteByte((byte)(house.GetGuildEmblemFlags() | (house.Emblem & 0x010000) >> 14));//new Guild Emblem pak.WriteShort((ushort)house.Emblem); //emblem diff --git a/GameServer/packets/Server/PacketLib190.cs b/GameServer/packets/Server/PacketLib190.cs index 39e52c67b2..48fbb1ec39 100644 --- a/GameServer/packets/Server/PacketLib190.cs +++ b/GameServer/packets/Server/PacketLib190.cs @@ -245,7 +245,7 @@ public override void SendPlayerForgedPosition(GamePlayer player) // Write Speed if (player.Steed != null && player.Steed.ObjectState == GameObject.eObjectState.Active) { - player.Heading = player.Steed.Heading; + player.Orientation = player.Steed.Orientation; pak.WriteShort(0x1800); } else @@ -289,13 +289,10 @@ public override void SendPlayerForgedPosition(GamePlayer player) pak.WriteShort(content); } - // Get Off Corrd - int offX = player.X - player.CurrentZone.XOffset; - int offY = player.Y - player.CurrentZone.YOffset; - - pak.WriteShort((ushort)player.Z); - pak.WriteShort((ushort)offX); - pak.WriteShort((ushort)offY); + var zoneCoord = player.Coordinate - player.CurrentZone.Offset; + pak.WriteShort((ushort)zoneCoord.Z); + pak.WriteShort((ushort)zoneCoord.X); + pak.WriteShort((ushort)zoneCoord.Y); // Write Zone pak.WriteShort(player.CurrentZone.ZoneSkinID); @@ -309,7 +306,7 @@ public override void SendPlayerForgedPosition(GamePlayer player) else { // Set Player always on ground, this is an "anti lag" packet - ushort contenthead = (ushort)(player.Heading + (true ? 0x1000 : 0)); + ushort contenthead = (ushort)(player.Orientation.InHeading + (true ? 0x1000 : 0)); pak.WriteShort(contenthead); // No Fall Speed. pak.WriteShort(0); diff --git a/GameServer/packets/Server/PacketLib199.cs b/GameServer/packets/Server/PacketLib199.cs index b5fa2b192d..f222e74a96 100644 --- a/GameServer/packets/Server/PacketLib199.cs +++ b/GameServer/packets/Server/PacketLib199.cs @@ -22,6 +22,7 @@ using System.Reflection; using DOL.Database; +using DOL.GS.Geometry; using DOL.Language; using log4net; @@ -116,7 +117,8 @@ public override void SendCharacterOverview(eRealm realm) Region reg = WorldMgr.GetRegion((ushort)characters[j].Region); if (reg != null) { - var description = m_gameClient.GetTranslatedSpotDescription(reg, characters[j].Xpos, characters[j].Ypos, characters[j].Zpos); + var coordinate = characters[j].GetPosition().Coordinate; + var description = GamePlayerUtils.GetTranslatedSpotDescription(reg, m_gameClient, coordinate); pak.FillString(description, 24); } else diff --git a/GameServer/quests/Atlantis/ArtifactTurnInQuest.cs b/GameServer/quests/Atlantis/ArtifactTurnInQuest.cs index 366f35ad14..b19abac185 100644 --- a/GameServer/quests/Atlantis/ArtifactTurnInQuest.cs +++ b/GameServer/quests/Atlantis/ArtifactTurnInQuest.cs @@ -27,6 +27,7 @@ using DOL.Language; using DOL.GS.PacketHandler; using log4net; +using DOL.GS.Geometry; namespace DOL.GS.Quests.Atlantis { @@ -178,13 +179,9 @@ public static void Init() if (log.IsWarnEnabled) log.Warn("Could not find " + m_scholarAlaria.Name + ", creating her ..."); m_scholarAlaria.Realm = eRealm.Midgard; - m_scholarAlaria.CurrentRegionID = 71; m_scholarAlaria.Size = 50; m_scholarAlaria.Level = 45; - m_scholarAlaria.X = 565733; - m_scholarAlaria.Y = 569502; - m_scholarAlaria.Z = 7255; - m_scholarAlaria.Heading = 708; + m_scholarAlaria.Position = Position.Create(regionID: 71, x: 565733, y: 569502, z: 7255, heading: 708); m_scholarAlaria.MaxSpeedBase = 200; m_scholarAlaria.SaveIntoDatabase(); @@ -203,13 +200,9 @@ public static void Init() if (log.IsWarnEnabled) log.Warn("Could not find " + m_scholarJarron.Name + ", creating him ..."); m_scholarJarron.Realm = eRealm.Albion; - m_scholarJarron.CurrentRegionID = 70; m_scholarJarron.Size = 50; m_scholarJarron.Level = 45; - m_scholarJarron.X = 577936; - m_scholarJarron.Y = 533228; - m_scholarJarron.Z = 7295; - m_scholarJarron.Heading = 3731; + m_scholarJarron.Position = Position.Create(regionID: 70, x: 577936, y: 533228, z: 7295, heading: 3731); m_scholarJarron.MaxSpeedBase = 200; m_scholarJarron.SaveIntoDatabase(); @@ -228,13 +221,9 @@ public static void Init() if (log.IsWarnEnabled) log.Warn("Could not find " + m_scholarElmer.Name + ", creating him ..."); m_scholarElmer.Realm = eRealm.Hibernia; - m_scholarElmer.CurrentRegionID = 72; m_scholarElmer.Size = 50; m_scholarElmer.Level = 45; - m_scholarElmer.X = 552291; - m_scholarElmer.Y = 576366; - m_scholarElmer.Z = 6767; - m_scholarElmer.Heading = 1074; + m_scholarElmer.Position = Position.Create(regionID: 72, x: 552291, y: 576366, z: 6767, heading: 1074); m_scholarElmer.MaxSpeedBase = 200; m_scholarElmer.SaveIntoDatabase(); diff --git a/GameServer/quests/QuestsMgr/BaseQuest.cs b/GameServer/quests/QuestsMgr/BaseQuest.cs index 9a36b7d37f..c274cb3713 100644 --- a/GameServer/quests/QuestsMgr/BaseQuest.cs +++ b/GameServer/quests/QuestsMgr/BaseQuest.cs @@ -32,6 +32,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Behaviour; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using DOL.Language; using log4net; @@ -239,41 +240,46 @@ protected virtual int MakeAnimEmoteSequence(RegionTimer callingTimer) return 0; } + [Obsolete("Use .TeleportTo(GameObject, GameObject, Position, string, int, int) instead!")] protected virtual void TeleportTo(GameObject target, GameObject caster, GameLocation location) - { - TeleportTo(target, caster, location, 0, 0); - } + => TeleportTo(target, caster, location, 0, 0); + [Obsolete("Use .TeleportTo(GameObject, GameObject, Position, string, int, int) instead!")] protected virtual void TeleportTo(GameObject target, GameObject caster, GameLocation location, uint delay) - { - TeleportTo(target, caster, location, delay, 0); - } + => TeleportTo(target, caster, location, delay, 0); - protected virtual void TeleportTo(GameObject target, GameObject caster, GameLocation location, uint delay, int fuzzyLocation) - { - delay *= 100; // 1/10sec to milliseconds - if (delay <= 0) - delay = 1; - m_animSpellObjectQueue.Enqueue(caster); - m_animSpellTeleportTimerQueue.Enqueue(new RegionTimer(caster, new RegionTimerCallback(MakeAnimSpellSequence), (int)delay)); + [Obsolete("Use .TeleportTo(GameObject, GameObject, Position, string, int, int) instead!")] + protected virtual void TeleportTo(GameObject target, GameObject caster, GameLocation location, uint delay, int randomSquareRadius) + => TeleportTo(target, caster, destination: location.Position, destinationName: location.Name, delay, randomSquareRadius); - m_animEmoteObjectQueue.Enqueue(target); - m_animEmoteTeleportTimerQueue.Enqueue(new RegionTimer(target, new RegionTimerCallback(MakeAnimEmoteSequence), (int)delay + 2000)); + protected virtual void TeleportTo(GameObject target, GameObject caster, Position destination, string destinationName, uint delay, int scatterRadius) + { + TeleportTo(target,caster,destination,delay,scatterRadius); - m_portObjectQueue.Enqueue(target); + if (destinationName != null) + { + m_questPlayer.Out.SendMessage(LanguageMgr.GetTranslation(m_questPlayer.Client, "BaseQuest.TeleportTo.Text1", target.Name, destinationName), eChatType.CT_System, eChatLoc.CL_SystemWindow); + } + } - location.X += Util.Random(0 - fuzzyLocation, fuzzyLocation); - location.Y += Util.Random(0 - fuzzyLocation, fuzzyLocation); + protected virtual void TeleportTo(GameObject target, GameObject caster, Position destination, uint delay, int scatterRadius) + { + delay *= 100; // 1/10sec to milliseconds + if (delay <= 0) + delay = 1; + m_animSpellObjectQueue.Enqueue(caster); + m_animSpellTeleportTimerQueue.Enqueue(new RegionTimer(caster, new RegionTimerCallback(MakeAnimSpellSequence), (int)delay)); - m_portDestinationQueue.Enqueue(location); - m_portTeleportTimerQueue.Enqueue(new RegionTimer(target, new RegionTimerCallback(MakePortSequence), (int)delay + 3000)); + m_animEmoteObjectQueue.Enqueue(target); + m_animEmoteTeleportTimerQueue.Enqueue(new RegionTimer(target, new RegionTimerCallback(MakeAnimEmoteSequence), (int)delay + 2000)); - if (location.Name != null) - { - m_questPlayer.Out.SendMessage(LanguageMgr.GetTranslation(m_questPlayer.Client, "BaseQuest.TeleportTo.Text1", target.Name, location.Name), eChatType.CT_System, eChatLoc.CL_SystemWindow); - } + m_portObjectQueue.Enqueue(target); - } + var randomOffset = Vector.Create(x: Util.Random(-scatterRadius, scatterRadius), y: Util.Random(-scatterRadius, scatterRadius)); + + m_portDestinationQueue.Enqueue(destination + randomOffset); + m_portTeleportTimerQueue.Enqueue(new RegionTimer(target, new RegionTimerCallback(MakePortSequence), (int)delay + 3000)); + } protected virtual int MakePortSequence(RegionTimer callingTimer) { @@ -281,8 +287,8 @@ protected virtual int MakePortSequence(RegionTimer callingTimer) { m_portTeleportTimerQueue.Dequeue(); GameObject gameObject = (GameObject)m_portObjectQueue.Dequeue(); - GameLocation location = (GameLocation)m_portDestinationQueue.Dequeue(); - gameObject.MoveTo(location.RegionID, location.X, location.Y, location.Z, location.Heading); + var destination = (Position)m_portDestinationQueue.Dequeue(); + gameObject.MoveTo(destination); } return 0; } diff --git a/GameServer/quests/QuestsMgr/DataQuest.cs b/GameServer/quests/QuestsMgr/DataQuest.cs index a1561c16bb..6abeb58009 100644 --- a/GameServer/quests/QuestsMgr/DataQuest.cs +++ b/GameServer/quests/QuestsMgr/DataQuest.cs @@ -33,6 +33,7 @@ using log4net; using DOL.GS.Finance; +using DOL.GS.Geometry; namespace DOL.GS.Quests { @@ -1969,7 +1970,7 @@ public static void RewardQuestNotify(DOLEvent e, object sender, EventArgs args) GameNPC npc = giver as GameNPC; player.Out.SendNPCsQuestEffect(npc, npc.GetQuestIndicator(player)); } - player.Out.SendSoundEffect(7, 0, 0, 0, 0, 0); + player.Out.SendSoundEffect(7, Position.Zero, 0); break; } } @@ -3064,7 +3065,7 @@ public virtual bool FinishQuest(GameObject obj, bool checkCustomStep) if (StartType == eStartType.RewardQuest) { - m_questPlayer.Out.SendSoundEffect(11, 0, 0, 0, 0, 0); + m_questPlayer.Out.SendSoundEffect(11, Position.Zero, 0); } if (!string.IsNullOrEmpty(m_dataQuest.FinishText)) // Give users option to have 'finish' text with rewardquest too { diff --git a/GameServer/quests/QuestsMgr/DataQuestRewardQuest.cs b/GameServer/quests/QuestsMgr/DataQuestRewardQuest.cs index 313035ff6b..da658542e6 100644 --- a/GameServer/quests/QuestsMgr/DataQuestRewardQuest.cs +++ b/GameServer/quests/QuestsMgr/DataQuestRewardQuest.cs @@ -33,6 +33,7 @@ using DOL.GS.Finance; using System.Collections.Specialized; using System.Text; +using DOL.GS.Geometry; namespace DOL.GS.Quests { @@ -1696,7 +1697,7 @@ public static void DQRewardQuestNotify(DOLEvent e, object sender, EventArgs args var npc = giver as GameNPC; player.Out.SendNPCsQuestEffect(npc, npc.GetQuestIndicator(player)); } - player.Out.SendSoundEffect(7, 0, 0, 0, 0, 0); + player.Out.SendSoundEffect(7, Position.Zero, 0); player.Out.SendMessage("You have acquired the quest: " + dq.Name, eChatType.CT_ScreenCenter, eChatLoc.CL_SystemWindow); if (!string.IsNullOrWhiteSpace(dq.AcceptText)) { @@ -1844,7 +1845,7 @@ public virtual bool FinishQuest(GameObject obj) // TODO swap sound depending on realm - m_questPlayer.Out.SendSoundEffect(11, 0, 0, 0, 0, 0); + m_questPlayer.Out.SendSoundEffect(11, Position.Zero, 0); if (obj is GameNPC) { diff --git a/GameServer/quests/QuestsMgr/RewardQuest.cs b/GameServer/quests/QuestsMgr/RewardQuest.cs index 20a979a654..36c329fe8e 100644 --- a/GameServer/quests/QuestsMgr/RewardQuest.cs +++ b/GameServer/quests/QuestsMgr/RewardQuest.cs @@ -24,6 +24,7 @@ using DOL.Language; using DOL.GS.PacketHandler; using DOL.GS.Finance; +using DOL.GS.Geometry; namespace DOL.GS.Quests { @@ -226,7 +227,7 @@ public override void Notify(DOLEvent e, object sender, EventArgs args) public override void OnQuestAssigned(GamePlayer player) { player.Out.SendMessage(String.Format(LanguageMgr.GetTranslation(player.Client.Account.Language, "RewardQuest.OnQuestAssigned", Name)), eChatType.CT_ScreenCenter, eChatLoc.CL_SystemWindow); - player.Out.SendSoundEffect(7, 0, 0, 0, 0, 0); + player.Out.SendSoundEffect(7, Position.Zero, 0); } /// @@ -239,7 +240,7 @@ public override void FinishQuest() if (QuestPlayer.Inventory.IsSlotsFree(inventorySpaceRequired, eInventorySlot.FirstBackpack, eInventorySlot.LastBackpack)) { base.FinishQuest(); - QuestPlayer.Out.SendSoundEffect(11, 0, 0, 0, 0, 0); + QuestPlayer.Out.SendSoundEffect(11, Position.Zero, 0); QuestPlayer.GainExperience(GameLiving.eXPSource.Quest, Rewards.Experience); QuestPlayer.AddMoney(Currency.Copper.Mint(Rewards.Money)); InventoryLogging.LogInventoryAction("(QUEST;" + Name + ")", QuestPlayer, eInventoryActionType.Quest, Rewards.Money); diff --git a/GameServer/quests/Tasks/KillTask.cs b/GameServer/quests/Tasks/KillTask.cs index 80e5c8770c..607a5fd35e 100644 --- a/GameServer/quests/Tasks/KillTask.cs +++ b/GameServer/quests/Tasks/KillTask.cs @@ -21,7 +21,9 @@ using System.Collections.Generic; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; +using DOL.Language; namespace DOL.GS.Quests { @@ -249,10 +251,7 @@ public override void Notify(DOLEvent e, object sender, EventArgs args) } droppeditem.Name = itemdrop.Name; droppeditem.Level = 1; - droppeditem.X = target.X; - droppeditem.Y = target.Y; - droppeditem.Z = target.Z; - droppeditem.CurrentRegion = target.CurrentRegion; + droppeditem.Position = target.Position; droppeditem.AddToWorld(); if (dropMessages.Count > 0) { @@ -327,33 +326,11 @@ public static bool BuildTask(GamePlayer player, GameLiving source) ((KillTask)player.Task).ItemIndex = Util.Random(0, TaskObjects.Length - 1); ((KillTask)player.Task).MobName = Mob.Name; player.Task.RecieverName = source.Name; - player.Out.SendMessage(source.Name + " says, *Very well " + player.Name + ", it's good to see adventurers willing to help out the realm in such times. Search to the " + GetDirectionFromHeading(Mob.Heading) + " and kill a " + Mob.Name + " and return to me for your reward. Good luck!*", eChatType.CT_System, eChatLoc.CL_SystemWindow); + player.Out.SendMessage(source.Name + " says, *Very well " + player.Name + ", it's good to see adventurers willing to help out the realm in such times. Search to the " + LanguageMgr.GetCardinalDirection(player.Client.Account.Language, Mob.Orientation) + " and kill a " + Mob.Name + " and return to me for your reward. Good luck!*", eChatType.CT_System, eChatLoc.CL_SystemWindow); player.Out.SendDialogBox(eDialogCode.SimpleWarning, 1, 1, 1, 1, eDialogType.Ok, false, "You have been given a task!"); return true; } } - public static string GetDirectionFromHeading(ushort heading) - { - if (heading < 0) - heading += 4096; - if (heading >= 3840 || heading <= 256) - return "South"; - else if (heading > 256 && heading < 768) - return "South West"; - else if (heading >= 768 && heading <= 1280) - return "West"; - else if (heading > 1280 && heading < 1792) - return "North West"; - else if (heading >= 1792 && heading <= 2304) - return "North"; - else if (heading > 2304 && heading < 2816) - return "North East"; - else if (heading >= 2816 && heading <= 3328) - return "East"; - else if (heading > 3328 && heading < 3840) - return "South East"; - return ""; - } /// /// Find a Random Mob in Radius Distance diff --git a/GameServer/realmabilities/Statics/GenericBase.cs b/GameServer/realmabilities/Statics/GenericBase.cs index ec0d626aa6..ea5063720f 100644 --- a/GameServer/realmabilities/Statics/GenericBase.cs +++ b/GameServer/realmabilities/Statics/GenericBase.cs @@ -4,6 +4,7 @@ using DOL.GS.Spells; using DOL.Events; using DOL.GS.PacketHandler; +using DOL.GS.Geometry; namespace DOL.GS.RealmAbilities.Statics { @@ -20,8 +21,12 @@ public abstract class GenericBase : GameStaticItem int currentPulse = 0; protected int getCurrentPulse () {return currentPulse;} - - public void CreateStatic(GamePlayer caster, Point3D gt, uint lifeTime, uint pulseFrequency, ushort radius) + + [Obsolete("Use .CreateStatic(GamePlayer,Coordinate,uint,ushort) instead!")] + public void CreateStatic(GamePlayer caster, Point3D gt, uint lifeTime, uint pulseFrequency, ushort radius) + => CreateStatic(caster, gt.ToCoordinate(), lifeTime, pulseFrequency, radius); + + public void CreateStatic(GamePlayer caster, Coordinate gt, uint lifeTime, uint pulseFrequency, ushort radius) { m_lifeTime = lifeTime; m_caster = caster; @@ -29,14 +34,12 @@ public void CreateStatic(GamePlayer caster, Point3D gt, uint lifeTime, uint puls m_pulseFrequency = pulseFrequency; this.Name = GetStaticName(); this.Model = GetStaticModel(); - this.X = gt.X; - this.Y = gt.Y; - this.Z = gt.Z; - this.CurrentRegionID = m_caster.CurrentRegionID; + Position = caster.Position.With(coordinate: gt); this.Level = caster.Level; this.Realm = caster.Realm; this.AddToWorld(); } + public override bool AddToWorld() { new RegionTimer(this, new RegionTimerCallback(PulseTimer),1000); diff --git a/GameServer/realmabilities/effects/rr5/BoilingCauldronEffect.cs b/GameServer/realmabilities/effects/rr5/BoilingCauldronEffect.cs index 9a6a34673b..677d516e01 100644 --- a/GameServer/realmabilities/effects/rr5/BoilingCauldronEffect.cs +++ b/GameServer/realmabilities/effects/rr5/BoilingCauldronEffect.cs @@ -70,15 +70,11 @@ public override void Stop() private void SummonCauldron() { Cauldron = new GameStaticItem(); - Cauldron.CurrentRegion = EffectOwner.CurrentRegion; - Cauldron.Heading = (ushort)((EffectOwner.Heading + 2048) % 4096); Cauldron.Level = cauldronLevel; Cauldron.Realm = EffectOwner.Realm; Cauldron.Name = cauldronName; Cauldron.Model = cauldronModel; - Cauldron.X = EffectOwner.X; - Cauldron.Y = EffectOwner.Y; - Cauldron.Z = EffectOwner.Z; + Cauldron.Position = EffectOwner.Position.TurnedAround(); Cauldron.AddToWorld(); new RegionTimer(EffectOwner, new RegionTimerCallback(CauldronCallBack), RealmAbilities.BoilingCauldronAbility.DURATION - 1000); diff --git a/GameServer/realmabilities/effects/rr5/MinionRescueEffect.cs b/GameServer/realmabilities/effects/rr5/MinionRescueEffect.cs index a9edd31d11..2bf3dd0ae1 100644 --- a/GameServer/realmabilities/effects/rr5/MinionRescueEffect.cs +++ b/GameServer/realmabilities/effects/rr5/MinionRescueEffect.cs @@ -26,6 +26,7 @@ using DOL.GS.PacketHandler; using DOL.GS.RealmAbilities; using DOL.GS.Spells; +using DOL.GS.Geometry; namespace DOL.GS.Effects { @@ -116,8 +117,6 @@ public override void Stop() private void SummonSpirit(int spiritId, GamePlayer targetPlayer) { spirits[spiritId] = new GameNPC(); - spirits[spiritId].CurrentRegion = EffectOwner.CurrentRegion; - spirits[spiritId].Heading = (ushort)((EffectOwner.Heading + 2048) % 4096); spirits[spiritId].Level = spiritLevel; spirits[spiritId].Realm = EffectOwner.Realm; spirits[spiritId].Name = spiritName; @@ -126,9 +125,8 @@ private void SummonSpirit(int spiritId, GamePlayer targetPlayer) spirits[spiritId].MaxSpeedBase = spiritSpeed; spirits[spiritId].GuildName = ""; spirits[spiritId].Size = 50; - spirits[spiritId].X = EffectOwner.X + Util.Random(20, 40) - Util.Random(20, 40); - spirits[spiritId].Y = EffectOwner.Y + Util.Random(20, 40) - Util.Random(20, 40); - spirits[spiritId].Z = EffectOwner.Z; + spirits[spiritId].Position = EffectOwner.Position.TurnedAround() + + Vector.Create(x: Util.Random(-20, 20), y: Util.Random(-20, 20)); spirits[spiritId].Flags |= GameNPC.eFlags.DONTSHOWNAME; spirits[spiritId].SetOwnBrain(new StandardMobBrain()); spirits[spiritId].AddToWorld(); diff --git a/GameServer/realmabilities/handlers/DecimationTrap.cs b/GameServer/realmabilities/handlers/DecimationTrap.cs index a0f10761e2..fe3811f462 100644 --- a/GameServer/realmabilities/handlers/DecimationTrap.cs +++ b/GameServer/realmabilities/handlers/DecimationTrap.cs @@ -4,6 +4,7 @@ using DOL.GS.Effects; using DOL.GS.PacketHandler; using DOL.Events; +using DOL.GS.Geometry; namespace DOL.GS.RealmAbilities { @@ -58,9 +59,9 @@ public override void Execute(GameLiving living) } } - if (living.GroundTarget == null) + if (living.GroundTargetPosition == Position.Nowhere) return; - if (!living.IsWithinRadius( living.GroundTarget, 1500 )) + if (living.Coordinate.DistanceTo(living.GroundTargetPosition) > 1500 ) return; GamePlayer player = living as GamePlayer; if (player == null) @@ -91,7 +92,7 @@ private int startSpell(RegionTimer timer) if (!owner.IsAlive) return 0; - traparea = new Area.Circle("decimation trap", owner.X, owner.Y, owner.Z, 50); + traparea = new Area.Circle("decimation trap", owner.Coordinate, 50); owner.CurrentRegion.AddArea(traparea); region = owner.CurrentRegionID; @@ -135,14 +136,14 @@ private void removeHandlers() private void getTargets() { - foreach (GamePlayer target in WorldMgr.GetPlayersCloseToSpot(region, traparea.X, traparea.Y, traparea.Z, 350)) + foreach (GamePlayer target in WorldMgr.GetPlayersCloseToSpot(Position.Create(region, traparea.X, traparea.Y, traparea.Z), 350)) { if (GameServer.ServerRules.IsAllowedToAttack(owner, target, true)) { DamageTarget(target); } } - foreach (GameNPC target in WorldMgr.GetNPCsCloseToSpot(region, traparea.X, traparea.Y, traparea.Z, 350)) + foreach (GameNPC target in WorldMgr.GetNPCsCloseToSpot(Position.Create(region, traparea.X, traparea.Y, traparea.Z), 350)) { if (GameServer.ServerRules.IsAllowedToAttack(owner, target, true)) { @@ -162,7 +163,7 @@ private void DamageTarget(GameLiving target) ticktimer.Stop(); removeHandlers(); } - int dist = target.GetDistanceTo( new Point3D( traparea.X, traparea.Y, traparea.Z ) ); + var dist = (int)target.Coordinate.DistanceTo(Coordinate.Create(traparea.X, traparea.Y, traparea.Z)); double mod = 1; if (dist > 0) mod = 1 - ((double)dist / 350); diff --git a/GameServer/realmabilities/handlers/NegativeMaelstromAbility.cs b/GameServer/realmabilities/handlers/NegativeMaelstromAbility.cs index ce736344ad..9b8bcf1e76 100644 --- a/GameServer/realmabilities/handlers/NegativeMaelstromAbility.cs +++ b/GameServer/realmabilities/handlers/NegativeMaelstromAbility.cs @@ -6,6 +6,7 @@ using DOL.GS.Effects; using DOL.Events; using DOL.Database; +using DOL.GS.Geometry; namespace DOL.GS.RealmAbilities { @@ -28,7 +29,7 @@ public override void Execute(GameLiving living) return; } - if ( caster.GroundTarget == null || !caster.IsWithinRadius( caster.GroundTarget, 1500 ) ) + if ( caster.GroundTargetPosition == Position.Nowhere || caster.Coordinate.DistanceTo(caster.GroundTargetPosition) > 1500) { caster.Out.SendMessage("You groundtarget is too far away to use this ability!", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; @@ -104,7 +105,7 @@ protected virtual int EndCast(RegionTimer timer) if (!castWasSuccess) return 0; Statics.NegativeMaelstromBase nm = new Statics.NegativeMaelstromBase(dmgValue); - nm.CreateStatic(player, player.GroundTarget, duration, 5, 350); + nm.CreateStatic(player, player.GroundTargetPosition.Coordinate, duration, 5, 350); DisableSkill(player); timer.Stop(); timer = null; diff --git a/GameServer/realmabilities/handlers/PerfectRecoveryAbility.cs b/GameServer/realmabilities/handlers/PerfectRecoveryAbility.cs index ddc1d4e7ac..9bccd2b6c7 100644 --- a/GameServer/realmabilities/handlers/PerfectRecoveryAbility.cs +++ b/GameServer/realmabilities/handlers/PerfectRecoveryAbility.cs @@ -183,7 +183,7 @@ public void ResurrectLiving(GamePlayer resurrectedPlayer, GameLiving rezzer) resurrectedPlayer.Health = (int)(resurrectedPlayer.MaxHealth * m_resurrectValue / 100); resurrectedPlayer.Mana = (int)(resurrectedPlayer.MaxMana * m_resurrectValue / 100); resurrectedPlayer.Endurance = (int)(resurrectedPlayer.MaxEndurance * m_resurrectValue / 100); //no endurance after any rez - resurrectedPlayer.MoveTo(rezzer.CurrentRegionID, rezzer.X, rezzer.Y, rezzer.Z, rezzer.Heading); + resurrectedPlayer.MoveTo(rezzer.Position); GameLiving living = resurrectedPlayer as GameLiving; GameTimer resurrectExpiredTimer = null; diff --git a/GameServer/realmabilities/handlers/StaticTempestAbility.cs b/GameServer/realmabilities/handlers/StaticTempestAbility.cs index bfd4e86786..6114606548 100644 --- a/GameServer/realmabilities/handlers/StaticTempestAbility.cs +++ b/GameServer/realmabilities/handlers/StaticTempestAbility.cs @@ -78,8 +78,7 @@ public override void Execute(GameLiving living) } } Statics.StaticTempestBase st = new Statics.StaticTempestBase(m_stunDuration); - Point3D targetSpot = new Point3D(caster.TargetObject.X, caster.TargetObject.Y, caster.TargetObject.Z); - st.CreateStatic(caster, targetSpot, m_duration, 5, 360); + st.CreateStatic(caster, caster.TargetObject.Coordinate, m_duration, 5, 360); DisableSkill(living); } public override int GetReUseDelay(int level) diff --git a/GameServer/realmabilities/handlers/ThornweedFieldAbility.cs b/GameServer/realmabilities/handlers/ThornweedFieldAbility.cs index 62602a2b6b..9c8397c03d 100644 --- a/GameServer/realmabilities/handlers/ThornweedFieldAbility.cs +++ b/GameServer/realmabilities/handlers/ThornweedFieldAbility.cs @@ -6,6 +6,7 @@ using DOL.GS.Effects; using DOL.Events; using DOL.Database; +using DOL.GS.Geometry; namespace DOL.GS.RealmAbilities { @@ -30,12 +31,12 @@ public override void Execute(GameLiving living) return; } - if (caster.GroundTarget == null ) + if (caster.GroundTargetPosition == Position.Nowhere ) { caster.Out.SendMessage( "You must set a ground target to use this ability!", eChatType.CT_System, eChatLoc.CL_SystemWindow ); return; } - else if(!caster.IsWithinRadius( caster.GroundTarget, 1500 )) + else if(caster.Coordinate.DistanceTo(caster.GroundTargetPosition) > 1500) { caster.Out.SendMessage("Your ground target is too far away to use this ability!", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; @@ -102,7 +103,7 @@ protected virtual int EndCast(RegionTimer timer) if (m_player.IsMezzed || m_player.IsStunned || m_player.IsSitting) return 0; Statics.ThornweedFieldBase twf = new Statics.ThornweedFieldBase(m_dmgValue); - twf.CreateStatic(m_player, m_player.GroundTarget, m_duration, 3, 500); + twf.CreateStatic(m_player, m_player.GroundTargetPosition.Coordinate, m_duration, 3, 500); DisableSkill(m_player); timer.Stop(); timer = null; diff --git a/GameServer/realmabilities/handlers/rr5/WallOfFlameAbility.cs b/GameServer/realmabilities/handlers/rr5/WallOfFlameAbility.cs index 4836c47778..0010b09b05 100644 --- a/GameServer/realmabilities/handlers/rr5/WallOfFlameAbility.cs +++ b/GameServer/realmabilities/handlers/rr5/WallOfFlameAbility.cs @@ -47,8 +47,7 @@ public override void Execute(GameLiving living) } Statics.WallOfFlameBase wof = new Statics.WallOfFlameBase(dmgValue); - Point3D targetSpot = new Point3D(caster.X, caster.Y, caster.Z); - wof.CreateStatic(caster, targetSpot, duration, 3, 150); + wof.CreateStatic(caster, caster.Coordinate, duration, 3, 150); DisableSkill(living); caster.StopCurrentSpellcast(); diff --git a/GameServer/relics/RelicPad.cs b/GameServer/relics/RelicPad.cs index 161c4c1bdc..a1cbc40289 100644 --- a/GameServer/relics/RelicPad.cs +++ b/GameServer/relics/RelicPad.cs @@ -95,7 +95,7 @@ public class Surface : Area.Circle private RelicPad m_relicPad; public Surface(RelicPad relicPad) - : base("", relicPad.X, relicPad.Y, relicPad.Z, RelicPad.Radius) + : base("", relicPad.Coordinate.X, relicPad.Coordinate.Y, relicPad.Coordinate.Z, RelicPad.Radius) { m_relicPad = relicPad; } diff --git a/GameServer/serverrules/AbstractServerRules.cs b/GameServer/serverrules/AbstractServerRules.cs index 1fa03aa2d8..b946b58dda 100644 --- a/GameServer/serverrules/AbstractServerRules.cs +++ b/GameServer/serverrules/AbstractServerRules.cs @@ -25,6 +25,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.Housing; using DOL.GS.Keeps; using DOL.GS.PacketHandler; @@ -240,12 +241,12 @@ public virtual void OnReleased(DOLEvent e, object sender, EventArgs args) StartImmunityTimer(player, ServerProperties.Properties.TIMER_KILLED_BY_MOB * 1000);//When Killed by a Mob } - /// - /// Should be called whenever a player teleports to a new location - /// - /// - /// - /// + public virtual void OnPlayerTeleport(GamePlayer player, Teleport destination) + { + OnPlayerTeleport(player, destination); + } + + [Obsolete("Use .OnPlayerTeleport(GamePlayer,Teleport) instead!")] public virtual void OnPlayerTeleport(GamePlayer player, GameLocation source, Teleport destination) { // override this in order to do something, like set immunity, when a player teleports @@ -1279,7 +1280,7 @@ and it will also let higher level players (the 35-50s who tend to hit this clamp if (player != null) { - AbstractGameKeep keep = GameServer.KeepManager.GetKeepCloseToSpot(living.CurrentRegionID, living, 16000); + AbstractGameKeep keep = GameServer.KeepManager.GetKeepCloseToSpot(living.Position, 16000); if (keep != null) { byte bonus = 0; @@ -1465,7 +1466,7 @@ public virtual void OnLivingKilled(GameLiving killedLiving, GameObject killer) public virtual void OnPlayerKilled(GamePlayer killedPlayer, GameObject killer) { if (ServerProperties.Properties.ENABLE_WARMAPMGR && killer is GamePlayer && killer.CurrentRegion.ID == 163) - WarMapMgr.AddFight((byte)killer.CurrentZone.ID, killer.X, killer.Y, (byte)killer.Realm, (byte)killedPlayer.Realm); + WarMapMgr.AddFight((byte)killer.CurrentZone.ID, killer.Position.X, killer.Position.Y, (byte)killer.Realm, (byte)killedPlayer.Realm); killedPlayer.LastDeathRealmPoints = 0; // "player has been killed recently" @@ -1646,7 +1647,7 @@ public virtual void OnPlayerKilled(GamePlayer killedPlayer, GameObject killer) if (!BG && living is GamePlayer) { - AbstractGameKeep keep = GameServer.KeepManager.GetKeepCloseToSpot(living.CurrentRegionID, living, 16000); + AbstractGameKeep keep = GameServer.KeepManager.GetKeepCloseToSpot(living.Position, 16000); if (keep != null) { byte bonus = 0; @@ -2196,15 +2197,14 @@ public virtual void BuyHousingItem(GamePlayer player, ushort slot, byte count, D } + [Obsolete("Use .PlaceHousingNPC(House, ItemTemplate, Coordinate, ushort) instead!")] + public virtual GameNPC PlaceHousingNPC(DOL.GS.Housing.House house, ItemTemplate item, IPoint3D location, ushort heading) + => PlaceHousingNPC(house, item, location.ToCoordinate(), heading); + /// /// Get a housing hookpoint NPC /// - /// - /// - /// - /// - /// - public virtual GameNPC PlaceHousingNPC(DOL.GS.Housing.House house, ItemTemplate item, IPoint3D location, ushort heading) + public virtual GameNPC PlaceHousingNPC(DOL.GS.Housing.House house, ItemTemplate item, Coordinate coordinate, ushort heading) { NpcTemplate npcTemplate = NpcTemplateMgr.GetTemplate(item.Bonus); @@ -2274,11 +2274,7 @@ public virtual GameNPC PlaceHousingNPC(DOL.GS.Housing.House house, ItemTemplate npc.CurrentHouse = house; npc.InHouse = true; npc.OwnerID = item.Id_nb; - npc.X = location.X; - npc.Y = location.Y; - npc.Z = location.Z; - npc.Heading = heading; - npc.CurrentRegionID = house.RegionID; + npc.Position = Position.Create(house.RegionID, coordinate, heading); if (!npc.IsPeaceful) { npc.Flags ^= GameNPC.eFlags.PEACE; @@ -2294,18 +2290,17 @@ public virtual GameNPC PlaceHousingNPC(DOL.GS.Housing.House house, ItemTemplate return null; } - + [Obsolete("Use .PlaceHousingInteriorItem(House, ItemTemplate, Coordinate, ushort) instead!")] public virtual GameStaticItem PlaceHousingInteriorItem(DOL.GS.Housing.House house, ItemTemplate item, IPoint3D location, ushort heading) + => PlaceHousingInteriorItem(house, item, location.ToCoordinate(), heading); + + public virtual GameStaticItem PlaceHousingInteriorItem(DOL.GS.Housing.House house, ItemTemplate item, Coordinate coordinate, ushort heading) { GameStaticItem hookpointObject = new GameStaticItem(); hookpointObject.CurrentHouse = house; hookpointObject.InHouse = true; hookpointObject.OwnerID = item.Id_nb; - hookpointObject.X = location.X; - hookpointObject.Y = location.Y; - hookpointObject.Z = location.Z; - hookpointObject.Heading = heading; - hookpointObject.CurrentRegionID = house.RegionID; + hookpointObject.Position = Position.Create(house.RegionID, coordinate, heading); hookpointObject.Name = item.Name; hookpointObject.Model = (ushort)item.Model; hookpointObject.AddToWorld(); diff --git a/GameServer/serverrules/AdventureWingJumpPoint.cs b/GameServer/serverrules/AdventureWingJumpPoint.cs index 99a0d7b669..c1c0ecec0b 100644 --- a/GameServer/serverrules/AdventureWingJumpPoint.cs +++ b/GameServer/serverrules/AdventureWingJumpPoint.cs @@ -18,6 +18,7 @@ */ using DOL.Database; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using System.Collections; using System.Collections.Generic; @@ -46,7 +47,7 @@ public bool IsAllowedToJump(ZonePoint targetPoint, GamePlayer player) { //Handles zoning INTO an instance. - GameLocation loc = null; + Position position = Position.Nowhere; AdventureWingInstance previousInstance = null; // Do we have a group ? @@ -113,26 +114,22 @@ public bool IsAllowedToJump(ZonePoint targetPoint, GamePlayer player) if(previousInstance == null) { - // I have no instance to go to, create one ! - previousInstance = (AdventureWingInstance)WorldMgr.CreateInstance(targetPoint.TargetRegion, typeof(AdventureWingInstance)); - if(targetPoint.SourceRegion != 0 && targetPoint.SourceRegion == player.CurrentRegionID) { - //source loc seems legit... - previousInstance.SourceEntrance = new GameLocation("source", targetPoint.SourceRegion, targetPoint.SourceX, targetPoint.SourceY, targetPoint.SourceZ); - } - - if(player.Group != null) - { - previousInstance.Group = player.Group; - previousInstance.Player = player.Group.Leader; - } - else - { - previousInstance.Group = null; - previousInstance.Player = player; - } - - //get region data - long mobs = 0; + // I have no instance to go to, create one ! + previousInstance = (AdventureWingInstance)WorldMgr.CreateInstance(targetPoint.TargetRegion, typeof(AdventureWingInstance)); + + if (player.Group != null) + { + previousInstance.Group = player.Group; + previousInstance.Player = player.Group.Leader; + } + else + { + previousInstance.Group = null; + previousInstance.Player = player; + } + + //get region data + long mobs = 0; long merchants = 0; long items = 0; long bindpoints = 0; @@ -193,15 +190,15 @@ public bool IsAllowedToJump(ZonePoint targetPoint, GamePlayer player) //get loc of instance if(previousInstance != null) { - loc = new GameLocation(previousInstance.Description + " (instance)", previousInstance.ID, targetPoint.TargetX, targetPoint.TargetY, targetPoint.TargetZ, targetPoint.TargetHeading); + position = targetPoint.GetTargetPosition().With(regionID: previousInstance.ID); } - if (loc != null) + if (position != Position.Nowhere) { // Move Player, changing target destination is failing !! - player.MoveTo(loc); + player.MoveTo(position); return false; } diff --git a/GameServer/serverrules/IServerRules.cs b/GameServer/serverrules/IServerRules.cs index 419de16231..99c9df6850 100644 --- a/GameServer/serverrules/IServerRules.cs +++ b/GameServer/serverrules/IServerRules.cs @@ -22,6 +22,7 @@ using DOL.Database; using DOL.GS.Styles; using DOL.GS.Keeps; +using DOL.GS.Geometry; namespace DOL.GS.ServerRules { @@ -252,12 +253,9 @@ public interface IServerRules /// void OnLivingKilled(GameLiving living, GameObject killer); - /// - /// Invoked when a player teleports somewhere - /// - /// - /// - /// + void OnPlayerTeleport(GamePlayer player, Teleport destination); + + [Obsolete("Use .OnPlayerTeleport(GamePlayer,Teleport) instead!")] void OnPlayerTeleport(GamePlayer player, GameLocation source, Teleport destination); /// @@ -443,23 +441,16 @@ public interface IServerRules /// /// Get a housing hookpoint NPC /// - /// - /// - /// - /// - /// + [Obsolete("Use .PlayerHousingNPC(House,ItemTemplate,Coordinate,ushort) instead!")] GameNPC PlaceHousingNPC(DOL.GS.Housing.House house, ItemTemplate item, IPoint3D location, ushort heading); - /// - /// Get a static interior object for a house hookpoint - /// - /// - /// - /// - /// - /// + GameNPC PlaceHousingNPC(DOL.GS.Housing.House house, ItemTemplate item, Coordinate coordinate, ushort heading); + + [Obsolete("Use .PlaceHousingInteriorItem(House,ItemTemplate,Coordinate,ushort) instead!")] GameStaticItem PlaceHousingInteriorItem(DOL.GS.Housing.House house, ItemTemplate item, IPoint3D location, ushort heading); + GameStaticItem PlaceHousingInteriorItem(DOL.GS.Housing.House house, ItemTemplate item, Coordinate coordinate, ushort heading); + /// /// Create a new consignment merchant for housing /// diff --git a/GameServer/serverrules/PvPServerRules.cs b/GameServer/serverrules/PvPServerRules.cs index aca7e9ef60..1592d6603c 100644 --- a/GameServer/serverrules/PvPServerRules.cs +++ b/GameServer/serverrules/PvPServerRules.cs @@ -101,13 +101,7 @@ public override void OnReleased(DOLEvent e, object sender, EventArgs args) } } - - /// - /// Should be called whenever a player teleports to a new location - /// - /// - /// - /// + [Obsolete("Use .OnPlayerTeleport(GamePlayer,Teleport) instead!")] public override void OnPlayerTeleport(GamePlayer player, GameLocation source, Teleport destination) { // Since region change already starts an immunity timer we only want to do this if a player @@ -134,7 +128,7 @@ public override void OnPlayerTeleport(GamePlayer player, GameLocation source, Te //No PVP Dungeons: http://support.darkageofcamelot.com/cgi-bin/support.cfg/php/enduser/std_adp.php?p_sid=frxnPUjg&p_lva=&p_refno=020709-000000&p_created=1026248996&p_sp=cF9ncmlkc29ydD0mcF9yb3dfY250PTE0JnBfc2VhcmNoX3RleHQ9JnBfc2VhcmNoX3R5cGU9MyZwX2NhdF9sdmwxPTI2JnBfY2F0X2x2bDI9fmFueX4mcF9zb3J0X2J5PWRmbHQmcF9wYWdlPTE*&p_li 21, //Tomb of Mithra - 129, //Nisse’s Lair (Nisee's Lair in regions.ini) + 129, //Nisse's Lair (Nisse's Lair in regions.ini) 221, //Muire Tomb (Undead in regions.ini) }; diff --git a/GameServer/serverrules/TaskDungeonJumpPoint.cs b/GameServer/serverrules/TaskDungeonJumpPoint.cs index f8744a7baf..f0a1910e35 100644 --- a/GameServer/serverrules/TaskDungeonJumpPoint.cs +++ b/GameServer/serverrules/TaskDungeonJumpPoint.cs @@ -18,6 +18,7 @@ */ using DOL.Database; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using DOL.GS.Quests; @@ -39,7 +40,7 @@ public class TaskDungeonJumpPoint : IJumpPointHandler public bool IsAllowedToJump(ZonePoint targetPoint, GamePlayer player) { //Handles zoning INTO an instance. - GameLocation loc = null; + var loc = Position.Nowhere; //First, we try the groups mission. if (player.Group != null) @@ -49,23 +50,23 @@ public bool IsAllowedToJump(ZonePoint targetPoint, GamePlayer player) { //Attempt to get the instance entrance location... TaskDungeonMission task = (TaskDungeonMission)grp.Mission; - loc = task.TaskRegion.InstanceEntranceLocation; + loc = task.TaskRegion.EntrancePosition; } } else if (player.Mission != null && player.Mission is TaskDungeonMission) { //Then, try personal missions... TaskDungeonMission task = (TaskDungeonMission)player.Mission; - loc = task.TaskRegion.InstanceEntranceLocation; + loc = task.TaskRegion.EntrancePosition; } - if (loc != null) + if (loc != Position.Nowhere) { targetPoint.TargetX = loc.X; targetPoint.TargetY = loc.Y; targetPoint.TargetZ = loc.Z; targetPoint.TargetRegion = loc.RegionID; - targetPoint.TargetHeading = loc.Heading; + targetPoint.TargetHeading = loc.Orientation.InHeading; return true; } diff --git a/GameServer/spells/Animist/SummonAnimistFnF.cs b/GameServer/spells/Animist/SummonAnimistFnF.cs index 8aa83a9092..d055314d47 100644 --- a/GameServer/spells/Animist/SummonAnimistFnF.cs +++ b/GameServer/spells/Animist/SummonAnimistFnF.cs @@ -37,14 +37,14 @@ public override bool CheckBeginCast(GameLiving selectedTarget) Region rgn = WorldMgr.GetRegion(Caster.CurrentRegion.ID); - if (rgn == null || rgn.GetZone(Caster.GroundTarget.X, Caster.GroundTarget.Y) == null) + if (rgn == null || rgn.GetZone(Caster.GroundTargetPosition.Coordinate) == null) { if (Caster is GamePlayer) MessageToCaster(LanguageMgr.GetTranslation((Caster as GamePlayer).Client, "SummonAnimistFnF.CheckBeginCast.NoGroundTarget"), eChatType.CT_SpellResisted); return false; } - foreach (GameNPC npc in Caster.CurrentRegion.GetNPCsInRadius(Caster.GroundTarget.X, Caster.GroundTarget.Y, Caster.GroundTarget.Z, (ushort)Properties.TURRET_AREA_CAP_RADIUS, false, true)) + foreach (GameNPC npc in Caster.CurrentRegion.GetNPCsInRadius(Caster.GroundTargetPosition.Coordinate, (ushort)Properties.TURRET_AREA_CAP_RADIUS, false, true)) if (npc.Brain is TurretFNFBrain) nCount++; diff --git a/GameServer/spells/Animist/SummonAnimistPet.cs b/GameServer/spells/Animist/SummonAnimistPet.cs index f02ebf6ac5..64646ecd8d 100644 --- a/GameServer/spells/Animist/SummonAnimistPet.cs +++ b/GameServer/spells/Animist/SummonAnimistPet.cs @@ -17,6 +17,7 @@ * */ using DOL.AI.Brain; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using DOL.Language; @@ -29,7 +30,7 @@ protected SummonAnimistPet(GameLiving caster, Spell spell, SpellLine line) public override bool CheckBeginCast(GameLiving selectedTarget) { - if (Caster.GroundTarget == null) + if (Caster.GroundTargetPosition == Position.Nowhere) { if (Caster is GamePlayer) MessageToCaster(LanguageMgr.GetTranslation((Caster as GamePlayer).Client, "SummonAnimistPet.CheckBeginCast.GroundTargetNull"), eChatType.CT_SpellResisted); @@ -43,7 +44,7 @@ public override bool CheckBeginCast(GameLiving selectedTarget) return false; } - if (!Caster.IsWithinRadius(Caster.GroundTarget, CalculateSpellRange())) + if (Caster.Coordinate.DistanceTo(Caster.GroundTargetPosition) > CalculateSpellRange()) { if (Caster is GamePlayer) MessageToCaster(LanguageMgr.GetTranslation((Caster as GamePlayer).Client, "SummonAnimistPet.CheckBeginCast.GroundTargetNotInSpellRange"), eChatType.CT_SpellResisted); @@ -54,7 +55,7 @@ public override bool CheckBeginCast(GameLiving selectedTarget) } public override void FinishSpellCast(GameLiving target) { - if (Caster.GroundTarget == null) + if (Caster.GroundTargetPosition == Position.Nowhere) { if (Caster is GamePlayer) MessageToCaster(LanguageMgr.GetTranslation((Caster as GamePlayer).Client, "SummonAnimistPet.CheckBeginCast.GroundTargetNull"), eChatType.CT_SpellResisted); @@ -75,7 +76,7 @@ public override void FinishSpellCast(GameLiving target) return; } - if (!Caster.IsWithinRadius(Caster.GroundTarget, CalculateSpellRange())) + if (Caster.Coordinate.DistanceTo(Caster.GroundTargetPosition) > CalculateSpellRange()) { if (Caster is GamePlayer) MessageToCaster(LanguageMgr.GetTranslation((Caster as GamePlayer).Client, "SummonAnimistPet.CheckBeginCast.GroundTargetNotInSpellRange"), eChatType.CT_SpellResisted); @@ -111,14 +112,8 @@ protected override IControlledBrain GetPetBrain(GameLiving owner) return new TurretBrain(owner); } - protected override void GetPetLocation(out int x, out int y, out int z, out ushort heading, out Region region) - { - x = Caster.GroundTarget.X; - y = Caster.GroundTarget.Y; - z = Caster.GroundTarget.Z; - heading = Caster.Heading; - region = Caster.CurrentRegion; - } + protected override Position GetSummonPosition() + => Caster.GroundTargetPosition; public override void CastSubSpells(GameLiving target) { } } diff --git a/GameServer/spells/Animist/TurretSpellHandler.cs b/GameServer/spells/Animist/TurretSpellHandler.cs index c2ac4c38c8..3a13276ee3 100644 --- a/GameServer/spells/Animist/TurretSpellHandler.cs +++ b/GameServer/spells/Animist/TurretSpellHandler.cs @@ -74,7 +74,7 @@ public override void ApplyEffectOnTarget(GameLiving target, double effectiveness { if (target != null && target.CurrentRegion != null) { - foreach (GameNPC npc in target.CurrentRegion.GetNPCsInRadius(target.X, target.Y, target.Z, (ushort)Spell.Radius, false, true)) + foreach (GameNPC npc in target.CurrentRegion.GetNPCsInRadius(target.Coordinate, (ushort)Spell.Radius, false, true)) { if (npc == null || !npc.IsAlive) { diff --git a/GameServer/spells/Archery/Archery.cs b/GameServer/spells/Archery/Archery.cs index a9154fc7e5..b3d5a79da5 100644 --- a/GameServer/spells/Archery/Archery.cs +++ b/GameServer/spells/Archery/Archery.cs @@ -22,6 +22,7 @@ using DOL.GS.Effects; using DOL.Events; using DOL.AI.Brain; +using DOL.GS.Geometry; namespace DOL.GS.Spells { @@ -107,7 +108,7 @@ public override bool CheckBeginCast(GameLiving selectedTarget) String targetType = m_spell.Target.ToLower(); if (targetType == "area") { - if (!m_caster.IsWithinRadius(m_caster.GroundTarget, CalculateSpellRange())) + if (m_caster.Coordinate.DistanceTo(m_caster.GroundTargetPosition) > CalculateSpellRange()) { MessageToCaster("Your area target is out of range. Select a closer target.", eChatType.CT_SpellResisted); return false; @@ -308,7 +309,7 @@ public override void FinishSpellCast(GameLiving target) Caster.LastAttackTickPvE = Caster.CurrentRegion.Time; Caster.LastAttackTickPvP = Caster.CurrentRegion.Time; - foreach (GameLiving npc in WorldMgr.GetNPCsCloseToSpot(Caster.CurrentRegionID, Caster.GroundTarget.X, Caster.GroundTarget.Y, Caster.GroundTarget.Z, (ushort)Spell.Radius)) + foreach (GameLiving npc in WorldMgr.GetNPCsCloseToSpot(Caster.GroundTargetPosition, (ushort)Spell.Radius)) { if (npc.Realm == 0 || Caster.Realm == 0) { diff --git a/GameServer/spells/Artifacts/bracerofzo.cs b/GameServer/spells/Artifacts/bracerofzo.cs index c4bbdb65d9..b52af3ffb8 100644 --- a/GameServer/spells/Artifacts/bracerofzo.cs +++ b/GameServer/spells/Artifacts/bracerofzo.cs @@ -21,6 +21,7 @@ using DOL.GS.PacketHandler; using DOL.GS.Effects; using DOL.AI.Brain; +using DOL.GS.Geometry; namespace DOL.GS.Spells { @@ -52,17 +53,13 @@ public override void OnEffectStart(GameSpellEffect effect) return; } - Point2D spawnPoint = Caster.GetPointFromHeading( Caster.Heading, 64 ); + var spawnPoint = Caster.Position.TurnedAround() + Vector.Create(Caster.Orientation, length: 64); int i = 0; for(i=0;i<3;i++) { deamons[i] = new ZoarkatPet(template); deamons[i].SetOwnBrain(new ProcPetBrain(player)); - deamons[i].X = spawnPoint.X + Util.Random(20,40) - Util.Random(20,40); - deamons[i].Y = spawnPoint.Y + Util.Random(20,40) - Util.Random(20,40); - deamons[i].Z = Caster.Z; - deamons[i].CurrentRegion = Caster.CurrentRegion; - deamons[i].Heading = (ushort)((Caster.Heading + 2048) % 4096); + deamons[i].Position = spawnPoint + Vector.Create(x: Util.Random(-20,20), y: Util.Random(-20,20)); deamons[i].Realm = Caster.Realm; deamons[i].CurrentSpeed = 0; deamons[i].Level = 36; diff --git a/GameServer/spells/AstralPetSummon.cs b/GameServer/spells/AstralPetSummon.cs index f652c3c3ab..9f397962fa 100644 --- a/GameServer/spells/AstralPetSummon.cs +++ b/GameServer/spells/AstralPetSummon.cs @@ -28,6 +28,7 @@ using DOL.Language; using DOL.Database; using DOL.GS.Styles; +using DOL.GS.Geometry; namespace DOL.GS.Spells { @@ -75,11 +76,8 @@ protected override void OnNpcReleaseCommand(DOLEvent e, object sender, EventArgs effect.Cancel(false); } - protected override void GetPetLocation(out int x, out int y, out int z, out ushort heading, out Region region) - { - base.GetPetLocation(out x, out y, out z, out heading, out region); - heading = Caster.Heading; - } + protected override Position GetSummonPosition() + => Caster.Position + Vector.Create(Caster.Orientation, length: 64); public AstralPetSummon(GameLiving caster, Spell spell, SpellLine line) : base(caster, spell, line) { } diff --git a/GameServer/spells/CommonAstralSpells.cs b/GameServer/spells/CommonAstralSpells.cs index 95f68234cf..d61de6339e 100644 --- a/GameServer/spells/CommonAstralSpells.cs +++ b/GameServer/spells/CommonAstralSpells.cs @@ -26,6 +26,7 @@ using DOL.Events; using DOL.GS; using DOL.GS.Effects; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using DOL.GS.Spells; using DOL.Language; @@ -121,20 +122,14 @@ public override void ApplyEffectOnTarget(GameLiving target, double effectiveness return; } - Point2D summonloc; + var summonPosition = target.Position.TurnedAround() + Vector.Create(target.Orientation, length: 64); beffect = CreateSpellEffect(target, effectiveness); { - summonloc = target.GetPointFromHeading(target.Heading, 64); - BrittleBrain controlledBrain = new BrittleBrain(player); controlledBrain.IsMainPet = false; summoned = new GameNPC(template); summoned.SetOwnBrain(controlledBrain); - summoned.X = summonloc.X; - summoned.Y = summonloc.Y; - summoned.Z = target.Z; - summoned.CurrentRegion = target.CurrentRegion; - summoned.Heading = (ushort)((target.Heading + 2048) % 4096); + summoned.Position = summonPosition; summoned.Realm = target.Realm; summoned.CurrentSpeed = 0; summoned.Level = Caster.Level; diff --git a/GameServer/spells/Masterlevel/Convoker.cs b/GameServer/spells/Masterlevel/Convoker.cs index a499d58b84..b02c740d8d 100644 --- a/GameServer/spells/Masterlevel/Convoker.cs +++ b/GameServer/spells/Masterlevel/Convoker.cs @@ -10,6 +10,7 @@ using log4net; using DOL.Database; using DOL.GS.RealmAbilities; +using DOL.GS.Geometry; namespace DOL.GS.Spells { @@ -59,11 +60,7 @@ public PrescienceNodeSpellHandler(GameLiving caster, Spell spell, SpellLine line font.Model = 2584; font.Name = spell.Name; font.Realm = caster.Realm; - font.X = caster.X; - font.Y = caster.Y; - font.Z = caster.Z; - font.CurrentRegionID = caster.CurrentRegionID; - font.Heading = caster.Heading; + font.Position = caster.Position; font.Owner = (GamePlayer)caster; // Construct the font spell @@ -137,11 +134,7 @@ public PowerTrapSpellHandler(GameLiving caster, Spell spell, SpellLine line) mine.Model = 2590; mine.Name = spell.Name; mine.Realm = caster.Realm; - mine.X = caster.X; - mine.Y = caster.Y; - mine.Z = caster.Z; - mine.CurrentRegionID = caster.CurrentRegionID; - mine.Heading = caster.Heading; + mine.Position = caster.Position; mine.Owner = (GamePlayer)caster; // Construct the mine spell @@ -191,11 +184,7 @@ public SpeedWrapWardSpellHandler(GameLiving caster, Spell spell, SpellLine line) font.Model = 2586; font.Name = spell.Name; font.Realm = caster.Realm; - font.X = caster.X; - font.Y = caster.Y; - font.Z = caster.Z; - font.CurrentRegionID = caster.CurrentRegionID; - font.Heading = caster.Heading; + font.Position = caster.Position; font.Owner = (GamePlayer)caster; // Construct the mine spell @@ -318,15 +307,13 @@ public override void OnEffectStart(GameSpellEffect effect) if ((effect.Owner is GamePlayer)) { GamePlayer casterPlayer = effect.Owner as GamePlayer; - if (casterPlayer.GroundTarget != null && casterPlayer.GroundTargetInView) + if (casterPlayer.GroundTargetPosition != Position.Nowhere && casterPlayer.GroundTargetInView) { GameEventMgr.AddHandler(casterPlayer, GamePlayerEvent.Moving, new DOLEventHandler(PlayerMoves)); GameEventMgr.AddHandler(warder, GameLivingEvent.Dying, new DOLEventHandler(BattleWarderDie)); GameEventMgr.AddHandler(casterPlayer, GamePlayerEvent.CastStarting, new DOLEventHandler(PlayerMoves)); GameEventMgr.AddHandler(casterPlayer, GamePlayerEvent.AttackFinished, new DOLEventHandler(PlayerMoves)); - warder.X = casterPlayer.GroundTarget.X; - warder.Y = casterPlayer.GroundTarget.Y; - warder.Z = casterPlayer.GroundTarget.Z; + warder.Position = casterPlayer.GroundTargetPosition; warder.AddBrain(new MLBrain()); warder.AddToWorld(); } @@ -385,7 +372,7 @@ private void BattleWarderDie(DOLEvent e, object sender, EventArgs args) public override bool CheckBeginCast(GameLiving selectedTarget) { if (!base.CheckBeginCast(selectedTarget)) return false; - if (!(m_caster.GroundTarget != null && m_caster.GroundTargetInView)) + if (!(m_caster.GroundTargetPosition != Position.Nowhere && m_caster.GroundTargetInView)) { MessageToCaster("Your area target is out of range. Set a closer ground position.", eChatType.CT_SpellResisted); return false; @@ -399,7 +386,7 @@ public BattlewarderSpellHandler(GameLiving caster, Spell spell, SpellLine line) warder = new GameNPC(); //Fill the object variables warder.CurrentRegion = caster.CurrentRegion; - warder.Heading = (ushort)((caster.Heading + 2048) % 4096); + warder.Orientation = caster.Orientation + Angle.Degrees(180); warder.Level = 70; warder.Realm = caster.Realm; warder.Name = "Battle Warder"; @@ -429,11 +416,7 @@ public DissonanceTrapSpellHandler(GameLiving caster, Spell spell, SpellLine line mine.Model = 2588; mine.Name = spell.Name; mine.Realm = caster.Realm; - mine.X = caster.X; - mine.Y = caster.Y; - mine.Z = caster.Z; - mine.CurrentRegionID = caster.CurrentRegionID; - mine.Heading = caster.Heading; + mine.Position = caster.Position; mine.Owner = (GamePlayer)caster; // Construct the mine spell @@ -512,20 +495,13 @@ public override void ApplyEffectOnTarget(GameLiving target, double effectiveness return; } - Point2D summonloc; beffect = CreateSpellEffect(target, effectiveness); { - summonloc = target.GetPointFromHeading( target.Heading, 64 ); - BrittleBrain controlledBrain = new BrittleBrain(player); controlledBrain.IsMainPet = false; summoned = new GameNPC(template); summoned.SetOwnBrain(controlledBrain); - summoned.X = summonloc.X; - summoned.Y = summonloc.Y; - summoned.Z = target.Z; - summoned.CurrentRegion = target.CurrentRegion; - summoned.Heading = (ushort)((target.Heading + 2048) % 4096); + summoned.Position = summoned.Position.TurnedAround() + Vector.Create(target.Orientation, length: 64); summoned.Realm = target.Realm; summoned.CurrentSpeed = 0; summoned.Level = 1; @@ -640,7 +616,7 @@ public class Convoker10SpellHandler : MasterlevelHandling { private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); - private int x, y, z; + private Position position = Position.Nowhere; GameNPC summoned = null; RegionTimer m_growTimer; private const int C_GROWTIMER = 2000; @@ -649,7 +625,7 @@ public Convoker10SpellHandler(GameLiving caster, Spell spell, SpellLine line) : public override bool CheckBeginCast(GameLiving selectedTarget) { - if(!CheckCastLocation()) + if(!CheckCastCoordinate()) return false; return base.CheckBeginCast(selectedTarget); } @@ -692,13 +668,9 @@ public override void ApplyEffectOnTarget(GameLiving target, double effectiveness summoned.SetOwnBrain(controlledBrain); //Suncheck: // Is needed, else it can cause error (i.e. /cast-command) - if (x == 0 || y == 0) - CheckCastLocation(); - summoned.X = x; - summoned.Y = y; - summoned.Z = z; - summoned.CurrentRegion = player.CurrentRegion; - summoned.Heading = (ushort)((player.Heading + 2048) % 4096); + if (position == Position.Nowhere) CheckCastCoordinate(); + + summoned.Position = position.With(orientation: Caster.Orientation + Angle.Degrees(180)); summoned.Realm = player.Realm; summoned.CurrentSpeed = 0; summoned.Size = 10; @@ -727,22 +699,18 @@ private int TitanGrows(RegionTimer timer) return 0; } - private bool CheckCastLocation() + private bool CheckCastCoordinate() { - x = Caster.X; - y = Caster.Y; - z = Caster.Z; + position = Caster.Position; if (Spell.Target.ToLower() == "area") { - if (Caster.GroundTargetInView && Caster.GroundTarget != null) + if (Caster.GroundTargetInView && Caster.GroundTargetPosition != Position.Nowhere) { - x = Caster.GroundTarget.X; - y = Caster.GroundTarget.Y; - z = Caster.GroundTarget.Z; + position = Caster.GroundTargetPosition; } else { - if (Caster.GroundTarget == null) + if (Caster.GroundTargetPosition == Position.Nowhere) { MessageToCaster("You must set a groundtarget!", eChatType.CT_SpellResisted); return false; diff --git a/GameServer/spells/Masterlevel/MasterLevelBase.cs b/GameServer/spells/Masterlevel/MasterLevelBase.cs index c85bbb7e5e..a370d62247 100644 --- a/GameServer/spells/Masterlevel/MasterLevelBase.cs +++ b/GameServer/spells/Masterlevel/MasterLevelBase.cs @@ -24,6 +24,7 @@ using DOL.GS.PacketHandler; using DOL.AI.Brain; using DOL.Database; +using DOL.GS.Geometry; namespace DOL.GS.Spells { @@ -76,7 +77,7 @@ public override IList SelectTargets(GameObject castTarget) case "area": if (Spell.Radius > 0) { - foreach (GamePlayer player in WorldMgr.GetPlayersCloseToSpot(Caster.CurrentRegionID, Caster.GroundTarget.X, Caster.GroundTarget.Y, Caster.GroundTarget.Z, (ushort)Spell.Radius)) + foreach (GamePlayer player in WorldMgr.GetPlayersCloseToSpot(Caster.GroundTargetPosition, (ushort)Spell.Radius)) { if (GameServer.ServerRules.IsAllowedToAttack(Caster, player, true)) { @@ -271,14 +272,14 @@ public override IList SelectTargets(GameObject castTarget) case "area": if (Spell.Radius > 0) { - foreach (GamePlayer player in WorldMgr.GetPlayersCloseToSpot(Caster.CurrentRegionID, Caster.GroundTarget.X, Caster.GroundTarget.Y, Caster.GroundTarget.Z, (ushort)Spell.Radius)) + foreach (GamePlayer player in WorldMgr.GetPlayersCloseToSpot(Caster.GroundTargetPosition, (ushort)Spell.Radius)) { if (GameServer.ServerRules.IsAllowedToAttack(Caster, player, true)) { list.Add(player); } } - foreach (GameNPC npc in WorldMgr.GetNPCsCloseToSpot(Caster.CurrentRegionID, Caster.GroundTarget.X, Caster.GroundTarget.Y, Caster.GroundTarget.Z, (ushort)Spell.Radius)) + foreach (GameNPC npc in WorldMgr.GetNPCsCloseToSpot(Caster.GroundTargetPosition, (ushort)Spell.Radius)) { if (GameServer.ServerRules.IsAllowedToAttack(Caster, npc, true)) { @@ -460,14 +461,14 @@ public override IList SelectTargets(GameObject castTarget) case "area": if (Spell.Radius > 0) { - foreach (GamePlayer player in WorldMgr.GetPlayersCloseToSpot(Caster.CurrentRegionID, Caster.GroundTarget.X, Caster.GroundTarget.Y, Caster.GroundTarget.Z, (ushort)Spell.Radius)) + foreach (GamePlayer player in WorldMgr.GetPlayersCloseToSpot(Caster.GroundTargetPosition, (ushort)Spell.Radius)) { if (GameServer.ServerRules.IsAllowedToAttack(Caster, player, true)) { list.Add(player); } } - foreach (GameNPC npc in WorldMgr.GetNPCsCloseToSpot(Caster.CurrentRegionID, Caster.GroundTarget.X, Caster.GroundTarget.Y, Caster.GroundTarget.Z, (ushort)Spell.Radius)) + foreach (GameNPC npc in WorldMgr.GetNPCsCloseToSpot(Caster.GroundTargetPosition, (ushort)Spell.Radius)) { if (GameServer.ServerRules.IsAllowedToAttack(Caster, npc, true)) { @@ -649,14 +650,14 @@ public override IList SelectTargets(GameObject castTarget) case "area": if (Spell.Radius > 0) { - foreach (GamePlayer player in WorldMgr.GetPlayersCloseToSpot(Caster.CurrentRegionID, Caster.GroundTarget.X, Caster.GroundTarget.Y, Caster.GroundTarget.Z, (ushort)Spell.Radius)) + foreach (GamePlayer player in WorldMgr.GetPlayersCloseToSpot(Caster.GroundTargetPosition, (ushort)Spell.Radius)) { if (GameServer.ServerRules.IsAllowedToAttack(Caster, player, true)) { list.Add(player); } } - foreach (GameNPC npc in WorldMgr.GetNPCsCloseToSpot(Caster.CurrentRegionID, Caster.GroundTarget.X, Caster.GroundTarget.Y, Caster.GroundTarget.Z, (ushort)Spell.Radius)) + foreach (GameNPC npc in WorldMgr.GetNPCsCloseToSpot(Caster.GroundTargetPosition, (ushort)Spell.Radius)) { if (GameServer.ServerRules.IsAllowedToAttack(Caster, npc, true)) { @@ -859,14 +860,14 @@ public override IList SelectTargets(GameObject castTarget) case "area": if (Spell.Radius > 0) { - foreach (GamePlayer player in WorldMgr.GetPlayersCloseToSpot(Caster.CurrentRegionID, Caster.GroundTarget.X, Caster.GroundTarget.Y, Caster.GroundTarget.Z, (ushort)Spell.Radius)) + foreach (GamePlayer player in WorldMgr.GetPlayersCloseToSpot(Caster.GroundTargetPosition, (ushort)Spell.Radius)) { if (GameServer.ServerRules.IsAllowedToAttack(Caster, player, true)) { list.Add(player); } } - foreach (GameNPC npc in WorldMgr.GetNPCsCloseToSpot(Caster.CurrentRegionID, Caster.GroundTarget.X, Caster.GroundTarget.Y, Caster.GroundTarget.Z, (ushort)Spell.Radius)) + foreach (GameNPC npc in WorldMgr.GetNPCsCloseToSpot(Caster.GroundTargetPosition, (ushort)Spell.Radius)) { if (GameServer.ServerRules.IsAllowedToAttack(Caster, npc, true)) { @@ -1170,7 +1171,7 @@ public override void OnEffectPulse(GameSpellEffect effect) { return; } - int ranged = storm.GetDistanceTo(new Point3D((int)effect.Owner.X, (int)effect.Owner.Y, (int)effect.Owner.Z)); + var ranged = (int)storm.Coordinate.DistanceTo(effect.Owner.Coordinate); if (ranged > 3000) return; if (s.Name == "Dazzling Array") diff --git a/GameServer/spells/Masterlevel/Perfecter.cs b/GameServer/spells/Masterlevel/Perfecter.cs index 01bde42741..6d0177f2cc 100644 --- a/GameServer/spells/Masterlevel/Perfecter.cs +++ b/GameServer/spells/Masterlevel/Perfecter.cs @@ -49,11 +49,7 @@ public FOHSpellHandler(GameLiving caster, Spell spell, SpellLine line) font.Model = 2585; font.Name = spell.Name; font.Realm = caster.Realm; - font.X = caster.X; - font.Y = caster.Y; - font.Z = caster.Z; - font.CurrentRegionID = caster.CurrentRegionID; - font.Heading = caster.Heading; + font.Position = caster.Position; font.Owner = (GamePlayer)caster; // Construct the font spell @@ -105,11 +101,7 @@ public FOPSpellHandler(GameLiving caster, Spell spell, SpellLine line) font.Model = 2583; font.Name = spell.Name; font.Realm = caster.Realm; - font.X = caster.X; - font.Y = caster.Y; - font.Z = caster.Z; - font.CurrentRegionID = caster.CurrentRegionID; - font.Heading = caster.Heading; + font.Position = caster.Position; font.Owner = (GamePlayer)caster; // Construct the font spell @@ -160,11 +152,7 @@ public FORSpellHandler(GameLiving caster, Spell spell, SpellLine line) font.Model = 2581; font.Name = spell.Name; font.Realm = caster.Realm; - font.X = caster.X; - font.Y = caster.Y; - font.Z = caster.Z; - font.CurrentRegionID = caster.CurrentRegionID; - font.Heading = caster.Heading; + font.Position = caster.Position; font.Owner = (GamePlayer)caster; // Construct the font spell @@ -232,11 +220,7 @@ public FODSpellHandler(GameLiving caster, Spell spell, SpellLine line) font.Model = 2582; font.Name = spell.Name; font.Realm = caster.Realm; - font.X = caster.X; - font.Y = caster.Y; - font.Z = caster.Z; - font.CurrentRegionID = caster.CurrentRegionID; - font.Heading = caster.Heading; + font.Position = caster.Position; font.Owner = (GamePlayer)caster; // Construct the font spell diff --git a/GameServer/spells/Masterlevel/Sojourner.cs b/GameServer/spells/Masterlevel/Sojourner.cs index 6923b5a094..7dd9be9721 100644 --- a/GameServer/spells/Masterlevel/Sojourner.cs +++ b/GameServer/spells/Masterlevel/Sojourner.cs @@ -9,6 +9,7 @@ using DOL.Events; using System.Collections.Specialized; using DOL.GS.Profession; +using DOL.GS.Geometry; namespace DOL.GS.Spells { @@ -100,11 +101,8 @@ public AncientTransmuterSpellHandler(GameLiving caster, Spell spell, SpellLine l GamePlayer casterPlayer = caster as GamePlayer; merchant = new GameMerchant(); //Fill the object variables - merchant.X = casterPlayer.X + Util.Random(20, 40) - Util.Random(20, 40); - merchant.Y = casterPlayer.Y + Util.Random(20, 40) - Util.Random(20, 40); - merchant.Z = casterPlayer.Z; - merchant.CurrentRegion = casterPlayer.CurrentRegion; - merchant.Heading = (ushort)((casterPlayer.Heading + 2048) % 4096); + merchant.Position = casterPlayer.Position.TurnedAround() + + Vector.Create(Util.Random(-20, 20), Util.Random(-20, 20)); merchant.Level = 1; merchant.Realm = casterPlayer.Realm; merchant.Name = "Ancient Transmuter"; @@ -177,7 +175,7 @@ public class FZSpellHandler : MasterlevelHandling protected RegionTimer m_expireTimer; protected GameNPC m_npc; protected GamePlayer m_target; - protected IPoint3D m_loc; + protected Coordinate m_loc; public override void OnDirectEffect(GameLiving target, double effectiveness) { @@ -214,15 +212,11 @@ private void Zephyr(GamePlayer target) m_npc = npc; npc.Realm = Caster.Realm; - npc.Heading = Caster.Heading; + npc.Position = Caster.Position; npc.Model = 1269; - npc.Y = Caster.Y; - npc.X = Caster.X; - npc.Z = Caster.Z; npc.Name = "Forceful Zephyr"; npc.MaxSpeedBase = 400; npc.Level = 55; - npc.CurrentRegion = Caster.CurrentRegion; npc.Flags |= GameNPC.eFlags.PEACE; npc.Flags |= GameNPC.eFlags.DONTSHOWNAME; npc.Flags |= GameNPC.eFlags.CANTTARGET; @@ -318,22 +312,13 @@ private void ArriveAtTarget(DOLEvent e, object obj, EventArgs args) if (Caster is GamePlayer) { //Calculate random target - m_loc = GetTargetLoc(); + m_loc = m_npc.Coordinate + Vector.Create(x: Util.Random(-1500, 1500), y: Util.Random(-1500, 1500));; (Caster as GamePlayer).Out.SendCheckLOS((Caster as GamePlayer), m_npc, new CheckLOSResponse(ZephyrCheckLOS)); } } public void ZephyrCheckLOS(GamePlayer player, ushort response, ushort targetOID) { - if ((response & 0x100) == 0x100) - m_npc.WalkTo(m_loc, 100); - } - - public virtual IPoint3D GetTargetLoc() - { - double targetX = m_npc.X + Util.Random(-1500, 1500); - double targetY = m_npc.Y + Util.Random(-1500, 1500); - - return new Point3D((int)targetX, (int)targetY, m_npc.Z); + if ((response & 0x100) == 0x100) m_npc.WalkTo(m_loc, 100); } public override int CalculateSpellResistChance(GameLiving target) @@ -430,7 +415,7 @@ public Groupport(GameLiving caster, Spell spell, SpellLine line) : base(caster, public override bool CheckBeginCast(GameLiving selectedTarget) { - if (Caster is GamePlayer && Caster.CurrentRegionID == 51 && ((GamePlayer)Caster).BindRegion == 51) + if (Caster is GamePlayer && Caster.CurrentRegionID == 51 && ((GamePlayer)Caster).BindPosition.RegionID == 51) { if (Caster.CurrentRegionID == 51) { @@ -471,7 +456,7 @@ public override void OnDirectEffect(GameLiving target, double effectiveness) if (pl != null) { SendEffectAnimation(pl, 0, false, 1); - pl.MoveTo((ushort)player.BindRegion, player.BindXpos, player.BindYpos, player.BindZpos, (ushort)player.BindHeading); + pl.MoveTo(player.BindPosition); } } } diff --git a/GameServer/spells/Masterlevel/Spymaster.cs b/GameServer/spells/Masterlevel/Spymaster.cs index 2bcdf00b45..f0220b6910 100644 --- a/GameServer/spells/Masterlevel/Spymaster.cs +++ b/GameServer/spells/Masterlevel/Spymaster.cs @@ -95,13 +95,9 @@ public DecoySpellHandler(GameLiving caster, Spell spell, SpellLine line) Random m_rnd = new Random(); decoy = new GameDecoy(); //Fill the object variables - decoy.CurrentRegion = caster.CurrentRegion; - decoy.Heading = (ushort)((caster.Heading + 2048) % 4096); decoy.Level = 50; decoy.Realm = caster.Realm; - decoy.X = caster.X; - decoy.Y = caster.Y; - decoy.Z = caster.Z; + decoy.Position = caster.Position.TurnedAround(); string TemplateId = ""; switch (caster.Realm) { @@ -179,11 +175,7 @@ public TangleSnareSpellHandler(GameLiving caster, Spell spell, SpellLine line) mine.Model = 2592; mine.Name = spell.Name; mine.Realm = caster.Realm; - mine.X = caster.X; - mine.Y = caster.Y; - mine.Z = caster.Z; - mine.CurrentRegionID = caster.CurrentRegionID; - mine.Heading = caster.Heading; + mine.Position = caster.Position; mine.Owner = (GamePlayer)caster; // Construct the mine spell @@ -232,11 +224,7 @@ public PoisonSpikeSpellHandler(GameLiving caster, Spell spell, SpellLine line) mine.Model = 2589; mine.Name = spell.Name; mine.Realm = caster.Realm; - mine.X = caster.X; - mine.Y = caster.Y; - mine.Z = caster.Z; - mine.CurrentRegionID = caster.CurrentRegionID; - mine.Heading = caster.Heading; + mine.Position = caster.Position; mine.Owner = (GamePlayer)caster; // Construct the mine spell @@ -369,12 +357,8 @@ public SiegeWreckerSpellHandler(GameLiving caster, Spell spell, SpellLine line) mine.Model = 2591; mine.Name = spell.Name; mine.Realm = caster.Realm; - mine.X = caster.X; - mine.Y = caster.Y; - mine.Z = caster.Z; + mine.Position = caster.Position; mine.MaxSpeedBase = 0; - mine.CurrentRegionID = caster.CurrentRegionID; - mine.Heading = caster.Heading; mine.Owner = (GamePlayer)caster; // Construct the mine spell diff --git a/GameServer/spells/Masterlevel/Stormlord.cs b/GameServer/spells/Masterlevel/Stormlord.cs index 706f1cec7a..3a496b7794 100644 --- a/GameServer/spells/Masterlevel/Stormlord.cs +++ b/GameServer/spells/Masterlevel/Stormlord.cs @@ -25,6 +25,7 @@ using DOL.Events; using System.Collections; using System.Collections.Generic; +using DOL.GS.Geometry; namespace DOL.GS.Spells { @@ -41,11 +42,7 @@ public DazzlingArraySpellHandler(GameLiving caster, Spell spell, SpellLine line) //Construct a new storm. storm = new GameStorm(); storm.Realm = caster.Realm; - storm.X = caster.X; - storm.Y = caster.Y; - storm.Z = caster.Z; - storm.CurrentRegionID = caster.CurrentRegionID; - storm.Heading = caster.Heading; + storm.Position = caster.Position; storm.Owner = (GamePlayer)caster; storm.Movable = true; @@ -156,7 +153,8 @@ public override void OnDirectEffect(GameLiving target, double effectiveness) GameNPC targetNPC = targetStorm as GameNPC; int range = Util.Random(0, 750); double angle = Util.RandomDouble() * 2 * Math.PI; - targetNPC.WalkTo(targetNPC.X + (int)(range * Math.Cos(angle)), targetNPC.Y + (int)(range * Math.Sin(angle)), targetNPC.Z, targetNPC.MaxSpeed); + var offset = Vector.Create(x: (int)(range * Math.Cos(angle)), y: (int)(range * Math.Sin(angle)) ); + targetNPC.WalkTo(targetNPC.Coordinate + offset, targetNPC.MaxSpeed); } } } @@ -180,11 +178,7 @@ public EnervatingGasSpellHandler(GameLiving caster, Spell spell, SpellLine line) //Construct a new storm. storm = new GameStorm(); storm.Realm = caster.Realm; - storm.X = caster.X; - storm.Y = caster.Y; - storm.Z = caster.Z; - storm.CurrentRegionID = caster.CurrentRegionID; - storm.Heading = caster.Heading; + storm.Position = caster.Position; storm.Owner = (GamePlayer)caster; storm.Movable = true; @@ -267,11 +261,7 @@ public InebriatingFumesSpellHandler(GameLiving caster, Spell spell, SpellLine li //Construct a new storm. storm = new GameStorm(); storm.Realm = caster.Realm; - storm.X = caster.X; - storm.Y = caster.Y; - storm.Z = caster.Z; - storm.CurrentRegionID = caster.CurrentRegionID; - storm.Heading = caster.Heading; + storm.Position = caster.Position; storm.Owner = (GamePlayer)caster; storm.Movable = true; @@ -350,11 +340,7 @@ public MentalSiphonSpellHandler(GameLiving caster, Spell spell, SpellLine line) //Construct a new storm. storm = new GameStorm(); storm.Realm = caster.Realm; - storm.X = caster.X; - storm.Y = caster.Y; - storm.Z = caster.Z; - storm.CurrentRegionID = caster.CurrentRegionID; - storm.Heading = caster.Heading; + storm.Position = caster.Position; storm.Owner = (GamePlayer)caster; storm.Movable = true; @@ -510,11 +496,7 @@ public ChokingVaporsSpellHandler(GameLiving caster, Spell spell, SpellLine line) //Construct a new storm. storm = new GameStorm(); storm.Realm = caster.Realm; - storm.X = caster.X; - storm.Y = caster.Y; - storm.Z = caster.Z; - storm.CurrentRegionID = caster.CurrentRegionID; - storm.Heading = caster.Heading; + storm.Position = caster.Position; storm.Owner = (GamePlayer)caster; storm.Movable = true; @@ -593,11 +575,7 @@ public SenseDullingCloudSpellHandler(GameLiving caster, Spell spell, SpellLine l //Construct a new storm. storm = new GameStorm(); storm.Realm = caster.Realm; - storm.X = caster.X; - storm.Y = caster.Y; - storm.Z = caster.Z; - storm.CurrentRegionID = caster.CurrentRegionID; - storm.Heading = caster.Heading; + storm.Position = caster.Position; storm.Owner = (GamePlayer)caster; storm.Movable = true; @@ -675,11 +653,7 @@ public EnergyTempestSpellHandler(GameLiving caster, Spell spell, SpellLine line) //Construct a new storm. storm = new GameStorm(); storm.Realm = caster.Realm; - storm.X = caster.X; - storm.Y = caster.Y; - storm.Z = caster.Z; - storm.CurrentRegionID = caster.CurrentRegionID; - storm.Heading = caster.Heading; + storm.Position = caster.Position; storm.Owner = (GamePlayer)caster; storm.Movable = true; diff --git a/GameServer/spells/ResurrectSpellHandler.cs b/GameServer/spells/ResurrectSpellHandler.cs index 49b2db186b..656b22be1b 100644 --- a/GameServer/spells/ResurrectSpellHandler.cs +++ b/GameServer/spells/ResurrectSpellHandler.cs @@ -170,7 +170,7 @@ protected virtual void ResurrectLiving(GameLiving living) else living.Endurance = 0; - living.MoveTo(m_caster.CurrentRegionID, m_caster.X, m_caster.Y, m_caster.Z, m_caster.Heading); + living.MoveTo(m_caster.Position); GameTimer resurrectExpiredTimer = null; lock (m_resTimersByLiving.SyncRoot) diff --git a/GameServer/spells/SpellHandler.cs b/GameServer/spells/SpellHandler.cs index ce57323695..1c36b80cc4 100644 --- a/GameServer/spells/SpellHandler.cs +++ b/GameServer/spells/SpellHandler.cs @@ -33,6 +33,7 @@ using DOL.Language; using log4net; +using DOL.GS.Geometry; namespace DOL.GS.Spells { @@ -749,7 +750,7 @@ public virtual bool CheckBeginCast(GameLiving selectedTarget, bool quiet) } if (targetType == "area") { - if (!m_caster.IsWithinRadius(m_caster.GroundTarget, CalculateSpellRange())) + if (m_caster.Coordinate.DistanceTo(m_caster.GroundTargetPosition) > CalculateSpellRange()) { if (!quiet) MessageToCaster("Your area target is out of range. Select a closer target.", eChatType.CT_SpellResisted); return false; @@ -1015,7 +1016,7 @@ public virtual bool CheckEndCast(GameLiving target) if (m_spell.Target.ToLower() == "area") { - if (!m_caster.IsWithinRadius(m_caster.GroundTarget, CalculateSpellRange())) + if (m_caster.Coordinate.DistanceTo(m_caster.GroundTargetPosition) > CalculateSpellRange()) { MessageToCaster("Your area target is out of range. Select a closer target.", eChatType.CT_SpellResisted); return false; @@ -1185,7 +1186,7 @@ public virtual bool CheckDuringCast(GameLiving target, bool quiet) if (m_spell.Target.ToLower() == "area") { - if (!m_caster.IsWithinRadius(m_caster.GroundTarget, CalculateSpellRange())) + if (m_caster.Coordinate.DistanceTo(m_caster.GroundTargetPosition) > CalculateSpellRange()) { if (!quiet) MessageToCaster("Your area target is out of range. Select a closer target.", eChatType.CT_SpellResisted); return false; @@ -1390,7 +1391,7 @@ public virtual bool CheckAfterCast(GameLiving target, bool quiet) if (m_spell.Target.ToLower() == "area") { - if (!m_caster.IsWithinRadius(m_caster.GroundTarget, CalculateSpellRange())) + if (m_caster.Coordinate.DistanceTo(m_caster.GroundTargetPosition) > CalculateSpellRange()) { if (!quiet) MessageToCaster("Your area target is out of range. Select a closer target.", eChatType.CT_SpellResisted); return false; @@ -2107,7 +2108,7 @@ public virtual IList SelectTargets(GameObject castTarget) else if (modifiedRadius > 0) { - foreach (GamePlayer player in WorldMgr.GetPlayersCloseToSpot(Caster.CurrentRegionID, Caster.GroundTarget.X, Caster.GroundTarget.Y, Caster.GroundTarget.Z, modifiedRadius)) + foreach (GamePlayer player in WorldMgr.GetPlayersCloseToSpot(Caster.GroundTargetPosition, modifiedRadius)) { if (GameServer.ServerRules.IsAllowedToAttack(Caster, player, true)) { @@ -2125,7 +2126,7 @@ public virtual IList SelectTargets(GameObject castTarget) else list.Add(player); } } - foreach (GameNPC npc in WorldMgr.GetNPCsCloseToSpot(Caster.CurrentRegionID, Caster.GroundTarget.X, Caster.GroundTarget.Y, Caster.GroundTarget.Z, modifiedRadius)) + foreach (GameNPC npc in WorldMgr.GetNPCsCloseToSpot(Caster.GroundTargetPosition, modifiedRadius)) { if (npc is GameStorm) list.Add(npc); @@ -2572,7 +2573,7 @@ public virtual bool StartSpell(GameLiving target) } else if (Spell.Target.ToLower() == "area") { - int dist = t.GetDistanceTo(Caster.GroundTarget); + int dist = (int)t.Coordinate.DistanceTo(Caster.GroundTargetPosition); if (dist >= 0) ApplyEffectOnTarget(t, (effectiveness - CalculateAreaVariance(t, dist, Spell.Radius))); } diff --git a/GameServer/spells/SummonIllusionBlade.cs b/GameServer/spells/SummonIllusionBlade.cs index 553ce0ce1d..7a24e9b07e 100644 --- a/GameServer/spells/SummonIllusionBlade.cs +++ b/GameServer/spells/SummonIllusionBlade.cs @@ -46,17 +46,7 @@ public override void ApplyEffectOnTarget(GameLiving target, double effectiveness IControlledBrain brain = GetPetBrain(Caster); m_pet = GetGamePet(template); m_pet.SetOwnBrain(brain as AI.ABrain); - int x, y, z; - ushort heading; - Region region; - - GetPetLocation(out x, out y, out z, out heading, out region); - - m_pet.X = x; - m_pet.Y = y; - m_pet.Z = z; - m_pet.Heading = heading; - m_pet.CurrentRegion = region; + m_pet.Position = GetSummonPosition(); // m_pet.CurrentSpeed = 0; m_pet.Realm = Caster.Realm; m_pet.Race = 0; diff --git a/GameServer/spells/SummonSpellHandler.cs b/GameServer/spells/SummonSpellHandler.cs index 01a7dedfc5..99d8e1ba71 100644 --- a/GameServer/spells/SummonSpellHandler.cs +++ b/GameServer/spells/SummonSpellHandler.cs @@ -24,6 +24,7 @@ using DOL.AI.Brain; using DOL.Events; using DOL.GS.Effects; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using DOL.Language; @@ -86,16 +87,20 @@ public override void FinishSpellCast(GameLiving target) #region ApplyEffectOnTarget Gets + [Obsolete("Use GetSummonPosition() instead!")] protected virtual void GetPetLocation(out int x, out int y, out int z, out ushort heading, out Region region) { - Point2D point = Caster.GetPointFromHeading( Caster.Heading, 64 ); - x = point.X; - y = point.Y; - z = Caster.Z; - heading = (ushort)((Caster.Heading + 2048) % 4096); - region = Caster.CurrentRegion; + var position = GetSummonPosition(); + x = position.X; + y = position.Y; + z = position.Z; + heading = position.Orientation.InHeading; + region = WorldMgr.GetRegion(position.RegionID); } + protected virtual Position GetSummonPosition() + => Caster.Position.TurnedAround() + Vector.Create(Caster.Orientation, length: 64); + protected virtual GamePet GetGamePet(INpcTemplate template) { return Caster.CreateGamePet(template); @@ -144,19 +149,7 @@ public override void ApplyEffectOnTarget(GameLiving target, double effectiveness m_pet.SummonSpellDamage = Spell.Damage; m_pet.SummonSpellValue = Spell.Value; - - int x, y, z; - ushort heading; - Region region; - - GetPetLocation(out x, out y, out z, out heading, out region); - - m_pet.X = x; - m_pet.Y = y; - m_pet.Z = z; - m_pet.Heading = heading; - m_pet.CurrentRegion = region; - + m_pet.Position = GetSummonPosition(); m_pet.CurrentSpeed = 0; m_pet.Realm = Caster.Realm; diff --git a/GameServer/spells/Teleport/GatewayPersonalBind.cs b/GameServer/spells/Teleport/GatewayPersonalBind.cs index 37edc37e84..ceb6314251 100644 --- a/GameServer/spells/Teleport/GatewayPersonalBind.cs +++ b/GameServer/spells/Teleport/GatewayPersonalBind.cs @@ -106,7 +106,7 @@ public override void ApplyEffectOnTarget(GameLiving target, double effectiveness UniPortalEffect effect = new UniPortalEffect(this, 1000); effect.Start(player); - player.MoveTo((ushort)player.BindRegion, player.BindXpos, player.BindYpos, player.BindZpos, (ushort)player.BindHeading); + player.MoveTo(player.BindPosition); } diff --git a/GameServer/spells/Teleport/UniPortal.cs b/GameServer/spells/Teleport/UniPortal.cs index 99572bb6de..1d52a50710 100644 --- a/GameServer/spells/Teleport/UniPortal.cs +++ b/GameServer/spells/Teleport/UniPortal.cs @@ -23,6 +23,7 @@ using DOL.Database; using DOL.Language; using DOL.GS.PacketHandler; +using DOL.GS.Geometry; namespace DOL.GS.Spells { @@ -76,7 +77,7 @@ public override void ApplyEffectOnTarget(GameLiving target, double effectiveness effect.Start(player); player.LeaveHouse(); - player.MoveTo((ushort)m_destination.RegionID, m_destination.X, m_destination.Y, m_destination.Z, (ushort)m_destination.Heading); + player.MoveTo(m_destination.GetPosition()); } } } diff --git a/GameServer/spells/Theurgist/SummonTheurgistPet.cs b/GameServer/spells/Theurgist/SummonTheurgistPet.cs index 3625ca825f..f8c34af3c8 100644 --- a/GameServer/spells/Theurgist/SummonTheurgistPet.cs +++ b/GameServer/spells/Theurgist/SummonTheurgistPet.cs @@ -19,6 +19,7 @@ using DOL.GS.PacketHandler; using DOL.AI.Brain; using DOL.GS.Effects; +using DOL.GS.Geometry; namespace DOL.GS.Spells { @@ -74,10 +75,7 @@ protected override IControlledBrain GetPetBrain(GameLiving owner) protected override void SetBrainToOwner(IControlledBrain brain) { } - protected override void GetPetLocation(out int x, out int y, out int z, out ushort heading, out Region region) - { - base.GetPetLocation(out x, out y, out z, out heading, out region); - heading = Caster.Heading; - } + protected override Position GetSummonPosition() + => Caster.Position + Vector.Create(Caster.Orientation, length: 64); } } diff --git a/GameServer/spells/negative/FearBrain.cs b/GameServer/spells/negative/FearBrain.cs index 5d30c03ee5..623f474c40 100644 --- a/GameServer/spells/negative/FearBrain.cs +++ b/GameServer/spells/negative/FearBrain.cs @@ -19,6 +19,7 @@ using System; using DOL.GS; +using DOL.GS.Geometry; namespace DOL.AI.Brain { @@ -45,18 +46,14 @@ public override void Think() } } - /// - /// Calculate flee target. - /// - ///The target to flee. protected virtual void CalculateFleeTarget(GameLiving target) { - ushort TargetAngle = (ushort)((Body.GetHeading(target) + 2048) % 4096); + var targetAngle = Body.Coordinate.GetOrientationTo(target.Coordinate) + Angle.Degrees(180); - Point2D fleePoint = Body.GetPointFromHeading(TargetAngle, 300); Body.StopFollowing(); Body.StopAttack(); - Body.PathTo(new Point3D(fleePoint.X, fleePoint.Y, Body.Z), Body.MaxSpeed); + var destination = Body.Position + Vector.Create(targetAngle, length: 300); + Body.PathTo(destination.Coordinate, Body.MaxSpeed); } } } diff --git a/GameServer/styles/StyleProcessor.cs b/GameServer/styles/StyleProcessor.cs index 74f4f5189c..f512a30374 100644 --- a/GameServer/styles/StyleProcessor.cs +++ b/GameServer/styles/StyleProcessor.cs @@ -138,7 +138,7 @@ public static bool CanUseStyle(GameLiving living, Style style, InventoryItem wea return false; // get players angle on target - float angle = target.GetAngle( living ); + var angle = target.GetAngleTo(living.Coordinate); //player.Out.SendDebugMessage("Positional check: "+style.OpeningRequirementValue+" angle "+angle+" target heading="+target.Heading); switch ((Style.eOpeningPosition)style.OpeningRequirementValue) @@ -146,17 +146,17 @@ public static bool CanUseStyle(GameLiving living, Style style, InventoryItem wea //Back Styles //60 degree since 1.62 patch case Style.eOpeningPosition.Back: - if (!(angle >= 150 && angle < 210)) return false; + if (!(angle.InDegrees >= 150 && angle.InDegrees < 210)) return false; break; // Side Styles //105 degree since 1.62 patch case Style.eOpeningPosition.Side: - if (!(angle >= 45 && angle < 150) && !(angle >= 210 && angle < 315)) return false; + if (!(angle.InDegrees >= 45 && angle.InDegrees < 150) && !(angle.InDegrees >= 210 && angle.InDegrees < 315)) return false; break; // Front Styles // 90 degree case Style.eOpeningPosition.Front: - if (!(angle >= 315 || angle < 45)) return false; + if (!(angle.InDegrees >= 315 || angle.InDegrees < 45)) return false; break; } //DOLConsole.WriteLine("Positional check success: "+style.OpeningRequirementValue); diff --git a/GameServer/world/AbstractArea.cs b/GameServer/world/AbstractArea.cs index 809d9810d4..8e8797547a 100644 --- a/GameServer/world/AbstractArea.cs +++ b/GameServer/world/AbstractArea.cs @@ -22,6 +22,7 @@ using DOL.Events; using DOL.Language; using DOL.GS.PacketHandler; +using DOL.GS.Geometry; namespace DOL.GS { @@ -182,18 +183,23 @@ public void RegisterPlayerLeave(DOLEventHandler callback) /// public abstract bool IsIntersectingZone(Zone zone); - /// - /// Checks wether given spot is within areas boundaries or not - /// - /// - /// - public abstract bool IsContaining(IPoint3D spot); + public abstract bool IsContaining(Coordinate spot, bool ignoreZ = false); + + [Obsolete("Use .IsContaining(Coordinate[,bool]) instead!")] + public virtual bool IsContaining(IPoint3D spot) + => IsContaining(spot.ToCoordinate(), ignoreZ: false); - public abstract bool IsContaining(IPoint3D spot, bool checkZ); + [Obsolete("Use .IsContaining(Coordinate[,bool]) instead!")] + public virtual bool IsContaining(IPoint3D spot, bool checkZ) + => IsContaining(spot.ToCoordinate(), ignoreZ: !checkZ); - public abstract bool IsContaining(int x, int y, int z); + [Obsolete("Use .IsContaining(Coordinate[,bool]) instead!")] + public virtual bool IsContaining(int x, int y, int z) + => IsContaining(Coordinate.Create(x, y, z), ignoreZ: false); - public abstract bool IsContaining(int x, int y, int z, bool checkZ); + [Obsolete("Use .IsContaining(Coordinate[,bool]) instead!")] + public virtual bool IsContaining(int x, int y, int z, bool checkZ) + => IsContaining(Coordinate.Create(x, y, z), ignoreZ: !checkZ); /// /// Called whenever a player leaves the given area diff --git a/GameServer/world/Area.cs b/GameServer/world/Area.cs index f5a0678b7c..13341e8dd6 100644 --- a/GameServer/world/Area.cs +++ b/GameServer/world/Area.cs @@ -21,6 +21,7 @@ using DOL.Events; using DOL.GS.PacketHandler; using DOL.Database; +using DOL.GS.Geometry; namespace DOL.GS { @@ -104,60 +105,28 @@ public int Height /// public override bool IsIntersectingZone(Zone zone) { - if (X+Width < zone.XOffset) + if (X+Width < zone.Offset.X) return false; - if (X-Width >= zone.XOffset + 65536) + if (X-Width >= zone.Offset.X + 65536) return false; - if (Y+Height < zone.YOffset) + if (Y+Height < zone.Offset.Y) return false; - if (Y-Height >= zone.YOffset + 65536) + if (Y-Height >= zone.Offset.Y + 65536) return false; return true; } - /// - /// Checks wether given point is within area boundaries - /// - /// - /// - public override bool IsContaining(IPoint3D p) - { - return IsContaining(p, true); - } - - public override bool IsContaining(int x, int y, int z) - { - return IsContaining(x, y, z, true); - } - - public override bool IsContaining(IPoint3D p, bool checkZ) - { - return IsContaining(p.X, p.Y, p.Z, checkZ); - } - - public override bool IsContaining(int x, int y, int z, bool checkZ) - { - long m_xdiff = (long)x - X; - if (m_xdiff < 0 || m_xdiff > Width) - return false; - - long m_ydiff = (long)y - Y; - if (m_ydiff < 0 || m_ydiff > Height) - return false; + public override bool IsContaining(Coordinate spot, bool ignoreZ = false) + { + long m_xdiff = (long)spot.X - X; + if (m_xdiff < 0 || m_xdiff > Width) return false; - /* - //SH: Removed Z checks when one of the two Z values is zero(on ground) - if (Z != 0 && spotZ != 0) - { - long m_zdiff = (long) spotZ - Z; - if (m_zdiff> Radius) - return false; - } - */ + long m_ydiff = (long)spot.Y - Y; + if (m_ydiff < 0 || m_ydiff > Height) return false; - return true; - } + return true; + } public override void LoadFromDatabase(DBArea area) { @@ -173,25 +142,6 @@ public override void LoadFromDatabase(DBArea area) public class Circle : AbstractArea { - - /// - /// The X coordinate of this Area - /// - protected int m_X; - - /// - /// The Y coordinate of this Area - /// - protected int m_Y; - - /// - /// The Z coordinate of this Area - /// - protected int m_Z; - - /// - /// The radius of the area in Coordinates - /// protected int m_Radius; protected long m_distSq; @@ -204,37 +154,26 @@ public Circle() public Circle( string desc, int x, int y, int z, int radius) : base(desc) { m_Description = desc; - m_X = x; - m_Y = y; - m_Z= z; - m_Radius= radius; + Center = Coordinate.Create(x, y, z); + m_Radius = radius; m_RadiusRadius = radius*radius; } - /// - /// Returns the X Coordinate of this Area - /// - public int X - { - get { return m_X; } - } + public Circle(string desc, Coordinate center, int radius) : base(desc) + { + m_Description = desc; + Center = center; + m_Radius = radius; - /// - /// Returns the Y Coordinate of this Area - /// - public int Y - { - get { return m_Y; } - } + m_RadiusRadius = radius * radius; + } - /// - /// Returns the Width of this Area - /// - public int Z - { - get { return m_Z; } - } + public Coordinate Center { get; private set; } + + public int X => Center.X; + public int Y => Center.Y; + public int Z => Center.Z; /// /// Returns the Height of this Area @@ -258,74 +197,51 @@ public int Radius /// public override bool IsIntersectingZone(Zone zone) { - if (X+Radius < zone.XOffset) + if (X+Radius < zone.Offset.X) return false; - if (X-Radius >= zone.XOffset + 65536) + if (X-Radius >= zone.Offset.X + 65536) return false; - if (Y+Radius < zone.YOffset) + if (Y+Radius < zone.Offset.Y) return false; - if (Y-Radius >= zone.YOffset + 65536) + if (Y-Radius >= zone.Offset.Y + 65536) return false; return true; } - public override bool IsContaining(IPoint3D spot) - { - return IsContaining(spot, true); - } - - public override bool IsContaining(int x, int y, int z, bool checkZ) - { - // spot is not in square around circle no need to check for circle... - long m_xdiff = (long)x - X; - if (m_xdiff > Radius) - return false; - - long m_ydiff = (long)y - Y; - if (m_ydiff > Radius) - return false; - + public override bool IsContaining(Coordinate spot, bool ignoreZ = false) + { + // spot is not in square around circle no need to check for circle... + long m_xdiff = (long)spot.X - X; + if (m_xdiff > Radius) + return false; - // check if spot is in circle - m_distSq = m_xdiff * m_xdiff + m_ydiff * m_ydiff; + long m_ydiff = (long)spot.Y - Y; + if (m_ydiff > Radius) + return false; - if (Z != 0 && z != 0 && checkZ) - { - long m_zdiff = (long)z - Z; - m_distSq += m_zdiff * m_zdiff; - } - return (m_distSq <= m_RadiusRadius); - } + // check if spot is in circle + m_distSq = m_xdiff * m_xdiff + m_ydiff * m_ydiff; - public override bool IsContaining(int x, int y, int z) - { - return IsContaining(x, y, z, true); - } + if (Z != 0 && spot.Z != 0 && !ignoreZ) + { + long m_zdiff = (long)spot.Z - Z; + m_distSq += m_zdiff * m_zdiff; + } - /// - /// Checks wether given point is within area boundaries - /// - /// - /// - /// - public override bool IsContaining(IPoint3D p, bool checkZ) - { - return IsContaining(p.X, p.Y, p.Z, checkZ); - } + return (m_distSq <= m_RadiusRadius); + } - public override void LoadFromDatabase(DBArea area) - { + public override void LoadFromDatabase(DBArea area) + { m_translationId = area.TranslationId; - m_Description = area.Description; - m_X = area.X; - m_Y = area.Y; - m_Z = area.Z; - m_Radius = area.Radius; - m_RadiusRadius = area.Radius * area.Radius; - } - } + m_Description = area.Description; + Center = Coordinate.Create(area.X, area.Y, area.Z); + m_Radius = area.Radius; + m_RadiusRadius = area.Radius * area.Radius; + } + } public class Polygon : AbstractArea { @@ -360,7 +276,7 @@ public int Radius /// /// The Points list /// - protected IList m_points; + protected IList m_points; public Polygon() : base() @@ -405,7 +321,7 @@ public string StringPoints set { m_stringpoints = value; - m_points = new List(); + m_points = new List(); if (m_stringpoints.Length < 1) return; string[] points = m_stringpoints.Split('|'); foreach (string point in points) @@ -414,7 +330,7 @@ public string StringPoints if (pts.Length != 2) continue; int x = Convert.ToInt32(pts[0]); int y = Convert.ToInt32(pts[1]); - Point2D p = new Point2D(x, y); + var p = Coordinate.Create(x, y); if (!m_points.Contains(p)) m_points.Add(p); } } @@ -428,53 +344,38 @@ public string StringPoints public override bool IsIntersectingZone(Zone zone) { // TODO if needed - if (X + Radius < zone.XOffset) + if (X + Radius < zone.Offset.X) return false; - if (X - Radius >= zone.XOffset + 65536) + if (X - Radius >= zone.Offset.X + 65536) return false; - if (Y + Radius < zone.YOffset) + if (Y + Radius < zone.Offset.Y) return false; - if (Y - Radius >= zone.YOffset + 65536) + if (Y - Radius >= zone.Offset.Y + 65536) return false; return true; } - public override bool IsContaining(int x, int y, int z, bool checkZ) - { - return IsContaining(new Point3D(x, y, z)); - } - - public override bool IsContaining(int x, int y, int z) - { - return IsContaining(new Point3D(x, y, z)); - } - - public override bool IsContaining(IPoint3D obj, bool checkZ) - { - return IsContaining(obj); - } - - public override bool IsContaining(IPoint3D obj) + public override bool IsContaining(Coordinate spot, bool ignoreZ = false) { if (m_points.Count < 3) return false; - Point2D p1, p2; + Coordinate p1, p2; bool inside = false; - Point2D oldpt = new Point2D(m_points[m_points.Count - 1].X, m_points[m_points.Count - 1].Y); + var lastPoint = m_points[m_points.Count - 1]; - foreach (Point2D pt in m_points) + foreach (var currentPoint in m_points) { - Point2D newpt = new Point2D(pt.X, pt.Y); + var newpt = currentPoint; - if (newpt.X > oldpt.X) { p1 = oldpt; p2 = newpt; } - else { p1 = newpt; p2 = oldpt; } + if (currentPoint.X > lastPoint.X) { p1 = lastPoint; p2 = currentPoint; } + else { p1 = currentPoint; p2 = lastPoint; } - if ((newpt.X < obj.X) == (obj.X <= oldpt.X) - && (obj.Y - p1.Y) * (p2.X - p1.X) < (p2.Y - p1.Y) * (obj.X - p1.X)) + if ((currentPoint.X < spot.X) == (spot.X <= lastPoint.X) + && (spot.Y - p1.Y) * (p2.X - p1.X) < (p2.Y - p1.Y) * (spot.X - p1.X)) inside = !inside; - oldpt = newpt; + lastPoint = currentPoint; } return inside; } diff --git a/GameServer/world/GameLocation.cs b/GameServer/world/GameLocation.cs index f461011e6f..88a09b1b17 100644 --- a/GameServer/world/GameLocation.cs +++ b/GameServer/world/GameLocation.cs @@ -17,109 +17,105 @@ * */ using System; +using DOL.GS.Geometry; namespace DOL.GS { - /// - /// - /// - public class GameLocation : Point3D, IGameLocation - { - protected ushort m_regionId; - protected ushort m_heading; - protected String m_name; - - public GameLocation(String name, ushort regionId, ushort zoneId, int x, int y, int z, ushort heading) : this(name,regionId,ConvertLocalXToGlobalX(x, zoneId),ConvertLocalYToGlobalY(y, zoneId),z, heading) - { - } + [Obsolete("Use DOL.GS.Geometry.Position instead!")] + public class GameLocation : IGameLocation + { + public GameLocation(String name, ushort regionId, ushort zoneId, int x, int y, int z, ushort heading) + : this(name, Position.Create(regionId, Coordinate.Create(x,y,z)+WorldMgr.GetZone(zoneId).Offset, heading)) { } - public GameLocation(String name, ushort regionId, int x, int y, int z) : this(name, regionId, x, y, z, 0) - { - } + public GameLocation(String name, ushort regionId, int x, int y, int z) + : this(name, Position.Create(regionId, x, y, z, heading: 0)) { } - public GameLocation(String name, ushort regionId, int x, int y, int z, ushort heading) : base(x, y, z) - { - m_regionId = regionId; - m_name = name; - m_heading = heading; - } + public GameLocation(String name, ushort regionId, int x, int y, int z, ushort heading) + : this(name, Position.Create(regionId, x, y, z, heading)) { } - /// - /// heading of this point - /// - public ushort Heading - { - get { return m_heading; } - set { m_heading = value; } - } + public GameLocation(String name, Position position) + { + Position = position; + Name = name; + } - /// - /// RegionID of this point - /// - public ushort RegionID - { - get { return m_regionId; } - set { m_regionId = value; } - } + public GameLocation(Position position) + { + Position = position; + } - /// - /// Name of this point - /// - public String Name - { - get { return m_name; } - set { m_name = value; } - } - - /// - /// calculates distance between 2 points - /// - /// - /// - /// - public int GetDistance( IGameLocation location ) - { - if (this.RegionID == location.RegionID) - { - return base.GetDistanceTo( location ); - } - else - { - return -1; - } - } + public Position Position { get; set; } = Position.Zero; + + public int X + { + get => Position.X; + set => Position.With(x: value); + } + + public int Y + { + get => Position.Y; + set => Position.With(y: value); + } + + public int Z + { + get => Position.Z; + set => Position.With(z: value); + } + + public ushort Heading + { + get => Position.Orientation.InHeading; + set => Position.With(heading: value); + } + + public ushort RegionID + { + get => Position.RegionID; + set => Position.With(regionID: value); + } + + public String Name { get; set; } = null; + + public int GetDistance(IGameLocation location) + { + if (this.RegionID != location.RegionID) return -1; + + return (int)Position.Coordinate.DistanceTo(location.Position.Coordinate); + } public static int ConvertLocalXToGlobalX(int localX, ushort zoneId) { Zone z = WorldMgr.GetZone(zoneId); - return z.XOffset + localX; + return z.Offset.X + localX; } public static int ConvertLocalYToGlobalY(int localY, ushort zoneId) { Zone z = WorldMgr.GetZone(zoneId); - return z.YOffset + localY; + return z.Offset.Y + localY; } public static int ConvertGlobalXToLocalX(int globalX, ushort zoneId) { Zone z = WorldMgr.GetZone(zoneId); - return globalX - z.XOffset; + return globalX - z.Offset.X; } public static int ConvertGlobalYToLocalY(int globalY, ushort zoneId) { Zone z = WorldMgr.GetZone(zoneId); - return globalY - z.YOffset; + return globalY - z.Offset.Y; } - [Obsolete( "Use instance method GetDistance( IGameLocation location )" )] public static int GetDistance( int r1, int x1, int y1, int z1, int r2, int x2, int y2, int z2 ) { - GameLocation loc1 = new GameLocation( "loc1", (ushort)r1, x1, y1, z1 ); - GameLocation loc2 = new GameLocation( "loc2", (ushort)r2, x2, y2, z2 ); + if (r1 != r2) return -1; + var loc1 = Coordinate.Create(x1,y1,z1); + var loc2 = Coordinate.Create(x2,y2,z2); - return loc1.GetDistance( loc2 ); + return (int)loc1.DistanceTo(loc2); } } } diff --git a/GameServer/world/IArea.cs b/GameServer/world/IArea.cs index e804d478d0..288c92d017 100644 --- a/GameServer/world/IArea.cs +++ b/GameServer/world/IArea.cs @@ -20,6 +20,7 @@ using System; using DOL.Events; +using DOL.GS.Geometry; using DOL.Language; namespace DOL.GS @@ -49,18 +50,19 @@ public interface IArea : ITranslatableObject /// /// bool IsIntersectingZone(Zone zone); - - /// - /// Checks wether given spot is within areas range or not - /// - /// - /// + + bool IsContaining(Coordinate spot, bool ignoreZ = false); + + [Obsolete("Use .IsContaining(Coordinate[,bool]) instead!")] bool IsContaining(IPoint3D spot); + [Obsolete("Use .IsContaining(Coordinate[,bool]) instead!")] bool IsContaining(IPoint3D spot, bool checkZ); + [Obsolete("Use .IsContaining(Coordinate[,bool]) instead!")] bool IsContaining(int x, int y, int z); + [Obsolete("Use .IsContaining(Coordinate[,bool]) instead!")] bool IsContaining(int x, int y, int z, bool checkZ); /// diff --git a/GameServer/world/IGameLocation.cs b/GameServer/world/IGameLocation.cs index 61b83d0b68..a37dcf2911 100644 --- a/GameServer/world/IGameLocation.cs +++ b/GameServer/world/IGameLocation.cs @@ -16,13 +16,16 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ +using DOL.GS.Geometry; + namespace DOL.GS { - /// - /// interface for classes that represent a point in 3d space - /// - public interface IGameLocation : IPoint3D + public interface IGameLocation { + int X { get; } + int Y { get; } + int Z { get; } + Position Position { get; } ushort RegionID { get; } ushort Heading { get; } string Name { get; } diff --git a/GameServer/world/IPoint2D.cs b/GameServer/world/IPoint2D.cs index b61d07fa56..e0bc9743bb 100644 --- a/GameServer/world/IPoint2D.cs +++ b/GameServer/world/IPoint2D.cs @@ -16,26 +16,22 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ +using System; + namespace DOL.GS { - /// - /// interface for classes that represent a point in 2d space - /// + [Obsolete("Use Coordinate instead!")] public interface IPoint2D { - /// - /// X - /// int X { get; set; } - - /// - /// Y - /// int Y { get; set; } ushort GetHeading(IPoint2D point); + Point2D GetPointFromHeading(ushort heading, int distance); + int GetDistance(IPoint2D point); + void Clear(); } } \ No newline at end of file diff --git a/GameServer/world/IPoint3D.cs b/GameServer/world/IPoint3D.cs index 5cc7b4dc88..a732a7fdc1 100644 --- a/GameServer/world/IPoint3D.cs +++ b/GameServer/world/IPoint3D.cs @@ -16,16 +16,13 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ +using System; + namespace DOL.GS { - /// - /// interface for classes that represent a point in 3d space - /// + [Obsolete("Use Coordinate instead!")] public interface IPoint3D : IPoint2D { - /// - /// Height Position - /// int Z { get; set; } } } \ No newline at end of file diff --git a/GameServer/world/Instance/BaseInstance.cs b/GameServer/world/Instance/BaseInstance.cs index 5088177467..f74a4a6900 100644 --- a/GameServer/world/Instance/BaseInstance.cs +++ b/GameServer/world/Instance/BaseInstance.cs @@ -30,6 +30,7 @@ using DOL.GS; using DOL.Database; +using DOL.GS.Geometry; namespace DOL.GS { @@ -415,11 +416,8 @@ protected override void OnTick() /// /// Gets the areas for a certain spot /// - /// - /// - /// /// - public override IList GetAreasOfZone(Zone zone, IPoint3D p, bool checkZ) + public override IList GetAreasOfZone(Zone zone, Coordinate loc, bool checkZ) { Zone checkZone = zone; var areas = new List(); @@ -446,7 +444,7 @@ public override IList GetAreasOfZone(Zone zone, IPoint3D p, bool checkZ) for (int i = 0; i < m_ZoneAreasCount[zoneIndex]; i++) { IArea area = (IArea)Areas[m_ZoneAreas[zoneIndex][i]]; - if (area.IsContaining(p, checkZ)) + if (area.IsContaining(loc, ignoreZ: !checkZ)) { areas.Add(area); } @@ -469,7 +467,7 @@ public override IList GetAreasOfZone(Zone zone, IPoint3D p, bool checkZ) /// /// /// - public override IList GetAreasOfZone(Zone zone, int x, int y, int z) + public override IList GetAreasOfZone(Zone zone, Coordinate loc) { Zone checkZone = zone; var areas = new List(); @@ -496,7 +494,7 @@ public override IList GetAreasOfZone(Zone zone, int x, int y, int z) for (int i = 0; i < m_ZoneAreasCount[zoneIndex]; i++) { IArea area = (IArea)Areas[m_ZoneAreas[zoneIndex][i]]; - if (area.IsContaining(x, y, z)) + if (area.IsContaining(loc)) areas.Add(area); } } diff --git a/GameServer/world/Instance/Instance.cs b/GameServer/world/Instance/Instance.cs index 4737b765f4..8062480752 100644 --- a/GameServer/world/Instance/Instance.cs +++ b/GameServer/world/Instance/Instance.cs @@ -27,6 +27,7 @@ using DOL.Database; using DOL.GS.Utils; using log4net; +using DOL.GS.Geometry; namespace DOL.GS { @@ -51,17 +52,13 @@ public Instance(ushort ID, GameTimer.TimeManager time, RegionData data) :base(ID log.Debug("Instance destructor called for " + Description); } - #region Entrance + [Obsolete("Use .InstanceEntranceName or .EntrancePosition instead!")] + public GameLocation InstanceEntranceLocation => new GameLocation(EntrancePosition); - protected GameLocation m_entranceLocation = null; + [Obsolete("This is going to be removed.")] + public string InstanceEntranceName { get; set; } = null; - /// - /// Returns the entrance location into this instance. - /// - public GameLocation InstanceEntranceLocation - { get { return m_entranceLocation; } } - - #endregion + public Position EntrancePosition { get; set; } = Position.Nowhere; #region LoadFromDatabase @@ -94,7 +91,7 @@ public virtual void LoadFromDatabase(string instanceName) case "entrance": { //create the entrance, then move to the next. - m_entranceLocation = new GameLocation(instanceName + "entranceRegion" + ID, ID, entry.X, entry.Y, entry.Z, entry.Heading); + EntrancePosition = Position.Create(regionID: ID, entry.X, entry.Y, entry.Z, entry.Heading); //move to the next entry, nothing more to do here... continue; } @@ -119,11 +116,7 @@ public virtual void LoadFromDatabase(string instanceName) //We now have an object that isnt null. Lets place it at the location, in this region. - obj.X = entry.X; - obj.Y = entry.Y; - obj.Z = entry.Z; - obj.Heading = entry.Heading; - obj.CurrentRegionID = ID; + obj.Position = Position.Create(regionID: ID, entry.X, entry.Y, entry.Z, entry.Heading); //If its an npc, load from the npc template about now. //By default, we ignore npctemplate if its set to 0. diff --git a/GameServer/world/Instance/RegionInstance.cs b/GameServer/world/Instance/RegionInstance.cs index ea526b04aa..de85fae4a1 100644 --- a/GameServer/world/Instance/RegionInstance.cs +++ b/GameServer/world/Instance/RegionInstance.cs @@ -46,11 +46,6 @@ public class RegionInstance : BaseInstance /// private List m_players_in; - /// - /// Entrance location of Instance, needed to force exit players. - /// - protected GameLocation m_sourceentrance; - /// /// List Containing players in instance /// @@ -58,15 +53,6 @@ protected List PlayersInside { get { return m_players_in; } } - - /// - /// Entrance location of Instance, needed to force exit players. - /// - public GameLocation SourceEntrance - { - get { return m_sourceentrance; } - set { m_sourceentrance = value; } - } /// /// On Player Enter override to add him to container diff --git a/GameServer/world/Pathing/IPathingMgr.cs b/GameServer/world/Pathing/IPathingMgr.cs index 771f27c5ba..d39490a16c 100644 --- a/GameServer/world/Pathing/IPathingMgr.cs +++ b/GameServer/world/Pathing/IPathingMgr.cs @@ -1,5 +1,6 @@ using System.Numerics; using System.Threading.Tasks; +using DOL.GS.Geometry; namespace DOL.GS { @@ -16,23 +17,9 @@ public interface IPathingMgr /// void Stop(); - /// - /// Returns a path that prevents collisions with the navmesh, but floats freely otherwise - /// - /// - /// Start in GlobalXYZ - /// End in GlobalXYZ - /// - WrappedPathingResult GetPathStraightAsync(Zone zone, Vector3 start, Vector3 end); + (LinePath Path,PathingError Error) GetPathStraightAsync(Zone zone, Coordinate start, Coordinate end); - /// - /// Returns a random point on the navmesh around the given position - /// - /// Zone - /// Start in GlobalXYZ - /// End in GlobalXYZ - /// null if no point found, Vector3 with point otherwise - Vector3? GetRandomPointAsync(Zone zone, Vector3 position, float radius); + Vector3? GetRandomPointAsync(Zone zone, Coordinate center, float radius); /// /// Returns the closest point on the navmesh, if available, or no point found. diff --git a/GameServer/world/Pathing/LocalPathingMgr.cs b/GameServer/world/Pathing/LocalPathingMgr.cs index e13ec0a997..88e7af4b7d 100644 --- a/GameServer/world/Pathing/LocalPathingMgr.cs +++ b/GameServer/world/Pathing/LocalPathingMgr.cs @@ -1,11 +1,13 @@ -using System; +using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Numerics; using System.Reflection; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; +using DOL.GS.Geometry; using log4net; namespace DOL.GS @@ -193,74 +195,46 @@ private static float[] ToRecastFloats(Vector3 value) return new[] { value.X * LocalPathingMgr.CONVERSION_FACTOR, value.Z * LocalPathingMgr.CONVERSION_FACTOR, value.Y * LocalPathingMgr.CONVERSION_FACTOR }; } - /// - /// Returns a path that prevents collisions with the navmesh, but floats freely otherwise - /// - /// - /// Start in GlobalXYZ - /// End in GlobalXYZ - /// - public WrappedPathingResult GetPathStraightAsync(Zone zone, Vector3 start, Vector3 end) + private static float[] CoordinateToRecastFloatArray(Coordinate loc) + => new[] { + loc.X * LocalPathingMgr.CONVERSION_FACTOR, + (loc.Z + 8) * LocalPathingMgr.CONVERSION_FACTOR, + loc.Y * LocalPathingMgr.CONVERSION_FACTOR + }; + + public (LinePath,PathingError) GetPathStraightAsync(Zone zone, Coordinate start, Coordinate destination) { - if (!_navmeshPtrs.ContainsKey(zone.ID)) - return new WrappedPathingResult - { - Error = PathingError.NoPathFound, - Points = null, - }; + var linePath = new LinePath(); + if (!_navmeshPtrs.ContainsKey(zone.ID)) return (linePath,PathingError.NoPathFound); - var result = new WrappedPathingResult(); NavMeshQuery query; if (!_navmeshQueries.Value.TryGetValue(zone.ID, out query)) { query = new NavMeshQuery(_navmeshPtrs[zone.ID]); _navmeshQueries.Value.Add(zone.ID, query); } - var startFloats = ToRecastFloats(start + Vector3.UnitZ * 8); - var endFloats = ToRecastFloats(end + Vector3.UnitZ * 8); + var startFloats = CoordinateToRecastFloatArray(start); + var endFloats = CoordinateToRecastFloatArray(destination); var numNodes = 0; var buffer = new float[MAX_POLY * 3]; var flags = new dtPolyFlags[MAX_POLY]; dtPolyFlags includeFilter = dtPolyFlags.ALL ^ dtPolyFlags.DISABLED; dtPolyFlags excludeFilter = 0; - var polyExt = ToRecastFloats(new Vector3(64, 64, 256)); + var polyExt = new[] { 2f, 2f, 8f }; //RecastFloatArray dtStraightPathOptions options = dtStraightPathOptions.DT_STRAIGHTPATH_ALL_CROSSINGS; var filter = new[] { includeFilter, excludeFilter }; var status = PathStraight(query, startFloats, endFloats, polyExt, filter, options, ref numNodes, buffer, flags); - if ((status & dtStatus.DT_SUCCESS) == 0) - { - result.Error = PathingError.NoPathFound; - result.Points = null; - return result; - } - - var points = new WrappedPathPoint[numNodes]; - var positions = Vector3ArrayFromRecastFloats(buffer, numNodes); - for (var i = 0; i < numNodes; i++) - { - points[i].Position = positions[i]; - points[i].Flags = flags[i]; - } + if ((status & dtStatus.DT_SUCCESS) == 0) return (linePath, PathingError.NoPathFound); - if ((status & dtStatus.DT_PARTIAL_RESULT) == 0) - result.Error = PathingError.PathFound; - else - result.Error = PathingError.PathFound; - result.Points = points; + linePath = LinePathFromRecastFloats(buffer, numNodes); - return result; + return (linePath,PathingError.PathFound); } - /// - /// Returns a random point on the navmesh around the given position - /// - /// Zone - /// Start in GlobalXYZ - /// End in GlobalXYZ - /// null if no point found, Vector3 with point otherwise - public Vector3? GetRandomPointAsync(Zone zone, Vector3 position, float radius) + + public Vector3? GetRandomPointAsync(Zone zone, Coordinate center, float radius) { if (!_navmeshPtrs.ContainsKey(zone.ID)) return null; @@ -275,7 +249,7 @@ public WrappedPathingResult GetPathStraightAsync(Zone zone, Vector3 start, Vecto _navmeshQueries.Value.Add(zone.ID, query); } var ptrs = _navmeshPtrs[zone.ID]; - var center = ToRecastFloats(position + Vector3.UnitZ * 8); + var centerAsFloatArray = CoordinateToRecastFloatArray(center); var cradius = (radius * CONVERSION_FACTOR); var outVec = new float[3]; @@ -285,7 +259,7 @@ public WrappedPathingResult GetPathStraightAsync(Zone zone, Vector3 start, Vecto var polyPickEx = new float[3] { 2.0f, 4.0f, 2.0f }; - var status = FindRandomPointAroundCircle(query, center, cradius, polyPickEx, filter, outVec); + var status = FindRandomPointAroundCircle(query, centerAsFloatArray, cradius, polyPickEx, filter, outVec); if ((status & dtStatus.DT_SUCCESS) != 0) result = new Vector3(outVec[0] * INV_FACTOR, outVec[2] * INV_FACTOR, outVec[1] * INV_FACTOR); @@ -335,6 +309,20 @@ private Vector3[] Vector3ArrayFromRecastFloats(float[] buffer, int numNodes) return result; } + private LinePath LinePathFromRecastFloats(float[] buffer, int numNodes) + { + var wayPoints = new Coordinate[numNodes]; + var conversionFactor = 32f; + for (var i = 0; i < numNodes; i++) + { + wayPoints[i] = Coordinate.Create( + x: (int)(buffer[i * 3 + 0] * conversionFactor), + y: (int)(buffer[i * 3 + 2] * conversionFactor), + z: (int)(buffer[i * 3 + 1] * conversionFactor)); + } + return LinePath.Create(wayPoints); + } + /// /// True if pathing is enabled for the specified zone /// diff --git a/GameServer/world/Pathing/NullPathingMgr.cs b/GameServer/world/Pathing/NullPathingMgr.cs index 0dd5c0fe12..afaa2e686c 100644 --- a/GameServer/world/Pathing/NullPathingMgr.cs +++ b/GameServer/world/Pathing/NullPathingMgr.cs @@ -1,5 +1,5 @@ -using System.Numerics; -using System.Threading.Tasks; +using System.Numerics; +using DOL.GS.Geometry; namespace DOL.GS { @@ -17,15 +17,11 @@ public void Stop() { } - public WrappedPathingResult GetPathStraightAsync(Zone zone, Vector3 start, Vector3 end) - { - return new WrappedPathingResult() { Error = PathingError.NavmeshUnavailable }; - } + public (LinePath, PathingError) GetPathStraightAsync(Zone zone, Coordinate start, Coordinate end) + => (new LinePath(), PathingError.NavmeshUnavailable); - public Vector3? GetRandomPointAsync(Zone zone, Vector3 position, float radius) - { - return null; - } + public Vector3? GetRandomPointAsync(Zone zone, Coordinate center, float radius) + => null; public Vector3? GetClosestPointAsync(Zone zone, Vector3 position, float xRange = 256, float yRange = 256, float zRange = 256) { @@ -37,6 +33,6 @@ public bool HasNavmesh(Zone zone) return false; } - public bool IsAvailable => false; + public bool IsAvailable => false; } } diff --git a/GameServer/world/Pathing/PathCalculator.cs b/GameServer/world/Pathing/PathCalculator.cs index 36317b3562..aa96fe4413 100644 --- a/GameServer/world/Pathing/PathCalculator.cs +++ b/GameServer/world/Pathing/PathCalculator.cs @@ -4,6 +4,7 @@ using System.Numerics; using System.Reflection; using System.Threading; +using DOL.GS.Geometry; using log4net; namespace DOL.GS @@ -60,8 +61,8 @@ public static bool IsSupported(GameNPC o) /// public GameDoor NextDoor { get; private set; } - private readonly Queue _pathNodes = new Queue(); - private Vector3 _lastTarget = Vector3.Zero; + private LinePath path = new LinePath(); + private Coordinate _lastTarget = Coordinate.Nowhere; /// /// Forces the path to be replot on the next CalculateNextTarget(...) @@ -88,40 +89,26 @@ public PathCalculator(GameNPC owner) /// /// /// - private bool ShouldPath(Vector3 target) + private bool ShouldPath(Coordinate target) { return ShouldPath(Owner, target); } - /// - /// Clears all data stored in this calculator - /// - public void Clear() - { - _pathNodes.Clear(); - _lastTarget = Vector3.Zero; - DidFindPath = false; - ForceReplot = true; - } - /// /// True if we should path towards the target point /// - /// - /// - /// - public static bool ShouldPath(GameNPC owner, Vector3 target) + public static bool ShouldPath(GameNPC owner, Coordinate destination) { - if (owner.GetDistanceTo(target) < MIN_PATHING_DISTANCE) + if (owner.Coordinate.DistanceTo(destination) < MIN_PATHING_DISTANCE) return false; // too close to path if (owner.IsFlying) return false; - if (owner.Z <= 0) + if (owner.Position.Z <= 0) return false; // this will probably result in some really awkward paths otherwise var zone = owner.CurrentZone; if (zone == null || !zone.IsPathingEnabled) return false; // we're in nirvana - if (owner.CurrentRegion.GetZone((int)target.X, (int)target.Y) != zone) + if (owner.CurrentRegion.GetZone(destination) != zone) return false; // target is in a different zone (TODO: implement this maybe? not sure if really required) return true; } @@ -134,7 +121,7 @@ public static bool ShouldPath(GameNPC owner, Vector3 target) private int isReplottingPath = IDLE; const int IDLE = 0, REPLOTTING = 1; - private void ReplotPath(Vector3 target) + private void ReplotPath(Coordinate destination) { // Try acquiring a pathing lock if (Interlocked.CompareExchange(ref isReplottingPath, REPLOTTING, IDLE) != IDLE) @@ -147,40 +134,15 @@ private void ReplotPath(Vector3 target) try { var currentZone = Owner.CurrentZone; - var currrentPos = new Vector3(Owner.X, Owner.Y, Owner.Z); - var pathingResult = PathingMgr.Instance.GetPathStraightAsync(currentZone, currrentPos, target); + var pathingResult = PathingMgr.Instance.GetPathStraightAsync(currentZone, Owner.Coordinate, destination); - lock (_pathNodes) + if (pathingResult.Error != PathingError.NoPathFound && pathingResult.Error != PathingError.NavmeshUnavailable && + !pathingResult.Path.Start.Equals(Coordinate.Nowhere)) { - _pathNodes.Clear(); - if (pathingResult.Error != PathingError.NoPathFound && pathingResult.Error != PathingError.NavmeshUnavailable && - pathingResult.Points != null) - { - DidFindPath = true; - var to = pathingResult.Points.Length - 1; /* remove target node only if no partial path */ - if (pathingResult.Error == PathingError.PartialPathFound) - { - to = pathingResult.Points.Length; - } - for (int i = 1; i < to; i++) /* remove first node */ - { - var pt = pathingResult.Points[i]; - if (pt.Position.X < -500000) - { - log.Error("PathCalculator.ReplotPath returned weird node: " + pt + " (result=" + pathingResult.Error + - "); this=" + this); - } - _pathNodes.Enqueue(pt); - } - } - else - { - //noPathFoundMetric.Mark(); - DidFindPath = false; - } - _lastTarget = target; - ForceReplot = false; + path = pathingResult.Path; } + _lastTarget = destination; + ForceReplot = false; } finally { @@ -191,77 +153,34 @@ private void ReplotPath(Vector3 target) } } - /// - /// Calculates the next point this NPC should walk to to reach the target - /// - /// - /// Next path node, or null if target reached. Throws a NoPathToTargetException if path is blocked/returns> - public Tuple CalculateNextTarget(Vector3 target) + public Coordinate CalculateNextLineSegment(Coordinate destination) { - if (!ShouldPath(target)) + if (!ShouldPath(destination)) { - DidFindPath = true; // not needed - return new Tuple(null, NoPathReason.NOPROBLEM); + return Coordinate.Nowhere; } // Check if we can reuse our path. We assume that we ourselves never "suddenly" warp to a completely // different position. - if (ForceReplot || !_lastTarget.IsInRange(target, MIN_TARGET_DIFF_REPLOT_DISTANCE)) + if (ForceReplot || _lastTarget.DistanceTo(destination) > MIN_TARGET_DIFF_REPLOT_DISTANCE) { - ReplotPath(target); + ReplotPath(destination); } - // Find the next node in the path to the target, but skip points that are too close - while (_pathNodes.Count > 0 && Owner.IsWithinRadius(_pathNodes.Peek().Position, NODE_REACHED_DISTANCE)) + while (path.PointCount > 0 && Owner.Coordinate.DistanceTo(path.CurrentWayPoint) <= NODE_REACHED_DISTANCE) { - _pathNodes.Dequeue(); - } - - // Scan the next few nodes for a potential door - // TODO(mlinder): Implement support for doors - NextDoor = null; - /*foreach (var node in _pathNodes.Take(1)) { - if ((node.Flags & dtPolyFlags.DOOR) != 0) { - var currentNode = node; - try { - NextDoor = - DoorMgr.GetDoorsInRadius(Owner.Region, node.Position, DOOR_SEARCH_DISTANCE) - .MinBy(x => x.Position.DistanceSquared(currentNode.Position)); - // TODO(mlinder): Confirm whether this actually makes sure that the path goes through a door, and not just next to it? - } catch (InvalidOperationException) { - // TODO(mlinder): this is really inefficient b/c of exception handling, duh - Owner.DebugSend("Did not find door in radius"); - } - break; - } + path.SelectNextWayPoint(); } - // Open doors automagically (maybe not the best place to do this?) - if (NextDoor != null) { - Owner.DebugSend("There is a door on the next segment: {0}", NextDoor); - if (!DealWithDoorOnPath(NextDoor)) - { - return new Tuple(null, NoPathReason.DOOR_EN_ROUTE); - } - }*/ + // Find the next node in the path to the target, but skip points that are too close + var nextWayPoint = path.CurrentWayPoint; - if (_pathNodes.Count == 0) - { - // Path end reached, or no path found - if (!DidFindPath) - return new Tuple(null, NoPathReason.RECAST_FOUND_NO_PATH); - return new Tuple(null, NoPathReason.UNKNOWN); // no more nodes (or no path) - } + if (path.PointCount == 0) return Coordinate.Nowhere; // no more nodes (or no path) - // Just walk to the next pathing node - var next = _pathNodes.Peek(); - return new Tuple(next.Position, NoPathReason.NOPROBLEM); + return nextWayPoint; } public override string ToString() - { - return - $"PathCalc[Target={_lastTarget}, Nodes={_pathNodes.Count}, NextNode={(_pathNodes.Count > 0 ? _pathNodes.Peek().ToString() : null)}, NextDoor={NextDoor}]"; - } + => $"PathCalc[Target={_lastTarget}, Nodes={path.PointCount}, NextNode={(path.PointCount > 0 ? path.CurrentWayPoint.ToString() : null)}, NextDoor={NextDoor}]"; } } diff --git a/GameServer/world/Pathing/PathingMgr.cs b/GameServer/world/Pathing/PathingMgr.cs index 1110895a45..cb0099f68c 100644 --- a/GameServer/world/Pathing/PathingMgr.cs +++ b/GameServer/world/Pathing/PathingMgr.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Reflection; using log4net; diff --git a/GameServer/world/Pathing/Structs.cs b/GameServer/world/Pathing/Structs.cs index fbd30088cc..6c77386fe8 100644 --- a/GameServer/world/Pathing/Structs.cs +++ b/GameServer/world/Pathing/Structs.cs @@ -1,26 +1,7 @@ -using System; -using System.Numerics; +using System; namespace DOL.GS { - public struct WrappedPathingResult - { - public PathingError Error; - public WrappedPathPoint[] Points; - } - - - public struct WrappedPathPoint - { - public Vector3 Position; - public dtPolyFlags Flags; - - public override string ToString() - { - return $"({Position}, {Flags})"; - } - } - [Flags] public enum dtPolyFlags : ushort { diff --git a/GameServer/world/Point2D.cs b/GameServer/world/Point2D.cs index 9bf30e1201..adace08771 100644 --- a/GameServer/world/Point2D.cs +++ b/GameServer/world/Point2D.cs @@ -20,84 +20,27 @@ namespace DOL.GS { - /// - /// represents a point in 2 dimensional space - /// + [Obsolete("Use Coordinate instead!")] public class Point2D : IPoint2D { - /// - /// The factor to convert a heading value to radians - /// - /// - /// Heading to degrees = heading * (360 / 4096) - /// Degrees to radians = degrees * (PI / 180) - /// public const double HEADING_TO_RADIAN = (360.0/4096.0)*(Math.PI/180.0); - - /// - /// The factor to convert radians to a heading value - /// - /// - /// Radians to degrees = radian * (180 / PI) - /// Degrees to heading = degrees * (4096 / 360) - /// public const double RADIAN_TO_HEADING = (180.0/Math.PI)*(4096.0/360.0); - /// - /// The X coord of this point - /// - protected int m_x; - - /// - /// The Y coord of this point - /// - protected int m_y; + public Point2D() { } - /// - /// Constructs a new 2D point object - /// - public Point2D() : this(0, 0) - { - } - - /// - /// Constructs a new 2D point object - /// - /// The X coord - /// The Y coord public Point2D(int x, int y) { - m_x = x; - m_y = y; - } - - /// - /// Constructs a new 2D point object - /// - /// The 2D point - public Point2D(IPoint2D point) : this(point.X, point.Y) - { + X = x; + Y = y; } - #region IPoint2D Members + public Point2D(IPoint2D point) + : this(point.X, point.Y) { } - /// - /// X coord of this point - /// - public virtual int X - { - get { return m_x; } - set { m_x = value; } - } + #region IPoint2D Members - /// - /// Y coord of this point - /// - public virtual int Y - { - get { return m_y; } - set { m_y = value; } - } + public virtual int X { get; set; } = 0; + public virtual int Y { get; set; } = 0; // Coordinate calculation functions in DOL are standard trigonometric functions, but // with some adjustments to account for the different coordinate system that DOL uses @@ -121,11 +64,6 @@ public virtual int Y // The DOL Heading grid is 0 at the bottom of the Y-axis and increases clockwise. // General trigonometry and the System.Math library use the Cartesian grid. - /// - /// Get the heading to a point - /// - /// Target point - /// Heading to target point public ushort GetHeading(IPoint2D point) { float dx = point.X - X; @@ -139,12 +77,6 @@ public ushort GetHeading(IPoint2D point) return (ushort) heading; } - /// - /// Get the point at the given heading and distance - /// - /// DOL Heading - /// Distance to point - /// Point at the given heading and distance public Point2D GetPointFromHeading(ushort heading, int distance) { double angle = heading*HEADING_TO_RADIAN; @@ -166,15 +98,6 @@ public Point2D GetPointFromHeading(ushort heading, int distance) return point; } - /// - /// Get the distance to a point - /// - /// - /// If you don't actually need the distance value, it is faster - /// to use IsWithinRadius (since it avoids the square root calculation) - /// - /// Target point - /// Distance to point public int GetDistance(IPoint2D point) { double dx = (double) X - point.X; @@ -197,15 +120,9 @@ public virtual void Clear() /// public override string ToString() { - return string.Format("({0}, {1})", m_x.ToString(), m_y.ToString()); + return string.Format("({0}, {1})", X.ToString(), Y.ToString()); } - /// - /// Determine if another point is within a given radius - /// - /// Target point - /// Radius - /// True if the point is within the radius, otherwise false public bool IsWithinRadius(IPoint2D point, int radius) { if (radius > ushort.MaxValue) diff --git a/GameServer/world/Point3D.cs b/GameServer/world/Point3D.cs index fa8508e92d..70c50412d2 100644 --- a/GameServer/world/Point3D.cs +++ b/GameServer/world/Point3D.cs @@ -21,9 +21,7 @@ namespace DOL.GS { - /// - /// Defines a 3D point - /// + [Obsolete("Use Coordinate instead!")] public class Point3D : Point2D, IPoint3D { /// @@ -96,18 +94,9 @@ public override void Clear() /// public override string ToString() { - return string.Format("({0}, {1}, {2})", m_x.ToString(), m_y.ToString(), m_z.ToString()); + return string.Format("({0}, {1}, {2})", X.ToString(), Y.ToString(), Z.ToString()); } - /// - /// Get the distance to a point - /// - /// - /// If you don't actually need the distance value, it is faster - /// to use IsWithinRadius (since it avoids the square root calculation) - /// - /// Target point - /// Distance to point public virtual int GetDistanceTo(IPoint3D point) { double dx = (double) X - point.X; @@ -137,25 +126,11 @@ public virtual float GetDistanceTo(Vector3 point) return Vector3.Distance(new Vector3(X, Y, Z), point); } - /// - /// Determine if another point is within a given radius - /// - /// Target point - /// Radius - /// True if the point is within the radius, otherwise false public bool IsWithinRadius(IPoint3D point, int radius) { return IsWithinRadius(point, radius, false); } - - /// - /// Determine if another point is within a given radius, optionally ignoring Z values - /// - /// Target point - /// Radius - /// ignore Z - /// True if the point is within the radius, otherwise false public bool IsWithinRadius(IPoint3D point, int radius, bool ignoreZ) { if (radius > ushort.MaxValue) @@ -201,12 +176,5 @@ public bool IsWithinRadius(IPoint3D point, int radius, bool ignoreZ) return true; } - - public bool IsWithinRadius(Vector3 point, int radius, bool ignoreZ = false) - { - if (ignoreZ || point.Z == 0 || Z == 0) - return Vector2.DistanceSquared(new Vector2(X, Y), point.ToVector2()) <= radius * radius; - return Vector3.DistanceSquared(new Vector3(X, Y, Z), point) <= radius * radius; - } } } \ No newline at end of file diff --git a/GameServer/world/Region.cs b/GameServer/world/Region.cs index 978f04e4ca..6b93cc41e1 100644 --- a/GameServer/world/Region.cs +++ b/GameServer/world/Region.cs @@ -30,6 +30,7 @@ using DOL.GS.Utils; using DOL.GS.ServerProperties; using log4net; +using DOL.GS.Geometry; namespace DOL.GS { @@ -403,7 +404,7 @@ public virtual bool IsDungeon var zone = Zones[0]; - if (zone.XOffset == dungeonOffset && zone.YOffset == dungeonOffset) + if (zone.Offset.X == dungeonOffset && zone.Offset.Y == dungeonOffset) return true; //Only dungeons got this offset return false; @@ -979,7 +980,7 @@ public virtual void LoadFromDatabase(Mob[] mobObjs, ref long mobCount, ref long internal bool AddObject(GameObject obj) { //Thread.Sleep(10000); - Zone zone = GetZone(obj.X, obj.Y); + Zone zone = GetZone(obj.Coordinate); if (zone == null) { if (log.IsWarnEnabled) @@ -1225,50 +1226,37 @@ public GameObject GetObject(ushort id) return m_objects[id - 1]; } - /// - /// Returns the zone that contains the specified x and y values - /// - /// X value for the zone you're retrieving - /// Y value for the zone you're retrieving - /// The zone you're retrieving or null if it couldn't be found - public Zone GetZone(int x, int y) + public Zone GetZone(Coordinate coordinate) { - int varX = x; - int varY = y; - foreach (Zone zone in m_zones) + foreach (var zone in m_zones) { - if (zone.XOffset <= varX && zone.YOffset <= varY && (zone.XOffset + zone.Width) > varX && (zone.YOffset + zone.Height) > varY) - return zone; + var isInZone = zone.Offset.X <= coordinate.X && zone.Offset.Y <= coordinate.Y + && (zone.Offset.X + zone.Width) > coordinate.X && (zone.Offset.Y + zone.Height) > coordinate.Y; + if (isInZone) return zone; } return null; } - /// - /// Gets the X offset for the specified zone - /// - /// X value for the zone's offset you're retrieving - /// Y value for the zone's offset you're retrieving - /// The X offset of the zone you specified or 0 if it couldn't be found + [Obsolete("Use .GetZone(Coordinate) instead!")] + public Zone GetZone(int x, int y) + => GetZone(Coordinate.Create(x,y)); + + [Obsolete("Use Zone.XOffset calculation instead.")] public int GetXOffInZone(int x, int y) { - Zone z = GetZone(x, y); + Zone z = GetZone(Coordinate.Create(x, y)); if (z == null) return 0; - return x - z.XOffset; + return x - z.Offset.X; } - /// - /// Gets the Y offset for the specified zone - /// - /// X value for the zone's offset you're retrieving - /// Y value for the zone's offset you're retrieving - /// The Y offset of the zone you specified or 0 if it couldn't be found + [Obsolete("Use Zone.YOffset calculation instead.")] public int GetYOffInZone(int x, int y) { - Zone z = GetZone(x, y); + Zone z = GetZone(Coordinate.Create(x, y)); if (z == null) return 0; - return y - z.YOffset; + return y - z.Offset.Y; } /// @@ -1392,46 +1380,20 @@ public virtual void RemoveArea(IArea area) } } - /// - /// Gets the areas for given location, - /// less performant than getAreasOfZone so use other on if possible - /// - /// - /// - public virtual IList GetAreasOfSpot(IPoint3D point) - { - Zone zone = GetZone(point.X, point.Y); - return GetAreasOfZone(zone, point); - } + [Obsolete("Use .GetAreasOfSpot(Coordinate) instead!")] + public IList GetAreasOfSpot(int x, int y, int z) + => GetAreasOfSpot(Coordinate.Create(x, y, z)); - /// - /// Gets the areas for a certain spot, - /// less performant than getAreasOfZone so use other on if possible - /// - /// - /// - /// - /// - public virtual IList GetAreasOfSpot(int x, int y, int z) + public IList GetAreasOfSpot(Coordinate coordinate) { - Zone zone = GetZone(x, y); - Point3D p = new Point3D(x, y, z); - return GetAreasOfZone(zone, p); + var zone = GetZone(coordinate); + return GetAreasOfZone(zone, coordinate); } - public virtual IList GetAreasOfZone(Zone zone, IPoint3D p) - { - return GetAreasOfZone(zone, p, true); - } + public virtual IList GetAreasOfZone(Zone zone, Coordinate spot) + => GetAreasOfZone(zone, spot, true); - /// - /// Gets the areas for a certain spot - /// - /// - /// - /// - /// - public virtual IList GetAreasOfZone(Zone zone, IPoint3D p, bool checkZ) + public virtual IList GetAreasOfZone(Zone zone, Coordinate spot, bool checkZ) { lock (m_lockAreas) { @@ -1444,8 +1406,8 @@ public virtual IList GetAreasOfZone(Zone zone, IPoint3D p, bool checkZ) { for (int i = 0; i < m_ZoneAreasCount[zoneIndex]; i++) { - IArea area = (IArea)m_Areas[m_ZoneAreas[zoneIndex][i]]; - if (area.IsContaining(p, checkZ)) + var area = (IArea)m_Areas[m_ZoneAreas[zoneIndex][i]]; + if (area.IsContaining(spot, ignoreZ: !checkZ)) { areas.Add(area); } @@ -1460,34 +1422,6 @@ public virtual IList GetAreasOfZone(Zone zone, IPoint3D p, bool checkZ) return areas; } } - - public virtual IList GetAreasOfZone(Zone zone, int x, int y, int z) - { - lock (m_lockAreas) - { - int zoneIndex = Zones.IndexOf(zone); - var areas = new List(); - - if (zoneIndex >= 0) - { - try - { - for (int i = 0; i < m_ZoneAreasCount[zoneIndex]; i++) - { - IArea area = (IArea)m_Areas[m_ZoneAreas[zoneIndex][i]]; - if (area.IsContaining(x, y, z)) - areas.Add(area); - } - } - catch (Exception e) - { - log.Error("GetArea exception.Area count " + m_ZoneAreasCount[zoneIndex], e); - } - } - return areas; - } - } - #endregion #region Notify @@ -1517,25 +1451,18 @@ public virtual void Notify(DOLEvent e, EventArgs args) #region Object in Radius (Added by Konik & WitchKing) #region New Get in radius - - /// - /// Gets objects in a radius around a point - /// - /// OBJECT_TYPE (0=item, 1=npc, 2=player) - /// origin X - /// origin Y - /// origin Z - /// radius around origin - /// Get an ObjectDistance enumerator - /// IEnumerable to be used with foreach + [Obsolete("Use .GetInRadius(eGameObjectType,Coordinate,ushort,bool,bool) instead!)")] protected IEnumerable GetInRadius(Zone.eGameObjectType type, int x, int y, int z, ushort radius, bool withDistance, bool ignoreZ) + => GetInRadius(type, Coordinate.Create(x, y, z), radius, withDistance, ignoreZ); + + protected IEnumerable GetInRadius(Zone.eGameObjectType type, Coordinate center, ushort radius, bool withDistance, bool ignoreZ) { // check if we are around borders of a zone - Zone startingZone = GetZone(x, y); + Zone startingZone = GetZone(center); if (startingZone != null) { - ArrayList res = startingZone.GetObjectsInRadius(type, x, y, z, radius, new ArrayList(), ignoreZ); + ArrayList res = startingZone.GetObjectsInRadius(type, center, radius, new ArrayList(), ignoreZ); uint sqRadius = (uint)radius * radius; @@ -1543,9 +1470,9 @@ protected IEnumerable GetInRadius(Zone.eGameObjectType type, int x, int y, int z { if ((currentZone != startingZone) && (currentZone.TotalNumberOfObjects > 0) - && CheckShortestDistance(currentZone, x, y, sqRadius)) + && CheckShortestDistance(currentZone, center, sqRadius)) { - res = currentZone.GetObjectsInRadius(type, x, y, z, radius, res, ignoreZ); + res = currentZone.GetObjectsInRadius(type, center, radius, res, ignoreZ); } } @@ -1556,16 +1483,16 @@ protected IEnumerable GetInRadius(Zone.eGameObjectType type, int x, int y, int z switch (type) { case Zone.eGameObjectType.ITEM: - tmp = new ItemDistanceEnumerator(x, y, z, res); + tmp = new ItemDistanceEnumerator(center, res); break; case Zone.eGameObjectType.NPC: - tmp = new NPCDistanceEnumerator(x, y, z, res); + tmp = new NPCDistanceEnumerator(center, res); break; case Zone.eGameObjectType.PLAYER: - tmp = new PlayerDistanceEnumerator(x, y, z, res); + tmp = new PlayerDistanceEnumerator(center, res); break; case Zone.eGameObjectType.DOOR: - tmp = new DoorDistanceEnumerator(x, y, z, res); + tmp = new DoorDistanceEnumerator(center, res); break; default: tmp = new EmptyEnumerator(); @@ -1582,46 +1509,37 @@ protected IEnumerable GetInRadius(Zone.eGameObjectType type, int x, int y, int z { if (log.IsDebugEnabled) { - log.Error("GetInRadius starting zone is null for (" + type + ", " + x + ", " + y + ", " + z + ", " + radius + ") in Region ID=" + ID); + log.Error("GetInRadius starting zone is null for (" + type + ", " + center + ", " + radius + ") in Region ID=" + ID); } return new EmptyEnumerator(); } } - - /// - /// get the shortest distance from a point to a zone - /// - /// The zone to check - /// X value of the point - /// Y value of the point - /// The square radius to compare the distance with - /// True if the distance is shorter false either - private static bool CheckShortestDistance(Zone zone, int x, int y, uint squareRadius) + private static bool CheckShortestDistance(Zone zone, Coordinate coordinate, uint squareRadius) { // coordinates of zone borders - int xLeft = zone.XOffset; - int xRight = zone.XOffset + zone.Width; - int yTop = zone.YOffset; - int yBottom = zone.YOffset + zone.Height; + int xLeft = zone.Offset.X; + int xRight = zone.Offset.X + zone.Width; + int yTop = zone.Offset.Y; + int yBottom = zone.Offset.Y + zone.Height; long distance = 0; - if ((y >= yTop) && (y <= yBottom)) + if ((coordinate.Y >= yTop) && (coordinate.Y <= yBottom)) { - int xdiff = Math.Min(FastMath.Abs(x - xLeft), FastMath.Abs(x - xRight)); + int xdiff = Math.Min(FastMath.Abs(coordinate.X - xLeft), FastMath.Abs(coordinate.X - xRight)); distance = (long)xdiff * xdiff; } else { - if ((x >= xLeft) && (x <= xRight)) + if ((coordinate.X >= xLeft) && (coordinate.X <= xRight)) { - int ydiff = Math.Min(FastMath.Abs(y - yTop), FastMath.Abs(y - yBottom)); + int ydiff = Math.Min(FastMath.Abs(coordinate.Y - yTop), FastMath.Abs(coordinate.Y - yBottom)); distance = (long)ydiff * ydiff; } else { - int xdiff = Math.Min(FastMath.Abs(x - xLeft), FastMath.Abs(x - xRight)); - int ydiff = Math.Min(FastMath.Abs(y - yTop), FastMath.Abs(y - yBottom)); + int xdiff = Math.Min(FastMath.Abs(coordinate.X - xLeft), FastMath.Abs(coordinate.X - xRight)); + int ydiff = Math.Min(FastMath.Abs(coordinate.Y - yTop), FastMath.Abs(coordinate.Y - yBottom)); distance = (long)xdiff * xdiff + (long)ydiff * ydiff; } } @@ -1629,61 +1547,33 @@ private static bool CheckShortestDistance(Zone zone, int x, int y, uint squareRa return (distance <= squareRadius); } - /// - /// Gets Items in a radius around a spot - /// - /// origin X - /// origin Y - /// origin Z - /// radius around origin - /// Get an ObjectDistance enumerator - /// IEnumerable to be used with foreach + [Obsolete("Use .GetItemsInRadius(Coordinate,ushort,bool) instead!")] public IEnumerable GetItemsInRadius(int x, int y, int z, ushort radius, bool withDistance) - { - return GetInRadius(Zone.eGameObjectType.ITEM, x, y, z, radius, withDistance, false); - } + => GetItemsInRadius(Coordinate.Create(x,y,z), radius, withDistance); - /// - /// Gets NPCs in a radius around a spot - /// - /// origin X - /// origin Y - /// origin Z - /// radius around origin - /// Get an ObjectDistance enumerator - /// IEnumerable to be used with foreach + [Obsolete("Use .GetNPCsInRadius(Coordinate,ushort,bool,bool) instead!")] public IEnumerable GetNPCsInRadius(int x, int y, int z, ushort radius, bool withDistance, bool ignoreZ) - { - return GetInRadius(Zone.eGameObjectType.NPC, x, y, z, radius, withDistance, ignoreZ); - } + => GetNPCsInRadius(Coordinate.Create(x,y,z), radius, withDistance, ignoreZ); - /// - /// Gets Players in a radius around a spot - /// - /// origin X - /// origin Y - /// origin Z - /// radius around origin - /// Get an ObjectDistance enumerator - /// IEnumerable to be used with foreach + [Obsolete("Use .GetPlayersInRadius(Coordinate,ushort,bool,bool) instead!")] public IEnumerable GetPlayersInRadius(int x, int y, int z, ushort radius, bool withDistance, bool ignoreZ) - { - return GetInRadius(Zone.eGameObjectType.PLAYER, x, y, z, radius, withDistance, ignoreZ); - } + => GetPlayersInRadius(Coordinate.Create(x,y,z), radius, withDistance, ignoreZ); - /// - /// Gets Doors in a radius around a spot - /// - /// origin X - /// origin Y - /// origin Z - /// radius around origin - /// Get an ObjectDistance enumerator - /// IEnumerable to be used with foreach - public virtual IEnumerable GetDoorsInRadius(int x, int y, int z, ushort radius, bool withDistance) - { - return GetInRadius(Zone.eGameObjectType.DOOR, x, y, z, radius, withDistance, false); - } + [Obsolete("Use .GetDoorsInRadius(Coordinate,ushort,bool) instead!")] + public IEnumerable GetDoorsInRadius(int x, int y, int z, ushort radius, bool withDistance) + => GetDoorsInRadius(Coordinate.Create(x,y,z), radius, withDistance); + + public IEnumerable GetItemsInRadius(Coordinate center, ushort radius, bool withDistance) + => GetInRadius(Zone.eGameObjectType.ITEM, center, radius, withDistance, false); + + public IEnumerable GetNPCsInRadius(Coordinate center, ushort radius, bool withDistance, bool ignoreZ) + => GetInRadius(Zone.eGameObjectType.NPC, center, radius, withDistance, ignoreZ); + + public IEnumerable GetPlayersInRadius(Coordinate coordinate, ushort radius, bool withDistance, bool ignoreZ) + => GetInRadius(Zone.eGameObjectType.PLAYER, coordinate, radius, withDistance, ignoreZ); + + public virtual IEnumerable GetDoorsInRadius(Coordinate center, ushort radius, bool withDistance) + => GetInRadius(Zone.eGameObjectType.DOOR, center, radius, withDistance, false); #endregion @@ -1822,99 +1712,89 @@ public void Reset() public abstract class DistanceEnumerator : ObjectEnumerator { - protected int m_X; - protected int m_Y; - protected int m_Z; + protected Coordinate coordinate; public DistanceEnumerator(int x, int y, int z, ArrayList elements) + : this(Coordinate.Create(x, y, z), elements) { } + + public DistanceEnumerator(Coordinate coordinate, ArrayList elements) : base(elements) { - m_X = x; - m_Y = y; - m_Z = z; + this.coordinate = coordinate; } } - /// - /// This enumerator returns the object and the distance towards the object - /// public class PlayerDistanceEnumerator : DistanceEnumerator { public PlayerDistanceEnumerator(int x, int y, int z, ArrayList elements) - : base(x, y, z, elements) - { - } + : base(Coordinate.Create(x, y, z), elements) { } + + public PlayerDistanceEnumerator(Coordinate coordinate, ArrayList elements) + : base(coordinate,elements) { } public override object Current { get { GamePlayer obj = (GamePlayer)m_currentObj; - return new PlayerDistEntry(obj, obj.GetDistanceTo(new Point3D(m_X, m_Y, m_Z))); + return new PlayerDistEntry(obj, (int)obj.Coordinate.DistanceTo(coordinate)); } } } - /// - /// This enumerator returns the object and the distance towards the object - /// public class NPCDistanceEnumerator : DistanceEnumerator { public NPCDistanceEnumerator(int x, int y, int z, ArrayList elements) - : base(x, y, z, elements) - { - } + : base(Coordinate.Create(x, y, z), elements) { } + + public NPCDistanceEnumerator(Coordinate coordinate, ArrayList elements) + : base(coordinate,elements) { } public override object Current { get { GameNPC obj = (GameNPC)m_currentObj; - return new NPCDistEntry(obj, obj.GetDistanceTo(new Point3D(m_X, m_Y, m_Z))); + return new NPCDistEntry(obj, (int)obj.Coordinate.DistanceTo(coordinate)); } } } - /// - /// This enumerator returns the object and the distance towards the object - /// public class ItemDistanceEnumerator : DistanceEnumerator { public ItemDistanceEnumerator(int x, int y, int z, ArrayList elements) - : base(x, y, z, elements) - { - } + : base(Coordinate.Create(x, y, z), elements) { } + + public ItemDistanceEnumerator(Coordinate coordinate, ArrayList elements) + : base(coordinate,elements) { } public override object Current { get { GameStaticItem obj = (GameStaticItem)m_currentObj; - return new ItemDistEntry(obj, obj.GetDistanceTo(new Point3D(m_X, m_Y, m_Z))); + return new ItemDistEntry(obj, (int)obj.Coordinate.DistanceTo(coordinate)); } } } - /// - /// This enumerator returns the object and the distance towards the object - /// public class DoorDistanceEnumerator : DistanceEnumerator { public DoorDistanceEnumerator(int x, int y, int z, ArrayList elements) - : base(x, y, z, elements) - { - } + : base(Coordinate.Create(x, y, z), elements) { } + + public DoorDistanceEnumerator(Coordinate coordinate, ArrayList elements) + : base(coordinate,elements) { } public override object Current { get { IDoor obj = (IDoor)m_currentObj; - return new DoorDistEntry(obj, obj.GetDistance(new Point3D(m_X, m_Y, m_Z))); + return new DoorDistEntry(obj, (int)obj.Coordinate.DistanceTo(coordinate)); } } } - #endregion #endregion diff --git a/GameServer/world/TeleportArea.cs b/GameServer/world/TeleportArea.cs index 1e0df8b1fd..f61548bae8 100644 --- a/GameServer/world/TeleportArea.cs +++ b/GameServer/world/TeleportArea.cs @@ -22,6 +22,7 @@ using DOL.GS; using DOL.Database; using DOL.GS.PacketHandler; +using DOL.GS.Geometry; namespace DOL.GS { @@ -52,40 +53,16 @@ protected void OnTeleport(GamePlayer player, Teleport destination) if (player.InCombat == false && GameRelic.IsPlayerCarryingRelic(player) == false) { player.LeaveHouse(); - GameLocation currentLocation = new GameLocation("TeleportStart", player.CurrentRegionID, player.X, player.Y, player.Z); - player.MoveTo((ushort)destination.RegionID, destination.X, destination.Y, destination.Z, (ushort)destination.Heading); - GameServer.ServerRules.OnPlayerTeleport(player, currentLocation, destination); + player.MoveTo(destination.GetPosition()); + GameServer.ServerRules.OnPlayerTeleport(player, destination); } } } - /// - /// Description of TeleportArea. - /// Used to teleport players when someone enters, Withtout Z-checks - /// - public class TeleportPillarArea : TeleportArea - { - - public override bool IsContaining(int x, int y, int z) - { - return base.IsContaining(x, y, z, false); - } - - public override bool IsContaining(IPoint3D spot) - { - return base.IsContaining(spot, false); - } - - public override bool IsContaining(int x, int y, int z, bool checkZ) - { - return base.IsContaining(x, y, z, false); - } - - public override bool IsContaining(IPoint3D p, bool checkZ) - { - return base.IsContaining(p, false); - } - - } + public class TeleportPillarArea : TeleportArea + { + public override bool IsContaining(Coordinate spot, bool ignoreZ) + => base.IsContaining(spot, ignoreZ: true); + } } diff --git a/GameServer/world/WorldMgr.cs b/GameServer/world/WorldMgr.cs index 17bf6f7448..c3e99d5472 100644 --- a/GameServer/world/WorldMgr.cs +++ b/GameServer/world/WorldMgr.cs @@ -33,6 +33,7 @@ using DOL.GS.Housing; using log4net; +using DOL.GS.Geometry; namespace DOL.GS { @@ -1620,118 +1621,32 @@ public static GameObject GetObjectTypeByIDFromRegion(ushort regionID, ushort oID return obj; } - /// - /// Returns an IEnumerator of GamePlayers that are close to a certain - /// spot in the region - /// - /// Region to search - /// X inside region - /// Y inside region - /// Z inside region - /// Wether or not to return the objects with distance - /// Radius to sarch for GameClients - /// IEnumerator that can be used to go through all players - public static IEnumerable GetPlayersCloseToSpot(ushort regionid, int x, int y, int z, ushort radiusToCheck, bool withDistance) - { - Region reg = GetRegion(regionid); - if (reg == null) - return new Region.EmptyEnumerator(); - return reg.GetPlayersInRadius(x, y, z, radiusToCheck, withDistance, false); - } - - /// - /// Returns an IEnumerator of GamePlayers that are close to a certain - /// spot in the region - /// - /// the game location to search from - /// Radius to sarch for GameClients - /// IEnumerator that can be used to go through all players - public static IEnumerable GetPlayersCloseToSpot(IGameLocation location, ushort radiusToCheck) - { - return GetPlayersCloseToSpot(location.RegionID, location.X, location.Y, location.Z, radiusToCheck, false); - } - - /// - /// Returns an IEnumerator of GamePlayers that are close to a certain - /// spot in the region - /// - /// Region to search - /// the 3D point to search from - /// Radius to sarch for GameClients - /// IEnumerator that can be used to go through all players - public static IEnumerable GetPlayersCloseToSpot(ushort regionid, IPoint3D point, ushort radiusToCheck) - { - return GetPlayersCloseToSpot(regionid, point.X, point.Y, point.Z, radiusToCheck, false); - } - - /// - /// Returns an IEnumerator of GamePlayers that are close to a certain - /// spot in the region - /// - /// Region to search - /// X inside region - /// Y inside region - /// Z inside region - /// Radius to sarch for GameClients - /// IEnumerator that can be used to go through all players - public static IEnumerable GetPlayersCloseToSpot(ushort regionid, int x, int y, int z, ushort radiusToCheck) - { - return GetPlayersCloseToSpot(regionid, x, y, z, radiusToCheck, false); - } + [Obsolete("Use GetPlayersCloseToSpot(ushort,Coordinate,ushort) instead!")] + public static IEnumerable GetPlayersCloseToSpot(IGameLocation location, ushort radiusToCheck) + => GetPlayersCloseToSpot(location.Position, radiusToCheck); - /// - /// Returns an IEnumerator of GameNPCs that are close to a certain - /// spot in the region - /// - /// Region to search - /// X inside region - /// Y inside region - /// Z inside region - /// Radius to sarch for GameNPCs - /// Wether or not to return the objects with distance - /// IEnumerator that can be used to go through all NPCs - public static IEnumerable GetNPCsCloseToSpot(ushort regionid, int x, int y, int z, ushort radiusToCheck, bool withDistance) - { - Region reg = GetRegion(regionid); - if (reg == null) - return new Region.EmptyEnumerator(); - return reg.GetNPCsInRadius(x, y, z, radiusToCheck, withDistance, false); - } + [Obsolete("Use GetPlayersCloseToSpot(ushort,Coordinate,ushort) instead!")] + public static IEnumerable GetPlayersCloseToSpot(ushort regionid, IPoint3D point, ushort radiusToCheck) + => GetPlayersCloseToSpot(Position.Create(regionid, point.X, point.Y, point.Z), radiusToCheck); - /// - /// Returns an IEnumerator of GameNPCs that are close to a certain - /// spot in the region - /// - /// Region to search - /// X inside region - /// Y inside region - /// Z inside region - /// Radius to sarch for GameNPCs - /// IEnumerator that can be used to go through all NPCs - public static IEnumerable GetNPCsCloseToSpot(ushort regionid, int x, int y, int z, ushort radiusToCheck) - { - return GetNPCsCloseToSpot(regionid, x, y, z, radiusToCheck, false); - } + [Obsolete("Use GetPlayersCloseToSpot(ushort,Coordinate,ushort) instead!")] + public static IEnumerable GetPlayersCloseToSpot(ushort regionid, int x, int y, int z, ushort radiusToCheck) + => GetPlayersCloseToSpot(Position.Create(regionid, x, y, z), radiusToCheck); - /// - /// Returns an IEnumerator of GameItems that are close to a certain - /// spot in the region - /// - /// Region to search - /// X inside region - /// Y inside region - /// Z inside region - /// Radius to sarch for GameItems - /// Wether or not to return the objects with distance - /// IEnumerator that can be used to go through all items - public static IEnumerable GetItemsCloseToSpot(ushort regionid, int x, int y, int z, ushort radiusToCheck, bool withDistance) - { - Region reg = GetRegion(regionid); - if (reg == null) - return new Region.EmptyEnumerator(); + public static IEnumerable GetPlayersCloseToSpot(Position position, ushort radiusToCheck) + { + Region reg = GetRegion(position.RegionID); + if (reg == null) + return new Region.EmptyEnumerator(); + return reg.GetPlayersInRadius(position.Coordinate, radiusToCheck, false, false); + } - return reg.GetItemsInRadius(x, y, z, radiusToCheck, withDistance); - } + public static IEnumerable GetNPCsCloseToSpot(Position position, ushort radiusToCheck) + { + Region reg = GetRegion(position.RegionID); + if (reg == null) return new Region.EmptyEnumerator(); + return reg.GetNPCsInRadius(position.Coordinate, radiusToCheck, false, false); + } /// /// Saves all players into the database. diff --git a/GameServer/world/WorldUpdateThread.cs b/GameServer/world/WorldUpdateThread.cs index 679ea6c16e..9569f2b082 100644 --- a/GameServer/world/WorldUpdateThread.cs +++ b/GameServer/world/WorldUpdateThread.cs @@ -28,6 +28,7 @@ using DOL.GS.Housing; using DOL.AI.Brain; using DOL.Events; +using DOL.GS.Geometry; namespace DOL.GS { @@ -422,7 +423,9 @@ public static void UpdatePlayerHousing(GamePlayer player, long nowTicks) // Get All House in Region IDictionary housesDict = HouseMgr.GetHouses(player.CurrentRegionID); // Build Vincinity List - var houses = housesDict.Values.Where(h => h != null && player.IsWithinRadius(h, HousingConstants.HouseViewingDistance)).ToArray(); + var houses = housesDict.Values + .Where(h => h != null && player.Coordinate.DistanceTo(h.Position) <= HousingConstants.HouseViewingDistance) + .ToArray(); try { diff --git a/GameServer/world/Zone.cs b/GameServer/world/Zone.cs index 1974d8d707..6d0dc3e2ea 100644 --- a/GameServer/world/Zone.cs +++ b/GameServer/world/Zone.cs @@ -26,6 +26,7 @@ using DOL.Language; using DOL.GS.Utils; using log4net; +using DOL.GS.Geometry; namespace DOL.GS { @@ -157,16 +158,6 @@ public void Remove() /// private string m_Description; - /// - /// The XOffset of this Zone inside the region - /// - private readonly int m_XOffset; - - /// - /// The YOffset of this Zone inside the region - /// - private readonly int m_YOffset; - /// /// The Width of the Zone in Coordinates /// @@ -224,8 +215,7 @@ public Zone(Region region, ushort id, string desc, int xoff, int yoff, int width m_Region = region; m_ID = id; m_Description = desc; - m_XOffset = xoff; - m_YOffset = yoff; + Offset = Vector.Create(x: xoff, y: yoff); m_Width = width; m_Height = height; m_zoneSkinID = zoneskinID; @@ -391,21 +381,13 @@ public string Description set { m_Description = value; } } - /// - /// Returns the XOffset of this Zone - /// - public int XOffset - { - get { return m_XOffset; } - } + public Vector Offset { get; init; } - /// - /// Returns the YOffset of this Zone - /// - public int YOffset - { - get { return m_YOffset; } - } + [Obsolete("Use .Offset instead!")] + public int XOffset => Offset.X; + + [Obsolete("Use .Offset instead!")] + public int YOffset => Offset.Y; /// /// Returns the Width of this Zone @@ -462,45 +444,18 @@ private short GetSubZoneOffset(int lineSubZoneIndex, int columnSubZoneIndex) return (short)(columnSubZoneIndex + (lineSubZoneIndex << SUBZONE_ARRAY_Y_SHIFT)); } + private short GetSubZoneIndex(Coordinate loc) + { + int xDiff = loc.X - Offset.X; + int yDiff = loc.Y - Offset.Y; - /// - /// Returns the SubZone index using a position in the zone - /// - /// X position - /// Y position - /// The SubZoneIndex - private short GetSubZoneIndex(int p_X, int p_Y) - { - int xDiff = p_X - m_XOffset; - int yDiff = p_Y - m_YOffset; - - if ((xDiff < 0) || (xDiff > 65535) || (yDiff < 0) || (yDiff > 65535)) - { - // the object is out of the zone - return -1; - } - else - { - // the object is in the zone - //DOLConsole.WriteWarning("GetSubZoneIndex : " + SUBZONE_NBR_ON_ZONE_SIDE + ", " + SUBZONE_NBR + ", " + SUBZONE_SHIFT + ", " + SUBZONE_ARRAY_Y_SHIFT); - - xDiff >>= SUBZONE_SHIFT; - yDiff >>= SUBZONE_SHIFT; - - return GetSubZoneOffset(yDiff, xDiff); - } - } - + var isOutOfZone = (xDiff < 0) || (xDiff > 65535) || (yDiff < 0) || (yDiff > 65535); + if (isOutOfZone) return -1; - /// - /// Get the index of the subzone from the GameObject position - /// - /// The GameObject - /// The index of the subzone - private short GetSubZoneIndex(GameObject p_Obj) - { - return GetSubZoneIndex(p_Obj.X, p_Obj.Y); - } + xDiff >>= SUBZONE_SHIFT; + yDiff >>= SUBZONE_SHIFT; + return GetSubZoneOffset(yDiff, xDiff); + } /// @@ -511,7 +466,7 @@ public void ObjectEnterZone(GameObject p_Obj) { if (!m_initialized) InitializeZone(); - int subZoneIndex = GetSubZoneIndex(p_Obj); + int subZoneIndex = GetSubZoneIndex(p_Obj.Coordinate); if ((subZoneIndex >= 0) && (subZoneIndex < SUBZONE_NBR)) { SubNodeElement element = new SubNodeElement(); @@ -558,7 +513,7 @@ private void ObjectEnterZone(eGameObjectType objectType, SubNodeElement element) { if (!m_initialized) InitializeZone(); - int subZoneIndex = GetSubZoneIndex(element.data); + int subZoneIndex = GetSubZoneIndex(element.data.Coordinate); if (log.IsDebugEnabled) { @@ -580,27 +535,20 @@ private void ObjectEnterZone(eGameObjectType objectType, SubNodeElement element) } - /// - /// Gets the lists of objects, located in the current Zone and of the given type, that are at most at a 'radius' distance from (x,y,z) - /// The found objects are appended to the given 'partialList'. - /// - /// the type of objects to look for - /// the x coordinate of the observation position - /// the y coordinate of the observation position - /// the z coordinate of the observation position - /// the radius to check against - /// an initial (eventually empty but initialized, i.e. never null !!) list of objects - /// partialList augmented with the new objects verigying both type and radius in the current Zone - internal ArrayList GetObjectsInRadius(eGameObjectType type, int x, int y, int z, ushort radius, ArrayList partialList, bool ignoreZ) + /// + /// Gets the lists of objects, located in the current Zone and of the given type, that are at most at a 'radius' distance from (x,y,z) + /// The found objects are appended to the given 'partialList'. + /// + internal ArrayList GetObjectsInRadius(eGameObjectType type, Coordinate coordinate, ushort radius, ArrayList partialList, bool ignoreZ) { if (!m_initialized) InitializeZone(); // initialise parameters uint sqRadius = (uint)radius * (uint)radius; - int referenceSubzoneIndex = GetSubZoneIndex(x, y); + int referenceSubzoneIndex = GetSubZoneIndex(coordinate); int typeIndex = (int)type; - int xInZone = x - m_XOffset; // x in zone coordinates - int yInZone = y - m_YOffset; // y in zone coordinates + int xInZone = coordinate.X - Offset.X; // x in zone coordinates + int yInZone = coordinate.Y - Offset.Y; // y in zone coordinates int cellNbr = (radius >> SUBZONE_SHIFT) + 1; // radius in terms of subzone number int xInCell = xInZone >> SUBZONE_SHIFT; // xInZone in terms of subzone coord @@ -655,7 +603,7 @@ internal ArrayList GetObjectsInRadius(eGameObjectType type, int x, int y, int z, { // we are in the subzone of the observation point // => check all distances for all objects in the subzone - UnsafeAddToListWithDistanceCheck(startElement, x, y, z, sqRadius, typeIndex, currentSubZoneIndex, partialList, inZoneElements, outOfZoneElements, ignoreZ); + UnsafeAddToListWithDistanceCheck(startElement, coordinate, sqRadius, typeIndex, currentSubZoneIndex, partialList, inZoneElements, outOfZoneElements, ignoreZ); UnsafeUpdateSubZoneTimestamp(currentSubZoneIndex, typeIndex); } } @@ -688,7 +636,7 @@ internal ArrayList GetObjectsInRadius(eGameObjectType type, int x, int y, int z, lock (startElement) { - UnsafeAddToListWithDistanceCheck(startElement, x, y, z, sqRadius, typeIndex, currentSubZoneIndex, partialList, inZoneElements, outOfZoneElements, ignoreZ); + UnsafeAddToListWithDistanceCheck(startElement, coordinate, sqRadius, typeIndex, currentSubZoneIndex, partialList, inZoneElements, outOfZoneElements, ignoreZ); UnsafeUpdateSubZoneTimestamp(currentSubZoneIndex, typeIndex); } } @@ -765,9 +713,7 @@ private void UnsafeAddToListWithoutDistanceCheck(SubNodeElement startElement, in private void UnsafeAddToListWithDistanceCheck( SubNodeElement startElement, - int x, - int y, - int z, + Coordinate coordinate, uint sqRadius, int typeIndex, int subZoneIndex, @@ -801,7 +747,7 @@ private void UnsafeAddToListWithDistanceCheck( } else { - if (CheckSquareDistance(x, y, z, currentObject.X, currentObject.Y, currentObject.Z, sqRadius, ignoreZ) && !partialList.Contains(currentObject)) + if (CheckSquareDistance(coordinate, currentObject.Coordinate, sqRadius, ignoreZ) && !partialList.Contains(currentObject)) { // the current object exists, is Active and still in the current subzone // moreover it is in the right range and not yet in the result set @@ -926,7 +872,7 @@ private bool ShouldElementMove(SubNodeElement currentElement, int typeIndex, int { // the current object exists, is Active and still in the Region where this Zone is located - int currentElementSubzoneIndex = GetSubZoneIndex(currentObject.X, currentObject.Y); + int currentElementSubzoneIndex = GetSubZoneIndex(currentObject.Coordinate); if (currentElementSubzoneIndex == -1) { @@ -1027,7 +973,7 @@ private void PlaceElementsInOtherZones(DOL.GS.Collections.Hashtable elements) for (int i = 0; i < currentList.Count; i++) { currentElement = (SubNodeElement)currentList[i]; - currentZone = ZoneRegion.GetZone(currentElement.data.X, currentElement.data.Y); + currentZone = ZoneRegion.GetZone(currentElement.data.Coordinate); if (currentZone != null) { @@ -1037,50 +983,30 @@ private void PlaceElementsInOtherZones(DOL.GS.Collections.Hashtable elements) } } - #endregion + #endregion - /// - /// Checks that the square distance between two arbitary points in space is lower or equal to the given square distance - /// - /// X of Point1 - /// Y of Point1 - /// Z of Point1 - /// X of Point2 - /// Y of Point2 - /// Z of Point2 - /// the square distance to check for - /// The distance - public static bool CheckSquareDistance(int x1, int y1, int z1, int x2, int y2, int z2, uint sqDistance, bool ignoreZ) - { - int xDiff = x1 - x2; - long dist = ((long)xDiff) * xDiff; + public static bool CheckSquareDistance(Coordinate locA, Coordinate locB, uint squaredDistance, bool ignoreZ) + { + int xDiff = locA.X - locB.X; + var dist = ((long)xDiff) * xDiff; - if (dist > sqDistance) - { - return false; - } + if (dist > squaredDistance) return false; - int yDiff = y1 - y2; - dist += ((long)yDiff) * yDiff; + int yDiff = locA.Y - locB.Y; + dist += ((long)yDiff) * yDiff; - if (dist > sqDistance) - { - return false; - } + if (dist > squaredDistance) return false; - if (ignoreZ == false) - { - int zDiff = z1 - z2; - dist += ((long)zDiff) * zDiff; - } + if (ignoreZ == false) + { + int zDiff = locA.Z - locB.Z; + dist += ((long)zDiff) * zDiff; + } - if (dist > sqDistance) - { - return false; - } + if (dist > squaredDistance) return false; - return true; - } + return true; + } /// @@ -1151,26 +1077,8 @@ private bool CheckMaxDistance(int x, int y, int xLeft, int xRight, int yTop, int #region Area functions - /// - /// Convinientmethod for Region.GetAreasOfZone(), - /// since zone.Region.getAreasOfZone(zone,x,y,z) is a bit confusing ... - /// - /// - /// - public IList GetAreasOfSpot(IPoint3D spot) - { - return GetAreasOfSpot(spot, true); - } - - public IList GetAreasOfSpot(int x, int y, int z) - { - return m_Region.GetAreasOfZone(this, x, y, z); - } - - public IList GetAreasOfSpot(IPoint3D spot, bool checkZ) - { - return m_Region.GetAreasOfZone(this, spot, checkZ); - } + public IList GetAreasOfSpot(Coordinate spot) + => m_Region.GetAreasOfZone(this, spot, true); #endregion diff --git a/GameServer/world/ZonePointEffects.cs b/GameServer/world/ZonePointEffects.cs index 647d2c226d..e088ef5ed1 100644 --- a/GameServer/world/ZonePointEffects.cs +++ b/GameServer/world/ZonePointEffects.cs @@ -22,6 +22,7 @@ using DOL.Events; using DOL.Database; +using DOL.GS.Geometry; namespace DOL.GS.GameEvents { @@ -47,7 +48,7 @@ public static void OnScriptsCompiled(DOLEvent e, object sender, EventArgs args) // processing all the ZP IList zonePoints = GameServer.Database.SelectAllObjects(); - foreach (ZonePoint z in zonePoints) + foreach (var z in zonePoints) { if (z.SourceRegion == 0) continue; @@ -61,10 +62,7 @@ public static void OnScriptsCompiled(DOLEvent e, object sender, EventArgs args) GameNPC npc = new GameNPC(zp); - npc.CurrentRegionID = z.SourceRegion; - npc.X = z.SourceX; - npc.Y = z.SourceY; - npc.Z = z.SourceZ; + npc.Position = z.GetSourcePosition().With(npc.Orientation); npc.Name = r.Description; npc.GuildName = "ZonePoint (Open)"; if (r.IsDisabled) npc.GuildName = "ZonePoint (Closed)"; diff --git a/GameServerScripts/behaviour/examples/TestBehaviour.cs b/GameServerScripts/behaviour/examples/TestBehaviour.cs index c19dba6362..5b173523cd 100644 --- a/GameServerScripts/behaviour/examples/TestBehaviour.cs +++ b/GameServerScripts/behaviour/examples/TestBehaviour.cs @@ -11,6 +11,7 @@ using DOL.GS.Quests; using DOL.GS.PacketHandler; using DOL.AI.Brain; +using DOL.GS.Geometry; namespace DOL.GS.Behaviour.Examples { @@ -43,15 +44,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (log.IsWarnEnabled) log.Warn("Could not find " + SirQuait.Name + ", creating ..."); SirQuait.Realm = eRealm.Albion; - SirQuait.CurrentRegionID = 1; SirQuait.Size = 50; SirQuait.Level = 10; SirQuait.MaxSpeedBase = 100; SirQuait.Faction = FactionMgr.GetFactionByID(0); - SirQuait.X = 531971; - SirQuait.Y = 478955; - SirQuait.Z = 0; - SirQuait.Heading = 3570; + SirQuait.Position = Position.Create(regionID: 1, x: 531971, y: 478955, z: 0, heading: 3570); SirQuait.RespawnInterval = 0; SirQuait.BodyType = 0; diff --git a/GameServerScripts/customnpc/Desmona harpies/AtlantisVisualModelNPC.cs b/GameServerScripts/customnpc/Desmona harpies/AtlantisVisualModelNPC.cs index 011e1c46bf..1bd6f9f118 100644 --- a/GameServerScripts/customnpc/Desmona harpies/AtlantisVisualModelNPC.cs +++ b/GameServerScripts/customnpc/Desmona harpies/AtlantisVisualModelNPC.cs @@ -37,7 +37,6 @@ public override void BroadcastUpdate() player.Out.SendObjectUpdate(this); player.Out.SendModelChange(this, GetClientVisualModel(player.Client)); } - m_lastUpdateTickCount = (uint)Environment.TickCount; } } } diff --git a/GameServerScripts/customnpc/PortalCeremonyBaseNPC.cs b/GameServerScripts/customnpc/PortalCeremonyBaseNPC.cs index feb38445af..bed3478796 100644 --- a/GameServerScripts/customnpc/PortalCeremonyBaseNPC.cs +++ b/GameServerScripts/customnpc/PortalCeremonyBaseNPC.cs @@ -18,7 +18,7 @@ */ using System; using System.Collections.Generic; - +using DOL.GS.Geometry; namespace DOL.GS.Scripts { @@ -29,6 +29,7 @@ namespace DOL.GS.Scripts /// public class PortalCeremonyBaseNPC : GameNPC { + private readonly Position destinationDummy = Position.Create(regionID: 0, x: 0, y: 0, z: 0, heading: 0); /// /// Portal Pad Model id to override /// @@ -82,35 +83,14 @@ protected virtual ushort PortalTeleporterEffectCritic { get {return 0;} } - - /// - /// Portal destination X - /// - protected virtual int PortalDestinationX - { - get {return 0;} - } - /// - /// Portal destination Y - /// - protected virtual int PortalDestinationY - { - get {return 0;} - } - /// - /// Portal destination Z - /// - protected virtual int PortalDestinationZ - { - get {return 0;} - } - /// - /// Portal destination Region - /// - protected virtual int PortalDestinationRegion - { - get {return 0;} - } + + protected virtual Position PortalDestination + => destinationDummy; + + protected virtual int PortalDestinationX => PortalDestination.X; + protected virtual int PortalDestinationY => PortalDestination.Y; + protected virtual int PortalDestinationZ => PortalDestination.Z; + protected virtual int PortalDestinationRegion => PortalDestination.RegionID; /// /// Interval between teleport in milliseconds @@ -157,10 +137,7 @@ public override bool AddToWorld() return false; // Add the Item Pad - m_worldObject.X = X; - m_worldObject.Y = Y; - m_worldObject.Z = Z; - m_worldObject.Heading = Heading; + m_worldObject.Position = Position; m_worldObject.Model = PortalWorldObjectModel; m_worldObject.AddToWorld(); @@ -170,12 +147,10 @@ public override bool AddToWorld() for (int cnt = 0 ; cnt < PortalTeleporterCount ; cnt++) { GameNPC teleporter = new GameNPC(teleporters); - Point2D tgt = GetPointFromHeading((ushort)((Heading+(cnt*divisor))%4096), PortalCeremonyRange); - teleporter.X = tgt.X; - teleporter.Y = tgt.Y; - teleporter.Z = Z; + var assistantOrientation = Orientation + Angle.Heading(cnt * divisor + 2048); + var assistantLocation = Position + Vector.Create(assistantOrientation, length: PortalCeremonyRange); + teleporter.Position = assistantLocation.With(orientation: assistantOrientation); teleporter.CurrentRegion = CurrentRegion; - teleporter.Heading = (ushort)((Heading+(cnt*divisor)+2048)%4096); m_teleporters.Add(teleporter); teleporter.AddToWorld(); } @@ -220,7 +195,7 @@ protected virtual int TeleportTimerCallback(RegionTimer respawnTimer) { GamePlayer ply = player; if (ply != null) - ply.MoveTo((ushort)PortalDestinationRegion, PortalDestinationX, PortalDestinationY, PortalDestinationZ, player.Heading); + ply.MoveTo(PortalDestination.With(player.Orientation)); } } diff --git a/GameServerScripts/customnpc/RegionTestNpc.cs b/GameServerScripts/customnpc/RegionTestNpc.cs index ccc5fe0a16..0fba418d29 100644 --- a/GameServerScripts/customnpc/RegionTestNpc.cs +++ b/GameServerScripts/customnpc/RegionTestNpc.cs @@ -1,4 +1,5 @@ using System; +using DOL.GS.Geometry; namespace DOL.GS { @@ -46,30 +47,24 @@ public override bool SayReceive(GameLiving source, string str) Say("Instance is currently null."); else { - int x = 32361; - int y = 31744; - int z = 16003; - ushort heading = 1075; + var entrancePosition = Position.Create(regionID: m_instance.ID, x: 32361, y: 31744, z: 16003, heading: 1075); - if (m_instance.InstanceEntranceLocation != null) + if (m_instance.EntrancePosition != Position.Nowhere) { - x = m_instance.InstanceEntranceLocation.X; - y = m_instance.InstanceEntranceLocation.Y; - z = m_instance.InstanceEntranceLocation.Z; - heading = m_instance.InstanceEntranceLocation.Heading; + entrancePosition = m_instance.EntrancePosition; } // save current position so player can use /instance exit - GameLocation saveLocation = new GameLocation(source.Name + "_exit", source.CurrentRegionID, source.X, source.Y, source.Z); - source.TempProperties.setProperty(saveLocation.Name, saveLocation); + var savePosition = source.Position.With(Angle.Zero); + source.TempProperties.setProperty(source.Name + "_exit", savePosition); Say("Instance ID " + m_instance.ID + ", Skin: " + m_instance.Skin + ", with " + m_instance.Zones.Count + " zones inside the region."); - if (!source.MoveTo(m_instance.ID, x, y, z, heading)) + if (!source.MoveTo(entrancePosition)) { Say("Source could not be moved to instance entrance; MoveTo returned false. Now trying to move to current location inside the instance."); - if (!source.MoveTo(m_instance.ID, source.X, source.Y, source.Z, source.Heading)) + if (!source.MoveTo(source.Position)) { Say("Sorry, that failed as well."); } @@ -102,7 +97,7 @@ public void OnCommand(GameClient client, string[] args) if (npc == null) continue; - log.Warn(index + ": Object name=" + npc.Name + ", {X/Y/Z} H = { " + npc.X + " / " + npc.Y + " / " + npc.Z + " } " + npc.Heading + "."); + log.Warn(index + ": Object name=" + npc.Name + ", {X/Y/Z} H = { " + npc.Position.X + " / " + npc.Position.Y + " / " + npc.Position.Z + " } " + npc.Orientation.InHeading + "."); log.Warn("Zone, zoneID " + npc.CurrentZone.ID + " (" + npc.CurrentZone.Description + "), zoneSkinID = " + npc.CurrentZone.ZoneSkinID + "."); } } diff --git a/GameServerScripts/gameevents/DOLTestServer.cs b/GameServerScripts/gameevents/DOLTestServer.cs index de4793fb52..8fed5d3d0a 100644 --- a/GameServerScripts/gameevents/DOLTestServer.cs +++ b/GameServerScripts/gameevents/DOLTestServer.cs @@ -28,6 +28,7 @@ using System; using System.Reflection; using DOL.Events; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; @@ -95,7 +96,8 @@ public static void DOLTestPlayerEnterWorld(DOLEvent e, object sender, EventArgs //DOLTopia (our selfproclaimed town to show off) //If the player is > 10.000 coordinates away or in another region //we send a dialog to the player and register a dialog-callback - if (player.CurrentRegionID != 1 || !player.IsWithinRadius( new Point2D( 531405, 479515 ), 10000 )) + var doltopiaLocation = Coordinate.Create(x: 531405, y: 479515); + if (player.CurrentRegionID != 1 || player.Coordinate.DistanceTo(doltopiaLocation, ignoreZ: true) > 10000) player.Out.SendCustomDialog("Do you want to be teleported to DOLTopia?", new CustomDialogResponse(TeleportToDOLTopia)); } @@ -121,7 +123,7 @@ public static void TeleportToDOLTopia(GamePlayer player, byte response) if (response != 0x01) return; //The player clicked on "OK" so we teleport him! - player.MoveTo(1, 531405, 479515, 0, 2790); + player.MoveTo(Position.Create(regionID: 1, x: 531405, y: 479515, z: 0, heading: 2790)); } } } \ No newline at end of file diff --git a/GameServerScripts/gameevents/FightingNPC.cs b/GameServerScripts/gameevents/FightingNPC.cs index 3ebe43e10e..dd246570e1 100644 --- a/GameServerScripts/gameevents/FightingNPC.cs +++ b/GameServerScripts/gameevents/FightingNPC.cs @@ -17,7 +17,7 @@ * */ /* - * Author: SmallHorse & Crystalö + * Author: SmallHorse & Crystal * Date: 20.11.2003 * This script should be put in /scripts/gameevents directory. * This event simulates a guard-trainer and some of his trainees. @@ -29,6 +29,7 @@ using System.Reflection; using System.Timers; using DOL.Events; +using DOL.GS.Geometry; using log4net; namespace DOL.GS.GameEvents @@ -47,8 +48,8 @@ public class FightingNPC : GameNPC //Empty constructor, sets the default parameters for this NPC public FightingNPC() : base() { - Z = 0; - Heading = 0x0; + Position = Position.With(z: 0); + Orientation = Angle.Degrees(0); Model = 40; Size = 50; Level = 10; @@ -93,9 +94,7 @@ public static void OnScriptsCompiled(DOLEvent e, object sender, EventArgs args) //We create our guardmaster-trainer m_guardMaster = new FightingNPC(); - m_guardMaster.X = 531771; - m_guardMaster.Y = 478755; - m_guardMaster.Heading = 3570; + m_guardMaster.Position = m_guardMaster.Position.With(x: 531771, y: 478755, heading: 3570); m_guardMaster.Name = "Master Guard Trainer"; //Now we add some nice equipment to the guard-trainer GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); @@ -156,37 +155,32 @@ public static void OnScriptsCompiled(DOLEvent e, object sender, EventArgs args) } //We set the position, model and size of our trainees - m_guardTrainee[0].X = m_guardMaster.X - 70; - m_guardTrainee[0].Y = m_guardMaster.Y - 66; - m_guardTrainee[0].Heading = m_guardTrainee[0].GetHeading( m_guardMaster ); + m_guardTrainee[0].Position = m_guardMaster.Position + Vector.Create(-70, -66); + m_guardTrainee[0].TurnTo(m_guardMaster.Coordinate); m_guardTrainee[0].Model = (ushort) m_rnd.Next(32, 55); m_guardTrainee[0].Size = (byte) (45 + m_rnd.Next(10)); - m_guardTrainee[1].X = m_guardMaster.X + 76; - m_guardTrainee[1].Y = m_guardMaster.Y - 29; - m_guardTrainee[1].Heading = m_guardTrainee[1].GetHeading( m_guardMaster ); - ; + m_guardTrainee[1].Position = m_guardMaster.Position + Vector.Create(76, -29); + m_guardTrainee[1].TurnTo(m_guardMaster.Coordinate); + m_guardTrainee[1].Model = (ushort) m_rnd.Next(32, 55); m_guardTrainee[1].Size = (byte) (45 + m_rnd.Next(10)); - m_guardTrainee[2].X = m_guardMaster.X - 110; - m_guardTrainee[2].Y = m_guardMaster.Y + 22; - m_guardTrainee[2].Heading = m_guardTrainee[2].GetHeading( m_guardMaster ); - ; + m_guardTrainee[2].Position = m_guardMaster.Position + Vector.Create(-110, 22); + m_guardTrainee[2].TurnTo(m_guardMaster.Coordinate); + m_guardTrainee[2].Model = (ushort) m_rnd.Next(32, 55); m_guardTrainee[2].Size = (byte) (45 + m_rnd.Next(10)); - m_guardTrainee[3].X = m_guardMaster.X - 34; - m_guardTrainee[3].Y = m_guardMaster.Y + 88; - m_guardTrainee[3].Heading = m_guardTrainee[3].GetHeading( m_guardMaster ); - ; + m_guardTrainee[3].Position = m_guardMaster.Position + Vector.Create(-34, 88); + m_guardTrainee[3].TurnTo(m_guardMaster.Coordinate); + m_guardTrainee[3].Model = (ushort) m_rnd.Next(32, 55); m_guardTrainee[3].Size = (byte) (45 + m_rnd.Next(10)); - m_guardTrainee[4].X = m_guardMaster.X + 52; - m_guardTrainee[4].Y = m_guardMaster.Y + 64; - m_guardTrainee[4].Heading = m_guardTrainee[4].GetHeading( m_guardMaster ); - ; + m_guardTrainee[4].Position = m_guardMaster.Position + Vector.Create(52, 64); + m_guardTrainee[4].TurnTo(m_guardMaster.Coordinate); + m_guardTrainee[4].Model = (ushort) m_rnd.Next(32, 55); m_guardTrainee[4].Size = (byte) (45 + m_rnd.Next(10)); diff --git a/GameServerScripts/gameevents/FollowingNPC.cs b/GameServerScripts/gameevents/FollowingNPC.cs index e233b5a498..92f5cb27c9 100644 --- a/GameServerScripts/gameevents/FollowingNPC.cs +++ b/GameServerScripts/gameevents/FollowingNPC.cs @@ -31,6 +31,7 @@ using System.Reflection; using System.Timers; using DOL.Events; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; @@ -57,17 +58,13 @@ public FollowingNPC() : base() //npc in the constructor. You can set //the npc position, model etc. in the //StartEvent() method too if you want. - X = 505599; - Y = 437679; - Z = 0; - Heading = 0x0; + Position = Position.Create(regionID: 1, x: 505599, y: 437679, orientation: Angle.Zero); Name = "Ugly Spider"; GuildName = "Rightclick me"; Model = 132; Size = 30; Level = 10; Realm = eRealm.Albion; - CurrentRegionID = 1; //At the beginning, the spider isn't following anyone m_playerToFollow = null; @@ -113,11 +110,10 @@ protected void CalculateWalkToSpot(object sender, ElapsedEventArgs args) } //Calculate the difference between our position and the players position - float diffx = (long) m_playerToFollow.X - X; - float diffy = (long) m_playerToFollow.Y - Y; + var diffVec = m_playerToFollow.Coordinate - Coordinate; //Calculate the distance to the player - float distance = (float) Math.Sqrt(diffx*diffx + diffy*diffy); + float distance = (float)Math.Sqrt(diffVec.X * diffVec.X + diffVec.Y * diffVec.Y); //If the player walks away too far, then we will stop following if (distance > 3000) @@ -135,13 +131,6 @@ protected void CalculateWalkToSpot(object sender, ElapsedEventArgs args) //Our spot will be 50 coordinates from the player, so we //calculate how much x and how much y we need to subtract //from the player to get the right x and y to walk to - diffx = (diffx/distance)*50; - diffy = (diffy/distance)*50; - - //Subtract the offset from the players position to get - //our target position - int newX = (int) (m_playerToFollow.X - diffx); - int newY = (int) (m_playerToFollow.Y - diffy); //Our speed is based on the distance to the player //We will walk faster to the player if the player @@ -152,7 +141,8 @@ protected void CalculateWalkToSpot(object sender, ElapsedEventArgs args) speed = 50; //Make the mob walk to the new spot - PathTo(new Point3D(newX, newY, 0), (short)speed); + var destination = m_playerToFollow.Coordinate - Vector.Create((int)(diffVec.X/distance*50),(int)(diffVec.X/distance*50)); + PathTo(destination, (short)speed); } } diff --git a/GameServerScripts/gameevents/HorseRace.cs b/GameServerScripts/gameevents/HorseRace.cs index 15de38df54..ed2fbc345c 100644 --- a/GameServerScripts/gameevents/HorseRace.cs +++ b/GameServerScripts/gameevents/HorseRace.cs @@ -36,6 +36,7 @@ using System.Reflection; using System.Timers; using DOL.Events; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; @@ -95,13 +96,9 @@ public RaceHorse(int origX, int origY, ushort origHeading) : base() m_originalY = origY; m_originalHeading = origHeading; - CurrentRegionID = 1; + Position = Position.Create(regionID: 1, x: m_originalX, y: m_originalY, z: 0, heading: m_originalHeading); Level = 10; Realm = 0; - X = m_originalX; - Y = m_originalY; - Z = 0; - Heading = m_originalHeading; GuildName = "Race Horse"; } @@ -187,7 +184,8 @@ public override bool RiderMount(GamePlayer rider, bool forced) GetStartPoint(out startX, out startY); //Make the mob and it's rider walk to our startposition! - WalkTo(startX, startY, 0, 250); + var destination = Coordinate.Create(x: startX, y: startY, z: 0 ); + WalkTo(destination, 250); //Set the horse state correctly HorseState = RaceHorseState.WalkingToStart; //Return true -> allow the mounting @@ -215,7 +213,8 @@ public override bool RiderDismount(bool forced, GamePlayer player) UnregisterRacingHorse(this); //Walk back to our grazing spot if the rider dismounts - WalkTo(m_originalX, m_originalY, 0, 75); + var destination = Coordinate.Create(x: m_originalX, y: m_originalY, z: 0 ); + WalkTo(destination, 75); //Set our horsestate correctly m_horseState = RaceHorseState.WalkingToGrazing; //Return true -> allow the dismounting @@ -234,11 +233,10 @@ public override void Notify(DOLEvent e, object sender, EventArgs args) m_currentPathPoint = 0; //Get the next point we will be racing to - int x, y; - GetNextPoint(m_currentPathPoint, out x, out y); + var destination = GetNextWalkTarget(m_currentPathPoint); //Turn the horse towards the next point on the path - TurnTo(x, y); + TurnTo(destination); //We are waiting for the race to start now! m_horseState = RaceHorseState.WaitingForRaceStart; @@ -246,7 +244,7 @@ public override void Notify(DOLEvent e, object sender, EventArgs args) else if (HorseState == RaceHorseState.WalkingToGrazing) { //We set our heading to our original heading - Heading = m_originalHeading; + Orientation = Angle.Heading(m_originalHeading); //We broadcast the update to the players around us BroadcastUpdate(); //Set the horse state back to grazing @@ -281,11 +279,9 @@ public override void Notify(DOLEvent e, object sender, EventArgs args) CurrentSpeed = 550; //We get our next pathpoint and - int nextX, nextY; - GetNextPoint(m_currentPathPoint, out nextX, out nextY); + var destination = GetNextWalkTarget(m_currentPathPoint); m_currentPathPoint++; - - WalkTo(nextX, nextY, 0, CurrentSpeed); + WalkTo(destination, CurrentSpeed); } } } @@ -302,25 +298,24 @@ public void StartRace() m_currentPathPoint = 0; //We fetch the next pathpoint - int x, y; - GetNextPoint(m_currentPathPoint, out x, out y); + var destination = GetNextWalkTarget(m_currentPathPoint); //Now our current point is 1 m_currentPathPoint++; //Walk to the target spot ... our speed is 500+random 20 Random rnd = new Random(); - WalkTo(x, y, 0, (short)(500 + rnd.Next(20))); + WalkTo(destination, (short)(500 + rnd.Next(20))); } //This function is used to return the next pathpoint for a horse //given the current pathpoint. The horses will race parallel to each //other, depending on their startnumber - protected void GetNextPoint(int curPoint, out int x, out int y) + protected Coordinate GetNextWalkTarget(int curPointIndex) { //We get the vector from our current point to the next point and turn //it by 90 degrees so it is normal to our vector to the next point - float normvx = racePoints[curPoint + 1, 1] - racePoints[curPoint, 1]; //DIFFY - float normvy = -(racePoints[curPoint + 1, 0] - racePoints[curPoint, 0]); //-DIFFX + float normvx = racePoints[curPointIndex + 1, 1] - racePoints[curPointIndex, 1]; //DIFFY + float normvy = -(racePoints[curPointIndex + 1, 0] - racePoints[curPointIndex, 0]); //-DIFFX //We now get the unit vector of our normal vector float len = (float) Math.Sqrt(normvx*normvx + normvy*normvy); @@ -353,9 +348,11 @@ protected void GetNextPoint(int curPoint, out int x, out int y) break; } - //return the next point with the correct offset - x = (int) (racePoints[curPoint + 1, 0] + offx); - y = (int) (racePoints[curPoint + 1, 1] + offy); + //return the next point with the correct offset + return Coordinate.Create( + x: (int)(racePoints[curPointIndex + 1, 0] + offx), + y: (int)(racePoints[curPointIndex + 1, 1] + offy) + ); } //Get the startpoint of our horse based on the startnumber diff --git a/GameServerScripts/gameevents/StartupLocations.cs b/GameServerScripts/gameevents/StartupLocations.cs index 515016acdd..282feda4e5 100644 --- a/GameServerScripts/gameevents/StartupLocations.cs +++ b/GameServerScripts/gameevents/StartupLocations.cs @@ -151,7 +151,7 @@ public static void CharacterSelection(DOLEvent ev, object sender, EventArgs args if (chArgs == null) return; - DOLCharacters ch = chArgs.Character; + var ch = chArgs.Character; // check if location looks ok. if (ch.Xpos == 0 && ch.Ypos == 0 && ch.Zpos == 0) diff --git a/GameServerScripts/gameevents/TalkingNPC.cs b/GameServerScripts/gameevents/TalkingNPC.cs index 7f7d417a5e..9a06fb8f53 100644 --- a/GameServerScripts/gameevents/TalkingNPC.cs +++ b/GameServerScripts/gameevents/TalkingNPC.cs @@ -28,6 +28,7 @@ using System; using System.Reflection; using DOL.Events; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; @@ -52,17 +53,13 @@ public TalkingNPC() : base() //npc in the constructor. You can set //the npc position, model etc. in the //StartEvent() method too if you want. - X = 505499; - Y = 437679; - Z = 0; - Heading = 0x0; + Position = Position.Create(regionID: 1, x: 505499, y: 437679, z: 0, heading: 0); Name = "The talking NPC"; GuildName = "Rightclick me"; Model = 5; Size = 50; Level = 10; Realm = eRealm.Albion; - CurrentRegionID = 1; } //This function is the callback function that is called when @@ -74,7 +71,7 @@ public override bool Interact(GamePlayer player) //Now we turn the npc into the direction of the person it is //speaking to. - TurnTo(player.X, player.Y); + TurnTo(player.Coordinate); //We send a message to player and make it appear in a popup //window. Text inside the [brackets] is clickable in popup @@ -101,7 +98,7 @@ public override bool WhisperReceive(GameLiving source, string str) //Now we turn the npc into the direction of the person it is //speaking to. - TurnTo(t.X, t.Y); + TurnTo(t.Coordinate); //We test what the player whispered to the npc and //send a reply. The Method SendReply used here is diff --git a/GameServerScripts/quests/Albion/AFewRepairs.cs b/GameServerScripts/quests/Albion/AFewRepairs.cs index c1dee67681..3a2ae6a9d1 100644 --- a/GameServerScripts/quests/Albion/AFewRepairs.cs +++ b/GameServerScripts/quests/Albion/AFewRepairs.cs @@ -33,6 +33,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -160,13 +161,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (log.IsWarnEnabled) log.Warn("Could not find " + briceYarley.Name + ", creating him ..."); briceYarley.Realm = eRealm.Albion; - briceYarley.CurrentRegionID = 1; briceYarley.Size = 51; briceYarley.Level = 43; - briceYarley.X = 370236; - briceYarley.Y = 679755; - briceYarley.Z = 5558; - briceYarley.Heading = 2468; + briceYarley.Position = Position.Create(regionID: 1, x: 370236, y: 679755, z: 5558, heading: 2468); briceYarley.MaxSpeedBase = 191; //You don't have to store the created mob in the db if you don't want, @@ -190,13 +187,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (log.IsWarnEnabled) log.Warn("Could not find " + patrickYarley.Name + ", creating him ..."); patrickYarley.Realm = eRealm.Albion; - patrickYarley.CurrentRegionID = 1; patrickYarley.Size = 51; patrickYarley.Level = 43; - patrickYarley.X = 371752; - patrickYarley.Y = 680486; - patrickYarley.Z = 5595; - patrickYarley.Heading = 0; + patrickYarley.Position = Position.Create(regionID: 1, x: 371752, y: 680486, z: 5595, heading: 0); patrickYarley.MaxSpeedBase = 200; //You don't have to store the created mob in the db if you don't want, diff --git a/GameServerScripts/quests/Albion/AMessageToTheManes.cs b/GameServerScripts/quests/Albion/AMessageToTheManes.cs index 57ce284251..39a9eb4089 100644 --- a/GameServerScripts/quests/Albion/AMessageToTheManes.cs +++ b/GameServerScripts/quests/Albion/AMessageToTheManes.cs @@ -29,6 +29,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -153,13 +154,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (log.IsWarnEnabled) log.Warn("Could not find " + sirJerem.Name + ", creating him ..."); sirJerem.Realm = eRealm.Albion; - sirJerem.CurrentRegionID = 1; sirJerem.Size = 49; sirJerem.Level = 38; - sirJerem.X = 573815; - sirJerem.Y = 530850; - sirJerem.Z = 2933; - sirJerem.Heading = 2685; + sirJerem.Position = Position.Create(regionID: 1, x: 573815, y: 530850, z: 2933, heading: 2685); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following diff --git a/GameServerScripts/quests/Albion/ANewHeroesWelcome.cs b/GameServerScripts/quests/Albion/ANewHeroesWelcome.cs index c429e9eb6c..c19fe84694 100644 --- a/GameServerScripts/quests/Albion/ANewHeroesWelcome.cs +++ b/GameServerScripts/quests/Albion/ANewHeroesWelcome.cs @@ -26,6 +26,7 @@ using System; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.Language; namespace DOL.GS.Quests.Albion @@ -156,7 +157,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + MasterClaistan.Name + ", creating him ..."); //MasterClaistan.GuildName = "Part of " + questTitle + " Quest"; MasterClaistan.Realm = eRealm.Albion; - MasterClaistan.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.HandsArmor, 39); @@ -169,10 +169,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) MasterClaistan.Size = 52; MasterClaistan.Level = 51; - MasterClaistan.X = 562190; - MasterClaistan.Y = 512571; - MasterClaistan.Z = 2500; - MasterClaistan.Heading = 1592; + MasterClaistan.Position = Position.Create(regionID: 1, x: 562190, y: 512571, z: 2500, heading: 1592); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -197,7 +194,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + PompinTheCrier.Name + ", creating him ..."); //MasterClaistan.GuildName = "Part of " + questTitle + " Quest"; PompinTheCrier.Realm = eRealm.Albion; - PompinTheCrier.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.HandsArmor, 39); @@ -210,10 +206,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) PompinTheCrier.Size = 50; PompinTheCrier.Level = 5; - PompinTheCrier.X = 560484; - PompinTheCrier.Y = 511756; - PompinTheCrier.Z = 2344; - PompinTheCrier.Heading = 420; + PompinTheCrier.Position = Position.Create(regionID: 1, x: 560484, y: 511756, z: 2344, heading: 420); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following diff --git a/GameServerScripts/quests/Albion/AfterTheAccident.cs b/GameServerScripts/quests/Albion/AfterTheAccident.cs index 697603a46b..36216e7b0a 100644 --- a/GameServerScripts/quests/Albion/AfterTheAccident.cs +++ b/GameServerScripts/quests/Albion/AfterTheAccident.cs @@ -19,6 +19,7 @@ using System; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.Language; namespace DOL.GS.Quests.Albion @@ -216,7 +217,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + SirPrescott.Name + ", creating him ..."); //SirPrescott.GuildName = "Part of " + questTitle + " Quest"; SirPrescott.Realm = eRealm.Albion; - SirPrescott.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.HandsArmor, 39); @@ -229,10 +229,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) SirPrescott.Size = 50; SirPrescott.Level = 50; - SirPrescott.X = 559862; - SirPrescott.Y = 513092; - SirPrescott.Z = 2408; - SirPrescott.Heading = 2480; + SirPrescott.Position = Position.Create(regionID: 1, x: 559862, y: 513092, z: 2408, heading: 2480); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following diff --git a/GameServerScripts/quests/Albion/AgainstTheGrain.cs b/GameServerScripts/quests/Albion/AgainstTheGrain.cs index 57b2b15339..ed871a3698 100644 --- a/GameServerScripts/quests/Albion/AgainstTheGrain.cs +++ b/GameServerScripts/quests/Albion/AgainstTheGrain.cs @@ -34,6 +34,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -145,7 +146,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + laridiaTheMinstrel.Name + ", creating him ..."); laridiaTheMinstrel.GuildName = "Part of " + questTitle + " Quest"; laridiaTheMinstrel.Realm = eRealm.Albion; - laridiaTheMinstrel.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.HandsArmor, 137, 9); @@ -159,10 +159,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) laridiaTheMinstrel.Size = 49; laridiaTheMinstrel.Level = 25; - laridiaTheMinstrel.X = 562280; - laridiaTheMinstrel.Y = 512243; - laridiaTheMinstrel.Z = 2448 ; - laridiaTheMinstrel.Heading = 3049; + laridiaTheMinstrel.Position = Position.Create(regionID: 1, x: 562280, y: 512243, z: 2448 , heading: 3049); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -187,7 +184,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + farmerAsma.Name + ", creating him ..."); farmerAsma.GuildName = "Part of " + questTitle + " Quest"; farmerAsma.Realm = eRealm.Albion; - farmerAsma.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 31); @@ -199,10 +195,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) farmerAsma.Size = 50; farmerAsma.Level = 35; - farmerAsma.X = 563939; - farmerAsma.Y = 509234; - farmerAsma.Z = 2744 ; - farmerAsma.Heading = 21; + farmerAsma.Position = Position.Create(regionID: 1, x: 563939, y: 509234, z: 2744 , heading: 21); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following diff --git a/GameServerScripts/quests/Albion/Aiding_Guard_Alakyrr.cs b/GameServerScripts/quests/Albion/Aiding_Guard_Alakyrr.cs index 0f0af229b9..297ce45962 100644 --- a/GameServerScripts/quests/Albion/Aiding_Guard_Alakyrr.cs +++ b/GameServerScripts/quests/Albion/Aiding_Guard_Alakyrr.cs @@ -34,6 +34,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; @@ -101,15 +102,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + GuardAlakyrr.Name + ", creating ..."); GuardAlakyrr.GuildName = "Part of " + questTitle + " Quest"; GuardAlakyrr.Realm = eRealm.Albion; - GuardAlakyrr.CurrentRegionID = 63; GuardAlakyrr.Size = 50; GuardAlakyrr.Level = 30; GuardAlakyrr.MaxSpeedBase = 191; GuardAlakyrr.Faction = FactionMgr.GetFactionByID(0); - GuardAlakyrr.X = 28707; - GuardAlakyrr.Y = 20147; - GuardAlakyrr.Z = 16760; - GuardAlakyrr.Heading = 4016; + GuardAlakyrr.Position = Position.Create(regionID: 63, x: 28707, y: 20147, z: 16760, heading: 4016); GuardAlakyrr.RespawnInterval = -1; GuardAlakyrr.BodyType = 0; diff --git a/GameServerScripts/quests/Albion/AndrewsSkins.cs b/GameServerScripts/quests/Albion/AndrewsSkins.cs index dba6944754..4915ebb28c 100644 --- a/GameServerScripts/quests/Albion/AndrewsSkins.cs +++ b/GameServerScripts/quests/Albion/AndrewsSkins.cs @@ -36,6 +36,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -153,7 +154,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + andrewWyatt.Name + ", creating him ..."); andrewWyatt.GuildName = "Part of " + questTitle + " Quest"; andrewWyatt.Realm = eRealm.Albion; - andrewWyatt.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.HandsArmor, 80); @@ -165,10 +165,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) andrewWyatt.Size = 48; andrewWyatt.Level = 30; - andrewWyatt.X = 559590; - andrewWyatt.Y = 511039; - andrewWyatt.Z = 2488; - andrewWyatt.Heading = 1524; + andrewWyatt.Position = Position.Create(regionID: 1, x: 559590, y: 511039, z: 2488, heading: 1524); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -192,7 +189,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) georNadren.Name = "Geor Nadren"; georNadren.GuildName = "Part of " + questTitle + " Quest"; georNadren.Realm = eRealm.Albion; - georNadren.CurrentRegionID = 10; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.HandsArmor, 39); @@ -205,10 +201,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) georNadren.Size = 51; georNadren.Level = 8; - georNadren.X = 37355; - georNadren.Y = 30943; - georNadren.Z = 8002; - georNadren.Heading = 3231; + georNadren.Position = Position.Create(regionID: 10, x: 37355, y: 30943, z: 8002, heading: 3231); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -231,7 +224,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) verNuren.Name = "Ver Nuren"; verNuren.GuildName = "Part of " + questTitle + " Quest"; verNuren.Realm = eRealm.Albion; - verNuren.CurrentRegionID = 10; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.LeftHandWeapon, 61); @@ -245,10 +237,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) verNuren.Size = 51; verNuren.Level = 8; - verNuren.X = 36799; - verNuren.Y = 30786; - verNuren.Z = 8010; - verNuren.Heading = 625; + verNuren.Position = Position.Create(regionID: 10, x: 36799, y: 30786, z: 8010, heading: 625); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following diff --git a/GameServerScripts/quests/Albion/ArgussArrows.cs b/GameServerScripts/quests/Albion/ArgussArrows.cs index 3c4091729d..8e75135512 100644 --- a/GameServerScripts/quests/Albion/ArgussArrows.cs +++ b/GameServerScripts/quests/Albion/ArgussArrows.cs @@ -37,6 +37,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -166,13 +167,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + argusBowman.Name + ", creating him ..."); argusBowman.GuildName = "Weapon Merchant"; argusBowman.Realm = eRealm.Albion; - argusBowman.CurrentRegionID = 1; argusBowman.Size = 50; argusBowman.Level = 18; - argusBowman.X = 530594; - argusBowman.Y = 480120; - argusBowman.Z = 2251; - argusBowman.Heading = 1627; + argusBowman.Position = Position.Create(regionID: 1, x: 530594, y: 480120, z: 2251, heading: 1627); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following diff --git a/GameServerScripts/quests/Albion/ArleighsAssistant.cs b/GameServerScripts/quests/Albion/ArleighsAssistant.cs index 9fe9e3686c..cd5b50bd4c 100644 --- a/GameServerScripts/quests/Albion/ArleighsAssistant.cs +++ b/GameServerScripts/quests/Albion/ArleighsAssistant.cs @@ -34,6 +34,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -157,30 +158,23 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) */ if (npcs.Length == 0) { - arleighPenn = new GameNPC(); - arleighPenn.Model = 8; - arleighPenn.Name = "Arleigh Penn"; - if (log.IsWarnEnabled) - log.Warn("Could not find " + arleighPenn.Name + ", creating him ..."); - arleighPenn.GuildName = "Dye Merchant"; - arleighPenn.Realm = eRealm.Albion; - arleighPenn.CurrentRegionID = 1; - arleighPenn.Size = 51; - arleighPenn.Level = 15; - arleighPenn.X = 574559; - arleighPenn.Y = 531482; - arleighPenn.Z = 2896; - arleighPenn.Heading = 2468; - - //You don't have to store the created mob in the db if you don't want, - //it will be recreated each time it is not found, just comment the following - //line if you rather not modify your database - if (SAVE_INTO_DATABASE) - arleighPenn.SaveIntoDatabase(); - - - arleighPenn.AddToWorld(); - + arleighPenn = new GameNPC(); + arleighPenn.Model = 8; + arleighPenn.Name = "Arleigh Penn"; + if (log.IsWarnEnabled) + log.Warn("Could not find " + arleighPenn.Name + ", creating him ..."); + arleighPenn.GuildName = "Dye Merchant"; + arleighPenn.Realm = eRealm.Albion; + arleighPenn.Size = 51; + arleighPenn.Level = 15; + arleighPenn.Position = Position.Create(regionID: 1, x: 574559, y: 531482, z: 2896, heading: 2468); + + //You don't have to store the created mob in the db if you don't want, + //it will be recreated each time it is not found, just comment the following + //line if you rather not modify your database + if (SAVE_INTO_DATABASE) arleighPenn.SaveIntoDatabase(); + + arleighPenn.AddToWorld(); } else arleighPenn = npcs[0]; diff --git a/GameServerScripts/quests/Albion/ArrowsForYettaFletcher.cs b/GameServerScripts/quests/Albion/ArrowsForYettaFletcher.cs index e771100cf3..07ac35a6d5 100644 --- a/GameServerScripts/quests/Albion/ArrowsForYettaFletcher.cs +++ b/GameServerScripts/quests/Albion/ArrowsForYettaFletcher.cs @@ -34,6 +34,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -147,14 +148,10 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + yettaFletcher.Name + ", creating him ..."); yettaFletcher.GuildName = "Part of " + questTitle + " Quest"; yettaFletcher.Realm = eRealm.Albion; - yettaFletcher.CurrentRegionID = 1; yettaFletcher.Size = 53; yettaFletcher.Level = 17; - yettaFletcher.X = 560072; - yettaFletcher.Y = 510125; - yettaFletcher.Z = 2473; - yettaFletcher.Heading = 1956; + yettaFletcher.Position = Position.Create(regionID: 1, x: 560072, y: 510125, z: 2473, heading: 1956); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following diff --git a/GameServerScripts/quests/Albion/BaseFrederickQuest.cs b/GameServerScripts/quests/Albion/BaseFrederickQuest.cs index 50d6cd754c..9e77a75994 100644 --- a/GameServerScripts/quests/Albion/BaseFrederickQuest.cs +++ b/GameServerScripts/quests/Albion/BaseFrederickQuest.cs @@ -39,6 +39,7 @@ using System.Reflection; using DOL.AI.Brain; using DOL.Database; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -163,7 +164,6 @@ public static GameNPC GetMasterFrederick() log.Warn("Could not find " + masterFrederick.Name + ", creating him ..."); masterFrederick.GuildName = "Part of Frederick Quests"; masterFrederick.Realm = eRealm.Albion; - masterFrederick.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 41); @@ -182,10 +182,7 @@ public static GameNPC GetMasterFrederick() masterFrederick.Size = 50; masterFrederick.Level = 50; - masterFrederick.X = 567969; - masterFrederick.Y = 509880; - masterFrederick.Z = 2861; - masterFrederick.Heading = 65; + masterFrederick.Position = Position.Create(regionID: 1, x: 567969, y: 509880, z: 2861, heading: 65); StandardMobBrain brain = new StandardMobBrain(); brain.AggroLevel = 0; diff --git a/GameServerScripts/quests/Albion/BeginningOfWar.cs b/GameServerScripts/quests/Albion/BeginningOfWar.cs index dbbb144af5..3f7347ff04 100644 --- a/GameServerScripts/quests/Albion/BeginningOfWar.cs +++ b/GameServerScripts/quests/Albion/BeginningOfWar.cs @@ -49,6 +49,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -75,7 +76,7 @@ public class BeginningOfWar : BaseFrederickQuest /// private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - /* Declare the variables we need inside our quest. + /* Declare the variables we need inside our quest. * You can declare static variables here, which will be available in * ALL instance of your quest and should be initialized ONLY ONCE inside * the OnScriptLoaded method. @@ -85,7 +86,8 @@ public class BeginningOfWar : BaseFrederickQuest * */ - protected static GameLocation locationFrederick = new GameLocation("Master Frederick", 1, 0, 19105 + 50, 26552 + 40, 2861, 0); + private static Coordinate fredericksLocation = Coordinate.Create(x: 19155, y: 26592, z: 2861) + WorldMgr.GetZone(0).Offset; + protected static Position locationFrederick = Position.Create(regionID: 1, fredericksLocation, heading: 0); protected const string questTitle = "Beginning of War"; protected const int minimumLevel = 4; @@ -93,7 +95,7 @@ public class BeginningOfWar : BaseFrederickQuest private static GameNPC masterFrederick = null; - private static GameLocation locationDunwynClone = new GameLocation(null, 1, 567604, 509619, 2813, 3292); + private static Position locationDunwynClone = Position.Create(regionID: 1, x: 567604, y: 509619, z: 2813, heading: 3292); private static GameNPC dunwyn = null; private GameNPC dunwynClone = null; @@ -181,14 +183,10 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) dunwyn.Name = "Master Dunwyn"; dunwyn.GuildName = "Part of " + questTitle + " Quest"; dunwyn.Realm = eRealm.Albion; - dunwyn.CurrentRegionID = 1; dunwyn.Size = 50; dunwyn.Level = 20; - dunwyn.X = 465383; - dunwyn.Y = 634773; - dunwyn.Z = 1840; - dunwyn.Heading = 187; + dunwyn.Position = Position.Create(regionID: 1, x: 465383, y: 634773, z: 1840, heading: 187); GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 798); @@ -218,14 +216,10 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) princessObera = new GameNPC(); princessObera.Name = "Princess Obera"; - princessObera.X = 579289; - princessObera.Y = 508200; - princessObera.Z = 2779; - princessObera.Heading = 347; + princessObera.Position = Position.Create(regionID: 1, x: 579289, y: 508200, z: 2779, heading: 347); princessObera.Model = 603; princessObera.GuildName = "Part of " + questTitle + " Quest"; princessObera.Realm = eRealm.None; - princessObera.CurrentRegionID = 1; princessObera.Size = 49; princessObera.Level = 3; @@ -266,19 +260,15 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) fairySorceress[i].Name = "ire fairy sorceress"; fairySorceress[i].GuildName = "Part of " + questTitle + " Quest"; fairySorceress[i].Realm = eRealm.None; - fairySorceress[i].CurrentRegionID = 1; fairySorceress[i].Size = 35; fairySorceress[i].Level = 3; - fairySorceress[i].X = princessObera.X + Util.Random(-150, 150); - fairySorceress[i].Y = princessObera.Y + Util.Random(-150, 150); - fairySorceress[i].Z = princessObera.Z; + fairySorceress[i].Position = princessObera.Position.With(heading: 93) + Vector.Create(x: Util.Random(-150, 150), y: Util.Random(-150, 150)); StandardMobBrain brain = new StandardMobBrain(); brain.AggroLevel = 30; brain.AggroRange = 300; fairySorceress[i].SetOwnBrain(brain); - fairySorceress[i].Heading = 93; //fairySorceress[i].EquipmentTemplateID = 200276; //You don't have to store the created mob in the db if you don't want, @@ -882,7 +872,7 @@ protected static void TalkToMasterDunwyn(DOLEvent e, object sender, EventArgs ar dunwyn.SayTo(player, "Hehe! Here you go!"); if (quest.Step == 13) { - quest.TeleportTo(player, dunwyn, locationFrederick, 10); + quest.TeleportTo(player, dunwyn, locationFrederick, "Master Frederick", 10, 0); } break; } @@ -1008,14 +998,10 @@ protected void CreateDunwynClone() dunwynClone.Model = dunwyn.Model; dunwynClone.GuildName = dunwyn.GuildName; dunwynClone.Realm = dunwyn.Realm; - dunwynClone.CurrentRegionID = 1; dunwynClone.Size = dunwyn.Size; dunwynClone.Level = 15; // to make the figthing against fairy sorceress a bit more dramatic :) - - dunwynClone.X = 567604 + Util.Random(-150, 150); - dunwynClone.Y = 509619 + Util.Random(-150, 150); - dunwynClone.Z = 2813; - dunwynClone.Heading = 3292; + dunwynClone.Position = Position.Create(regionID: 1, x: 567604, y: 509619, z: 2813, heading: 3292) + + Vector.Create(x: Util.Random(-150, 150), y: Util.Random(-150, 150)); GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 798); @@ -1042,7 +1028,7 @@ protected void CreateDunwynClone() } else { - TeleportTo(dunwynClone, dunwynClone, locationDunwynClone); + TeleportTo(dunwynClone, dunwynClone, locationDunwynClone, delay: 0, scatterRadius: 0); } } diff --git a/GameServerScripts/quests/Albion/BoarStew.cs b/GameServerScripts/quests/Albion/BoarStew.cs index 8c4bdc2f2f..16fd39effe 100644 --- a/GameServerScripts/quests/Albion/BoarStew.cs +++ b/GameServerScripts/quests/Albion/BoarStew.cs @@ -29,6 +29,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -152,13 +153,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + masterGerol.Name + ", creating him ..."); masterGerol.GuildName = "Healer"; masterGerol.Realm = eRealm.Albion; - masterGerol.CurrentRegionID = 1; masterGerol.Size = 45; masterGerol.Level = 20; - masterGerol.X = 578668; - masterGerol.Y = 556823; - masterGerol.Z = 2184; - masterGerol.Heading = 79; + masterGerol.Position = Position.Create(regionID: 1, x: 578668, y: 556823, z: 2184, heading: 79); masterGerol.MaxSpeedBase = 200; //You don't have to store the created mob in the db if you don't want, diff --git a/GameServerScripts/quests/Albion/BoulderlingBalm.cs b/GameServerScripts/quests/Albion/BoulderlingBalm.cs index a57c974c8a..2cade6f41d 100644 --- a/GameServerScripts/quests/Albion/BoulderlingBalm.cs +++ b/GameServerScripts/quests/Albion/BoulderlingBalm.cs @@ -31,6 +31,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -160,13 +161,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + brotherMaynard.Name + ", creating him ..."); brotherMaynard.GuildName = "Healer"; brotherMaynard.Realm = eRealm.Albion; - brotherMaynard.CurrentRegionID = 1; brotherMaynard.Size = 52; brotherMaynard.Level = 27; - brotherMaynard.X = 574190; - brotherMaynard.Y = 530721; - brotherMaynard.Z = 2896; - brotherMaynard.Heading = 1251; + brotherMaynard.Position = Position.Create(regionID: 1, x: 574190, y: 530721, z: 2896, heading: 1251); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following diff --git a/GameServerScripts/quests/Albion/BreakingTheBandits.cs b/GameServerScripts/quests/Albion/BreakingTheBandits.cs index b6ea46c968..58cff095f8 100644 --- a/GameServerScripts/quests/Albion/BreakingTheBandits.cs +++ b/GameServerScripts/quests/Albion/BreakingTheBandits.cs @@ -34,6 +34,7 @@ using DOL.GS.PacketHandler; using log4net; using DOL.GS.Finance; +using DOL.GS.Geometry; /* I suggest you declare yourself some namespaces for your quests * Like: DOL.GS.Quests.Albion * DOL.GS.Quests.Midgard @@ -157,13 +158,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (log.IsWarnEnabled) log.Warn("Could not find " + atheleys.Name + ", creating him ..."); atheleys.Realm = eRealm.Albion; - atheleys.CurrentRegionID = 1; atheleys.Size = 50; atheleys.Level = 30; - atheleys.X = 574375; - atheleys.Y = 530243; - atheleys.Z = 2906; - atheleys.Heading = 1922; + atheleys.Position = Position.Create(regionID: 1, x: 574375, y: 530243, z: 2906, heading: 1922); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -191,13 +188,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find Mostram, creating him ..."); mostram.GuildName = ""; mostram.Realm = eRealm.None; - mostram.CurrentRegionID = 1; mostram.Size = 52; mostram.Level = 9; - mostram.X = 574338; - mostram.Y = 536865; - mostram.Z = 2361; - mostram.Heading = 57; + mostram.Position = Position.Create(regionID: 1, x: 574338, y: 536865, z: 2361, heading: 57); StandardMobBrain brain = new StandardMobBrain(); brain.AggroLevel = 0; diff --git a/GameServerScripts/quests/Albion/BuildingABetterBow.cs b/GameServerScripts/quests/Albion/BuildingABetterBow.cs index 8c6db84421..70f5a36e74 100644 --- a/GameServerScripts/quests/Albion/BuildingABetterBow.cs +++ b/GameServerScripts/quests/Albion/BuildingABetterBow.cs @@ -34,6 +34,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -148,7 +149,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + elvarIronhand.Name + ", creating him ..."); elvarIronhand.GuildName = "Part of " + questTitle + " Quest"; elvarIronhand.Realm = eRealm.Albion; - elvarIronhand.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.RightHandWeapon, 12); @@ -157,10 +157,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) elvarIronhand.Size = 54; elvarIronhand.Level = 17; - elvarIronhand.X = 561351; - elvarIronhand.Y = 510292; - elvarIronhand.Z = 2400; - elvarIronhand.Heading = 3982; + elvarIronhand.Position = Position.Create(regionID: 1, x: 561351, y: 510292, z: 2400, heading: 3982); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following diff --git a/GameServerScripts/quests/Albion/Cellar_Infestation.cs b/GameServerScripts/quests/Albion/Cellar_Infestation.cs index 88c212ea39..b3ab3468b0 100644 --- a/GameServerScripts/quests/Albion/Cellar_Infestation.cs +++ b/GameServerScripts/quests/Albion/Cellar_Infestation.cs @@ -36,8 +36,9 @@ using DOL.GS.Behaviour; using DOL.GS.Behaviour.Attributes; using DOL.AI.Brain; +using DOL.GS.Geometry; - namespace DOL.GS.Quests.Albion { +namespace DOL.GS.Quests.Albion { /* The first thing we do, is to declare the class we create * as Quest. To do this, we derive from the abstract class @@ -120,15 +121,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + MistressLaws.Name + ", creating ..."); MistressLaws.GuildName = "Part of " + questTitle + " Quest"; MistressLaws.Realm = eRealm.Albion; - MistressLaws.CurrentRegionID = 51; MistressLaws.Size = 52; MistressLaws.Level = 40; MistressLaws.MaxSpeedBase = 191; MistressLaws.Faction = FactionMgr.GetFactionByID(0); - MistressLaws.X = 536859; - MistressLaws.Y = 548403; - MistressLaws.Z = 4800; - MistressLaws.Heading = 1035; + MistressLaws.Position = Position.Create(regionID: 51, x: 536859, y: 548403, z: 4800, heading: 1035); MistressLaws.RespawnInterval = -1; MistressLaws.BodyType = 0; @@ -165,15 +162,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + YlaineBarrett.Name + ", creating ..."); YlaineBarrett.GuildName = "Part of " + questTitle + " Quest"; YlaineBarrett.Realm = eRealm.Albion; - YlaineBarrett.CurrentRegionID = 51; YlaineBarrett.Size = 50; YlaineBarrett.Level = 40; YlaineBarrett.MaxSpeedBase = 191; YlaineBarrett.Faction = FactionMgr.GetFactionByID(0); - YlaineBarrett.X = 522790; - YlaineBarrett.Y = 542142; - YlaineBarrett.Z = 3230; - YlaineBarrett.Heading = 1661; + YlaineBarrett.Position = Position.Create(regionID: 51, x: 522790, y: 542142, z: 3230, heading: 1661); YlaineBarrett.RespawnInterval = -1; YlaineBarrett.BodyType = 0; diff --git a/GameServerScripts/quests/Albion/CemmethsOrders.cs b/GameServerScripts/quests/Albion/CemmethsOrders.cs index 0a9c5645ea..9a39a8d33c 100644 --- a/GameServerScripts/quests/Albion/CemmethsOrders.cs +++ b/GameServerScripts/quests/Albion/CemmethsOrders.cs @@ -26,6 +26,7 @@ using System; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.Language; namespace DOL.GS.Quests.Albion @@ -260,7 +261,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) //k109: My preference, no guildname for quest NPCs. Uncomment if you like that... //Cemmeth.GuildName = "Part of " + questTitle + " Quest"; CemmethBudgwold.Realm = eRealm.Albion; - CemmethBudgwold.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.HandsArmor, 49); //Slot 22 @@ -276,10 +276,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) CemmethBudgwold.Size = 50; CemmethBudgwold.Level = 38; - CemmethBudgwold.X = 560528; - CemmethBudgwold.Y = 513140; - CemmethBudgwold.Z = 2394; - CemmethBudgwold.Heading = 2275; + CemmethBudgwold.Position = Position.Create(regionID: 1, x: 560528, y: 513140, z: 2394, heading: 2275); if (SAVE_INTO_DATABASE) CemmethBudgwold.SaveIntoDatabase(); diff --git a/GameServerScripts/quests/Albion/ChildsPlay.cs b/GameServerScripts/quests/Albion/ChildsPlay.cs index b0ed518472..f66adadb6b 100644 --- a/GameServerScripts/quests/Albion/ChildsPlay.cs +++ b/GameServerScripts/quests/Albion/ChildsPlay.cs @@ -38,6 +38,7 @@ using DOL.GS.Behaviour; using DOL.GS.Behaviour.Attributes; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using DOL.GS.Quests; using DOL.Language; @@ -77,7 +78,7 @@ public class childsplay : BaseQuest private static ItemTemplate daringstuddedjerkin_alb = null; private static ItemTemplate daringstuddedleggings_alb = null; private static ItemTemplate daringstuddedsleeves_alb = null; - private static GameLocation Albion_Statue = new GameLocation("Childs Play (Alb)", 489, 27580, 40006, 14483); + private static Position Albion_Statue = Position.Create(regionID: 489, x: 27580, y: 40006, z: 14483); private static IArea Albion_Statue_Area = null; @@ -121,15 +122,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (log.IsWarnEnabled) log.Warn("Could not find " + Charles.Name + ", creating ..."); Charles.Realm = eRealm.Albion; - Charles.CurrentRegionID = 1; Charles.Size = 37; Charles.Level = 1; Charles.MaxSpeedBase = 191; Charles.Faction = FactionMgr.GetFactionByID(0); - Charles.X = 559883; - Charles.Y = 511489; - Charles.Z = 2382; - Charles.Heading = 3515; + Charles.Position = Position.Create(regionID: 1, x: 559883, y: 511489, z: 2382, heading: 3515); Charles.RespawnInterval = -1; Charles.BodyType = 0; @@ -1474,7 +1471,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) #endregion #region defineAreas - Albion_Statue_Area = WorldMgr.GetRegion(Albion_Statue.RegionID).AddArea(new Area.Circle("", Albion_Statue.X, Albion_Statue.Y, Albion_Statue.Z, 500)); + Albion_Statue_Area = WorldMgr.GetRegion(Albion_Statue.RegionID).AddArea(new Area.Circle("", Albion_Statue.Coordinate, 500)); Albion_Statue_Area.RegisterPlayerEnter(new DOLEventHandler(PlayerEnterStatueArea)); #endregion diff --git a/GameServerScripts/quests/Albion/CityOfCamelot.cs b/GameServerScripts/quests/Albion/CityOfCamelot.cs index 61e94a029b..00d57d9e8e 100644 --- a/GameServerScripts/quests/Albion/CityOfCamelot.cs +++ b/GameServerScripts/quests/Albion/CityOfCamelot.cs @@ -36,6 +36,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -75,14 +76,19 @@ public class CityOfCamelot : BaseFrederickQuest protected const string questTitle = "City of Camelot"; protected const int minimumLevel = 1; protected const int maximumLevel = 1; - - protected static GameLocation armsManTrainer = new GameLocation("Armsman Trainer", 10, 30985, 31520, 8216, 0); - protected static GameLocation reaverTrainer = new GameLocation("Reaver Trainer", 10, 32545, 26900, 7830, 0); - protected static GameLocation paladinTrainer = new GameLocation("Paladin Trainer", 10, 38920, 27845, 8636, 0); - protected static GameLocation mercenaryTrainer = new GameLocation("Mercenary Trainer", 10, 32826, 26831, 7995, 0); - - protected static GameLocation vaultKeeper = new GameLocation("Vault Keeper", 10, 35408, 23830, 8751, 0); - protected static GameLocation mainGates = new GameLocation("Main Gates", 10, 40069, 26463, 8255, 0); + + private static Position armsManTrainerPosition + = Position.Create(regionID: 10, x: 30985, y: 31520, z: 8216, heading: 0); + private static Position reaverTrainerPosition + = Position.Create(regionID: 10, x: 32545, y: 26900, z: 7830, heading: 0); + private static Position paladinTrainerPosition + = Position.Create(regionID: 10, x: 38920, y: 27845, z: 8636, heading: 0); + private static Position mercenaryTrainerPosition + = Position.Create(regionID: 10, x: 32826, y: 26831, z: 7995, heading: 0); + private static Position vaultKeeperPosition + = Position.Create(regionID: 10, x: 35408, y: 23830, z: 8751, heading: 0); + private static Position mainGatesPosition + = Position.Create(regionID: 10, x: 40069, y: 26463, z: 8255, heading: 0); private static GameNPC masterFrederick = null; private static GameNPC lordUrqhart = null; @@ -167,13 +173,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) lordUrqhart.Name = "Lord Urqhart"; lordUrqhart.GuildName = "Vault Keeper"; lordUrqhart.Realm = eRealm.Albion; - lordUrqhart.CurrentRegionID = 10; lordUrqhart.Size = 49; lordUrqhart.Level = 50; - lordUrqhart.X = 35500; - lordUrqhart.Y = 23857; - lordUrqhart.Z = 8751; - lordUrqhart.Heading = 603; + lordUrqhart.Position = Position.Create(regionID: 10, x: 35500, y: 23857, z: 8751, heading: 603); lordUrqhart.EquipmentTemplateID = "1707104"; //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -196,13 +198,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) bombard.Name = "Bombard"; bombard.GuildName = "Stable Master"; bombard.Realm = eRealm.Albion; - bombard.CurrentRegionID = 1; bombard.Size = 49; bombard.Level = 4; - bombard.X = 515718; - bombard.Y = 496739; - bombard.Z = 3352; - bombard.Heading = 2500; + bombard.Position = Position.Create(regionID: 1, x: 515718, y: 496739, z: 3352, heading: 2500); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -735,26 +733,26 @@ protected static void TalkToAssistant(DOLEvent e, object sender, EventArgs args) break; case "paladin": - quest.TeleportTo(paladinTrainer); + quest.TeleportWithAssistantTo(paladinTrainerPosition, "Paladin Trainer"); break; case "armsman": - quest.TeleportTo(armsManTrainer); + quest.TeleportWithAssistantTo(armsManTrainerPosition, "Armsman Trainer"); break; case "reaver": - quest.TeleportTo(reaverTrainer); + quest.TeleportWithAssistantTo(reaverTrainerPosition, "Reaver Trainer"); break; case "mercenary": - quest.TeleportTo(mercenaryTrainer); + quest.TeleportWithAssistantTo(mercenaryTrainerPosition, "Mercenary Trainer"); break; case "main gates": - quest.TeleportTo(mainGates); + quest.TeleportWithAssistantTo(mainGatesPosition, "Main Gates"); break; case "vault keeper": if (quest.Step == 3) { quest.Step = 4; } - quest.TeleportTo(vaultKeeper); + quest.TeleportWithAssistantTo(vaultKeeperPosition, "Vault Keeper"); break; case "go away": @@ -766,15 +764,12 @@ protected static void TalkToAssistant(DOLEvent e, object sender, EventArgs args) } } - /** - * Convinient Method for teleporintg with assistant - */ - protected void TeleportTo(GameLocation target) - { - TeleportTo(m_questPlayer, assistant, target, 5); - TeleportTo(assistant, assistant, target, 25, 50); - } + private void TeleportWithAssistantTo(Position destination, string destinationName) + { + TeleportTo(m_questPlayer, assistant, destination, destinationName, 5, 0); + TeleportTo(assistant, assistant, destination, destinationName, 25, 50); + } protected static void PlayerEnterWorld(DOLEvent e, object sender, EventArgs args) @@ -859,7 +854,7 @@ protected virtual int CreateAssistant(RegionTimer timer) { if (assistant != null && assistant.ObjectState == GameObject.eObjectState.Active) { - assistant.MoveTo(m_questPlayer.CurrentRegionID, m_questPlayer.X + 50, m_questPlayer.Y + 30, m_questPlayer.Z, m_questPlayer.Heading); + assistant.MoveTo(m_questPlayer.Position + Vector.Create(x: 50, y: 30)); } else { @@ -868,13 +863,9 @@ protected virtual int CreateAssistant(RegionTimer timer) assistant.Name = m_questPlayer.Name + "'s Assistant"; assistant.GuildName = "Part of " + questTitle + " Quest"; assistant.Realm = m_questPlayer.Realm; - assistant.CurrentRegionID = m_questPlayer.CurrentRegionID; assistant.Size = 25; assistant.Level = 5; - assistant.X = m_questPlayer.X + 50; - assistant.Y = m_questPlayer.Y + 50; - assistant.Z = m_questPlayer.Z; - assistant.Heading = m_questPlayer.Heading; + assistant.Position = m_questPlayer.Position + Vector.Create(x: 50, y: 50); assistant.AddToWorld(); diff --git a/GameServerScripts/quests/Albion/ClericMulgrut.cs b/GameServerScripts/quests/Albion/ClericMulgrut.cs index 30542612f1..0ebb594a07 100644 --- a/GameServerScripts/quests/Albion/ClericMulgrut.cs +++ b/GameServerScripts/quests/Albion/ClericMulgrut.cs @@ -33,6 +33,7 @@ using DOL.AI.Brain; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -146,7 +147,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + hughGallen.Name + ", creating him ..."); hughGallen.GuildName = "Part of " + questTitle + " Quest"; hughGallen.Realm = eRealm.Albion; - hughGallen.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.HandsArmor, 39); @@ -159,10 +159,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) hughGallen.Size = 49; hughGallen.Level = 38; - hughGallen.X = 574640; - hughGallen.Y = 531109; - hughGallen.Z = 2896; - hughGallen.Heading = 2275; + hughGallen.Position = Position.Create(regionID: 1, x: 574640, y: 531109, z: 2896, heading: 2275); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -477,14 +474,10 @@ public override void Notify(DOLEvent e, object sender, EventArgs args) mulgrutMaggot.Model = 467; mulgrutMaggot.Name = "Mulgrut Maggot"; mulgrutMaggot.Realm = eRealm.None; - mulgrutMaggot.CurrentRegionID = 1; mulgrutMaggot.Size = 60; mulgrutMaggot.Level = 5; - mulgrutMaggot.X = 565941; - mulgrutMaggot.Y = 528121; - mulgrutMaggot.Z = 2152; - mulgrutMaggot.Heading = 2278; + mulgrutMaggot.Position = Position.Create(regionID: 1, x: 565941, y: 528121, z: 2152, heading: 2278); StandardMobBrain brain = new StandardMobBrain(); // set a brain witch find a lot mob friend to attack the player mulgrutMaggot.SetOwnBrain(brain); diff --git a/GameServerScripts/quests/Albion/Collection.cs b/GameServerScripts/quests/Albion/Collection.cs index 3278b2815b..277a37150a 100644 --- a/GameServerScripts/quests/Albion/Collection.cs +++ b/GameServerScripts/quests/Albion/Collection.cs @@ -36,6 +36,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -80,7 +81,7 @@ public class Collection : BaseFrederickQuest private static GameNPC[] general = new GameNPC[3]; private static String[] generalNames = {"Palearis", "Bohad", "Fluvale"}; - private static GameLocation[] generalLocations = new GameLocation[3]; + private static Position[] generalLocations = new Position[3]; private static ItemTemplate fairyGeneralWings = null; @@ -144,9 +145,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) masterFrederick = GetMasterFrederick(); - generalLocations[0] = new GameLocation(generalNames[0], 1, 568589, 501801, 2134, 23); - generalLocations[1] = new GameLocation(generalNames[1], 1, 572320, 499246, 2472, 14); - generalLocations[2] = new GameLocation(generalNames[2], 1, 571900, 510559, 2210, 170); + generalLocations[0] = Position.Create(regionID: 1, x: 568589, y: 501801, z: 2134, heading: 23); + generalLocations[1] = Position.Create(regionID: 1, x: 572320, y: 499246, z: 2472, heading: 14); + generalLocations[2] = Position.Create(regionID: 1, x: 571900, y: 510559, z: 2210, heading: 170); GameNPC[] npcs = null; for (int i = 0; i < general.Length; i++) @@ -163,14 +164,10 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) general[i].Model = 603; general[i].Name = generalNames[i]; - general[i].X = generalLocations[i].X; - general[i].Y = generalLocations[i].Y; - general[i].Z = generalLocations[i].Z; - general[i].Heading = generalLocations[i].Heading; + general[i].Position = generalLocations[i]; general[i].GuildName = "Part of " + questTitle + " Quest"; general[i].Realm = eRealm.None; - general[i].CurrentRegionID = generalLocations[i].RegionID; general[i].Size = 49; general[i].Level = 2; diff --git a/GameServerScripts/quests/Albion/Culmination.cs b/GameServerScripts/quests/Albion/Culmination.cs index cb405f6224..da4f16ea51 100644 --- a/GameServerScripts/quests/Albion/Culmination.cs +++ b/GameServerScripts/quests/Albion/Culmination.cs @@ -36,6 +36,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -161,14 +162,10 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) queenTatiana = new GameNPC(); queenTatiana.Name = "Queen Tatiana"; - queenTatiana.X = 558500; - queenTatiana.Y = 533042; - queenTatiana.Z = 2573; - queenTatiana.Heading = 174; + queenTatiana.Position = Position.Create(regionID: 1, x: 558500, y: 533042, z: 2573, heading: 174); queenTatiana.Model = 603; queenTatiana.GuildName = "Part of " + questTitle + " Quest"; queenTatiana.Realm = eRealm.None; - queenTatiana.CurrentRegionID = 1; queenTatiana.Size = 49; queenTatiana.Level = 5; @@ -210,19 +207,14 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) fairySorceress[i].Name = "ire fairy sorceress"; fairySorceress[i].GuildName = "Part of " + questTitle + " Quest"; fairySorceress[i].Realm = eRealm.None; - fairySorceress[i].CurrentRegionID = 1; fairySorceress[i].Size = 35; fairySorceress[i].Level = 5; - fairySorceress[i].X = queenTatiana.X + Util.Random(30, 150); - fairySorceress[i].Y = queenTatiana.Y + Util.Random(30, 150); - fairySorceress[i].Z = queenTatiana.Z; + fairySorceress[i].Position = queenTatiana.Position.With(heading: 93) + Vector.Create(x: Util.Random(30, 150), y: Util.Random(30, 150)); StandardMobBrain brain = new StandardMobBrain(); brain.AggroLevel = 30; brain.AggroRange = 600; fairySorceress[i].SetOwnBrain(brain); - - fairySorceress[i].Heading = 93; //fairySorceress[i].EquipmentTemplateID = 200276; //You don't have to store the created mob in the db if you don't want, @@ -838,14 +830,10 @@ protected void CreateDunwynClone() dunwynClone.Model = 9; dunwynClone.GuildName = "Part of " + questTitle + " Quest"; dunwynClone.Realm = eRealm.Albion; - dunwynClone.CurrentRegionID = 1; dunwynClone.Size = 50; dunwynClone.Level = 14; - - dunwynClone.X = GameLocation.ConvertLocalXToGlobalX(8602, 0) + Util.Random(-150, 150); - dunwynClone.Y = GameLocation.ConvertLocalYToGlobalY(47193, 0) + Util.Random(-150, 150); - dunwynClone.Z = 2409; - dunwynClone.Heading = 342; + dunwynClone.Position = Position.CreateInZone(zoneID: 0, x: 8602, y: 47193, z: 2409, heading: 342) + + Vector.Create(x: Util.Random(-150, 150), y: Util.Random(-150, 150)); template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 798); @@ -868,7 +856,7 @@ protected void CreateDunwynClone() } else { - dunwynClone.MoveTo(1, 567604, 509619, 2813, 3292); + dunwynClone.MoveTo(Position.Create(regionID: 1, x: 567604, y: 509619, z: 2813, heading: 3292)); } @@ -886,15 +874,11 @@ protected void CreateDunwynClone() recruits[i].GuildName = "Part of " + questTitle + " Quest"; recruits[i].Realm = eRealm.Albion; - recruits[i].CurrentRegionID = 1; recruits[i].Size = 50; recruits[i].Level = 6; - recruits[i].X = GameLocation.ConvertLocalXToGlobalX(8602, 0) + Util.Random(-150, 150); - recruits[i].Y = GameLocation.ConvertLocalYToGlobalY(47193, 0) + Util.Random(-150, 150); - - recruits[i].Z = 2409; - recruits[i].Heading = 187; + recruits[i].Position = Position.CreateInZone(zoneID: 0, x: 8602, y: 47193, z: 2409, heading: 187) + + Vector.Create(x: Util.Random(-150, 150), y: Util.Random(-150, 150)); StandardMobBrain brain = new StandardMobBrain(); brain.AggroLevel = 0; diff --git a/GameServerScripts/quests/Albion/Disenchanted.cs b/GameServerScripts/quests/Albion/Disenchanted.cs index f8dd179763..5cde51fefe 100644 --- a/GameServerScripts/quests/Albion/Disenchanted.cs +++ b/GameServerScripts/quests/Albion/Disenchanted.cs @@ -33,6 +33,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -161,13 +162,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + palune.Name + ", creating him ..."); palune.GuildName = "Enchanter"; palune.Realm = eRealm.Albion; - palune.CurrentRegionID = 1; palune.Size = 52; palune.Level = 27; - palune.X = 573735; - palune.Y = 530508; - palune.Z = 2957; - palune.Heading = 3083; + palune.Position = Position.Create(regionID: 1, x: 573735, y: 530508, z: 2957, heading: 3083); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -191,13 +188,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + guardCynon.Name + ", creating him ..."); guardCynon.GuildName = "Part of " + questTitle + " Quest"; guardCynon.Realm = eRealm.Albion; - guardCynon.CurrentRegionID = 1; guardCynon.Size = 51; guardCynon.Level = 25; - guardCynon.X = 577920; - guardCynon.Y = 557362; - guardCynon.Z = 2159; - guardCynon.Heading = 3982; + guardCynon.Position = Position.Create(regionID: 1, x: 577920, y: 557362, z: 2159, heading: 3982); guardCynon.MaxSpeedBase = 200; //You don't have to store the created mob in the db if you don't want, diff --git a/GameServerScripts/quests/Albion/DredgeUpAPledge.cs b/GameServerScripts/quests/Albion/DredgeUpAPledge.cs index 428455d4dc..a5cd6909b8 100644 --- a/GameServerScripts/quests/Albion/DredgeUpAPledge.cs +++ b/GameServerScripts/quests/Albion/DredgeUpAPledge.cs @@ -26,6 +26,7 @@ using System; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.Language; namespace DOL.GS.Quests.Albion @@ -105,7 +106,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) //k109: My preference, no guildname for quest NPCs. Uncomment if you like that... //sirDorian.GuildName = "Part of " + questTitle + " Quest"; sirDorian.Realm = eRealm.Albion; - sirDorian.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.HandsArmor, 49); @@ -118,10 +118,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) sirDorian.Size = 52; sirDorian.Level = 40; - sirDorian.X = 560869; - sirDorian.Y = 511737; - sirDorian.Z = 2344; - sirDorian.Heading = 2930; + sirDorian.Position = Position.Create(regionID: 1, x: 560869, y: 511737, z: 2344, heading: 2930); if (SAVE_INTO_DATABASE) sirDorian.SaveIntoDatabase(); diff --git a/GameServerScripts/quests/Albion/Frontiers.cs b/GameServerScripts/quests/Albion/Frontiers.cs index 6114e6bdb0..12905ca897 100644 --- a/GameServerScripts/quests/Albion/Frontiers.cs +++ b/GameServerScripts/quests/Albion/Frontiers.cs @@ -38,6 +38,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using DOL.GS.Profession; using log4net; @@ -84,8 +85,8 @@ public class Frontiers : BaseFrederickQuest private static GameNPC alice = null; private static GameStableMaster uliam = null; - private static GameLocation locationAlice = null; - private static GameLocation locationUliam = null; + private static Position locationAlice = Position.Nowhere; + private static Position locationUliam = Position.Nowhere; private static GameStableMaster colm = null; private static GameNPC dragonfly = null; @@ -170,13 +171,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) masterVisur.Name = "Master Visur"; masterVisur.GuildName = "Part of " + questTitle + " Quest"; masterVisur.Realm = eRealm.Albion; - masterVisur.CurrentRegionID = 1; masterVisur.Size = 49; masterVisur.Level = 55; - masterVisur.X = 585589; - masterVisur.Y = 478396; - masterVisur.Z = 3368; - masterVisur.Heading = 56; + masterVisur.Position = Position.Create(regionID: 1, x: 585589, y: 478396, z: 3368, heading: 56); masterVisur.MaxSpeedBase = 200; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); @@ -210,12 +207,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) alice.Name = "Scryer Alice"; alice.GuildName = "Part of " + questTitle + " Quest"; alice.Realm = eRealm.Albion; - alice.CurrentRegionID = 1; alice.Size = 51; alice.Level = 50; - alice.X = 436598; - alice.Y = 650425; - alice.Z = 2448; + alice.Position = Position.Create(regionID: 1, x: 436598, y: 650425, z: 2448, heading: 3766); GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 81); @@ -232,7 +226,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) // alice.AddNPCEquipment(Slot.CLOAK, 91, 0, 0, 0); // alice.AddNPCEquipment(Slot.RIGHTHAND, 3, 0, 0, 0); - alice.Heading = 3766; alice.MaxSpeedBase = 200; alice.EquipmentTemplateID = "200276"; alice.Flags = (GameNPC.eFlags) 18; @@ -252,8 +245,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) else alice = npcs[0]; - Point2D point = alice.GetPointFromHeading( alice.Heading, 30 ); - locationAlice = new GameLocation(alice.CurrentZone.Description, alice.CurrentRegionID, point.X, point.Y, alice.Z); + locationAlice = alice.Position + Vector.Create(alice.Orientation, length: 30); dragonflyTicket = CreateTicketTo("Castle Sauvage", "hs_src_castlesauvage"); horseTicket = CreateTicketTo("Camelot Hills", "hs_src_camelothills"); @@ -268,7 +260,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) colm.Name = "Dragonfly Handler Colm"; colm.GuildName = "Stable Master"; colm.Realm = eRealm.Albion; - colm.CurrentRegionID = 1; colm.Size = 51; colm.Level = 50; @@ -284,10 +275,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) // colm.AddNPCEquipment(Slot.FEET, 84, 10, 0, 0); // colm.AddNPCEquipment(Slot.CLOAK, 57, 32, 0, 0); - colm.X = 562775; - colm.Y = 512453; - colm.Z = 2438; - colm.Heading = 158; + colm.Position = Position.Create(regionID: 1, x: 562775, y: 512453, z: 2438, heading: 158); colm.MaxSpeedBase = 200; StandardMobBrain brain = new StandardMobBrain(); @@ -331,19 +319,15 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) dragonfly.Name = "dragonfly hatchling"; dragonfly.GuildName = "Part of " + questTitle + " Quest"; dragonfly.Realm = eRealm.None; - dragonfly.CurrentRegionID = 1; dragonfly.Size = 25; dragonfly.Level = 31; - dragonfly.X = colm.X + 80; - dragonfly.Y = colm.Y + 100; - dragonfly.Z = colm.Z; + dragonfly.Position = colm.Position.With(heading: 2434) + Vector.Create(x: 80,y: 100); StandardMobBrain brain = new StandardMobBrain(); brain.AggroLevel = 0; brain.AggroRange = 0; dragonfly.SetOwnBrain(brain); - dragonfly.Heading = 2434; dragonfly.MaxSpeedBase = 400; //dragonfly.EquipmentTemplateID = 200276; @@ -366,13 +350,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) uliam.Name = "Uliam"; uliam.GuildName = "Stable Master"; uliam.Realm = eRealm.Albion; - uliam.CurrentRegionID = 1; uliam.Size = 51; uliam.Level = 50; - uliam.X = 585609; - uliam.Y = 478980; - uliam.Z = 2183; - uliam.Heading = 93; + uliam.Position = Position.Create(regionID: 1, x: 585609, y: 478980, z: 2183, heading: 93); uliam.MaxSpeedBase = 200; StandardMobBrain brain = new StandardMobBrain(); @@ -393,8 +373,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) else uliam = npcs[0] as GameStableMaster; - Point2D uliamloc = uliam.GetPointFromHeading( uliam.Heading, 30 ); - locationUliam = new GameLocation(uliam.CurrentZone.Description, uliam.CurrentRegionID, uliam.X, uliam.Y, uliam.Z); + locationUliam = uliam.Position + Vector.Create(uliam.Orientation, length: 30); /* foreach (GameNPC npc in WorldMgr.GetNPCsCloseToObject(uliam, 400)) @@ -880,7 +859,7 @@ protected static void TalkToAlice(DOLEvent e, object sender, EventArgs args) GiveItem(alice, player, horseTicket); quest.Step = 5; - quest.TeleportTo(player, alice, locationUliam, 50); + quest.TeleportTo(player, alice, locationUliam, uliam.CurrentZone.Description, 50, 0); } break; } @@ -910,7 +889,7 @@ protected static void TalkToMasterVisur(DOLEvent e, object sender, EventArgs arg masterVisur.SayTo(player, "From sodden ground to the glow of the moon, let each vessel in this circle depart to lands now lost from the light of our fair Camelot!"); quest.Step = 3; - quest.TeleportTo(player, masterVisur, locationAlice, 30); + quest.TeleportTo(player, masterVisur, locationAlice, alice.CurrentZone.Description, 30, 0); return; } diff --git a/GameServerScripts/quests/Albion/GodelevasNeed.cs b/GameServerScripts/quests/Albion/GodelevasNeed.cs index 118fd45a48..08efeccac5 100644 --- a/GameServerScripts/quests/Albion/GodelevasNeed.cs +++ b/GameServerScripts/quests/Albion/GodelevasNeed.cs @@ -34,6 +34,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -80,7 +81,7 @@ public class GodelevasNeed : BaseQuest private static ItemTemplate reedBracer = null; - private static GameLocation cotswoldVillageBridge = new GameLocation("Bridge Location", 1, 557671, 512396, 1876); + private static Coordinate cotswoldBridgeLocation = Coordinate.Create(x: 557671, y: 512396, z: 1876); /* We need to define the constructors from the base class here, else there might be problems * when loading this quest... @@ -155,7 +156,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + godelevaDowden.Name + ", creating him ..."); godelevaDowden.GuildName = "Part of " + questTitle + " Quest"; godelevaDowden.Realm = eRealm.Albion; - godelevaDowden.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.FeetArmor, 138); @@ -166,10 +166,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) godelevaDowden.Size = 48; godelevaDowden.Level = 40; - godelevaDowden.X = 559528; - godelevaDowden.Y = 510953; - godelevaDowden.Z = 2488; - godelevaDowden.Heading = 1217; + godelevaDowden.Position = Position.Create(regionID: 1, x: 559528, y: 510953, z: 2488, heading: 1217); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -479,7 +476,7 @@ protected static void PlayerUseSlot(DOLEvent e, object sender, EventArgs args) InventoryItem item = player.Inventory.GetItem((eInventorySlot)uArgs.Slot); if (item != null && item.Id_nb == woodenBucket.Id_nb) { - if (player.IsWithinRadius(cotswoldVillageBridge, 500)) + if (player.Coordinate.DistanceTo(cotswoldBridgeLocation) <= 500) { SendSystemMessage(player, "You use the wooden bucket and scoop up some fresh river water."); diff --git a/GameServerScripts/quests/Albion/GreenerPastures.cs b/GameServerScripts/quests/Albion/GreenerPastures.cs index 8ed65ce4c8..1680594fc6 100644 --- a/GameServerScripts/quests/Albion/GreenerPastures.cs +++ b/GameServerScripts/quests/Albion/GreenerPastures.cs @@ -36,6 +36,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -79,9 +80,9 @@ public class GreenerPastures : BaseQuest private static ItemTemplate farmerAsmasMap = null; - private static GameLocation firstField = new GameLocation("First Field", 1, 568278, 504052, 2168); - private static GameLocation secondField = new GameLocation("Second Field", 1, 573718, 509044, 2192); - private static GameLocation thirdField = new GameLocation("Third Field", 1, 577336, 513324, 2169); + private static Position firstField = Position.Create(regionID: 1, x: 568278, y: 504052, z: 2168); + private static Position secondField = Position.Create(regionID: 1, x: 573718, y: 509044, z: 2192); + private static Position thirdField = Position.Create(regionID: 1, x: 577336, y: 513324, z: 2169); private static IArea firstFieldArea = null; private static IArea secondFieldArea = null; @@ -150,7 +151,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + farmerAsma.Name + ", creating him ..."); farmerAsma.GuildName = "Part of " + questTitle + " Quest"; farmerAsma.Realm = eRealm.Albion; - farmerAsma.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 31); @@ -162,10 +162,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) farmerAsma.Size = 50; farmerAsma.Level = 35; - farmerAsma.X = 563939; - farmerAsma.Y = 509234; - farmerAsma.Z = 2744 ; - farmerAsma.Heading = 21; + farmerAsma.Position = Position.Create(regionID: 1, x: 563939, y: 509234, z: 2744 , heading: 21); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -217,13 +214,13 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) #endregion - firstFieldArea = WorldMgr.GetRegion(firstField.RegionID).AddArea(new Area.Circle("First Vacant Field", firstField.X, firstField.Y, 0, 1450)); + firstFieldArea = WorldMgr.GetRegion(firstField.RegionID).AddArea(new Area.Circle("First Vacant Field", firstField.Coordinate, 1450)); firstFieldArea.RegisterPlayerEnter(new DOLEventHandler(PlayerEnterFirstFieldArea)); - secondFieldArea = WorldMgr.GetRegion(secondField.RegionID).AddArea(new Area.Circle("Second Vacant Field", secondField.X, secondField.Y, 0, 1100)); + secondFieldArea = WorldMgr.GetRegion(secondField.RegionID).AddArea(new Area.Circle("Second Vacant Field", secondField.Coordinate, 1100)); secondFieldArea.RegisterPlayerEnter(new DOLEventHandler(PlayerEnterSecondFieldArea)); - thirdFieldArea = WorldMgr.GetRegion(thirdField.RegionID).AddArea(new Area.Circle("Third Vacant Field", thirdField.X, thirdField.Y, 0, 1100)); + thirdFieldArea = WorldMgr.GetRegion(thirdField.RegionID).AddArea(new Area.Circle("Third Vacant Field", thirdField.Coordinate, 1100)); thirdFieldArea.RegisterPlayerEnter(new DOLEventHandler(PlayerEnterThirdFieldArea)); /* Now we add some hooks to the npc we found. diff --git a/GameServerScripts/quests/Albion/GreetingsArmsman.cs b/GameServerScripts/quests/Albion/GreetingsArmsman.cs index 0744e55333..507d7e67d8 100644 --- a/GameServerScripts/quests/Albion/GreetingsArmsman.cs +++ b/GameServerScripts/quests/Albion/GreetingsArmsman.cs @@ -24,6 +24,7 @@ using DOL.AI.Brain; using DOL.GS.PacketHandler; using log4net; +using DOL.GS.Geometry; namespace DOL.GS.Quests.Albion { @@ -281,7 +282,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + captainKinzee.Name + ", creating him ..."); captainKinzee.GuildName = "Part of " + questTitle + " Quest"; captainKinzee.Realm = eRealm.Albion; - captainKinzee.CurrentRegionID = 27; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.HandsArmor, 691); @@ -296,10 +296,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) captainKinzee.Size = 50; captainKinzee.Level = 50; - captainKinzee.X = 98343; - captainKinzee.Y = 90564; - captainKinzee.Z = 5716; - captainKinzee.Heading = 3698; + captainKinzee.Position = Position.Create(regionID: 27, x: 98343, y: 90564, z: 5716, heading: 3698); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following diff --git a/GameServerScripts/quests/Albion/GreetingsPaladin.cs b/GameServerScripts/quests/Albion/GreetingsPaladin.cs index 209d71c794..9b754d9330 100644 --- a/GameServerScripts/quests/Albion/GreetingsPaladin.cs +++ b/GameServerScripts/quests/Albion/GreetingsPaladin.cs @@ -24,6 +24,7 @@ using DOL.AI.Brain; using DOL.GS.PacketHandler; using log4net; +using DOL.GS.Geometry; namespace DOL.GS.Quests.Albion { @@ -281,7 +282,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + sirStrain.Name + ", creating him ..."); sirStrain.GuildName = "Part of " + questTitle + " Quest"; sirStrain.Realm = eRealm.Albion; - sirStrain.CurrentRegionID = 27; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.HandsArmor, 696); @@ -295,10 +295,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) sirStrain.Size = 50; sirStrain.Level = 50; - sirStrain.X = 98507; - sirStrain.Y = 90637; - sirStrain.Z = 5716; - sirStrain.Heading = 147; + sirStrain.Position = Position.Create(regionID: 27, x: 98507, y: 90637, z: 5716, heading: 147); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following diff --git a/GameServerScripts/quests/Albion/HalfOgreAllMan.cs b/GameServerScripts/quests/Albion/HalfOgreAllMan.cs index 966af5e7d0..6cbc3a8fe5 100644 --- a/GameServerScripts/quests/Albion/HalfOgreAllMan.cs +++ b/GameServerScripts/quests/Albion/HalfOgreAllMan.cs @@ -34,6 +34,7 @@ using DOL.AI.Brain; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -164,7 +165,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + madissair.Name + ", creating him ..."); madissair.GuildName = "Part of " + questTitle + " Quest"; madissair.Realm = eRealm.Albion; - madissair.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.RightHandWeapon,8); @@ -178,10 +178,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) madissair.Size = 50; madissair.Level = 30; - madissair.X = 561064; - madissair.Y = 512291; - madissair.Z = 2407; - madissair.Heading = 721; + madissair.Position = Position.Create(regionID: 1, x: 561064, y: 512291, z: 2407, heading: 721); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -205,7 +202,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + eileenMorton.Name + ", creating him ..."); eileenMorton.GuildName = "Part of " + questTitle + " Quest"; eileenMorton.Realm = eRealm.Albion; - eileenMorton.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TwoHandWeapon, 227); @@ -218,10 +214,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) eileenMorton.Size = 52; eileenMorton.Level = 21; - eileenMorton.X = 559495; - eileenMorton.Y = 510743; - eileenMorton.Z = 2496; - eileenMorton.Heading = 716; + eileenMorton.Position = Position.Create(regionID: 1, x: 559495, y: 510743, z: 2496, heading: 716); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -245,7 +238,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + scribeVeral.Name + ", creating him ..."); scribeVeral.GuildName = "Part of " + questTitle + " Quest"; scribeVeral.Realm = eRealm.Albion; - scribeVeral.CurrentRegionID = 10; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.HandsArmor, 142, 43); @@ -256,10 +248,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) scribeVeral.Size = 50; scribeVeral.Level = 8; - scribeVeral.X = 35308; - scribeVeral.Y = 21876; - scribeVeral.Z = 8447; - scribeVeral.Heading = 284; + scribeVeral.Position = Position.Create(regionID: 10, x: 35308, y: 21876, z: 8447, heading: 284); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -283,7 +272,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + serawen.Name + ", creating him ..."); serawen.GuildName = "Part of " + questTitle + " Quest"; serawen.Realm = eRealm.Albion; - serawen.CurrentRegionID = 10; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 2160); @@ -292,10 +280,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) serawen.Size = 51; serawen.Level = 30; - serawen.X = 35863; - serawen.Y = 27167; - serawen.Z = 8449; - serawen.Heading = 3298; + serawen.Position = Position.Create(regionID: 10, x: 35863, y: 27167, z: 8449, heading: 3298); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following diff --git a/GameServerScripts/quests/Albion/HeartOfSephucoth.cs b/GameServerScripts/quests/Albion/HeartOfSephucoth.cs index b5e85f618a..66fd2d2cf0 100644 --- a/GameServerScripts/quests/Albion/HeartOfSephucoth.cs +++ b/GameServerScripts/quests/Albion/HeartOfSephucoth.cs @@ -35,6 +35,7 @@ using DOL.AI.Brain; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -152,7 +153,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + eowylnAstos.Name + ", creating him ..."); eowylnAstos.GuildName = "Part of " + questTitle + " Quest"; eowylnAstos.Realm = eRealm.Albion; - eowylnAstos.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 58, 40); @@ -161,10 +161,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) eowylnAstos.Size = 54; eowylnAstos.Level = 17; - eowylnAstos.X = 559680; - eowylnAstos.Y = 513793; - eowylnAstos.Z = 2619; - eowylnAstos.Heading = 3185; + eowylnAstos.Position = Position.Create(regionID: 1, x: 559680, y: 513793, z: 2619, heading: 3185); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -564,14 +561,10 @@ public override void Notify(DOLEvent e, object sender, EventArgs args) sephucoth.Model = 136; sephucoth.Name = "Sephucoth"; sephucoth.Realm = eRealm.None; - sephucoth.CurrentRegionID = 1; sephucoth.Size = 55; sephucoth.Level = 7; - sephucoth.X = 560836; - sephucoth.Y = 527260; - sephucoth.Z = 2082; - sephucoth.Heading = 1480; + sephucoth.Position = Position.Create(regionID: 1, x: 560836, y: 527260, z: 2082, heading: 1480); StandardMobBrain brain = new StandardMobBrain(); // set a brain witch find a lot mob friend to attack the player sephucoth.SetOwnBrain(brain); // so this mob must be abble to cast diff --git a/GameServerScripts/quests/Albion/HuntForArachneida.cs b/GameServerScripts/quests/Albion/HuntForArachneida.cs index 054177e1ab..ed3726d68e 100644 --- a/GameServerScripts/quests/Albion/HuntForArachneida.cs +++ b/GameServerScripts/quests/Albion/HuntForArachneida.cs @@ -37,6 +37,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -165,13 +166,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) kealan.GuildName = "Part of " + questTitle + " Quest"; kealan.Realm = eRealm.Albion; - kealan.CurrentRegionID = 1; kealan.Size = 48; kealan.Level = 32; - kealan.X = 493414; - kealan.Y = 593089; - kealan.Z = 1797; - kealan.Heading = 830; + kealan.Position = Position.Create(regionID: 1, x: 493414, y: 593089, z: 1797, heading: 830); kealan.EquipmentTemplateID = "11704675"; @@ -198,13 +195,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) arachneida.GuildName = "Part of " + questTitle + " Quest"; arachneida.Realm = eRealm.None; - arachneida.CurrentRegionID = 1; arachneida.Size = 90; arachneida.Level = 12; - arachneida.X = 534851; - arachneida.Y = 609656; - arachneida.Z = 2456; - arachneida.Heading = 2080; + arachneida.Position = Position.Create(regionID: 1, x: 534851, y: 609656, z: 2456, heading: 2080); arachneida.EquipmentTemplateID = "2"; diff --git a/GameServerScripts/quests/Albion/HuntForSlith.cs b/GameServerScripts/quests/Albion/HuntForSlith.cs index 82907ef94c..d9eb709ed3 100644 --- a/GameServerScripts/quests/Albion/HuntForSlith.cs +++ b/GameServerScripts/quests/Albion/HuntForSlith.cs @@ -33,6 +33,7 @@ using DOL.AI.Brain; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -146,7 +147,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + commanderBurcrif.Name + ", creating him ..."); commanderBurcrif.GuildName = "Part of " + questTitle + " Quest"; commanderBurcrif.Realm = eRealm.Albion; - commanderBurcrif.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TwoHandWeapon, 26); @@ -162,10 +162,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) commanderBurcrif.Size = 53; commanderBurcrif.Level = 45; - commanderBurcrif.X = 517270; - commanderBurcrif.Y = 495711; - commanderBurcrif.Z = 3352; - commanderBurcrif.Heading = 2093; + commanderBurcrif.Position = Position.Create(regionID: 1, x: 517270, y: 495711, z: 3352, heading: 2093); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -476,14 +473,10 @@ public override void Notify(DOLEvent e, object sender, EventArgs args) slith.Model = 31; slith.Name = "Slith"; slith.Realm = eRealm.None; - slith.CurrentRegionID = 1; slith.Size = 50; slith.Level = 7; - slith.X = 524840; - slith.Y = 490529; - slith.Z = 2545; - slith.Heading = 2082; + slith.Position = Position.Create(regionID: 1, x: 524840, y: 490529, z: 2545, heading: 2082); StandardMobBrain brain = new StandardMobBrain(); // set a brain witch find a lot mob friend to attack the player slith.SetOwnBrain(brain); diff --git a/GameServerScripts/quests/Albion/ImportantDelivery.cs b/GameServerScripts/quests/Albion/ImportantDelivery.cs index 5b1a54bf87..688e5f933e 100644 --- a/GameServerScripts/quests/Albion/ImportantDelivery.cs +++ b/GameServerScripts/quests/Albion/ImportantDelivery.cs @@ -35,6 +35,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -154,13 +155,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + dunan.Name + ", creating ..."); dunan.GuildName = "Part of " + questTitle + " Quest"; dunan.Realm = eRealm.Albion; - dunan.CurrentRegionID = 1; dunan.Size = 49; dunan.Level = 21; - dunan.X = 531663; - dunan.Y = 479785; - dunan.Z = 2200; - dunan.Heading = 1579; + dunan.Position = Position.Create(regionID: 1, x: 531663, y: 479785, z: 2200, heading: 1579); dunan.EquipmentTemplateID = "1707754"; //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -182,13 +179,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + bombard.Name + ", creating ..."); bombard.GuildName = "Stable Master"; bombard.Realm = eRealm.Albion; - bombard.CurrentRegionID = 1; bombard.Size = 49; bombard.Level = 4; - bombard.X = 515718; - bombard.Y = 496739; - bombard.Z = 3352; - bombard.Heading = 2500; + bombard.Position = Position.Create(regionID: 1, x: 515718, y: 496739, z: 3352, heading: 2500); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -210,13 +203,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + vuloch.Name + ", creating ..."); vuloch.GuildName = "Stable Master"; vuloch.Realm = eRealm.Albion; - vuloch.CurrentRegionID = 1; vuloch.Size = 50; vuloch.Level = 4; - vuloch.X = 553089; - vuloch.Y = 513380; - vuloch.Z = 2896; - vuloch.Heading = 2139; + vuloch.Position = Position.Create(regionID: 1, x: 553089, y: 513380, z: 2896, heading: 2139); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -239,13 +228,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + yaren.Name + ", creating ..."); yaren.GuildName = "Stable Master"; yaren.Realm = eRealm.Albion; - yaren.CurrentRegionID = 1; yaren.Size = 48; yaren.Level = 4; - yaren.X = 529638; - yaren.Y = 478091; - yaren.Z = 2200; - yaren.Heading = 3160; + yaren.Position = Position.Create(regionID: 1, x: 529638, y: 478091, z: 2200, heading: 3160); yaren.EquipmentTemplateID = "11701347"; //You don't have to store the created mob in the db if you don't want, diff --git a/GameServerScripts/quests/Albion/IreFairyIre.cs b/GameServerScripts/quests/Albion/IreFairyIre.cs index ee672d1d19..8ec3c48e96 100644 --- a/GameServerScripts/quests/Albion/IreFairyIre.cs +++ b/GameServerScripts/quests/Albion/IreFairyIre.cs @@ -37,6 +37,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -159,14 +160,10 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + nob.Name + ", creating him ..."); nob.GuildName = "Part of " + questTitle + " Quest"; nob.Realm = eRealm.Albion; - nob.CurrentRegionID = 1; nob.Size = 45; nob.Level = 4; - nob.X = 573019; - nob.Y = 504485; - nob.Z = 2199; - nob.Heading = 10; + nob.Position = Position.Create(regionID: 1, x: 573019, y: 504485, z: 2199, heading: 10); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -189,7 +186,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + colm.Name + ", creating ..."); colm.GuildName = "Stable Master"; colm.Realm = eRealm.Albion; - colm.CurrentRegionID = 1; colm.Size = 51; colm.Level = 50; @@ -205,10 +201,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) // colm.AddNPCEquipment(Slot.FEET, 84, 10, 0, 0); // colm.AddNPCEquipment(Slot.CLOAK, 57, 32, 0, 0); - colm.X = 562775; - colm.Y = 512453; - colm.Z = 2438; - colm.Heading = 158; + colm.Position = Position.Create(regionID: 1, x: 562775, y: 512453, z: 2438, heading: 158); colm.MaxSpeedBase = 200; StandardMobBrain brain = new StandardMobBrain(); @@ -238,14 +231,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + haruld.Name + ", creating ..."); haruld.GuildName = "Stable Master"; haruld.Realm = eRealm.Albion; - haruld.CurrentRegionID = 1; haruld.Size = 49; haruld.Level = 4; - - haruld.X = 572479; - haruld.Y = 504410; - haruld.Z = 2184; - haruld.Heading = 944; + haruld.Position = Position.Create(regionID: 1, x: 572479, y: 504410, z: 2184, heading: 944); haruld.MaxSpeedBase = 100; StandardMobBrain brain = new StandardMobBrain(); @@ -274,14 +262,10 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) fairyDragonflyHandler.Name = "Fairy Dragonfly Handler"; if (log.IsWarnEnabled) log.Warn("Could not find " + fairyDragonflyHandler.Name + ", creating ..."); - fairyDragonflyHandler.X = 575334; - fairyDragonflyHandler.Y = 506403; - fairyDragonflyHandler.Z = 2331; - fairyDragonflyHandler.Heading = 114; + fairyDragonflyHandler.Position = Position.Create(regionID: 1, x: 575334, y: 506403, z: 2331, heading: 114); fairyDragonflyHandler.Model = 603; fairyDragonflyHandler.GuildName = "Part of " + questTitle + " Quest"; fairyDragonflyHandler.Realm = eRealm.None; - fairyDragonflyHandler.CurrentRegionID = 1; fairyDragonflyHandler.Size = 49; fairyDragonflyHandler.Level = 3; @@ -620,13 +604,9 @@ protected void initDragonflyHatchling() dragonflyHatchling.Name = "Dragonfly Hatchling"; dragonflyHatchling.GuildName = "Part of " + questTitle + " Quest"; dragonflyHatchling.Flags ^= GameNPC.eFlags.PEACE; - dragonflyHatchling.CurrentRegionID = 1; dragonflyHatchling.Size = 25; dragonflyHatchling.Level = 3; - dragonflyHatchling.X = fairyDragonflyHandler.X + Util.Random(-150, 150); - dragonflyHatchling.Y = fairyDragonflyHandler.Y + Util.Random(-150, 150); - dragonflyHatchling.Z = fairyDragonflyHandler.Z; - dragonflyHatchling.Heading = 93; + dragonflyHatchling.Position = fairyDragonflyHandler.Position.With(heading: 93) + Vector.Create(x: Util.Random(-150, 150), y: Util.Random(-150, 150)); dragonflyHatchling.MaxSpeedBase = 200; StandardMobBrain brain = new StandardMobBrain(); diff --git a/GameServerScripts/quests/Albion/LawrencesOil.cs b/GameServerScripts/quests/Albion/LawrencesOil.cs index 01fdbbfbe2..f741835478 100644 --- a/GameServerScripts/quests/Albion/LawrencesOil.cs +++ b/GameServerScripts/quests/Albion/LawrencesOil.cs @@ -34,6 +34,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -148,7 +149,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + brotherLawrence.Name + ", creating him ..."); brotherLawrence.GuildName = "Part of " + questTitle + " Quest"; brotherLawrence.Realm = eRealm.Albion; - brotherLawrence.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.RightHandWeapon, 14, 20); @@ -158,10 +158,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) brotherLawrence.Size = 54; brotherLawrence.Level = 29; - brotherLawrence.X = 560559; - brotherLawrence.Y = 511892; - brotherLawrence.Z = 2344; - brotherLawrence.Heading = 662; + brotherLawrence.Position = Position.Create(regionID: 1, x: 560559, y: 511892, z: 2344, heading: 662); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following diff --git a/GameServerScripts/quests/Albion/MarlinsSalesPitch.cs b/GameServerScripts/quests/Albion/MarlinsSalesPitch.cs index f556345cd7..0c0b2df365 100644 --- a/GameServerScripts/quests/Albion/MarlinsSalesPitch.cs +++ b/GameServerScripts/quests/Albion/MarlinsSalesPitch.cs @@ -31,6 +31,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -159,13 +160,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + marlinThuler.Name + ", creating him ..."); marlinThuler.GuildName = "Instrument Merchant"; marlinThuler.Realm = eRealm.Albion; - marlinThuler.CurrentRegionID = 1; marlinThuler.Size = 52; marlinThuler.Level = 40; - marlinThuler.X = 578189; - marlinThuler.Y = 557031; - marlinThuler.Z = 2340; - marlinThuler.Heading = 1513; + marlinThuler.Position = Position.Create(regionID: 1, x: 578189, y: 557031, z: 2340, heading: 1513); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following diff --git a/GameServerScripts/quests/Albion/MovementAndInteraction.cs b/GameServerScripts/quests/Albion/MovementAndInteraction.cs index 0cff6ba58f..95f66a007e 100644 --- a/GameServerScripts/quests/Albion/MovementAndInteraction.cs +++ b/GameServerScripts/quests/Albion/MovementAndInteraction.cs @@ -33,6 +33,7 @@ using DOL.GS.Behaviour; using DOL.Language; using log4net; +using DOL.GS.Geometry; namespace DOL.GS.Quests.Albion { public class MovementAndInteraction : BaseQuest @@ -50,7 +51,7 @@ public class MovementAndInteraction : BaseQuest private static GameNPC questGiver = null; private static GameNPC questTarget = null; - private static GameLocation targetLocation = new GameLocation("Tutorial", 27, 94789, 101439, 5248); + private static Position targetPosition = Position.Create(regionID: 27, x: 94789, y: 101439, z: 5248); private static IArea targetArea = null; public MovementAndInteraction() : base() @@ -114,7 +115,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (log.IsWarnEnabled) log.Warn("Could not find " + questGiver.Name + ", creating him ..."); questGiver.Realm = eRealm.Albion; - questGiver.CurrentRegionID = 27; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.HandsArmor, 691, 0); //Slot 22 @@ -128,10 +128,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) questGiver.Size = 55; questGiver.Level = 70; - questGiver.X = 95510; - questGiver.Y = 101313; - questGiver.Z = 5340; - questGiver.Heading = 3060; + questGiver.Position = Position.Create(regionID: 27, x: 95510, y: 101313, z: 5340, heading: 3060); if (SAVE_INTO_DATABASE) questGiver.SaveIntoDatabase(); @@ -151,7 +148,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (log.IsWarnEnabled) log.Warn("Could not find " + questTarget.Name + ", creating him ..."); questTarget.Realm = eRealm.Albion; - questTarget.CurrentRegionID = 27; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.HandsArmor, 665, 0); //Slot 22 @@ -165,10 +161,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) questTarget.Size = 50; questTarget.Level = 38; - questTarget.X = 94789; - questTarget.Y = 101439; - questTarget.Z = 5248; - questTarget.Heading = 2878; + questTarget.Position = Position.Create(regionID: 27, x: 94789, y: 101439, z: 5248, heading: 2878); if (SAVE_INTO_DATABASE) questTarget.SaveIntoDatabase(); @@ -180,7 +173,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) #endregion #region defineAreas - targetArea = WorldMgr.GetRegion(targetLocation.RegionID).AddArea(new Area.Circle("", targetLocation.X, targetLocation.Y, targetLocation.Z, 200)); + targetArea = WorldMgr.GetRegion(targetPosition.RegionID).AddArea(new Area.Circle("", targetPosition.Coordinate, 200)); #endregion #region defineBehaviours diff --git a/GameServerScripts/quests/Albion/Nuisances.cs b/GameServerScripts/quests/Albion/Nuisances.cs index f070183cf0..02e814357e 100644 --- a/GameServerScripts/quests/Albion/Nuisances.cs +++ b/GameServerScripts/quests/Albion/Nuisances.cs @@ -34,6 +34,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -77,7 +78,7 @@ public class Nuisances : BaseFrederickQuest protected GameNPC ireFairy = null; - private static GameLocation fairyLocation = new GameLocation("Ire Fairy", 1, 561200, 505951, 2405); + private static Position fairyPosition = Position.Create(regionID: 1, x: 561200, y: 505951, z: 2405); private static IArea fairyArea = null; @@ -291,7 +292,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) #endregion - fairyArea = WorldMgr.GetRegion(fairyLocation.RegionID).AddArea(new Area.Circle("Fairy contamined Area", fairyLocation.X, fairyLocation.Y, 0, 1500)); + fairyArea = WorldMgr.GetRegion(fairyPosition.RegionID).AddArea(new Area.Circle("Fairy contamined Area", fairyPosition.Coordinate, 1500)); fairyArea.RegisterPlayerEnter(new DOLEventHandler(PlayerEnterFairyArea)); /* Now we add some hooks to the npc we found. @@ -342,7 +343,7 @@ public static void ScriptUnloaded(DOLEvent e, object sender, EventArgs args) GameEventMgr.RemoveHandler(GamePlayerEvent.DeclineQuest, new DOLEventHandler(SubscribeQuest)); fairyArea.UnRegisterPlayerEnter(new DOLEventHandler(PlayerEnterFairyArea)); - WorldMgr.GetRegion(fairyLocation.RegionID).RemoveArea(fairyArea); + WorldMgr.GetRegion(fairyPosition.RegionID).RemoveArea(fairyArea); GameEventMgr.RemoveHandler(GamePlayerEvent.GameEntered, new DOLEventHandler(PlayerEnterWorld)); @@ -380,13 +381,11 @@ protected virtual void CreateFairy() ireFairy.Name = "Ire Fairy"; ireFairy.GuildName = "Part of " + questTitle + " Quest"; ireFairy.Realm = eRealm.None; - ireFairy.CurrentRegionID = 1; ireFairy.Size = 50; ireFairy.Level = 4; - ireFairy.X = GameLocation.ConvertLocalXToGlobalX(12336, 0) + Util.Random(-150, 150); - ireFairy.Y = GameLocation.ConvertLocalYToGlobalY(22623, 0) + Util.Random(-150, 150); - ireFairy.Z = 2405; - ireFairy.Heading = 226; + var camelotHills = WorldMgr.GetZone(0); + ireFairy.Position = Position.CreateInZone(zoneID: 0, x: 12336, y: 22623, z: 2405, heading: 226) + + Vector.Create(x: Util.Random(-150, 150), y: Util.Random(-150, 150)); StandardMobBrain brain = new StandardMobBrain(); brain.AggroLevel = 20; diff --git a/GameServerScripts/quests/Albion/RecruitingNothingButTrouble.cs b/GameServerScripts/quests/Albion/RecruitingNothingButTrouble.cs index 8694b53d24..eb3daa6200 100644 --- a/GameServerScripts/quests/Albion/RecruitingNothingButTrouble.cs +++ b/GameServerScripts/quests/Albion/RecruitingNothingButTrouble.cs @@ -26,6 +26,7 @@ using System; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.Language; namespace DOL.GS.Quests.Albion @@ -311,7 +312,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) //k109: My preference, no guildname for quest NPCs. Uncomment if you like that... //Rheda.GuildName = "Part of " + questTitle + " Quest"; Rheda.Realm = eRealm.Albion; - Rheda.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.HandsArmor, 80); @@ -324,10 +324,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Rheda.Size = 52; Rheda.Level = 25; - Rheda.X = 559712; - Rheda.Y = 513513; - Rheda.Z = 2428; - Rheda.Heading = 3822; + Rheda.Position = Position.Create(regionID: 1, x: 559712, y: 513513, z: 2428, heading: 3822); if (SAVE_INTO_DATABASE) Rheda.SaveIntoDatabase(); diff --git a/GameServerScripts/quests/Albion/RevengeTheOtherWhiteMeat.cs b/GameServerScripts/quests/Albion/RevengeTheOtherWhiteMeat.cs index 0466752030..1740e678fa 100644 --- a/GameServerScripts/quests/Albion/RevengeTheOtherWhiteMeat.cs +++ b/GameServerScripts/quests/Albion/RevengeTheOtherWhiteMeat.cs @@ -34,6 +34,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -74,8 +75,9 @@ public class RevengeTheOtherWhiteMeat : BaseQuest protected const int maximumLevel = 8; private static GameNPC farmerAsma = null; - - private static GameLocation wilburSpawnLocation = new GameLocation("Wilbur Location", 1, 500646, 491255, 2298); + + private static Coordinate wilburSpawnLocation = Coordinate.Create(x: 500646, y: 491255, z: 2298); + //private static GameLocation wilburSpawnLocation = new GameLocation("Wilbur Location", 1, 500646, 491255, 2298); /* We need to define the constructors from the base class here, else there might be problems * when loading this quest... @@ -147,7 +149,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + farmerAsma.Name + ", creating him ..."); farmerAsma.GuildName = "Part of " + questTitle + " Quest"; farmerAsma.Realm = eRealm.Albion; - farmerAsma.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 31); @@ -159,10 +160,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) farmerAsma.Size = 50; farmerAsma.Level = 35; - farmerAsma.X = 563939; - farmerAsma.Y = 509234; - farmerAsma.Z = 2744 ; - farmerAsma.Heading = 21; + farmerAsma.Position = Position.Create(regionID: 1, x: 563939, y: 509234, z: 2744 , heading: 21); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -487,7 +485,6 @@ public override void Notify(DOLEvent e, object sender, EventArgs args) pigHerderWyatt.Model = 39; pigHerderWyatt.Name = "Pig Herder Wyatt"; pigHerderWyatt.Realm = eRealm.Albion; - pigHerderWyatt.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.FeetArmor, 143); @@ -497,14 +494,12 @@ public override void Notify(DOLEvent e, object sender, EventArgs args) pigHerderWyatt.Size = 54; pigHerderWyatt.Level = 33; - pigHerderWyatt.X = wilburSpawnLocation.X - 1000; - pigHerderWyatt.Y = wilburSpawnLocation.Y + 1500; - pigHerderWyatt.Z = wilburSpawnLocation.Z; - pigHerderWyatt.Heading = 2548; + pigHerderWyatt.Position = Position.Create(regionID: 1, wilburSpawnLocation + Vector.Create(x: -1000, y: 1500), Angle.Heading(2548)); pigHerderWyatt.AddToWorld(); GameEventMgr.AddHandler(pigHerderWyatt, GameNPCEvent.ArriveAtTarget, new DOLEventHandler(OnCloseToDeadWilbur)); - pigHerderWyatt.WalkTo(gArgs.Target.X - 90, gArgs.Target.Y + 90, gArgs.Target.Z, 200); + var offset = Vector.Create(x: -90, y: 90 ); + pigHerderWyatt.WalkTo(gArgs.Target.Coordinate + offset, 200); return; } @@ -536,7 +531,9 @@ public int OnCloseToDeadWilburCallBack(RegionTimer timer) pigHerderWyatt.Yell("The King's men will hear about this!!! Oh, Wilbur..."); pigHerderWyatt.Emote(eEmote.Cry); GameEventMgr.AddHandler(pigHerderWyatt, GameNPCEvent.CloseToTarget, new DOLEventHandler(OnRemovePigHerder)); - pigHerderWyatt.WalkTo(wilburSpawnLocation.X - 1000, wilburSpawnLocation.Y + 1500, wilburSpawnLocation.Z, 200); + var movementOffset = Vector.Create(x: -1000, y: 1500 ); + short speed = 200; + pigHerderWyatt.WalkTo(wilburSpawnLocation + movementOffset, speed); } return 0; } diff --git a/GameServerScripts/quests/Albion/ShakenSquire.cs b/GameServerScripts/quests/Albion/ShakenSquire.cs index 2ffbd6e018..8f35803ae8 100644 --- a/GameServerScripts/quests/Albion/ShakenSquire.cs +++ b/GameServerScripts/quests/Albion/ShakenSquire.cs @@ -34,6 +34,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -148,7 +149,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + sirJerem.Name + ", creating him ..."); sirJerem.GuildName = "Part of " + questTitle + " Quest"; sirJerem.Realm = eRealm.Albion; - sirJerem.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TwoHandWeapon, 68, 21); @@ -164,10 +164,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) sirJerem.Size = 51; sirJerem.Level = 38; - sirJerem.X = 573815; - sirJerem.Y = 530850; - sirJerem.Z = 2933; - sirJerem.Heading = 2685; + sirJerem.Position = Position.Create(regionID: 1, x: 573815, y: 530850, z: 2933, heading: 2685); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -191,7 +188,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + squireGalune.Name + ", creating him ..."); squireGalune.GuildName = "Part of " + questTitle + " Quest"; squireGalune.Realm = eRealm.Albion; - squireGalune.CurrentRegionID = 21; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.RightHandWeapon, 320); @@ -204,10 +200,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) squireGalune.Size = 45; squireGalune.Level = 8; - squireGalune.X = 33219; - squireGalune.Y = 31931; - squireGalune.Z = 16240; - squireGalune.Heading = 477; + squireGalune.Position = Position.Create(regionID: 21, x: 33219, y: 31931, z: 16240, heading: 477); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -239,19 +232,15 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + smallSpider.Name + ", creating him ..."); smallSpider.GuildName = "Part of " + questTitle + " Quest"; smallSpider.Realm = eRealm.None; - smallSpider.CurrentRegionID = 21; smallSpider.Size = 17; smallSpider.Level = 5; - smallSpider.X = 33158; - smallSpider.Y = 31973; - smallSpider.Z = 16240; + smallSpider.Position = Position.Create(regionID: 21, x: 33158, y: 31973, z: 16240, heading: 2605); StandardMobBrain brain = new StandardMobBrain(); brain.AggroLevel = 0; brain.AggroRange = 0; smallSpider.SetOwnBrain(brain); - smallSpider.Heading = 2605; smallSpider.MaxSpeedBase = 0; //You don't have to store the created mob in the db if you don't want, @@ -620,7 +609,10 @@ public override void Notify(DOLEvent e, object sender, EventArgs args) if(Step == 2) { EnemyKilledEventArgs gArgs = (EnemyKilledEventArgs) args; - if (gArgs.Target.Name == "small spider" && gArgs.Target.CurrentRegionID == smallSpider.CurrentRegionID && gArgs.Target.X == smallSpider.X && gArgs.Target.Y == smallSpider.Y) + if (gArgs.Target.Name == "small spider" + && gArgs.Target.CurrentRegionID == smallSpider.CurrentRegionID + && gArgs.Target.Position.X == smallSpider.Position.X + && gArgs.Target.Position.Y == smallSpider.Position.Y) { Step = 3; return; diff --git a/GameServerScripts/quests/Albion/ToReachTheBreach.cs b/GameServerScripts/quests/Albion/ToReachTheBreach.cs index f101d8ae1f..16d98fb659 100644 --- a/GameServerScripts/quests/Albion/ToReachTheBreach.cs +++ b/GameServerScripts/quests/Albion/ToReachTheBreach.cs @@ -28,6 +28,7 @@ using System; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.Language; namespace DOL.GS.Quests.Albion @@ -43,7 +44,7 @@ public class ToReachTheBreach : RewardQuest private static GameNPC LadyGrynoch = null; private QuestGoal FoundBreach; - private static GameLocation Demons_Breach = new GameLocation("Demon's Breach", 1, 562731, 514531, 2751); + private static Position Demons_Breach = Position.Create(regionID: 1, x: 562731, y: 514531, z: 2751); private static IArea Demons_Breach_Area = null; @@ -201,7 +202,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) //k109: My preference, no guildname for quest NPCs. Uncomment if you like that... //LadyGrynoch.GuildName = "Part of " + questTitle + " Quest"; LadyGrynoch.Realm = eRealm.Albion; - LadyGrynoch.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 58); //Slot 25 @@ -210,10 +210,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) LadyGrynoch.Size = 51; LadyGrynoch.Level = 38; - LadyGrynoch.X = 559698; - LadyGrynoch.Y = 513578; - LadyGrynoch.Z = 2428; - LadyGrynoch.Heading = 2742; + LadyGrynoch.Position = Position.Create(regionID: 1, x: 559698, y: 513578, z: 2428, heading: 2742); if (SAVE_INTO_DATABASE) LadyGrynoch.SaveIntoDatabase(); @@ -225,7 +222,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) #endregion #region defineAreas - Demons_Breach_Area = WorldMgr.GetRegion(Demons_Breach.RegionID).AddArea(new Area.Circle("", Demons_Breach.X, Demons_Breach.Y, Demons_Breach.Z, 200)); + Demons_Breach_Area = WorldMgr.GetRegion(Demons_Breach.RegionID).AddArea(new Area.Circle("", Demons_Breach.Coordinate, 200)); Demons_Breach_Area.RegisterPlayerEnter(new DOLEventHandler(PlayerEnterDemonBreachArea)); #endregion diff --git a/GameServerScripts/quests/Albion/TombWithAView.cs b/GameServerScripts/quests/Albion/TombWithAView.cs index 876a7b59ee..66d44b8470 100644 --- a/GameServerScripts/quests/Albion/TombWithAView.cs +++ b/GameServerScripts/quests/Albion/TombWithAView.cs @@ -26,6 +26,7 @@ using System; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.Language; namespace DOL.GS.Quests.Albion @@ -41,7 +42,7 @@ public class TombWithAView : RewardQuest private static GameNPC LadyGrynoch = null; private QuestGoal FoundTomb; - private static GameLocation Burial_Tomb = new GameLocation("Burial Tomb", 1, 562679, 517225, 2935); + private static Position Burial_Tomb = Position.Create(regionID: 1, x: 562679, y: 517225, z: 2935); private static IArea Burial_Tomb_Area = null; @@ -256,7 +257,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) //k109: My preference, no guildname for quest NPCs. Uncomment if you like that... //LadyGrynoch.GuildName = "Part of " + questTitle + " Quest"; LadyGrynoch.Realm = eRealm.Albion; - LadyGrynoch.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 58); //Slot 25 @@ -265,10 +265,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) LadyGrynoch.Size = 51; LadyGrynoch.Level = 38; - LadyGrynoch.X = 559698; - LadyGrynoch.Y = 513578; - LadyGrynoch.Z = 2428; - LadyGrynoch.Heading = 2742; + LadyGrynoch.Position = Position.Create(regionID: 1, x: 559698, y: 513578, z: 2428, heading: 2742); if (SAVE_INTO_DATABASE) LadyGrynoch.SaveIntoDatabase(); @@ -280,7 +277,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) #endregion #region defineAreas - Burial_Tomb_Area = WorldMgr.GetRegion(Burial_Tomb.RegionID).AddArea(new Area.Circle("", Burial_Tomb.X, Burial_Tomb.Y, Burial_Tomb.Z, 200)); + Burial_Tomb_Area = WorldMgr.GetRegion(Burial_Tomb.RegionID).AddArea(new Area.Circle("", Burial_Tomb.Coordinate, 200)); Burial_Tomb_Area.RegisterPlayerEnter(new DOLEventHandler(PlayerEnterBurialTombArea)); #endregion diff --git a/GameServerScripts/quests/Albion/TraitorInCotswold.cs b/GameServerScripts/quests/Albion/TraitorInCotswold.cs index d560a32ddf..fcc67bc818 100644 --- a/GameServerScripts/quests/Albion/TraitorInCotswold.cs +++ b/GameServerScripts/quests/Albion/TraitorInCotswold.cs @@ -35,6 +35,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -82,9 +83,8 @@ public class TraitorInCotswold : BaseFrederickQuest private static ItemTemplate recruitsBoots = null; private static ItemTemplate recruitsQuiltedBoots = null; - private static GameLocation felinEnd = new GameLocation("Lady Felin", 1, 558999, 514944, 2628, 2332); - private static GameLocation felinStart = new GameLocation("Lady Felin", 1, 558846, 516434, 2519, 2332); - + private static Position felinStart = Position.Create(regionID: 1, x: 558846, y: 516434, z: 2519, heading: 2332 ); + private static Position felinEnd = Position.Create(regionID: 1, x: 558999, y: 514944, z: 2628, heading: 2332 ); /* We need to define the constructors from the base class here, else there might be problems * when loading this quest... @@ -151,13 +151,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) ladyFelin.Name = "Lady Felin"; ladyFelin.GuildName = "Part of " + questTitle + " Quest"; ladyFelin.Realm = eRealm.None; - ladyFelin.CurrentRegionID = 1; ladyFelin.Size = 50; ladyFelin.Level = 30; - ladyFelin.X = 558846; - ladyFelin.Y = 516434; - ladyFelin.Z = 2519; - ladyFelin.Heading = 2332; + ladyFelin.Position = felinStart; StandardMobBrain brain = new StandardMobBrain(); brain.AggroLevel = 0; @@ -442,7 +438,7 @@ protected static void PlayerUseSlot(DOLEvent e, object sender, EventArgs args) InventoryItem item = player.Inventory.GetItem((eInventorySlot)uArgs.Slot); if (item != null && item.Id_nb == necklaceOfDoppelganger.Id_nb) { - if (player.IsWithinRadius( felinEnd, 2500 )) + if (player.Coordinate.DistanceTo(felinEnd) <= 2500) { foreach (GamePlayer visPlayer in player.GetPlayersInRadius(WorldMgr.VISIBILITY_DISTANCE)) { @@ -455,12 +451,9 @@ protected static void PlayerUseSlot(DOLEvent e, object sender, EventArgs args) if (!ladyFelin.IsAlive || ladyFelin.ObjectState != GameObject.eObjectState.Active) { - ladyFelin.X = felinStart.X; - ladyFelin.Y = felinStart.Y; - ladyFelin.Z = felinStart.Z; - ladyFelin.Heading = felinStart.Heading; + ladyFelin.Position = felinStart; ladyFelin.AddToWorld(); - ladyFelin.WalkTo(felinEnd.X, felinEnd.Y, felinEnd.Z, ladyFelin.MaxSpeed); + ladyFelin.WalkTo(felinEnd.Coordinate, ladyFelin.MaxSpeed); } quest.Step = 3; } @@ -482,10 +475,7 @@ protected static void PlayerEnterWorld(DOLEvent e, object sender, EventArgs args if (quest.Step == 3 && (!ladyFelin.IsAlive || ladyFelin.ObjectState != GameObject.eObjectState.Active)) { - ladyFelin.X = felinEnd.X; - ladyFelin.Y = felinEnd.Y; - ladyFelin.Z = felinEnd.Z; - ladyFelin.Heading = felinEnd.Heading; + ladyFelin.Position = felinEnd; ladyFelin.AddToWorld(); } } diff --git a/GameServerScripts/quests/Albion/TreviansBestFriend.cs b/GameServerScripts/quests/Albion/TreviansBestFriend.cs index 0f5e486b58..dd5a03aeb4 100644 --- a/GameServerScripts/quests/Albion/TreviansBestFriend.cs +++ b/GameServerScripts/quests/Albion/TreviansBestFriend.cs @@ -31,6 +31,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -171,7 +172,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + trevian.Name + ", creating him ..."); trevian.GuildName = "Part of " + questTitle + " Quest"; trevian.Realm = eRealm.Albion; - trevian.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 798, 36); @@ -185,10 +185,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) // trevian.AddNPCEquipment((byte) eVisibleItems.TWO_HANDED, 19, 0, 0, 0); trevian.Size = 52; trevian.Level = 20; - trevian.X = 456104; - trevian.Y = 633914; - trevian.Z = 1693; - trevian.Heading = 289; + trevian.Position = Position.Create(regionID: 1, x: 456104, y: 633914, z: 1693, heading: 289); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -212,13 +209,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) puppy.Name = "Trevian's Puppy"; puppy.GuildName = "Part of " + questTitle + " Quest"; puppy.Realm = eRealm.Albion; - puppy.CurrentRegionID = 1; puppy.Size = 22; puppy.Level = 5; - puppy.X = 456051; - puppy.Y = 633858; - puppy.Z = 1728; - puppy.Heading = 3781; + puppy.Position = Position.Create(regionID: 1, x: 456051, y: 633858, z: 1728, heading: 3781); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -241,7 +234,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) guardBrydus.Name = "Guard Brydus"; guardBrydus.GuildName = "Part of " + questTitle + " Quest"; guardBrydus.Realm = eRealm.Albion; - guardBrydus.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TwoHandWeapon, 6); @@ -253,10 +245,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) // guardBrydus.AddNPCEquipment((byte) eVisibleItems.CLOAK, 91, 0, 0, 0); guardBrydus.Size = 52; guardBrydus.Level = 30; - guardBrydus.X = 436698; - guardBrydus.Y = 650425; - guardBrydus.Z = 2448; - guardBrydus.Heading = 184; + guardBrydus.Position = Position.Create(regionID: 1, x: 436698, y: 650425, z: 2448, heading: 184); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -282,8 +271,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) banditAbductorLeader.GuildName = "Part of " + questTitle + " Quest"; banditAbductorLeader.Realm = eRealm.None; - banditAbductorLeader.CurrentRegionID = 1; - GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.RightHandWeapon, 4); template.AddNPCEquipment(eInventorySlot.Cloak, 57); @@ -295,10 +282,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) banditAbductorLeader.Size = 52; banditAbductorLeader.Level = 10; - banditAbductorLeader.X = 438629; - banditAbductorLeader.Y = 644884; - banditAbductorLeader.Z = 1904; - banditAbductorLeader.Heading = 6; + banditAbductorLeader.Position = Position.Create(regionID: 1, x: 438629, y: 644884, z: 1904, heading: 6); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -322,7 +306,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) banditAbductor1.Name = banditAbductorName; banditAbductor1.GuildName = "Part of " + questTitle + " Quest"; banditAbductor1.Realm = eRealm.None; - banditAbductor1.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.RightHandWeapon, 4); @@ -332,10 +315,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) // banditAbductor1.AddNPCEquipment((byte) eVisibleItems.RIGHT_HAND, 4, 0, 0, 0); banditAbductor1.Size = 50; banditAbductor1.Level = 9; - banditAbductor1.X = banditAbductorLeader.X + 100; - banditAbductor1.Y = banditAbductorLeader.Y - 100; - banditAbductor1.Z = banditAbductorLeader.Z; - banditAbductor1.Heading = 50; + banditAbductor1.Position = banditAbductorLeader.Position.With(heading: 50) + Vector.Create(x: 100, y: -100); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -353,7 +333,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) banditAbductor2.Name = banditAbductorName; banditAbductor2.GuildName = "Part of " + questTitle + " Quest"; banditAbductor2.Realm = eRealm.None; - banditAbductor2.CurrentRegionID = 1; template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.RightHandWeapon, 4); @@ -363,10 +342,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) // banditAbductor2.AddNPCEquipment((byte) eVisibleItems.RIGHT_HAND, 4, 0, 0, 0); banditAbductor2.Size = 50; banditAbductor2.Level = 9; - banditAbductor2.X = banditAbductorLeader.X - 150; - banditAbductor2.Y = banditAbductorLeader.Y - 150; - banditAbductor2.Z = banditAbductorLeader.Z; - banditAbductor2.Heading = 0; + banditAbductor2.Position = banditAbductorLeader.Position.With(Angle.Zero) - Vector.Create(x: 150, y: 150); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -984,7 +960,7 @@ protected static void PlayerEnterWorld(DOLEvent e, object sender, EventArgs args if (quest.Step == 6) { quest.AddLilybet(); - quest.lilybet.MoveTo(player.CurrentRegionID, player.X + 100, player.Y, player.Z, player.Heading); + quest.lilybet.MoveTo(player.Position + Vector.Create(x: 100)); InventoryItem cloak = player.Inventory.GetItem(eInventorySlot.Cloak); if (cloak != null && cloak.Id_nb == treviansHoodedCloak.Id_nb) @@ -1032,7 +1008,7 @@ protected static void TalkToTrevian(DOLEvent e, object sender, EventArgs args) trevian.SayTo(player, "Thank you so very much! I thought I would never see Lilybet again. She has been such a faithful companion to me considering I am an amateur Sorcerer; I could not bear the thought of [losing her]. Lilybet, go back to the Wharf for some much needed rest."); quest.Step = 7; quest.lilybet.StopFollowing(); - quest.lilybet.WalkTo(455433, 633010, 1736, quest.lilybet.MaxSpeed); + quest.lilybet.WalkTo(Coordinate.Create(x: 455433, y: 633010, z: 1736), quest.lilybet.MaxSpeed); } else if (quest.Step == 1) // resume talk with trevian { @@ -1414,6 +1390,7 @@ private static void AttackPlayer(GamePlayer player) private void AddLilybet() { + var lilybetPosition = banditAbductorLeader.Position.With(heading: 330) - Vector.Create(x: 300, y: 500); if (lilybet == null) { lilybet = new GameNPC(); @@ -1424,11 +1401,7 @@ private void AddLilybet() lilybet.CurrentRegionID = 1; lilybet.Size = 43; lilybet.Level = 6; - lilybet.X = banditAbductorLeader.X - 300; - lilybet.Y = banditAbductorLeader.Y - 500; - lilybet.Z = banditAbductorLeader.Z; - lilybet.Heading = 330; - + lilybet.Position = lilybetPosition; StandardMobBrain brain = new StandardMobBrain(); brain.AggroLevel = 0; @@ -1446,17 +1419,15 @@ private void AddLilybet() // if lilybet is alive move here to origial position if (lilybet.IsAlive) { - lilybet.MoveTo(1, banditAbductorLeader.X - 300, banditAbductorLeader.Y - 500, banditAbductorLeader.Z, 330); + lilybet.MoveTo(lilybetPosition); } else { - // if she died respawn here to oiginal position + // if she died respawn here to original position lilybet.Health = lilybet.MaxHealth; lilybet.Mana = lilybet.MaxMana; lilybet.Endurance = lilybet.MaxEndurance; - lilybet.X = banditAbductorLeader.X - 300; - lilybet.Y = banditAbductorLeader.Y - 500; - lilybet.Z = banditAbductorLeader.Z; + lilybet.Position = lilybetPosition; lilybet.AddToWorld(); } diff --git a/GameServerScripts/quests/Albion/WhenBloodSpeaks.cs b/GameServerScripts/quests/Albion/WhenBloodSpeaks.cs index c3ba912a4f..490ef8a080 100644 --- a/GameServerScripts/quests/Albion/WhenBloodSpeaks.cs +++ b/GameServerScripts/quests/Albion/WhenBloodSpeaks.cs @@ -26,6 +26,7 @@ using System; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.Language; namespace DOL.GS.Quests.Albion @@ -266,7 +267,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) //k109: My preference, no guildname for quest NPCs. Uncomment if you like that... //MasterKless.GuildName = "Part of " + questTitle + " Quest"; MasterKless.Realm = eRealm.Albion; - MasterKless.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 1005); //Slot 25 @@ -277,10 +277,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) MasterKless.Size = 51; MasterKless.Level = 50; - MasterKless.X = 559370; - MasterKless.Y = 513587; - MasterKless.Z = 2428; - MasterKless.Heading = 2685; + MasterKless.Position = Position.Create(regionID: 1, x: 559370, y: 513587, z: 2428, heading: 2685); if (SAVE_INTO_DATABASE) MasterKless.SaveIntoDatabase(); diff --git a/GameServerScripts/quests/Albion/WhenGoodBrowniesGoBad.cs b/GameServerScripts/quests/Albion/WhenGoodBrowniesGoBad.cs index f9be562cd7..30fe99442f 100644 --- a/GameServerScripts/quests/Albion/WhenGoodBrowniesGoBad.cs +++ b/GameServerScripts/quests/Albion/WhenGoodBrowniesGoBad.cs @@ -26,6 +26,7 @@ using System; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.Language; namespace DOL.GS.Quests.Albion @@ -209,7 +210,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) //k109: My preference, no guildname for quest NPCs. Uncomment if you like that... //MasterKless.GuildName = "Part of " + questTitle + " Quest"; MasterKless.Realm = eRealm.Albion; - MasterKless.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 1005); //Slot 25 @@ -220,10 +220,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) MasterKless.Size = 51; MasterKless.Level = 50; - MasterKless.X = 559370; - MasterKless.Y = 513587; - MasterKless.Z = 2428; - MasterKless.Heading = 2685; + MasterKless.Position = Position.Create(regionID: 1, x: 559370, y: 513587, z: 2428, heading: 2685); if (SAVE_INTO_DATABASE) MasterKless.SaveIntoDatabase(); diff --git a/GameServerScripts/quests/Albion/WolfPeltCloak.cs b/GameServerScripts/quests/Albion/WolfPeltCloak.cs index 8afb20a698..25b2734bd5 100644 --- a/GameServerScripts/quests/Albion/WolfPeltCloak.cs +++ b/GameServerScripts/quests/Albion/WolfPeltCloak.cs @@ -43,6 +43,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -166,13 +167,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + stewardWillie.Name + ", creating him ..."); stewardWillie.GuildName = "Part of " + questTitle; stewardWillie.Realm = eRealm.Albion; - stewardWillie.CurrentRegionID = 1; stewardWillie.Size = 52; stewardWillie.Level = 35; - stewardWillie.X = 503547; - stewardWillie.Y = 474330; - stewardWillie.Z = 2788; - stewardWillie.Heading = 3163; + stewardWillie.Position = Position.Create(regionID: 1, x: 503547, y: 474330, z: 2788, heading: 3163); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -198,7 +195,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + lynnet.Name + ", creating ..."); lynnet.GuildName = "Part of " + questTitle; lynnet.Realm = eRealm.Albion; //Needs to be none, else we can't kill him ;-) - lynnet.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 58, 30); @@ -207,10 +203,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) // lynnet.AddNPCEquipment((byte) eEquipmentItems.TORSO, 58, 30, 0, 0); lynnet.Size = 48; lynnet.Level = 15; - lynnet.X = 530112; - lynnet.Y = 478662; - lynnet.Z = 2200; - lynnet.Heading = 3203; + lynnet.Position = Position.Create(regionID: 1, x: 530112, y: 478662, z: 2200, heading: 3203); //You don't have to store the creted mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -233,7 +226,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + don.Name + ", creating ..."); don.GuildName = "Part of " + questTitle; don.Realm = eRealm.Albion; //Needs to be none, else we can't kill him ;-) - don.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 58, 44); @@ -242,10 +234,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) // don.AddNPCEquipment((byte) eEquipmentItems.TORSO, 58, 44, 0, 0); don.Size = 48; don.Level = 15; - don.X = 505411; - don.Y = 495024; - don.Z = 2495; - don.Heading = 2048; + don.Position = Position.Create(regionID: 1, x: 505411, y: 495024, z: 2495, heading: 2048); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following diff --git a/GameServerScripts/quests/Albion/YdeniasCrush.cs b/GameServerScripts/quests/Albion/YdeniasCrush.cs index 633f914ee6..3c98fcdad2 100644 --- a/GameServerScripts/quests/Albion/YdeniasCrush.cs +++ b/GameServerScripts/quests/Albion/YdeniasCrush.cs @@ -35,6 +35,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -151,7 +152,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + ydeniaPhilpott.Name + ", creating him ..."); ydeniaPhilpott.GuildName = "Part of " + questTitle + " Quest"; ydeniaPhilpott.Realm = eRealm.Albion; - ydeniaPhilpott.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TwoHandWeapon, 227); @@ -166,10 +166,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) ydeniaPhilpott.Size = 51; ydeniaPhilpott.Level = 40; - ydeniaPhilpott.X = 559315; - ydeniaPhilpott.Y = 510705; - ydeniaPhilpott.Z = 2488; - ydeniaPhilpott.Heading = 3993; + ydeniaPhilpott.Position = Position.Create(regionID: 1, x: 559315, y: 510705, z: 2488, heading: 3993); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -193,7 +190,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) elvarTambor.Name = "Elvar Tambor"; elvarTambor.GuildName = "Part of " + questTitle + " Quest"; elvarTambor.Realm = eRealm.Albion; - elvarTambor.CurrentRegionID = 1; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.RightHandWeapon, 3); @@ -207,10 +203,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) elvarTambor.Size = 50; elvarTambor.Level = 15; - elvarTambor.X = 574711; - elvarTambor.Y = 529887; - elvarTambor.Z = 2896; - elvarTambor.Heading = 2366; + elvarTambor.Position = Position.Create(regionID: 1, x: 574711, y: 529887, z: 2896, heading: 2366); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following diff --git a/GameServerScripts/quests/Albion/epic/Academy50.cs b/GameServerScripts/quests/Albion/epic/Academy50.cs index bc5933d842..4036ca49c4 100644 --- a/GameServerScripts/quests/Albion/epic/Academy50.cs +++ b/GameServerScripts/quests/Albion/epic/Academy50.cs @@ -35,6 +35,7 @@ using DOL.AI.Brain; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; @@ -109,7 +110,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 1 && npc.X == 559690 && npc.Y == 510258) + if (npc.CurrentRegionID == 1) { Ferowl = npc; break; @@ -124,13 +125,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + Ferowl.Name + " , creating it ..."); Ferowl.GuildName = ""; Ferowl.Realm = eRealm.Albion; - Ferowl.CurrentRegionID = 1; Ferowl.Size = 51; Ferowl.Level = 40; - Ferowl.X = 559690; - Ferowl.Y = 510258; - Ferowl.Z = 2720; - Ferowl.Heading = 703; + Ferowl.Position = Position.Create(regionID: 1, x: 559690, y: 510258, z: 2720, heading: 703); Ferowl.AddToWorld(); if (SAVE_INTO_DATABASE) @@ -142,7 +139,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 1 && npc.X == 306056 && npc.Y == 670106) + if (npc.CurrentRegionID == 1) { Morgana = npc; break; @@ -157,13 +154,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + Morgana.Name + " , creating it ..."); Morgana.GuildName = ""; Morgana.Realm = eRealm.None; - Morgana.CurrentRegionID = 1; Morgana.Size = 51; Morgana.Level = 90; - Morgana.X = 306056; - Morgana.Y = 670106; - Morgana.Z = 3095; - Morgana.Heading = 3261; + Morgana.Position = Position.Create(regionID: 1, x: 306056, y: 670106, z: 3095, heading: 3261); StandardMobBrain brain = new StandardMobBrain(); brain.AggroLevel = 0; @@ -189,7 +182,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 1 && npc.X == 306025 && npc.Y == 670473) + if (npc.CurrentRegionID == 1) { Bechard = npc; break; @@ -204,13 +197,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Bechard.Name = "Bechard"; Bechard.GuildName = ""; Bechard.Realm = eRealm.None; - Bechard.CurrentRegionID = 1; Bechard.Size = 50; Bechard.Level = 63; - Bechard.X = 306025; - Bechard.Y = 670473; - Bechard.Z = 2863; - Bechard.Heading = 3754; + Bechard.Position = Position.Create(regionID: 1, x: 306025, y: 670473, z: 2863, heading: 3754); Bechard.AddToWorld(); if (SAVE_INTO_DATABASE) @@ -222,7 +211,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 1 && npc.X == 306252 && npc.Y == 670274) + if (npc.CurrentRegionID == 1) { Silcharde = npc; break; @@ -237,13 +226,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Silcharde.Name = "Silcharde"; Silcharde.GuildName = ""; Silcharde.Realm = eRealm.None; - Silcharde.CurrentRegionID = 1; Silcharde.Size = 50; Silcharde.Level = 63; - Silcharde.X = 306252; - Silcharde.Y = 670274; - Silcharde.Z = 2857; - Silcharde.Heading = 3299; + Silcharde.Position = Position.Create(regionID: 1, x: 306252, y: 670274, z: 2857, heading: 3299); Silcharde.AddToWorld(); if (SAVE_INTO_DATABASE) @@ -1047,7 +1032,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) #endregion - morganaArea = WorldMgr.GetRegion(Morgana.CurrentRegionID).AddArea(new Area.Circle(null, Morgana.X, Morgana.Y, 0, 1000)); + morganaArea = WorldMgr.GetRegion(Morgana.CurrentRegionID).AddArea(new Area.Circle(null, Morgana.Coordinate, 1000)); morganaArea.RegisterPlayerEnter(new DOLEventHandler(PlayerEnterMorganaArea)); GameEventMgr.AddHandler(GamePlayerEvent.AcceptQuest, new DOLEventHandler(SubscribeQuest)); @@ -1120,13 +1105,9 @@ protected virtual void CreateMorgana() log.Warn("Could not find " + Morgana.Name + " , creating it ..."); Morgana.GuildName = ""; Morgana.Realm = eRealm.None; - Morgana.CurrentRegionID = 1; Morgana.Size = 51; Morgana.Level = 90; - Morgana.X = 306056; - Morgana.Y = 670106; - Morgana.Z = 3095; - Morgana.Heading = 3261; + Morgana.Position = Position.Create(regionID: 1, x: 306056, y: 670106, z: 3095, heading: 3261); StandardMobBrain brain = new StandardMobBrain(); diff --git a/GameServerScripts/quests/Albion/epic/Church50.cs b/GameServerScripts/quests/Albion/epic/Church50.cs index b4f9f01320..0f7a9cbe01 100644 --- a/GameServerScripts/quests/Albion/epic/Church50.cs +++ b/GameServerScripts/quests/Albion/epic/Church50.cs @@ -34,6 +34,7 @@ using System.Reflection; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; @@ -98,7 +99,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 1 && npc.X == 408557 && npc.Y == 651675) + if (npc.CurrentRegionID == 1) { Roben = npc; break; @@ -113,13 +114,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Roben.Name = "Roben Fraomar"; Roben.GuildName = ""; Roben.Realm = eRealm.Albion; - Roben.CurrentRegionID = 1; Roben.Size = 52; Roben.Level = 50; - Roben.X = 408557; - Roben.Y = 651675; - Roben.Z = 5200; - Roben.Heading = 3049; + Roben.Position = Position.Create(regionID: 1, x: 408557, y: 651675, z: 5200, heading: 3049); Roben.AddToWorld(); if (SAVE_INTO_DATABASE) @@ -131,7 +128,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 1 && npc.X == 322231 && npc.Y == 671546) + if (npc.CurrentRegionID == 1) { Blythe = npc; break; @@ -146,13 +143,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Blythe.Name = "Sister Blythe"; Blythe.GuildName = ""; Blythe.Realm = eRealm.None; - Blythe.CurrentRegionID = 1; Blythe.Size = 50; Blythe.Level = 69; - Blythe.X = 322231; - Blythe.Y = 671546; - Blythe.Z = 2762; - Blythe.Heading = 1683; + Blythe.Position = Position.Create(regionID: 1, x: 322231, y: 671546, z: 2762, heading: 1683); Blythe.AddToWorld(); if (SAVE_INTO_DATABASE) @@ -1028,7 +1021,7 @@ public override void FinishQuest() *#26 seek out Loken in Raumarik Loc 47k, 25k, 4k, and kill him purp and 2 blue adds *#27 return to Roben *#28 give her the ball of flame - *#29 talk with Roben about Loken’s demise + *#29 talk with Roben about Loken's demise *#30 go to MorlinCaan in Jordheim *#31 give her the sealed pouch *#32 you get your epic armor as a reward diff --git a/GameServerScripts/quests/Albion/epic/Defenders50.cs b/GameServerScripts/quests/Albion/epic/Defenders50.cs index a0c3fcf88b..c7e2d28590 100644 --- a/GameServerScripts/quests/Albion/epic/Defenders50.cs +++ b/GameServerScripts/quests/Albion/epic/Defenders50.cs @@ -17,6 +17,7 @@ using System.Reflection; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; @@ -99,7 +100,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 1 && npc.X == 466464 && npc.Y == 634554) + if (npc.CurrentRegionID == 1) { Lidmann = npc; break; @@ -117,13 +118,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Lidmann.GuildName = ""; Lidmann.Realm = eRealm.Albion; - Lidmann.CurrentRegionID = 1; Lidmann.Size = 50; Lidmann.Level = 50; - Lidmann.X = 466464; - Lidmann.Y = 634554; - Lidmann.Z = 1954; - Lidmann.Heading = 1809; + Lidmann.Position = Position.Create(regionID: 1, x: 466464, y: 634554, z: 1954, heading: 1809); Lidmann.AddToWorld(); if (SAVE_INTO_DATABASE) { @@ -137,7 +134,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 1 && npc.X == 316218 && npc.Y == 664484) + if (npc.CurrentRegionID == 1) { Uragaig = npc; break; @@ -152,13 +149,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Uragaig.Name = "Cailleach Uragaig"; Uragaig.GuildName = ""; Uragaig.Realm = eRealm.None; - Uragaig.CurrentRegionID = 1; Uragaig.Size = 55; Uragaig.Level = 70; - Uragaig.X = 316218; - Uragaig.Y = 664484; - Uragaig.Z = 2736; - Uragaig.Heading = 3072; + Uragaig.Position = Position.Create(regionID: 1, x: 316218, y: 664484, z: 2736, heading: 3072); Uragaig.AddToWorld(); if (SAVE_INTO_DATABASE) { @@ -1537,7 +1530,7 @@ public override void FinishQuest() *#26 seek out Loken in Raumarik Loc 47k, 25k, 4k, and kill him purp and 2 blue adds *#27 return to Lidmann *#28 give her the ball of flame - *#29 talk with Lidmann about Loken’s demise + *#29 talk with Lidmann about Loken's demise *#30 go to MorlinCaan in Jordheim *#31 give her the sealed pouch *#32 you get your epic armor as a reward diff --git a/GameServerScripts/quests/Albion/epic/Shadows50.cs b/GameServerScripts/quests/Albion/epic/Shadows50.cs index 83f912e84d..f409ab119a 100644 --- a/GameServerScripts/quests/Albion/epic/Shadows50.cs +++ b/GameServerScripts/quests/Albion/epic/Shadows50.cs @@ -17,6 +17,7 @@ using System.Reflection; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; @@ -108,7 +109,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 1 && npc.X == 466464 && npc.Y == 634554) + if (npc.CurrentRegionID == 1) { Lidmann = npc; break; @@ -123,13 +124,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Lidmann.Name = "Lidmann Halsey"; Lidmann.GuildName = ""; Lidmann.Realm = eRealm.Albion; - Lidmann.CurrentRegionID = 1; Lidmann.Size = 50; Lidmann.Level = 50; - Lidmann.X = 466464; - Lidmann.Y = 634554; - Lidmann.Z = 1954; - Lidmann.Heading = 1809; + Lidmann.Position = Position.Create(regionID: 1, x: 466464, y: 634554, z: 1954, heading: 1809); Lidmann.AddToWorld(); if (SAVE_INTO_DATABASE) { @@ -142,7 +139,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 1 && npc.X == 316218 && npc.Y == 664484) + if (npc.CurrentRegionID == 1) { Uragaig = npc; break; @@ -157,13 +154,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Uragaig.Name = "Cailleach Uragaig"; Uragaig.GuildName = ""; Uragaig.Realm = eRealm.None; - Uragaig.CurrentRegionID = 1; Uragaig.Size = 55; Uragaig.Level = 70; - Uragaig.X = 316218; - Uragaig.Y = 664484; - Uragaig.Z = 2736; - Uragaig.Heading = 3072; + Uragaig.Position = Position.Create(regionID: 1, x: 316218, y: 664484, z: 2736, heading: 3072); Uragaig.AddToWorld(); if (SAVE_INTO_DATABASE) { @@ -2060,7 +2053,7 @@ public override void FinishQuest() *#26 seek out Loken in Raumarik Loc 47k, 25k, 4k, and kill him purp and 2 blue adds *#27 return to Lidmann *#28 give her the ball of flame - *#29 talk with Lidmann about Loken’s demise + *#29 talk with Lidmann about Loken's demise *#30 go to MorlinCaan in Jordheim *#31 give her the sealed pouch *#32 you get your epic armor as a reward diff --git a/GameServerScripts/quests/Examples and Tutorials/Classic quest/HelpSirQuait.cs b/GameServerScripts/quests/Examples and Tutorials/Classic quest/HelpSirQuait.cs index 1c4f35f9db..ce80e9d803 100644 --- a/GameServerScripts/quests/Examples and Tutorials/Classic quest/HelpSirQuait.cs +++ b/GameServerScripts/quests/Examples and Tutorials/Classic quest/HelpSirQuait.cs @@ -36,8 +36,9 @@ using DOL.GS.Behaviour; using DOL.GS.Behaviour.Attributes; using DOL.AI.Brain; +using DOL.GS.Geometry; - namespace DOL.GS.Quests.Examples { +namespace DOL.GS.Quests.Examples { /* The first thing we do, is to declare the class we create * as Quest. To do this, we derive from the abstract class @@ -118,15 +119,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + SirQuait.Name + ", creating ..."); SirQuait.GuildName = "Part of " + questTitle + " Quest"; SirQuait.Realm = eRealm.Albion; - SirQuait.CurrentRegionID = 1; SirQuait.Size = 50; SirQuait.Level = 10; SirQuait.MaxSpeedBase = 100; SirQuait.Faction = FactionMgr.GetFactionByID(0); - SirQuait.X = 531971; - SirQuait.Y = 478955; - SirQuait.Z = 0; - SirQuait.Heading = 3570; + SirQuait.Position = Position.Create(regionID: 1, x: 531971, y: 478955, z: 0, heading: 3570); SirQuait.RespawnInterval = 0; SirQuait.BodyType = 0; @@ -160,15 +157,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + EvilThiefoftheShadowclan.Name + ", creating ..."); EvilThiefoftheShadowclan.GuildName = "Part of " + questTitle + " Quest"; EvilThiefoftheShadowclan.Realm = eRealm.None; - EvilThiefoftheShadowclan.CurrentRegionID = 1; EvilThiefoftheShadowclan.Size = 50; EvilThiefoftheShadowclan.Level = 1; EvilThiefoftheShadowclan.MaxSpeedBase = 100; EvilThiefoftheShadowclan.Faction = FactionMgr.GetFactionByID(0); - EvilThiefoftheShadowclan.X = 532571; - EvilThiefoftheShadowclan.Y = 479055; - EvilThiefoftheShadowclan.Z = 2200; - EvilThiefoftheShadowclan.Heading = 3570; + EvilThiefoftheShadowclan.Position = Position.Create(regionID: 1, x: 532571, y: 479055, z: 2200, heading: 3570); EvilThiefoftheShadowclan.RespawnInterval = 0; EvilThiefoftheShadowclan.BodyType = 0; diff --git a/GameServerScripts/quests/Examples and Tutorials/MasterLevel encounter/ML1FireIsland.cs b/GameServerScripts/quests/Examples and Tutorials/MasterLevel encounter/ML1FireIsland.cs index 0321da5288..a41c696dcf 100644 --- a/GameServerScripts/quests/Examples and Tutorials/MasterLevel encounter/ML1FireIsland.cs +++ b/GameServerScripts/quests/Examples and Tutorials/MasterLevel encounter/ML1FireIsland.cs @@ -10,6 +10,7 @@ using log4net; using System.Reflection; using DOL.GS.Atlantis; +using DOL.GS.Geometry; namespace DOL.GS { @@ -122,16 +123,15 @@ public void SpawnEncounter() //First we spawn the 30 Wall of Fire mobs around the perimeter of the island. for (int i = 0; i < 30; i++) { - SpawnAfire(FirePosition[i, 0], FirePosition[i, 1], FirePosition[i, 2]); + var fireLocation = Coordinate.Create(x: FirePosition[i, 0], y: FirePosition[i, 1], z:FirePosition[i, 2]); + SpawnAfire(Position.Create((ushort)Ianetor.playerregion, fireLocation, heading: 1690)); } //Next we spawn the two sets of stair guards - for (int i = 0; i < 4; i++) + for (int i = 0; i < 8; i++) { - SpawnAGuard(GuardPosition[i, 0], GuardPosition[i, 1], GuardPosition[i, 2], 3720); - } - for (int i = 4; i < 8; i++) - { - SpawnAGuard(GuardPosition[i, 0], GuardPosition[i, 1], GuardPosition[i, 2], 1735); + var guardPosition = Position.Create((ushort)Ianetor.playerregion, x: GuardPosition[i, 0], y: GuardPosition[i, 1], z: GuardPosition[i, 2]); + if (i < 4) SpawnAGuard(guardPosition.With(heading: 3720)); + else SpawnAGuard(guardPosition.With(heading: 1735)); } //Next we spawn Sunkaio @@ -140,15 +140,11 @@ public void SpawnEncounter() sunkaio.Size = 100; sunkaio.Level = 68; //level 65 on live sunkaio.Name = "Sunkaio"; - sunkaio.CurrentRegionID = (ushort)Ianetor.playerregion; - sunkaio.Heading = 1690; sunkaio.Realm = 0; sunkaio.CurrentSpeed = 0; sunkaio.MaxSpeedBase = 191; sunkaio.GuildName = ""; - sunkaio.X = 431865; - sunkaio.Y = 544121; - sunkaio.Z = 8311; + sunkaio.Position = Position.Create(regionID: (ushort)Ianetor.playerregion, x: 431865, y: 544121, z: 8311, heading: 1690); sunkaio.RoamingRange = 0; sunkaio.RespawnInterval = 0; sunkaio.BodyType = 0; @@ -170,15 +166,11 @@ public void SpawnEncounter() zopureo.Size = 100; zopureo.Level = 70; zopureo.Name = "Zopureo"; - zopureo.CurrentRegionID = (ushort)Ianetor.playerregion; - zopureo.Heading = 1690; zopureo.Realm = 0; zopureo.CurrentSpeed = 0; zopureo.MaxSpeedBase = 0; zopureo.GuildName = ""; - zopureo.X = 432767; - zopureo.Y = 543483; - zopureo.Z = 8291; + zopureo.Position = Position.Create(regionID: (ushort)Ianetor.playerregion, x: 432767, y: 543483, z: 8291, heading: 1690); zopureo.RoamingRange = 0; zopureo.RespawnInterval = 0; zopureo.BodyType = 0; @@ -200,15 +192,11 @@ public void SpawnEncounter() aithos.Size = 100; aithos.Level = 68; //level 65 on live aithos.Name = "Aithos"; - aithos.CurrentRegionID = (ushort)Ianetor.playerregion; - aithos.Heading = 1690; aithos.Realm = 0; aithos.CurrentSpeed = 0; aithos.MaxSpeedBase = 191; aithos.GuildName = ""; - aithos.X = 432377; - aithos.Y = 543728; - aithos.Z = 8334; + aithos.Position = Position.Create((ushort)Ianetor.playerregion, x: 432377, y: 543728, z: 8334, heading: 1690); aithos.RoamingRange = 0; aithos.RespawnInterval = 0; aithos.BodyType = 0; @@ -334,22 +322,18 @@ public static void DeSpawnEncounter() return 0; } - public void SpawnAfire(int fireX, int fireY, int fireZ) + public void SpawnAfire(Position position) { GameWallofFire fire = new GameWallofFire(); fire.Model = 1; fire.Size = 50; fire.Level = 99; fire.Name = "Wall of Fire"; - fire.CurrentRegionID = (ushort)Ianetor.playerregion; - fire.Heading = 1690; fire.Realm = 0; fire.CurrentSpeed = 0; fire.MaxSpeedBase = 0; fire.GuildName = ""; - fire.X = fireX; - fire.Y = fireY; - fire.Z = fireZ; + fire.Position = position; fire.RoamingRange = 0; fire.RespawnInterval = 0; fire.BodyType = 0; @@ -367,22 +351,18 @@ public void SpawnAfire(int fireX, int fireY, int fireZ) return; } - public void SpawnAGuard(int guardX, int guardY, int guardZ, ushort heading) + public void SpawnAGuard(Position position) { GameStairGuard guard = new GameStairGuard(); guard.Model = 1349; guard.Size = 37; guard.Level = 80; //level 70 on live guard.Name = "daleros ephoros"; - guard.CurrentRegionID = (ushort)Ianetor.playerregion; - guard.Heading = heading; + guard.Position = position; guard.Realm = 0; guard.CurrentSpeed = 0; guard.MaxSpeedBase = 300; guard.GuildName = ""; - guard.X = guardX; - guard.Y = guardY; - guard.Z = guardZ; guard.RoamingRange = 0; guard.RespawnInterval = 0; guard.BodyType = 0; @@ -507,40 +487,32 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Loading Master Level 1: Fire Island. Spawned Ianetor's."); } - public static void SpawnIanetor1(int region) + public static void SpawnIanetor1(int regionID) { Ianetor ianetor1 = new Ianetor(); ianetor1.Name = "Ianetor"; ianetor1.GuildName = ""; ianetor1.Model = 1194; ianetor1.Realm = 0; - ianetor1.CurrentRegionID = (ushort)region; ianetor1.Size = 35; ianetor1.Level = 0; - ianetor1.X = 433401; - ianetor1.Y = 546420; - ianetor1.Z = 8481; - ianetor1.Heading = 3720; + ianetor1.Position = Position.Create((ushort)regionID, x: 433401, y: 546420, z: 8481, heading: 3720); ianetor1.RoamingRange = 0; ianetor1.Flags ^= GameNPC.eFlags.PEACE; ianetor1.CurrentSpeed = 0; ianetor1.MaxSpeedBase = 0; ianetor1.AddToWorld(); } - public static void SpawnIanetor2(int region) + public static void SpawnIanetor2(int regionID) { Ianetor ianetor2 = new Ianetor(); ianetor2.Name = "Ianetor"; ianetor2.GuildName = ""; ianetor2.Model = 1194; ianetor2.Realm = 0; - ianetor2.CurrentRegionID = (ushort)region; ianetor2.Size = 35; ianetor2.Level = 0; - ianetor2.X = 431100; - ianetor2.Y = 541433; - ianetor2.Z = 8481; - ianetor2.Heading = 1735; + ianetor2.Position = Position.Create((ushort)regionID, x: 431100, y: 541433, z: 8481, heading: 1735); ianetor2.RoamingRange = 0; ianetor2.Flags ^= GameNPC.eFlags.PEACE; ianetor2.CurrentSpeed = 0; @@ -661,45 +633,40 @@ public override void TakeDamage(GameObject source, eDamageType damageType, int d } } - public void SpawnPurros() - { - SpawnAPurro(432802, 543389, 8291); - SpawnAPurro(432709, 543571, 8302); - SpawnAPurro(432664, 543446, 8298); - SpawnAPurro(432867, 543538, 8285); - } - - public void SpawnAPurro(int purroX, int purroY, int purroZ) - { - GamePurros purro = new GamePurros(); - purro.Model = 911; - purro.Size = 50; - purro.Level = 60; - purro.Name = "purros"; - purro.CurrentRegionID = (ushort)Ianetor.playerregion; - purro.Heading = 1690; - purro.Realm = 0; - purro.CurrentSpeed = 0; - purro.MaxSpeedBase = 350; - purro.GuildName = ""; - purro.X = purroX; - purro.Y = purroY; - purro.Z = purroZ; - purro.RoamingRange = 0; - purro.RespawnInterval = 0; - purro.BodyType = 0; - - PurroBrain pbrain = new PurroBrain(); - pbrain.AggroLevel = 100; - pbrain.AggroRange = 200; - purro.SetOwnBrain(pbrain); - - purro.AddToWorld(); - Ianetor.PurrosList.Add(purro); - GameEventMgr.AddHandler(purro, GameNPCEvent.Dying, new DOLEventHandler(Ianetor.PurroHasDied)); - return; - - } + public void SpawnPurros() + { + var purroLocations = new[]{ + Coordinate.Create(432802, 543389, 8291), + Coordinate.Create(432709, 543571, 8302), + Coordinate.Create(432664, 543446, 8298), + Coordinate.Create(432867, 543538, 8285) + }; + foreach(var purroLoc in purroLocations) + { + GamePurros purro = new GamePurros(); + purro.Model = 911; + purro.Size = 50; + purro.Level = 60; + purro.Name = "purros"; + purro.Realm = 0; + purro.CurrentSpeed = 0; + purro.MaxSpeedBase = 350; + purro.GuildName = ""; + purro.Position = Position.Create((ushort)Ianetor.playerregion,purroLoc,heading: 1690); + purro.RoamingRange = 0; + purro.RespawnInterval = 0; + purro.BodyType = 0; + + PurroBrain pbrain = new PurroBrain(); + pbrain.AggroLevel = 100; + pbrain.AggroRange = 200; + purro.SetOwnBrain(pbrain); + + purro.AddToWorld(); + Ianetor.PurrosList.Add(purro); + GameEventMgr.AddHandler(purro, GameNPCEvent.Dying, new DOLEventHandler(Ianetor.PurroHasDied)); + } + } public static void ZopureoChangeHealth(int damage) { diff --git a/GameServerScripts/quests/Examples and Tutorials/Search quest/WingsOfTheIsleHibernia.cs b/GameServerScripts/quests/Examples and Tutorials/Search quest/WingsOfTheIsleHibernia.cs index a7eff17e3a..4fdef2f086 100644 --- a/GameServerScripts/quests/Examples and Tutorials/Search quest/WingsOfTheIsleHibernia.cs +++ b/GameServerScripts/quests/Examples and Tutorials/Search quest/WingsOfTheIsleHibernia.cs @@ -59,6 +59,7 @@ Reed Flute * using DOL.Language; using DOL.GS.PacketHandler; using log4net; +using DOL.GS.Geometry; namespace DOL.GS.Quests.Hibernia { @@ -310,14 +311,10 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) } npcBaeth.GuildName = "Part of " + questTitle + " Quest"; npcBaeth.Realm = eRealm.Hibernia; - npcBaeth.CurrentRegionID = 27; npcBaeth.Size = 52; npcBaeth.Level = 30; - npcBaeth.X = 356650; - npcBaeth.Y = 355078; - npcBaeth.Z = 5015; - npcBaeth.Heading = 2959; + npcBaeth.Position = Position.Create(regionID: 27, x: 356650, y: 355078, z: 5015, heading: 2959); if (SAVE_INTO_DATABASE) { @@ -344,15 +341,10 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) } npcJessica.GuildName = "Part of " + questTitle + " Quest"; npcJessica.Realm = eRealm.Hibernia; - npcJessica.CurrentRegionID = 27; npcJessica.Size = 38; npcJessica.Level = 1; - npcJessica.X = 358068; - npcJessica.Y = 347553; - npcJessica.Z = 5491; - npcJessica.Heading = 49; - + npcJessica.Position = Position.Create(regionID: 27, x: 358068, y: 347553, z: 5491, heading: 49); if (SAVE_INTO_DATABASE) { npcJessica.SaveIntoDatabase(); diff --git a/GameServerScripts/quests/Hibernia/BaseAddrirQuest.cs b/GameServerScripts/quests/Hibernia/BaseAddrirQuest.cs index 3da7f3377f..25c2aaf31b 100644 --- a/GameServerScripts/quests/Hibernia/BaseAddrirQuest.cs +++ b/GameServerScripts/quests/Hibernia/BaseAddrirQuest.cs @@ -34,6 +34,7 @@ using System.Reflection; using DOL.AI.Brain; using DOL.Database; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -154,7 +155,6 @@ public static GameNPC GetAddrir() log.Warn("Could not find " + addrir.Name + ", creating him ..."); addrir.GuildName = "Part of Addrir Quests"; addrir.Realm = eRealm.Hibernia; - addrir.CurrentRegionID = 200; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 58, 35); @@ -169,11 +169,8 @@ public static GameNPC GetAddrir() addrir.Size = 50; addrir.Level = 50; - addrir.X = GameLocation.ConvertLocalXToGlobalX(26955, 200); - addrir.Y = GameLocation.ConvertLocalYToGlobalY(7789, 200); - addrir.Z = 5196; - addrir.Heading = 22; - + var loughDerg = WorldMgr.GetZone(200); + addrir.Position = Position.Create(regionID: 200, x: 26955, y: 7789, z: 5196, heading: 22) + loughDerg.Offset; StandardMobBrain brain = new StandardMobBrain(); brain.AggroLevel = 0; brain.AggroRange = 0; diff --git a/GameServerScripts/quests/Hibernia/BonesToBlades.cs b/GameServerScripts/quests/Hibernia/BonesToBlades.cs index 9c18cd2abc..c0d3079470 100644 --- a/GameServerScripts/quests/Hibernia/BonesToBlades.cs +++ b/GameServerScripts/quests/Hibernia/BonesToBlades.cs @@ -35,6 +35,7 @@ using DOL.Language; using log4net; using DOL.GS.Behaviour.Requirements; +using DOL.GS.Geometry; namespace DOL.GS.Quests.Hibernia { @@ -125,7 +126,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) questGiver = new GameNPC(); questGiver.Name = questGiverName; questGiver.Realm = eRealm.Hibernia; - questGiver.CurrentRegionID = 200; // select * from NPCEquipment where TemplateID in (select EquipmentTemplateID from Mob where name = ?) GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); @@ -140,11 +140,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) questGiver.Model = 388; questGiver.Size = 51; questGiver.Level = 35; - questGiver.X = 346768; - questGiver.Y = 489521; - questGiver.Z = 5200; - questGiver.Heading = 2594; - + questGiver.Position = Position.Create(regionID: 200, x: 346768, y: 489521, z: 5200, heading: 2594); if (SAVE_INTO_DATABASE) questGiver.SaveIntoDatabase(); @@ -162,7 +158,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (log.IsWarnEnabled) log.Warn("Could not find " + questTarget.Name + ", creating him ..."); questTarget.Realm = eRealm.Hibernia; - questTarget.CurrentRegionID = 200; // select * from NPCEquipment where TemplateID in (select EquipmentTemplateID from Mob where name = ?) GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); @@ -178,11 +173,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) questTarget.Model = 381; questTarget.Size = 50; questTarget.Level = 12; - questTarget.X = 347327; - questTarget.Y = 492700; - questTarget.Z = 5199; - questTarget.Heading = 2468; - + questTarget.Position = Position.Create(regionID: 200, x: 347327, y: 492700, z: 5199, heading: 2468); if (SAVE_INTO_DATABASE) questTarget.SaveIntoDatabase(); diff --git a/GameServerScripts/quests/Hibernia/ChildsPlay.cs b/GameServerScripts/quests/Hibernia/ChildsPlay.cs index 78aeaf41c4..967908d13f 100644 --- a/GameServerScripts/quests/Hibernia/ChildsPlay.cs +++ b/GameServerScripts/quests/Hibernia/ChildsPlay.cs @@ -38,6 +38,7 @@ using DOL.GS.Behaviour; using DOL.GS.Behaviour.Attributes; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using DOL.GS.Quests; using DOL.Language; @@ -77,7 +78,7 @@ public class childsplay : BaseQuest private static ItemTemplate daringstuddedjerkin_hib = null; private static ItemTemplate daringstuddedleggings_hib = null; private static ItemTemplate daringstuddedsleeves_hib = null; - private static GameLocation Hib_Statue = new GameLocation("Childs Play (Hib)", 489, 27580, 40006, 14483); + private static Position Hib_Statue = Position.Create(regionID: 489, x: 27580, y: 40006, z: 14483); private static IArea Hib_Statue_Area = null; @@ -121,15 +122,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (log.IsWarnEnabled) log.Warn("Could not find " + Charles.Name + ", creating ..."); Charles.Realm = eRealm.Hibernia; - Charles.CurrentRegionID = 200; Charles.Size = 37; Charles.Level = 1; Charles.MaxSpeedBase = 191; Charles.Faction = FactionMgr.GetFactionByID(0); - Charles.X = 348034; - Charles.Y = 490940; - Charles.Z = 5200; - Charles.Heading = 1149; + Charles.Position = Position.Create(regionID: 200, x: 348034, y: 490940, z: 5200, heading: 1149); Charles.RespawnInterval = -1; Charles.BodyType = 0; @@ -1473,7 +1470,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) #endregion #region defineAreas - Hib_Statue_Area = WorldMgr.GetRegion(Hib_Statue.RegionID).AddArea(new Area.Circle("", Hib_Statue.X, Hib_Statue.Y, Hib_Statue.Z, 500)); + Hib_Statue_Area = WorldMgr.GetRegion(Hib_Statue.RegionID).AddArea(new Area.Circle("", Hib_Statue.Coordinate, 500)); Hib_Statue_Area.RegisterPlayerEnter(new DOLEventHandler(PlayerEnterStatueArea)); #endregion diff --git a/GameServerScripts/quests/Hibernia/CityOfTirnaNog.cs b/GameServerScripts/quests/Hibernia/CityOfTirnaNog.cs index e8d868b466..e9566915b0 100644 --- a/GameServerScripts/quests/Hibernia/CityOfTirnaNog.cs +++ b/GameServerScripts/quests/Hibernia/CityOfTirnaNog.cs @@ -36,6 +36,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -76,13 +77,16 @@ public class CityOfTirnaNog : BaseAddrirQuest protected const int minimumLevel = 1; protected const int maximumLevel = 1; - protected static GameLocation heroTrainer = new GameLocation("Hero Trainer", 201, 31555, 26198, 7767, 2462); - protected static GameLocation bladeMasterTrainer = new GameLocation("Blademaster Trainer", 201, 29819, 26485, 7767, 1403); - protected static GameLocation championTrainer = new GameLocation("Champion Trainer", 201, 31783, 27885, 7767, 3377); - //protected static GameLocation mercenaryTrainer = new GameLocation("Mercenary Trainer", 10, 32826, 26831, 7995, 0); - - protected static GameLocation vaultKeeper = new GameLocation("Vault Keeper", 201, 33175, 31237, 8000, 1970); - protected static GameLocation eastGates = new GameLocation("East Gates", 201, 22648, 34592, 6250, 995); + protected static Position heroTrainer + = Position.Create(regionID: 201, x: 31555, y: 26198, z: 7767, heading: 2462); + protected static Position bladeMasterTrainer + = Position.Create(regionID: 201, x: 29819, y: 26485, z: 7767, heading: 1403); + protected static Position championTrainer + = Position.Create(regionID: 201, x: 31783, y: 27885, z: 7767, heading: 3377); + protected static Position vaultKeeper + = Position.Create(regionID: 201, x: 33175, y: 31237, z: 8000, heading: 1970); + protected static Position eastGates + = Position.Create(regionID: 201, x: 22648, y: 34592, z: 6250, heading: 995); private static GameNPC addrir = null; private static GameNPC hylvian = null; @@ -172,13 +176,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + hylvian.Name + ", creating ..."); hylvian.GuildName = "Part of " + questTitle + " Quest"; hylvian.Realm = eRealm.Hibernia; - hylvian.CurrentRegionID = 201; hylvian.Size = 51; hylvian.Level = 44; - hylvian.X = 33163; - hylvian.Y = 31142; - hylvian.Z = 8000; - hylvian.Heading = 11; + hylvian.Position = Position.Create(regionID: 201, x: 33163, y: 31142, z: 8000, heading: 11); hylvian.EquipmentTemplateID = "7400147"; //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -201,13 +201,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + freagus.Name + ", creating ..."); freagus.GuildName = "Stable Master"; freagus.Realm = eRealm.Hibernia; - freagus.CurrentRegionID = 200; freagus.Size = 48; freagus.Level = 30; - freagus.X = 341008; - freagus.Y = 469180; - freagus.Z = 5200; - freagus.Heading = 1934; + freagus.Position = Position.Create(regionID: 200, x: 341008, y: 469180, z: 5200, heading: 1934); freagus.EquipmentTemplateID = "3800664"; //You don't have to store the created mob in the db if you don't want, @@ -230,13 +226,10 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + gweonry.Name + ", creating ..."); gweonry.GuildName = "Stable Master"; gweonry.Realm = eRealm.Hibernia; - gweonry.CurrentRegionID = 200; gweonry.Size = 48; gweonry.Level = 30; - gweonry.X = GameLocation.ConvertLocalXToGlobalX(16334, 200); - gweonry.Y = GameLocation.ConvertLocalYToGlobalY(3384, 200); - gweonry.Z = 5200; - gweonry.Heading = 245; + var loughDerg = WorldMgr.GetZone(200); + gweonry.Position = Position.Create(regionID: 200, x: 16334, y: 3384, z: 5200, heading: 245) + loughDerg.Offset; //gweonry.EquipmentTemplateID="3800664"; //You don't have to store the created mob in the db if you don't want, @@ -813,17 +806,16 @@ protected static void TalkToAssistant(DOLEvent e, object sender, EventArgs args) break; case "champion": - quest.TeleportTo(championTrainer); + quest.TeleportTo(championTrainer, "Champion Trainer"); break; case "hero": - quest.TeleportTo(heroTrainer); + quest.TeleportTo(heroTrainer, "Hero Trainer"); break; case "blademaster": - quest.TeleportTo(bladeMasterTrainer); + quest.TeleportTo(bladeMasterTrainer, "Blademaster Trainer"); break; - //case "mercenary": quest.TeleportTo(mercenaryTrainer); break; case "east gates": - quest.TeleportTo(eastGates); + quest.TeleportTo(eastGates, "East Gates"); if (quest.Step == 7) { quest.Step = 8; @@ -834,7 +826,7 @@ protected static void TalkToAssistant(DOLEvent e, object sender, EventArgs args) { quest.Step = 4; } - quest.TeleportTo(vaultKeeper); + quest.TeleportTo(vaultKeeper, "Vault Keeper"); break; case "go away": @@ -850,10 +842,10 @@ protected static void TalkToAssistant(DOLEvent e, object sender, EventArgs args) * Convinient Method for teleporintg with assistant */ - protected void TeleportTo(GameLocation target) + protected void TeleportTo(Position destination, string destinationName) { - TeleportTo(m_questPlayer, assistant, target, 5); - TeleportTo(assistant, assistant, target, 25, 50); + TeleportTo(m_questPlayer, assistant, destination, destinationName, 5, 0); + TeleportTo(assistant, assistant, destination, 25, 50); } @@ -939,7 +931,7 @@ protected virtual int CreateAssistant(RegionTimer callingTimer) { if (assistant != null && assistant.ObjectState == GameObject.eObjectState.Active) { - assistant.MoveTo(m_questPlayer.CurrentRegionID, m_questPlayer.X + 50, m_questPlayer.Y + 30, m_questPlayer.Z, m_questPlayer.Heading); + assistant.MoveTo(m_questPlayer.Position + Vector.Create(x: 50, y: 30)); } else { @@ -948,13 +940,9 @@ protected virtual int CreateAssistant(RegionTimer callingTimer) assistant.Name = m_questPlayer.Name + "'s Assistant"; assistant.GuildName = "Part of " + questTitle + " Quest"; assistant.Realm = m_questPlayer.Realm; - assistant.CurrentRegionID = m_questPlayer.CurrentRegionID; assistant.Size = 25; assistant.Level = 5; - assistant.X = m_questPlayer.X + 50; - assistant.Y = m_questPlayer.Y + 50; - assistant.Z = m_questPlayer.Z; - assistant.Heading = m_questPlayer.Heading; + assistant.Position = m_questPlayer.Position + Vector.Create(x: 50,y: 50); assistant.AddToWorld(); diff --git a/GameServerScripts/quests/Hibernia/ImportantDelivery.cs b/GameServerScripts/quests/Hibernia/ImportantDelivery.cs index 49f3d67f97..740f078dd9 100644 --- a/GameServerScripts/quests/Hibernia/ImportantDelivery.cs +++ b/GameServerScripts/quests/Hibernia/ImportantDelivery.cs @@ -39,6 +39,7 @@ using DOL.GS.PacketHandler; using log4net; using DOL.GS.Finance; +using DOL.GS.Geometry; /* I suggest you declare yourself some namespaces for your quests * Like: DOL.GS.Quests.Albion * DOL.GS.Quests.Midgard @@ -157,13 +158,10 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find" + aethic.Name + " , creating ..."); aethic.GuildName = "Part of " + questTitle + " Quest"; aethic.Realm = eRealm.Hibernia; - aethic.CurrentRegionID = 200; aethic.Size = 49; aethic.Level = 21; - aethic.X = GameLocation.ConvertLocalXToGlobalX(23761, 200); - aethic.Y = GameLocation.ConvertLocalYToGlobalY(45658, 200); - aethic.Z = 5448; - aethic.Heading = 320; + var loughDerg = WorldMgr.GetZone(200); + aethic.Position = Position.Create(regionID: 200, x: 23761, y: 45658, z: 5448, heading: 320) + loughDerg.Offset; //aethic.EquipmentTemplateID = "1707754"; //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -185,13 +183,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + freagus.Name + ", creating ..."); freagus.GuildName = "Stable Master"; freagus.Realm = eRealm.Hibernia; - freagus.CurrentRegionID = 200; freagus.Size = 48; freagus.Level = 30; - freagus.X = 341008; - freagus.Y = 469180; - freagus.Z = 5200; - freagus.Heading = 1934; + freagus.Position = Position.Create(regionID: 200, x: 341008, y: 469180, z: 5200, heading: 1934); freagus.EquipmentTemplateID = "3800664"; //You don't have to store the created mob in the db if you don't want, @@ -214,13 +208,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) rumdor.Name = "Rumdor"; rumdor.GuildName = "Stable Master"; rumdor.Realm = eRealm.Hibernia; - rumdor.CurrentRegionID = 200; rumdor.Size = 53; rumdor.Level = 33; - rumdor.X = 347175; - rumdor.Y = 491836; - rumdor.Z = 5226; - rumdor.Heading = 1262; + rumdor.Position = Position.Create(regionID: 200, x: 347175, y: 491836, z: 5226, heading: 1262); rumdor.EquipmentTemplateID = "3800664"; //You don't have to store the created mob in the db if you don't want, @@ -244,13 +234,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + truichon.Name + ", creating ..."); truichon.GuildName = "Stable Master"; truichon.Realm = eRealm.Hibernia; - truichon.CurrentRegionID = 1; truichon.Size = 50; truichon.Level = 33; - truichon.X = 343464; - truichon.Y = 526708; - truichon.Z = 5448; - truichon.Heading = 68; + truichon.Position = Position.Create(regionID: 1, x: 343464, y: 526708, z: 5448, heading: 68); //truichon.EquipmentTemplateID = "5448"; //You don't have to store the created mob in the db if you don't want, diff --git a/GameServerScripts/quests/Hibernia/MagicalBacklash.cs b/GameServerScripts/quests/Hibernia/MagicalBacklash.cs index 1f048a02de..c204ee3551 100644 --- a/GameServerScripts/quests/Hibernia/MagicalBacklash.cs +++ b/GameServerScripts/quests/Hibernia/MagicalBacklash.cs @@ -27,6 +27,7 @@ using System; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.Language; namespace DOL.GS.Quests.Hibernia @@ -309,7 +310,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) //k109: My preference, no guildname for quest NPCs. Uncomment if you like that... //Josson.GuildName = "Part of " + questTitle + " Quest"; Josson.Realm = eRealm.Hibernia; - Josson.CurrentRegionID = 200; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.HandsArmor, 386); //Slot 22 @@ -323,10 +323,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Josson.Size = 48; Josson.Level = 50; - Josson.X = 346627; - Josson.Y = 491453; - Josson.Z = 5247; - Josson.Heading = 2946; + Josson.Position = Position.Create(regionID: 200, x: 346627, y: 491453, z: 5247, heading: 2946); if (SAVE_INTO_DATABASE) Josson.SaveIntoDatabase(); diff --git a/GameServerScripts/quests/Hibernia/Nuisances.cs b/GameServerScripts/quests/Hibernia/Nuisances.cs index 2c63774eaa..8b4b540baf 100644 --- a/GameServerScripts/quests/Hibernia/Nuisances.cs +++ b/GameServerScripts/quests/Hibernia/Nuisances.cs @@ -34,6 +34,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -76,7 +77,13 @@ public class Nuisances : BaseAddrirQuest private static GameNPC addrir = null; private GameNPC sluagh = null; - private static GameLocation sluaghLocation = new GameLocation("sluagh Location", 200, 200, 27416, 4129, 5221, 310); + protected static Zone loughDerg = WorldMgr.GetZone(200); + private static Position sluaghPosition = Position.Create( + regionID: loughDerg.ZoneRegion.ID, + x: 27416 + loughDerg.Offset.X, + y: 4129 + loughDerg.Offset.Y, + z: 5221, + heading: 310); private static IArea sluaghArea = null; private static ItemTemplate emptyMagicBox = null; @@ -292,7 +299,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) #endregion - sluaghArea = WorldMgr.GetRegion(sluaghLocation.RegionID).AddArea(new Area.Circle("Sluagh contamined Area", sluaghLocation.X, sluaghLocation.Y, 0, 1500)); + sluaghArea = WorldMgr.GetRegion(sluaghPosition.RegionID).AddArea(new Area.Circle("Sluagh contamined Area", sluaghPosition.Coordinate, 1500)); sluaghArea.RegisterPlayerEnter(new DOLEventHandler(PlayerEnterSluaghArea)); /* Now we add some hooks to the npc we found. @@ -336,7 +343,7 @@ public static void ScriptUnloaded(DOLEvent e, object sender, EventArgs args) return; sluaghArea.UnRegisterPlayerEnter(new DOLEventHandler(PlayerEnterSluaghArea)); - WorldMgr.GetRegion(sluaghLocation.RegionID).RemoveArea(sluaghArea); + WorldMgr.GetRegion(sluaghPosition.RegionID).RemoveArea(sluaghArea); /* Removing hooks works just as adding them but instead of * AddHandler, we call RemoveHandler, the parameters stay the same @@ -379,13 +386,9 @@ protected virtual void CreateSluagh() sluagh.Name = "Sluagh Footsoldier"; sluagh.GuildName = "Part of " + questTitle + " Quest"; sluagh.Realm = eRealm.None; - sluagh.CurrentRegionID = 200; sluagh.Size = 50; sluagh.Level = 4; - sluagh.X = sluaghLocation.X + Util.Random(-150, 150); - sluagh.Y = sluaghLocation.Y + Util.Random(-150, 150); - sluagh.Z = sluaghLocation.Z; - sluagh.Heading = sluaghLocation.Heading; + sluagh.Position = sluaghPosition + Vector.Create(x: Util.Random(-150, 150), y: Util.Random(-150, 150)); StandardMobBrain brain = new StandardMobBrain(); brain.AggroLevel = 20; diff --git a/GameServerScripts/quests/Hibernia/SearchForKnowledge.cs b/GameServerScripts/quests/Hibernia/SearchForKnowledge.cs index 5e5e243534..cbe6d4b639 100644 --- a/GameServerScripts/quests/Hibernia/SearchForKnowledge.cs +++ b/GameServerScripts/quests/Hibernia/SearchForKnowledge.cs @@ -26,6 +26,7 @@ using System; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.Language; namespace DOL.GS.Quests.Hibernia @@ -169,7 +170,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + Blercyn.Name + ", creating him ..."); //Blercyn.GuildName = "Part of " + questTitle + " Quest"; Blercyn.Realm = eRealm.Hibernia; - Blercyn.CurrentRegionID = 200; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 58); @@ -178,10 +178,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Blercyn.Size = 50; Blercyn.Level = 50; - Blercyn.X = 348614; - Blercyn.Y = 492141; - Blercyn.Z = 5199; - Blercyn.Heading = 1539; + Blercyn.Position = Position.Create(regionID: 200, x: 348614, y: 492141, z: 5199, heading: 1539); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -206,7 +203,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + Epona.Name + ", creating him ..."); //Blercyn.GuildName = "Part of " + questTitle + " Quest"; Epona.Realm = eRealm.Hibernia; - Epona.CurrentRegionID = 200; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 58); @@ -215,10 +211,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Epona.Size = 50; Epona.Level = 50; - Epona.X = 347606; - Epona.Y = 490658; - Epona.Z = 5227; - Epona.Heading = 1342; + Epona.Position = Position.Create(regionID: 200, x: 347606, y: 490658, z: 5227, heading: 1342); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following diff --git a/GameServerScripts/quests/Hibernia/ToReachTheBreach.cs b/GameServerScripts/quests/Hibernia/ToReachTheBreach.cs index 9d96e4e68c..45262d1110 100644 --- a/GameServerScripts/quests/Hibernia/ToReachTheBreach.cs +++ b/GameServerScripts/quests/Hibernia/ToReachTheBreach.cs @@ -29,6 +29,7 @@ using System.Reflection; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using DOL.Language; using log4net; @@ -46,7 +47,7 @@ public class ToReachTheBreach : RewardQuest private static GameNPC Richael = null; private QuestGoal FoundBreach; - private static GameLocation Demons_Breach = new GameLocation("Demon's Breach", 200, 354760, 486115, 5973); + private static Position Demons_Breach = Position.Create(regionID: 200, x: 354760, y: 486115, z: 5973); private static IArea Demons_Breach_Area = null; @@ -214,7 +215,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) //k109: My preference, no guildname for quest NPCs. Uncomment if you like that... //Richael.GuildName = "Part of " + questTitle + " Quest"; Richael.Realm = eRealm.Hibernia; - Richael.CurrentRegionID = 200; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.HandsArmor, 416, 37); //Slot 22 @@ -228,10 +228,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Richael.Size = 48; Richael.Level = 38; - Richael.X = 347089; - Richael.Y = 491290; - Richael.Z = 5247; - Richael.Heading = 978; + Richael.Position = Position.Create(regionID: 200, x: 347089, y: 491290, z: 5247, heading: 978); if (SAVE_INTO_DATABASE) Richael.SaveIntoDatabase(); @@ -243,7 +240,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) #endregion #region defineAreas - Demons_Breach_Area = WorldMgr.GetRegion(Demons_Breach.RegionID).AddArea(new Area.Circle("", Demons_Breach.X, Demons_Breach.Y, Demons_Breach.Z, 200)); + Demons_Breach_Area = WorldMgr.GetRegion(Demons_Breach.RegionID).AddArea(new Area.Circle("", Demons_Breach.Coordinate, 200)); Demons_Breach_Area.RegisterPlayerEnter(new DOLEventHandler(PlayerEnterDemonBreachArea)); #endregion diff --git a/GameServerScripts/quests/Hibernia/TraitorInMagMell.cs b/GameServerScripts/quests/Hibernia/TraitorInMagMell.cs index 41f6ad1b5c..ec7b169fd1 100644 --- a/GameServerScripts/quests/Hibernia/TraitorInMagMell.cs +++ b/GameServerScripts/quests/Hibernia/TraitorInMagMell.cs @@ -35,6 +35,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -82,9 +83,8 @@ public class TraitorInMagMell : BaseAddrirQuest private static ItemTemplate recruitsBoots = null; private static ItemTemplate recruitsQuiltedBoots = null; - private static GameLocation legadaEnd = new GameLocation("Lady Legada", 200, 200, 12235, 8713, 5304, 218); - private static GameLocation legadaStart = new GameLocation("Lady Legada", 200, 330877, 492742, 5439, 2657); - + private static Position legadaStart = Position.Create(regionID: 200, x: 330877, y: 492742, z: 5439, heading: 2657 ); + private static Position legadaEnd = Position.Create(regionID: 200, x: 12235, y: 8713, z: 5304, heading: 218 ); /* We need to define the constructors from the base class here, else there might be problems * when loading this quest... @@ -151,13 +151,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) ladyLegada.Name = "Lady Legada"; ladyLegada.GuildName = "Part of " + questTitle + " Quest"; ladyLegada.Realm = eRealm.None; - ladyLegada.CurrentRegionID = legadaStart.RegionID; ladyLegada.Size = 50; ladyLegada.Level = 30; - ladyLegada.X = legadaStart.X; - ladyLegada.Y = legadaStart.Y; - ladyLegada.Z = legadaStart.Z; - ladyLegada.Heading = legadaStart.Heading; + ladyLegada.Position = legadaStart; StandardMobBrain brain = new StandardMobBrain(); brain.AggroLevel = 0; @@ -439,7 +435,7 @@ protected static void PlayerUseSlot(DOLEvent e, object sender, EventArgs args) InventoryItem item = player.Inventory.GetItem((eInventorySlot)uArgs.Slot); if (item != null && item.Id_nb == necklaceOfDoppelganger.Id_nb) { - if (player.IsWithinRadius( legadaEnd, 2500 )) + if (player.Coordinate.DistanceTo(legadaEnd) <= 2500) { foreach (GamePlayer visPlayer in player.GetPlayersInRadius(WorldMgr.VISIBILITY_DISTANCE)) { @@ -452,12 +448,9 @@ protected static void PlayerUseSlot(DOLEvent e, object sender, EventArgs args) if (!ladyLegada.IsAlive || ladyLegada.ObjectState != GameObject.eObjectState.Active) { - ladyLegada.X = legadaStart.X; - ladyLegada.Y = legadaStart.Y; - ladyLegada.Z = legadaStart.Z; - ladyLegada.Heading = legadaStart.Heading; + ladyLegada.Position = legadaStart; ladyLegada.AddToWorld(); - ladyLegada.WalkTo(legadaEnd.X, legadaEnd.Y, legadaEnd.Z, ladyLegada.MaxSpeed); + ladyLegada.WalkTo(legadaEnd.Coordinate, ladyLegada.MaxSpeed); } quest.Step = 3; } @@ -479,10 +472,7 @@ protected static void PlayerEnterWorld(DOLEvent e, object sender, EventArgs args if (quest.Step == 3 && (!ladyLegada.IsAlive || ladyLegada.ObjectState != GameObject.eObjectState.Active)) { - ladyLegada.X = legadaEnd.X; - ladyLegada.Y = legadaEnd.Y; - ladyLegada.Z = legadaEnd.Z; - ladyLegada.Heading = legadaEnd.Heading; + ladyLegada.Position = legadaEnd; ladyLegada.AddToWorld(); } } diff --git a/GameServerScripts/quests/Hibernia/epic/Essence50.cs b/GameServerScripts/quests/Hibernia/epic/Essence50.cs index 087820c43d..376be993f6 100644 --- a/GameServerScripts/quests/Hibernia/epic/Essence50.cs +++ b/GameServerScripts/quests/Hibernia/epic/Essence50.cs @@ -39,6 +39,7 @@ using System.Reflection; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; @@ -116,7 +117,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 201 && npc.X == 32927 && npc.Y == 32743) + if (npc.CurrentRegionID == 201) { Brigit = npc; break; @@ -131,13 +132,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Brigit.Name = "Brigit"; Brigit.GuildName = ""; Brigit.Realm = eRealm.Hibernia; - Brigit.CurrentRegionID = 201; Brigit.Size = 51; Brigit.Level = 50; - Brigit.X = 32927; - Brigit.Y = 32743; - Brigit.Z = 8008; - Brigit.Heading = 3254; + Brigit.Position = Position.Create(regionID: 201, x: 32927, y: 32743, z: 8008, heading: 3254); Brigit.AddToWorld(); if (SAVE_INTO_DATABASE) { @@ -150,7 +147,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 200 && npc.X == 470547 && npc.Y == 531497) + if (npc.Position.RegionID == 200) { Caithor = npc; break; @@ -165,13 +162,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Caithor.Name = "Caithor"; Caithor.GuildName = ""; Caithor.Realm = eRealm.None; - Caithor.CurrentRegionID = 200; Caithor.Size = 60; Caithor.Level = 65; - Caithor.X = 470547; - Caithor.Y = 531497; - Caithor.Z = 4984; - Caithor.Heading = 3319; + Caithor.Position = Position.Create(regionID: 200, x: 470547, y: 531497, z: 4984, heading: 3319); Caithor.AddToWorld(); if (SAVE_INTO_DATABASE) { @@ -1539,7 +1532,7 @@ public override void FinishQuest() *#26 seek out Loken in Raumarik Loc 47k, 25k, 4k, and kill him purp and 2 blue adds *#27 return to Brigit *#28 give her the ball of flame - *#29 talk with Brigit about Loken’s demise + *#29 talk with Brigit about Loken's demise *#30 go to MorlinCaan in Jordheim *#31 give her the sealed pouch *#32 you get your epic armor as a reward diff --git a/GameServerScripts/quests/Hibernia/epic/Focus50.cs b/GameServerScripts/quests/Hibernia/epic/Focus50.cs index eeb62a13b6..68712e90c3 100644 --- a/GameServerScripts/quests/Hibernia/epic/Focus50.cs +++ b/GameServerScripts/quests/Hibernia/epic/Focus50.cs @@ -34,6 +34,7 @@ using System.Reflection; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; @@ -116,7 +117,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 200 && npc.X == 421281 && npc.Y == 516273) + if (npc.CurrentRegionID == 200) { Ainrebh = npc; break; @@ -131,13 +132,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Ainrebh.Name = "Ainrebh"; Ainrebh.GuildName = "Enchanter"; Ainrebh.Realm = eRealm.Hibernia; - Ainrebh.CurrentRegionID = 200; Ainrebh.Size = 48; Ainrebh.Level = 40; - Ainrebh.X = 421281; - Ainrebh.Y = 516273; - Ainrebh.Z = 1877; - Ainrebh.Heading = 3254; + Ainrebh.Position = Position.Create(regionID: 200, x: 421281, y: 516273, z: 1877, heading: 3254); Ainrebh.AddToWorld(); if (SAVE_INTO_DATABASE) { @@ -150,7 +147,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 200 && npc.X == 488306 && npc.Y == 521440) + if (npc.CurrentRegionID == 200) { GreenMaw = npc; break; @@ -165,13 +162,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) GreenMaw.Name = "Green Maw"; GreenMaw.GuildName = ""; GreenMaw.Realm = eRealm.None; - GreenMaw.CurrentRegionID = 200; GreenMaw.Size = 50; GreenMaw.Level = 65; - GreenMaw.X = 488306; - GreenMaw.Y = 521440; - GreenMaw.Z = 6328; - GreenMaw.Heading = 1162; + GreenMaw.Position = Position.Create(regionID: 200, x: 488306, y: 521440, z: 6328, heading: 1162); GreenMaw.AddToWorld(); if (SAVE_INTO_DATABASE) { @@ -1568,7 +1561,7 @@ public override void FinishQuest() *#26 seek out Loken in Raumarik Loc 47k, 25k, 4k, and kill him purp and 2 blue adds *#27 return to Ainrebh *#28 give her the ball of flame - *#29 talk with Ainrebh about Loken’s demise + *#29 talk with Ainrebh about Loken's demise *#30 go to MorlinCaan in Jordheim *#31 give her the sealed pouch *#32 you get your epic armor as a reward diff --git a/GameServerScripts/quests/Hibernia/epic/Harmony50.cs b/GameServerScripts/quests/Hibernia/epic/Harmony50.cs index 1b9a466302..807dcc441f 100644 --- a/GameServerScripts/quests/Hibernia/epic/Harmony50.cs +++ b/GameServerScripts/quests/Hibernia/epic/Harmony50.cs @@ -17,6 +17,7 @@ using System.Reflection; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; @@ -116,7 +117,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 200 && npc.X == 343442 && npc.Y == 706235) + if (npc.CurrentRegionID == 200) { Revelin = npc; break; @@ -131,13 +132,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Revelin.Name = "Revelin"; Revelin.GuildName = ""; Revelin.Realm = eRealm.Hibernia; - Revelin.CurrentRegionID = 200; Revelin.Size = 42; Revelin.Level = 20; - Revelin.X = 343442; - Revelin.Y = 706235; - Revelin.Z = 6336; - Revelin.Heading = 2127; + Revelin.Position = Position.Create(regionID: 200, x: 343442, y: 706235, z: 6336, heading: 2127); Revelin.Flags ^= GameNPC.eFlags.PEACE; Revelin.AddToWorld(); if (SAVE_INTO_DATABASE) @@ -151,7 +148,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 200 && npc.X == 479042 && npc.Y == 508134) + if (npc.CurrentRegionID == 200) { Cailean = npc; break; @@ -166,13 +163,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Cailean.Name = "Cailean"; Cailean.GuildName = ""; Cailean.Realm = eRealm.None; - Cailean.CurrentRegionID = 200; Cailean.Size = 60; Cailean.Level = 65; - Cailean.X = 479042; - Cailean.Y = 508134; - Cailean.Z = 4569; - Cailean.Heading = 3319; + Cailean.Position = Position.Create(regionID: 200, x: 479042, y: 508134, z: 4569, heading: 3319); Cailean.AddToWorld(); if (SAVE_INTO_DATABASE) { @@ -2383,7 +2376,7 @@ public override void FinishQuest() *#26 seek out Loken in Raumarik Loc 47k, 25k, 4k, and kill him purp and 2 blue adds *#27 return to Revelin *#28 give her the ball of flame - *#29 talk with Revelin about Loken’s demise + *#29 talk with Revelin about Loken's demise *#30 go to MorlinCaan in Jordheim *#31 give her the sealed pouch *#32 you get your epic armor as a reward diff --git a/GameServerScripts/quests/Midgard/A_Beary_Bad_Problem.cs b/GameServerScripts/quests/Midgard/A_Beary_Bad_Problem.cs index 190d6ee297..e2e220c826 100644 --- a/GameServerScripts/quests/Midgard/A_Beary_Bad_Problem.cs +++ b/GameServerScripts/quests/Midgard/A_Beary_Bad_Problem.cs @@ -33,6 +33,7 @@ using DOL.Events; using DOL.GS.Behaviour; using DOL.GS.Behaviour.Attributes; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using DOL.GS.Quests; using DOL.Language; @@ -119,15 +120,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + VikingKreimhilde.Name + ", creating ..."); VikingKreimhilde.GuildName = "Part of " + questTitle + " Quest"; VikingKreimhilde.Realm = eRealm.Midgard; - VikingKreimhilde.CurrentRegionID = 100; VikingKreimhilde.Size = 51; VikingKreimhilde.Level = 50; VikingKreimhilde.MaxSpeedBase = 191; VikingKreimhilde.Faction = FactionMgr.GetFactionByID(0); - VikingKreimhilde.X = 803999; - VikingKreimhilde.Y = 726551; - VikingKreimhilde.Z = 4752; - VikingKreimhilde.Heading = 2116; + VikingKreimhilde.Position = Position.Create(regionID: 100, x: 803999, y: 726551, z: 4752, heading: 2116); VikingKreimhilde.RespawnInterval = -1; VikingKreimhilde.BodyType = 0; diff --git a/GameServerScripts/quests/Midgard/Amoras_Aid.cs b/GameServerScripts/quests/Midgard/Amoras_Aid.cs index 0a77e3e1f6..2f433cc62a 100644 --- a/GameServerScripts/quests/Midgard/Amoras_Aid.cs +++ b/GameServerScripts/quests/Midgard/Amoras_Aid.cs @@ -36,8 +36,9 @@ using DOL.GS.Behaviour; using DOL.GS.Behaviour.Attributes; using DOL.AI.Brain; +using DOL.GS.Geometry; - namespace DOL.GS.Quests.Midgard { +namespace DOL.GS.Quests.Midgard { /* The first thing we do, is to declare the class we create * as Quest. To do this, we derive from the abstract class @@ -120,15 +121,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + Lycla.Name + ", creating ..."); Lycla.GuildName = "Part of " + questTitle + " Quest"; Lycla.Realm = eRealm.Midgard; - Lycla.CurrentRegionID = 100; Lycla.Size = 48; Lycla.Level = 50; Lycla.MaxSpeedBase = 191; Lycla.Faction = FactionMgr.GetFactionByID(0); - Lycla.X = 749032; - Lycla.Y = 814613; - Lycla.Z = 4408; - Lycla.Heading = 170; + Lycla.Position = Position.Create(regionID: 100, x: 749032, y: 814613, z: 4408, heading: 170); Lycla.RespawnInterval = -1; Lycla.BodyType = 0; @@ -162,15 +159,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + Amora.Name + ", creating ..."); Amora.GuildName = "Part of " + questTitle + " Quest"; Amora.Realm = eRealm.Midgard; - Amora.CurrentRegionID = 100; Amora.Size = 49; Amora.Level = 28; Amora.MaxSpeedBase = 191; Amora.Faction = FactionMgr.GetFactionByID(0); - Amora.X = 747714; - Amora.Y = 814910; - Amora.Z = 4636; - Amora.Heading = 3456; + Amora.Position = Position.Create(regionID: 100, x: 747714, y: 814910, z: 4636, heading: 3456); Amora.RespawnInterval = -1; Amora.BodyType = 0; @@ -204,15 +197,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + Kari.Name + ", creating ..."); Kari.GuildName = "Part of " + questTitle + " Quest"; Kari.Realm = eRealm.Midgard; - Kari.CurrentRegionID = 100; Kari.Size = 51; Kari.Level = 20; Kari.MaxSpeedBase = 191; Kari.Faction = FactionMgr.GetFactionByID(0); - Kari.X = 749114; - Kari.Y = 814019; - Kari.Z = 4408; - Kari.Heading = 3595; + Kari.Position = Position.Create(regionID: 100, x: 749114, y: 814019, z: 4408, heading: 3595); Kari.RespawnInterval = -1; Kari.BodyType = 0; diff --git a/GameServerScripts/quests/Midgard/Bad_Food.cs b/GameServerScripts/quests/Midgard/Bad_Food.cs index 1f4e4898a7..d96c53fc48 100644 --- a/GameServerScripts/quests/Midgard/Bad_Food.cs +++ b/GameServerScripts/quests/Midgard/Bad_Food.cs @@ -36,8 +36,9 @@ using DOL.GS.Behaviour; using DOL.GS.Behaviour.Attributes; using DOL.AI.Brain; +using DOL.GS.Geometry; - namespace DOL.GS.Quests.Midgard { +namespace DOL.GS.Quests.Midgard { /* The first thing we do, is to declare the class we create * as Quest. To do this, we derive from the abstract class @@ -118,15 +119,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + Pedra.Name + ", creating ..."); Pedra.GuildName = "Part of " + questTitle + " Quest"; Pedra.Realm = eRealm.Midgard; - Pedra.CurrentRegionID = 151; Pedra.Size = 51; Pedra.Level = 50; Pedra.MaxSpeedBase = 191; Pedra.Faction = FactionMgr.GetFactionByID(0); - Pedra.X = 289895; - Pedra.Y = 356014; - Pedra.Z = 3866; - Pedra.Heading = 1661; + Pedra.Position = Position.Create(regionID: 151, x: 289895, y: 356014, z: 3866, heading: 1661); Pedra.RespawnInterval = -1; Pedra.BodyType = 0; @@ -160,15 +157,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + Kedra.Name + ", creating ..."); Kedra.GuildName = "Part of " + questTitle + " Quest"; Kedra.Realm = eRealm.Midgard; - Kedra.CurrentRegionID = 151; Kedra.Size = 51; Kedra.Level = 50; Kedra.MaxSpeedBase = 191; Kedra.Faction = FactionMgr.GetFactionByID(0); - Kedra.X = 289612; - Kedra.Y = 354560; - Kedra.Z = 3866; - Kedra.Heading = 3902; + Kedra.Position = Position.Create(regionID: 151, x: 289612, y: 354560, z: 3866, heading: 3902); Kedra.RespawnInterval = -1; Kedra.BodyType = 0; diff --git a/GameServerScripts/quests/Midgard/BaseDalikorQuest.cs b/GameServerScripts/quests/Midgard/BaseDalikorQuest.cs index 2a77f291ef..470b77fb6b 100644 --- a/GameServerScripts/quests/Midgard/BaseDalikorQuest.cs +++ b/GameServerScripts/quests/Midgard/BaseDalikorQuest.cs @@ -39,6 +39,7 @@ using System.Reflection; using DOL.AI.Brain; using DOL.Database; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -75,7 +76,9 @@ public abstract class BaseDalikorQuest : BaseQuest * */ - protected static GameLocation locationDalikor = new GameLocation("Dalikor", 100, 100, 41211, 50221, 5018, 242); + protected static Zone valeOfMularn = WorldMgr.GetZone(100); + protected static Position locationDalikor + = Position.Create(valeOfMularn.ZoneRegion.ID, 41211, 50221, 5018, 242) + valeOfMularn.Offset; /* We need to define the constructors from the base class here, else there might be problems * when loading this quest... @@ -166,7 +169,6 @@ public static GameNPC GetDalikor() log.Warn("Could not find " + dalikor.Name + ", creating him ..."); dalikor.GuildName = "Part of Dalikor Quests"; dalikor.Realm = eRealm.Midgard; - dalikor.CurrentRegionID = locationDalikor.RegionID; GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 348); @@ -187,10 +189,7 @@ public static GameNPC GetDalikor() dalikor.Size = 50; dalikor.Level = 50; - dalikor.X = locationDalikor.X; - dalikor.Y = locationDalikor.Y; - dalikor.Z = locationDalikor.Z; - dalikor.Heading = locationDalikor.Heading; + dalikor.Position = locationDalikor; StandardMobBrain brain = new StandardMobBrain(); brain.AggroLevel = 0; diff --git a/GameServerScripts/quests/Midgard/Bear Skins.cs b/GameServerScripts/quests/Midgard/Bear Skins.cs index 61101f9926..366881ca3a 100644 --- a/GameServerScripts/quests/Midgard/Bear Skins.cs +++ b/GameServerScripts/quests/Midgard/Bear Skins.cs @@ -36,8 +36,9 @@ using DOL.GS.Behaviour; using DOL.GS.Behaviour.Attributes; using DOL.AI.Brain; +using DOL.GS.Geometry; - namespace DOL.GS.Quests.Midgard { +namespace DOL.GS.Quests.Midgard { /* The first thing we do, is to declare the class we create * as Quest. To do this, we derive from the abstract class @@ -116,15 +117,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + Helen.Name + ", creating ..."); Helen.GuildName = "Part of " + questTitle + " Quest"; Helen.Realm = eRealm.Midgard; - Helen.CurrentRegionID = 100; Helen.Size = 49; Helen.Level = 41; Helen.MaxSpeedBase = 191; Helen.Faction = FactionMgr.GetFactionByID(0); - Helen.X = 805693; - Helen.Y = 701160; - Helen.Z = 4960; - Helen.Heading = 3470; + Helen.Position = Position.Create(regionID: 100, x: 805693, y: 701160, z: 4960, heading: 3470); Helen.RespawnInterval = -1; Helen.BodyType = 0; diff --git a/GameServerScripts/quests/Midgard/BeginningOfWar.cs b/GameServerScripts/quests/Midgard/BeginningOfWar.cs index 98c56345b0..fdfa8e3bf2 100644 --- a/GameServerScripts/quests/Midgard/BeginningOfWar.cs +++ b/GameServerScripts/quests/Midgard/BeginningOfWar.cs @@ -48,6 +48,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -90,7 +91,7 @@ public class BeginningOfWar : BaseDalikorQuest private static GameNPC dalikor = null; - private static GameLocation locationBriediClone = new GameLocation(null, 100, 794455, 721224, 4989, 3292); + private static Position locationBriediClone = Position.Create(regionID: 100, x: 794455, y: 721224, z: 4989, heading: 3292); private static GameNPC briedi = null; private GameNPC briediClone = null; @@ -180,14 +181,10 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + briedi.Name + ", creating him ..."); briedi.GuildName = "Part of " + questTitle + " Quest"; briedi.Realm = eRealm.Midgard; - briedi.CurrentRegionID = 100; briedi.Size = 50; briedi.Level = 45; - briedi.X = GameLocation.ConvertLocalXToGlobalX(26240, 103); - briedi.Y = GameLocation.ConvertLocalYToGlobalY(15706, 103); - briedi.Z = 4489; - briedi.Heading = 292; + briedi.Position = Position.CreateInZone(zoneID: 103, x: 26240, y: 15706, z: 4489, heading: 292); GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 348); @@ -228,14 +225,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) princessAiyr.Name = "Princess Aiyr"; if (log.IsWarnEnabled) log.Warn("Could not find " + princessAiyr.Name + ", creating ..."); - princessAiyr.X = GameLocation.ConvertLocalXToGlobalX(39315, 100); - princessAiyr.Y = GameLocation.ConvertLocalYToGlobalY(38957, 100); - princessAiyr.Z = 5460; - princessAiyr.Heading = 1; + var valeOfMularn = WorldMgr.GetZone(100); + princessAiyr.Position = Position.CreateInZone(zoneID: 100, x: 39315, y: 38957, z: 5460, heading: 1); princessAiyr.Model = 678; princessAiyr.GuildName = "Part of " + questTitle + " Quest"; princessAiyr.Realm = eRealm.None; - princessAiyr.CurrentRegionID = 100; princessAiyr.Size = 49; princessAiyr.Level = 3; @@ -276,19 +270,15 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + askefruerSorceress[i].Name + ", creating ..."); askefruerSorceress[i].GuildName = "Part of " + questTitle + " Quest"; askefruerSorceress[i].Realm = eRealm.None; - askefruerSorceress[i].CurrentRegionID = 100; askefruerSorceress[i].Size = 35; askefruerSorceress[i].Level = 3; - askefruerSorceress[i].X = princessAiyr.X + Util.Random(-150, 150); - askefruerSorceress[i].Y = princessAiyr.Y + Util.Random(-150, 150); - askefruerSorceress[i].Z = princessAiyr.Z; + askefruerSorceress[i].Position = princessAiyr.Position.With(heading: 93) + Vector.Create(x: Util.Random(-150, 150), y: Util.Random(-150, 150)); StandardMobBrain brain = new StandardMobBrain(); brain.AggroLevel = 30; brain.AggroRange = 300; askefruerSorceress[i].SetOwnBrain(brain); - askefruerSorceress[i].Heading = 93; //fairySorceress[i].EquipmentTemplateID = 200276; //You don't have to store the created mob in the db if you don't want, @@ -915,7 +905,7 @@ protected static void TalkToMasterBriedi(DOLEvent e, object sender, EventArgs ar briedi.SayTo(player, "Off you go!"); if (quest.Step == 13) { - quest.TeleportTo(player, briedi, locationDalikor, 10); + quest.TeleportTo(player, briedi, locationDalikor, "Dalikor", delay: 10, scatterRadius: 0); } break; } @@ -1031,14 +1021,9 @@ protected void CreateBriediClone() briediClone.Model = briedi.Model; briediClone.GuildName = briedi.GuildName; briediClone.Realm = briedi.Realm; - briediClone.CurrentRegionID = locationBriediClone.RegionID; briediClone.Size = briedi.Size; briediClone.Level = 15; // to make the figthing against fairy sorceress a bit more dramatic :) - - briediClone.X = locationBriediClone.X + Util.Random(-150, 150); - briediClone.Y = locationBriediClone.X + Util.Random(-150, 150); - briediClone.Z = locationBriediClone.Y; - briediClone.Heading = locationBriediClone.Heading; + briediClone.Position = locationBriediClone + Vector.Create(x: Util.Random(-150, 150), y: Util.Random(-150, 150)); GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 348); @@ -1073,7 +1058,7 @@ protected void CreateBriediClone() } else { - TeleportTo(briediClone, briediClone, locationBriediClone); + TeleportTo(briediClone, briediClone, locationBriediClone, delay: 0, scatterRadius: 0); } } diff --git a/GameServerScripts/quests/Midgard/Childs_Play.cs b/GameServerScripts/quests/Midgard/Childs_Play.cs index 234816f16b..02679a8baa 100644 --- a/GameServerScripts/quests/Midgard/Childs_Play.cs +++ b/GameServerScripts/quests/Midgard/Childs_Play.cs @@ -37,6 +37,7 @@ using DOL.GS.Behaviour; using DOL.GS.Behaviour.Attributes; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using DOL.GS.Quests; using DOL.Language; @@ -77,7 +78,8 @@ public class childsplay : BaseQuest private static ItemTemplate daringstuddedleggings = null; private static ItemTemplate daringstuddedsleeves = null; //private static AbstractArea Statua = null; - private static GameLocation Mid_Statue = new GameLocation("Childs Play (Mid)", 489, 27580, 40006, 14483); + private static ushort demonsBreachRegionId = 489; + private static Position Mid_Statue = Position.Create(demonsBreachRegionId, x: 27580, y: 40006, z: 14483); private static IArea Mid_Statue_Area = null; @@ -122,15 +124,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + Charles.Name + ", creating ..."); //Charles.GuildName = "Part of " + questTitle + " Quest"; Charles.Realm = eRealm.Midgard; - Charles.CurrentRegionID = 100; Charles.Size = 37; Charles.Level = 1; Charles.MaxSpeedBase = 191; Charles.Faction = FactionMgr.GetFactionByID(0); - Charles.X = 803946; - Charles.Y = 727221; - Charles.Z = 4680; - Charles.Heading = 1592; + Charles.Position = Position.Create(regionID: 100, x: 803946, y: 727221, z: 4680, heading: 1592); Charles.RespawnInterval = -1; Charles.BodyType = 0; @@ -1475,7 +1473,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) #endregion #region defineAreas - Mid_Statue_Area = WorldMgr.GetRegion(Mid_Statue.RegionID).AddArea(new Area.Circle("", Mid_Statue.X, Mid_Statue.Y, Mid_Statue.Z, 500)); + Mid_Statue_Area = WorldMgr.GetRegion(Mid_Statue.RegionID).AddArea(new Area.Circle("", Mid_Statue.Coordinate, 500)); Mid_Statue_Area.RegisterPlayerEnter(new DOLEventHandler(PlayerEnterStatueArea)); #endregion diff --git a/GameServerScripts/quests/Midgard/CityOfJordheim.cs b/GameServerScripts/quests/Midgard/CityOfJordheim.cs index 5a6a1d83de..5896a0e317 100644 --- a/GameServerScripts/quests/Midgard/CityOfJordheim.cs +++ b/GameServerScripts/quests/Midgard/CityOfJordheim.cs @@ -38,6 +38,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -78,15 +79,13 @@ public class CityOfJordheim : BaseDalikorQuest protected const int minimumLevel = 1; protected const int maximumLevel = 1; - protected static GameLocation warriorTrainer = new GameLocation("Warrior Trainer", 101, 29902, 35916, 8005, 2275); - protected static GameLocation savageTrainer = new GameLocation("Savage Trainer", 101, 28882, 35823, 8021, 2662); - protected static GameLocation skaldTrainer = new GameLocation("Skald Trainer", 101, 30395, 34943, 8005, 4004); - protected static GameLocation thaneTrainer = new GameLocation("Thane Trainer", 101, 29811, 34936, 8005, 159); - - protected static GameLocation westGates = new GameLocation("West Gates", 101, 36017, 32659, 8005, 1045); - - protected static GameLocation vaultKeeper = new GameLocation("Vault Keeper", 101, 31929, 28279, 8819, 2013); - protected static GameLocation berserkerTrainer = new GameLocation("Berserker Trainer", 101, 30327, 35598, 8002, 1706); + protected static Position warriorTrainer = Position.Create(regionID: 101, x: 29902, y: 35916, z: 8005, heading: 2275); + protected static Position savageTrainer = Position.Create(regionID: 101, x: 28882, y: 35823, z: 8021, heading: 2662); + protected static Position skaldTrainer = Position.Create(regionID: 101, x: 30395, y: 34943, z: 8005, heading: 4004); + protected static Position thaneTrainer = Position.Create(regionID: 101, x: 29811, y: 34936, z: 8005, heading: 159); + protected static Position westGates = Position.Create(regionID: 101, x: 36017, y: 32659, z: 8005, heading: 1045); + protected static Position vaultKeeper = Position.Create(regionID: 101, x: 31929, y: 28279, z: 8819, heading: 2013); + protected static Position berserkerTrainer = Position.Create(regionID: 101, x: 30327, y: 35598, z: 8002, heading: 1706); private static GameNPC dalikor = null; private static GameNPC yuliwyf = null; @@ -172,13 +171,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + yuliwyf.Name + ", creating ..."); yuliwyf.GuildName = "Part of " + questTitle + " Quest"; yuliwyf.Realm = eRealm.Midgard; - yuliwyf.CurrentRegionID = 101; yuliwyf.Size = 51; yuliwyf.Level = 50; - yuliwyf.X = 31929; - yuliwyf.Y = 28279; - yuliwyf.Z = 8819; - yuliwyf.Heading = 2013; + yuliwyf.Position = Position.Create(regionID: 101, x: 31929, y: 28279, z: 8819, heading: 2013); yuliwyf.EquipmentTemplateID = "5101262"; //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -201,13 +196,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + harlfug.Name + ", creating her ..."); harlfug.GuildName = "Stable Master"; harlfug.Realm = eRealm.Midgard; - harlfug.CurrentRegionID = 100; harlfug.Size = 52; harlfug.Level = 41; - harlfug.X = 773458; - harlfug.Y = 754240; - harlfug.Z = 4600; - harlfug.Heading = 2707; + harlfug.Position = Position.Create(regionID: 100, x: 773458, y: 754240, z: 4600, heading: 2707); harlfug.EquipmentTemplateID = "5100798"; //You don't have to store the created mob in the db if you don't want, @@ -748,29 +739,29 @@ protected static void TalkToAssistant(DOLEvent e, object sender, EventArgs args) break; case "skald": - quest.TeleportTo(skaldTrainer); + quest.TeleportTo(skaldTrainer, "Skald Trainer"); break; case "warrior": - quest.TeleportTo(warriorTrainer); + quest.TeleportTo(warriorTrainer, "Warrior Trainer"); break; case "savage": - quest.TeleportTo(savageTrainer); + quest.TeleportTo(savageTrainer, "Savage Trainer"); break; case "thane": - quest.TeleportTo(thaneTrainer); + quest.TeleportTo(thaneTrainer, "Thane Trainer"); break; case "berserker": - quest.TeleportTo(berserkerTrainer); + quest.TeleportTo(berserkerTrainer, "Berserker Trainer"); break; case "west gates": - quest.TeleportTo(westGates); + quest.TeleportTo(westGates, "West Gates"); break; case "vault keeper": if (quest.Step == 3) { quest.Step = 4; } - quest.TeleportTo(vaultKeeper); + quest.TeleportTo(vaultKeeper, "Vault Keeper"); break; case "go away": @@ -786,10 +777,10 @@ protected static void TalkToAssistant(DOLEvent e, object sender, EventArgs args) * Convinient Method for teleporintg with assistant */ - protected void TeleportTo(GameLocation target) + protected void TeleportTo(Position destination, string destinationName) { - TeleportTo(m_questPlayer, assistant, target, 5); - TeleportTo(assistant, assistant, target, 25, 50); + TeleportTo(m_questPlayer, assistant, destination, destinationName, delay: 5, scatterRadius: 0); + TeleportTo(assistant, assistant, destination, 25, 50); } @@ -875,7 +866,7 @@ protected virtual int CreateAssistant(RegionTimer callingTimer) { if (assistant != null && assistant.ObjectState == GameObject.eObjectState.Active) { - assistant.MoveTo(m_questPlayer.CurrentRegionID, m_questPlayer.X + 50, m_questPlayer.Y + 30, m_questPlayer.Z, m_questPlayer.Heading); + assistant.MoveTo(m_questPlayer.Position + Vector.Create(x: 50, y: 30)); } else { @@ -884,13 +875,9 @@ protected virtual int CreateAssistant(RegionTimer callingTimer) assistant.Name = m_questPlayer.Name + "'s Assistant"; assistant.GuildName = "Part of " + questTitle + " Quest"; assistant.Realm = m_questPlayer.Realm; - assistant.CurrentRegionID = m_questPlayer.CurrentRegionID; assistant.Size = 25; assistant.Level = 5; - assistant.X = m_questPlayer.X + 50; - assistant.Y = m_questPlayer.Y + 50; - assistant.Z = m_questPlayer.Z; - assistant.Heading = m_questPlayer.Heading; + assistant.Position = m_questPlayer.Position + Vector.Create(x: 50, y: 50); assistant.AddToWorld(); diff --git a/GameServerScripts/quests/Midgard/Collection.cs b/GameServerScripts/quests/Midgard/Collection.cs index e1dddf034d..f340de24ae 100644 --- a/GameServerScripts/quests/Midgard/Collection.cs +++ b/GameServerScripts/quests/Midgard/Collection.cs @@ -36,6 +36,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -80,7 +81,7 @@ public class Collection : BaseDalikorQuest private static GameNPC[] general = new GameNPC[3]; private static String[] generalNames = {"Mitan", "Ostadi", "Seiki"}; - private static GameLocation[] generalLocations = new GameLocation[3]; + private static Position[] generalLocations = new Position[3]; private static ItemTemplate askefruerWings = null; private static ItemTemplate dustyOldMap = null; @@ -144,9 +145,25 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) #region defineNPCs - generalLocations[0] = new GameLocation(generalNames[0], 100, 100, 40124, 44594, 4712, 216); - generalLocations[1] = new GameLocation(generalNames[1], 100, 100, 46821, 40884, 4972, 21); - generalLocations[2] = new GameLocation(generalNames[2], 100, 100, 56104, 43865, 5460, 48); + var valeOfMularn = WorldMgr.GetZone(100); + generalLocations[0] = Position.Create( + regionID: valeOfMularn.ZoneRegion.ID, + x: 40124 + valeOfMularn.Offset.X, + y: 44594 + valeOfMularn.Offset.Y, + z: 4712, + heading: 216); + generalLocations[1] = Position.Create( + regionID: valeOfMularn.ZoneRegion.ID, + x: 46821 + valeOfMularn.Offset.X, + y: 40884 + valeOfMularn.Offset.Y, + z: 4972, + heading: 21); + generalLocations[2] = Position.Create( + regionID: valeOfMularn.ZoneRegion.ID, + x: 56104 + valeOfMularn.Offset.X, + y: 43865 + valeOfMularn.Offset.Y, + z: 5460, + heading: 48); GameNPC[] npcs = null; for (int i = 0; i < general.Length; i++) @@ -164,13 +181,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) general[i].GuildName = "Part of " + questTitle + " Quest"; general[i].Name = generalNames[i]; - general[i].X = generalLocations[i].X; - general[i].Y = generalLocations[i].Y; - general[i].Z = generalLocations[i].Z; - general[i].Heading = generalLocations[i].Heading; + general[i].Position = generalLocations[i]; general[i].Realm = eRealm.None; - general[i].CurrentRegionID = generalLocations[i].RegionID; general[i].Size = 49; general[i].Level = 2; diff --git a/GameServerScripts/quests/Midgard/Culmination.cs b/GameServerScripts/quests/Midgard/Culmination.cs index 84ddc2c46a..a61e5d348a 100644 --- a/GameServerScripts/quests/Midgard/Culmination.cs +++ b/GameServerScripts/quests/Midgard/Culmination.cs @@ -36,6 +36,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -162,14 +163,10 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) queenVuuna = new GameNPC(); queenVuuna.Name = "Queen Vuuna"; - queenVuuna.X = GameLocation.ConvertLocalXToGlobalX(47071, 100); - queenVuuna.Y = GameLocation.ConvertLocalYToGlobalY(38934, 100); - queenVuuna.Z = 4747; - queenVuuna.Heading = 50; + queenVuuna.Position = Position.CreateInZone(zoneID: 100, x: 47071, y: 38934, z: 4747, heading: 50); queenVuuna.Model = 678; queenVuuna.GuildName = "Part of " + questTitle + " Quest"; queenVuuna.Realm = eRealm.None; - queenVuuna.CurrentRegionID = 100; queenVuuna.Size = 49; queenVuuna.Level = 5; @@ -211,20 +208,15 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) askefruerSorceress[i].Name = "askefruer sorceress"; askefruerSorceress[i].GuildName = "Part of " + questTitle + " Quest"; askefruerSorceress[i].Realm = eRealm.None; - askefruerSorceress[i].CurrentRegionID = 100; askefruerSorceress[i].Size = 35; askefruerSorceress[i].Level = 5; - askefruerSorceress[i].X = queenVuuna.X + Util.Random(30, 150); - askefruerSorceress[i].Y = queenVuuna.Y + Util.Random(30, 150); - askefruerSorceress[i].Z = queenVuuna.Z; + askefruerSorceress[i].Position = queenVuuna.Position.With(heading: 93) + Vector.Create(x: Util.Random(30, 150), y: Util.Random(30, 150)); StandardMobBrain brain = new StandardMobBrain(); brain.AggroLevel = 30; brain.AggroRange = 600; askefruerSorceress[i].SetOwnBrain(brain); - askefruerSorceress[i].Heading = 93; - //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following //line if you rather not modify your database @@ -833,6 +825,7 @@ protected virtual int DeleteBriediClone(RegionTimer callingTimer) protected void CreateBriediClone() { + var briediPosition = Position.Create(regionID: 100, x: 45394 + valeOfMularn.Offset.X, y: 39768 + valeOfMularn.Offset.Y, z: 4709, heading: 107); GameNpcInventoryTemplate template; if (briediClone == null) { @@ -845,10 +838,7 @@ protected void CreateBriediClone() briediClone.Size = 50; briediClone.Level = 45; - briediClone.X = GameLocation.ConvertLocalXToGlobalX(45394, 100); - briediClone.Y = GameLocation.ConvertLocalYToGlobalY(39768, 100); - briediClone.Z = 4709; - briediClone.Heading = 107; + briediClone.Position = briediPosition; template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 348); @@ -879,7 +869,7 @@ protected void CreateBriediClone() } else { - briediClone.MoveTo(100, GameLocation.ConvertLocalXToGlobalX(45394, 100), GameLocation.ConvertLocalYToGlobalY(39768, 100), 4709, 107); + briediClone.MoveTo(briediPosition); } @@ -897,15 +887,9 @@ protected void CreateBriediClone() recruits[i].GuildName = "Part of " + questTitle + " Quest"; recruits[i].Realm = eRealm.Midgard; - recruits[i].CurrentRegionID = briediClone.CurrentRegionID; - recruits[i].Size = 50; recruits[i].Level = 6; - recruits[i].X = briediClone.X + Util.Random(-150, 150); - recruits[i].Y = briediClone.Y + Util.Random(-150, 150); - - recruits[i].Z = briediClone.Z; - recruits[i].Heading = 187; + recruits[i].Position = briediClone.Position.With(heading: 187) + Vector.Create(x: Util.Random(-150, 150), y: Util.Random(-150, 150)); StandardMobBrain brain = new StandardMobBrain(); brain.AggroLevel = 0; diff --git a/GameServerScripts/quests/Midgard/Essence_of_Life.cs b/GameServerScripts/quests/Midgard/Essence_of_Life.cs index e42371f40f..5603265a99 100644 --- a/GameServerScripts/quests/Midgard/Essence_of_Life.cs +++ b/GameServerScripts/quests/Midgard/Essence_of_Life.cs @@ -36,8 +36,9 @@ using DOL.GS.Behaviour; using DOL.GS.Behaviour.Attributes; using DOL.AI.Brain; +using DOL.GS.Geometry; - namespace DOL.GS.Quests.Midgard { +namespace DOL.GS.Quests.Midgard { /* The first thing we do, is to declare the class we create * as Quest. To do this, we derive from the abstract class @@ -120,14 +121,10 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + AmbientRatStatua.Name + ", creating ..."); AmbientRatStatua.GuildName = "Part of " + questTitle + " Quest"; AmbientRatStatua.Realm = eRealm.None; - AmbientRatStatua.CurrentRegionID = 229; AmbientRatStatua.Size = 1; AmbientRatStatua.Level = 1; AmbientRatStatua.MaxSpeedBase = 0; - AmbientRatStatua.X = 40887; - AmbientRatStatua.Y = 39276; - AmbientRatStatua.Z = 17040; - AmbientRatStatua.Heading = 0; + AmbientRatStatua.Position = Position.Create(regionID: 229, x: 40887, y: 39276, z: 17040, heading: 0); AmbientRatStatua.RespawnInterval = -1; AmbientRatStatua.BodyType = 0; @@ -161,15 +158,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + Ballach.Name + ", creating ..."); Ballach.GuildName = "Part of " + questTitle + " Quest"; Ballach.Realm = eRealm.Midgard; - Ballach.CurrentRegionID = 243; Ballach.Size = 48; Ballach.Level = 20; Ballach.MaxSpeedBase = 0; Ballach.Faction = FactionMgr.GetFactionByID(0); - Ballach.X = 27723; - Ballach.Y = 39184; - Ballach.Z = 20156; - Ballach.Heading = 2070; + Ballach.Position = Position.Create(regionID: 243, x: 27723, y: 39184, z: 20156, heading: 2070); Ballach.RespawnInterval = -1; Ballach.BodyType = 0; diff --git a/GameServerScripts/quests/Midgard/Frontiers.cs b/GameServerScripts/quests/Midgard/Frontiers.cs index 9a76fe40d0..cf471a5ee4 100644 --- a/GameServerScripts/quests/Midgard/Frontiers.cs +++ b/GameServerScripts/quests/Midgard/Frontiers.cs @@ -38,6 +38,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using DOL.GS.Profession; using DOL.Language; @@ -86,8 +87,8 @@ public class Frontiers : BaseDalikorQuest private static GameNPC idora = null; private static GameStableMaster vorgar = null; - private static GameLocation locationIdora = null; - private static GameLocation locationVorgar = null; + private static Position idoraPosition = Position.Nowhere; + private static Position vorgarPosition = Position.Nowhere; private static GameStableMaster njiedi = null; private static GameNPC griffin = null; @@ -172,13 +173,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) annark.Name = "Stor Gothi Annark"; annark.GuildName = "Part of " + questTitle + " Quest"; annark.Realm = eRealm.Midgard; - annark.CurrentRegionID = 100; annark.Size = 51; annark.Level = 66; - annark.X = 765357; - annark.Y = 668790; - annark.Z = 5759; - annark.Heading = 7711; + annark.Position = Position.Create(regionID: 100, x: 765357, y: 668790, z: 5759, heading: 7711); //annark.AddNPCEquipment((byte)eEquipmentItems.TORSO, 798, 0, 0, 0); //annark.AddNPCEquipment((byte)eEquipmentItems.RIGHT_HAND, 19, 0, 0, 0); @@ -205,12 +202,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) idora.Name = LanguageMgr.GetTranslation(ServerProperties.Properties.SERV_LANGUAGE, "Mid.Frontiers.NPCScryerIdora"); idora.GuildName = "Part of " + questTitle + " Quest"; idora.Realm = eRealm.Midgard; - idora.CurrentRegionID = 234; idora.Size = 52; idora.Level = 50; - idora.X = 558081; - idora.Y = 573988; - idora.Z = 8640; + idora.Position = Position.Create(regionID: 234, x: 558081, y: 573988, z: 8640, heading: 1558); GameNpcInventoryTemplate template = new GameNpcInventoryTemplate(); template.AddNPCEquipment(eInventorySlot.TorsoArmor, 81); @@ -227,7 +221,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) // idora.AddNPCEquipment(Slot.CLOAK, 91, 0, 0, 0); // idora.AddNPCEquipment(Slot.RIGHTHAND, 3, 0, 0, 0); - idora.Heading = 1558; idora.MaxSpeedBase = 200; idora.EquipmentTemplateID = "200292"; @@ -246,8 +239,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) else idora = npcs[0]; - Point2D point = idora.GetPointFromHeading( idora.Heading, 30 ); - locationIdora = new GameLocation(idora.CurrentZone.Description, idora.CurrentRegionID, point.X, point.Y, idora.Z); + idoraPosition = idora.Position + Vector.Create(idora.Orientation, length: 30); ticketToSvasudFaste = CreateTicketTo("Svasud Faste", "hs_mularn_svasudfaste"); ticketToMularn = CreateTicketTo("Mularn", "hs_svasudfaste_mularn"); @@ -263,7 +255,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + njiedi.Name + ", creating ..."); njiedi.GuildName = "Stable Master"; njiedi.Realm = eRealm.Midgard; - njiedi.CurrentRegionID = 100; njiedi.Size = 51; njiedi.Level = 50; @@ -278,11 +269,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) // njiedi.AddNPCEquipment(Slot.LEGS, 82, 10, 0, 0); // njiedi.AddNPCEquipment(Slot.FEET, 84, 10, 0, 0); // njiedi.AddNPCEquipment(Slot.CLOAK, 57, 32, 0, 0); - - njiedi.X = GameLocation.ConvertLocalXToGlobalX(55561, 100); - njiedi.Y = GameLocation.ConvertLocalYToGlobalY(58225, 100); - njiedi.Z = 5005; - njiedi.Heading = 126; + njiedi.Position = Position.CreateInZone(zoneID: 100, x: 55561, y: 58225, z: 5005, heading: 126); StandardMobBrain brain = new StandardMobBrain(); brain.AggroLevel = 0; @@ -324,19 +311,15 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + griffin.Name + ", creating ..."); griffin.GuildName = "Part of " + questTitle + " Quest"; griffin.Realm = eRealm.Midgard; - griffin.CurrentRegionID = njiedi.CurrentRegionID; griffin.Size = 50; griffin.Level = 50; - griffin.X = njiedi.X + 80; - griffin.Y = njiedi.Y + 100; - griffin.Z = njiedi.Z; + griffin.Position = njiedi.Position.With(heading: 93) + Vector.Create(x: 80, y: 100); StandardMobBrain brain = new StandardMobBrain(); brain.AggroLevel = 0; brain.AggroRange = 0; griffin.SetOwnBrain(brain); - griffin.Heading = 93; griffin.MaxSpeedBase = 400; //dragonfly.EquipmentTemplateID = 200276; @@ -361,13 +344,10 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + vorgar.Name + ", creating ..."); vorgar.GuildName = "Stable Master"; vorgar.Realm = eRealm.Midgard; - vorgar.CurrentRegionID = 100; vorgar.Size = 51; vorgar.Level = 50; - vorgar.X = GameLocation.ConvertLocalXToGlobalX(10660, 100); - vorgar.Y = GameLocation.ConvertLocalYToGlobalY(3437, 100); - vorgar.Z = 5717; - vorgar.Heading = 327; + vorgar.Position = Position.Create(valeOfMularn.ZoneRegion.ID, x: 10660, y: 3437, z: 5717, heading: 327); + vorgar.Position += valeOfMularn.Offset; vorgar.MaxSpeedBase = 200; StandardMobBrain brain = new StandardMobBrain(); @@ -390,8 +370,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) else vorgar = npcs[0] as GameStableMaster; - Point2D vorgarloc = vorgar.GetPointFromHeading( vorgar.Heading, 30 ); - locationVorgar = new GameLocation(vorgar.CurrentZone.Description, vorgar.CurrentRegionID, vorgarloc.X, vorgarloc.Y, vorgar.Z); + vorgarPosition = vorgar.Position + Vector.Create(vorgar.Orientation, length: 30); #endregion @@ -826,7 +805,7 @@ protected static void TalkToIdora(DOLEvent e, object sender, EventArgs args) GiveItem(idora, player, translatedPlans); GiveItem(idora, player, ticketToMularn); quest.Step = 5; - quest.TeleportTo(player, idora, locationVorgar, 50); + quest.TeleportTo(player, idora, vorgarPosition, delay: 50, scatterRadius: 0); } } @@ -855,7 +834,7 @@ protected static void TalkToAnnark(DOLEvent e, object sender, EventArgs args) { annark.SayTo(player, LanguageMgr.GetTranslation(ServerProperties.Properties.SERV_LANGUAGE, "Mid.Frontiers.TalkToAnnark.Talk1")); quest.Step = 3; - quest.TeleportTo(player, annark, locationIdora, 30); + quest.TeleportTo(player, annark, idoraPosition, delay: 30, scatterRadius: 0); return; } diff --git a/GameServerScripts/quests/Midgard/ImportantDelivery.cs b/GameServerScripts/quests/Midgard/ImportantDelivery.cs index 0d0be081dd..8022cbe478 100644 --- a/GameServerScripts/quests/Midgard/ImportantDelivery.cs +++ b/GameServerScripts/quests/Midgard/ImportantDelivery.cs @@ -35,6 +35,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -157,13 +158,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find" + abohas.Name + " , creating her ..."); abohas.GuildName = "Part of " + questTitle + " Quest"; abohas.Realm = eRealm.Midgard; - abohas.CurrentRegionID = 100; abohas.Size = 49; abohas.Level = 21; - abohas.X = GameLocation.ConvertLocalXToGlobalX(52274, 100); - abohas.Y = GameLocation.ConvertLocalYToGlobalY(29985, 100); - abohas.Z = 4960; - abohas.Heading = 123; + abohas.Position = Position.CreateInZone(zoneID: 100, x: 52274, y: 29985, z: 4960, heading: 123); //abohas.EquipmentTemplateID = "1707754"; //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -185,13 +182,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + harlfug.Name + ", creating her ..."); harlfug.GuildName = "Stable Master"; harlfug.Realm = eRealm.Midgard; - harlfug.CurrentRegionID = 100; harlfug.Size = 52; harlfug.Level = 41; - harlfug.X = 773458; - harlfug.Y = 754240; - harlfug.Z = 4600; - harlfug.Heading = 2707; + harlfug.Position = Position.Create(regionID: 100, x: 773458, y: 754240, z: 4600, heading: 2707); harlfug.EquipmentTemplateID = "5100798"; //You don't have to store the created mob in the db if you don't want, @@ -214,13 +207,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + gularg.Name + ", creating her ..."); gularg.GuildName = "Stable Master"; gularg.Realm = eRealm.Midgard; - gularg.CurrentRegionID = 100; gularg.Size = 50; gularg.Level = 41; - gularg.X = 803766; - gularg.Y = 721959; - gularg.Z = 4686; - gularg.Heading = 3925; + gularg.Position = Position.Create(regionID: 100, x: 803766, y: 721959, z: 4686, heading: 3925); gularg.EquipmentTemplateID = "5100798"; //You don't have to store the created mob in the db if you don't want, @@ -244,13 +233,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + yolafson.Name + ", creating her ..."); yolafson.GuildName = "Stable Master"; yolafson.Realm = eRealm.Midgard; - yolafson.CurrentRegionID = 100; yolafson.Size = 51; yolafson.Level = 41; - yolafson.X = 805721; - yolafson.Y = 700414; - yolafson.Z = 4960; - yolafson.Heading = 1206; + yolafson.Position = Position.Create(regionID: 100, x: 805721, y: 700414, z: 4960, heading: 1206); yolafson.EquipmentTemplateID = "5100798"; //You don't have to store the created mob in the db if you don't want, diff --git a/GameServerScripts/quests/Midgard/Learn_The_Hunt.cs b/GameServerScripts/quests/Midgard/Learn_The_Hunt.cs index 771442385d..5ec50af95f 100644 --- a/GameServerScripts/quests/Midgard/Learn_The_Hunt.cs +++ b/GameServerScripts/quests/Midgard/Learn_The_Hunt.cs @@ -36,8 +36,9 @@ using DOL.GS.Behaviour; using DOL.GS.Behaviour.Attributes; using DOL.AI.Brain; +using DOL.GS.Geometry; - namespace DOL.GS.Quests.Midgard { +namespace DOL.GS.Quests.Midgard { /* The first thing we do, is to declare the class we create * as Quest. To do this, we derive from the abstract class @@ -116,15 +117,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + Aegan.Name + ", creating ..."); Aegan.GuildName = "Part of " + questTitle + " Quest"; Aegan.Realm = eRealm.Midgard; - Aegan.CurrentRegionID = 100; Aegan.Size = 51; Aegan.Level = 41; Aegan.MaxSpeedBase = 191; Aegan.Faction = FactionMgr.GetFactionByID(0); - Aegan.X = 805398; - Aegan.Y = 725829; - Aegan.Z = 4700; - Aegan.Heading = 3595; + Aegan.Position = Position.Create(regionID: 100, x: 805398, y: 725829, z: 4700, heading: 3595); Aegan.RespawnInterval = -1; Aegan.BodyType = 0; diff --git a/GameServerScripts/quests/Midgard/Mauler_Invasion.cs b/GameServerScripts/quests/Midgard/Mauler_Invasion.cs index b762a0ae15..ad4d2d856f 100644 --- a/GameServerScripts/quests/Midgard/Mauler_Invasion.cs +++ b/GameServerScripts/quests/Midgard/Mauler_Invasion.cs @@ -33,6 +33,7 @@ using DOL.Events; using DOL.GS.Behaviour; using DOL.GS.Behaviour.Attributes; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using DOL.GS.Quests; using DOL.Language; @@ -118,15 +119,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + VikingKreimhilde.Name + ", creating ..."); VikingKreimhilde.GuildName = "Part of " + questTitle + " Quest"; VikingKreimhilde.Realm = eRealm.Midgard; - VikingKreimhilde.CurrentRegionID = 100; VikingKreimhilde.Size = 51; VikingKreimhilde.Level = 50; VikingKreimhilde.MaxSpeedBase = 191; VikingKreimhilde.Faction = FactionMgr.GetFactionByID(0); - VikingKreimhilde.X = 803999; - VikingKreimhilde.Y = 726551; - VikingKreimhilde.Z = 4752; - VikingKreimhilde.Heading = 2116; + VikingKreimhilde.Position = Position.Create(regionID: 100, x: 803999, y: 726551, z: 4752, heading: 2116); VikingKreimhilde.RespawnInterval = -1; VikingKreimhilde.BodyType = 0; diff --git a/GameServerScripts/quests/Midgard/Mead_Run.cs b/GameServerScripts/quests/Midgard/Mead_Run.cs index 94d9877b54..da1c95b2bb 100644 --- a/GameServerScripts/quests/Midgard/Mead_Run.cs +++ b/GameServerScripts/quests/Midgard/Mead_Run.cs @@ -36,8 +36,9 @@ using DOL.GS.Behaviour; using DOL.GS.Behaviour.Attributes; using DOL.AI.Brain; +using DOL.GS.Geometry; - namespace DOL.GS.Quests.Midgard { +namespace DOL.GS.Quests.Midgard { /* The first thing we do, is to declare the class we create * as Quest. To do this, we derive from the abstract class @@ -122,15 +123,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + Audun.Name + ", creating ..."); Audun.GuildName = "Part of " + questTitle + " Quest"; Audun.Realm = eRealm.Midgard; - Audun.CurrentRegionID = 101; Audun.Size = 48; Audun.Level = 49; Audun.MaxSpeedBase = 191; Audun.Faction = FactionMgr.GetFactionByID(0); - Audun.X = 33283; - Audun.Y = 35305; - Audun.Z = 8027; - Audun.Heading = 1763; + Audun.Position = Position.Create(regionID: 101, x: 33283, y: 35305, z: 8027, heading: 1763); Audun.RespawnInterval = -1; Audun.BodyType = 0; @@ -167,15 +164,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + GuardOlja.Name + ", creating ..."); GuardOlja.GuildName = "Part of " + questTitle + " Quest"; GuardOlja.Realm = eRealm.Midgard; - GuardOlja.CurrentRegionID = 229; GuardOlja.Size = 50; GuardOlja.Level = 50; GuardOlja.MaxSpeedBase = 191; GuardOlja.Faction = FactionMgr.GetFactionByID(0); - GuardOlja.X = 47994; - GuardOlja.Y = 37341; - GuardOlja.Z = 21812; - GuardOlja.Heading = 204; + GuardOlja.Position = Position.Create(regionID: 229, x: 47994, y: 37341, z: 21812, heading: 204); GuardOlja.RespawnInterval = -1; GuardOlja.BodyType = 0; diff --git a/GameServerScripts/quests/Midgard/Nuisances.cs b/GameServerScripts/quests/Midgard/Nuisances.cs index 7b98f35ac8..003bb1cf42 100644 --- a/GameServerScripts/quests/Midgard/Nuisances.cs +++ b/GameServerScripts/quests/Midgard/Nuisances.cs @@ -34,6 +34,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -76,7 +77,9 @@ public class Nuisances : BaseDalikorQuest private static GameNPC dalikor = null; private GameNPC askefruer = null; - private static GameLocation askefruerLocation = new GameLocation("Fallen Askefruer", 100, 100, 44585, 56194, 4780, 294); + private static Position askefruerPosition + = Position.Create(regionID: valeOfMularn.ZoneRegion.ID, x: 44585, y: 56194, z: 4780, heading: 294) + + valeOfMularn.Offset; private static IArea askefruerArea = null; private static ItemTemplate emptyMagicBox = null; @@ -290,7 +293,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) #endregion - askefruerArea = WorldMgr.GetRegion(askefruerLocation.RegionID).AddArea(new Area.Circle("Askefruer contamined Area", askefruerLocation.X, askefruerLocation.Y, 0, 1500)); + askefruerArea = WorldMgr.GetRegion(askefruerPosition.RegionID).AddArea(new Area.Circle("Askefruer contamined Area", askefruerPosition.Coordinate, 1500)); askefruerArea.RegisterPlayerEnter(new DOLEventHandler(PlayerEnterAskefruerArea)); /* Now we add some hooks to the npc we found. @@ -333,7 +336,7 @@ public static void ScriptUnloaded(DOLEvent e, object sender, EventArgs args) return; askefruerArea.UnRegisterPlayerEnter(new DOLEventHandler(PlayerEnterAskefruerArea)); - WorldMgr.GetRegion(askefruerLocation.RegionID).RemoveArea(askefruerArea); + WorldMgr.GetRegion(askefruerPosition.RegionID).RemoveArea(askefruerArea); /* Removing hooks works just as adding them but instead of * AddHandler, we call RemoveHandler, the parameters stay the same @@ -376,13 +379,9 @@ protected virtual void CreateAskefruer() askefruer.Name = "Fallen Askefruer"; askefruer.GuildName = "Part of " + questTitle + " Quest"; askefruer.Realm = eRealm.None; - askefruer.CurrentRegionID = askefruerLocation.RegionID; askefruer.Size = 50; askefruer.Level = 4; - askefruer.X = askefruerLocation.X + Util.Random(-150, 150); - askefruer.Y = askefruerLocation.Y + Util.Random(-150, 150); - askefruer.Z = askefruerLocation.Z; - askefruer.Heading = askefruerLocation.Heading; + askefruer.Position = askefruerPosition + Vector.Create(x: Util.Random(-150, 150), y: Util.Random(-150,150)); StandardMobBrain brain = new StandardMobBrain(); brain.AggroLevel = 20; diff --git a/GameServerScripts/quests/Midgard/Rindas_Lost_Key.cs b/GameServerScripts/quests/Midgard/Rindas_Lost_Key.cs index bea5aeaf47..0a1a7e6962 100644 --- a/GameServerScripts/quests/Midgard/Rindas_Lost_Key.cs +++ b/GameServerScripts/quests/Midgard/Rindas_Lost_Key.cs @@ -36,8 +36,9 @@ using DOL.GS.Behaviour; using DOL.GS.Behaviour.Attributes; using DOL.AI.Brain; +using DOL.GS.Geometry; - namespace DOL.GS.Quests.Midgard { +namespace DOL.GS.Quests.Midgard { /* The first thing we do, is to declare the class we create * as Quest. To do this, we derive from the abstract class @@ -124,15 +125,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + DwarvenGuardRinda.Name + ", creating ..."); DwarvenGuardRinda.GuildName = "Part of " + questTitle + " Quest"; DwarvenGuardRinda.Realm = eRealm.Midgard; - DwarvenGuardRinda.CurrentRegionID = 100; DwarvenGuardRinda.Size = 53; DwarvenGuardRinda.Level = 41; DwarvenGuardRinda.MaxSpeedBase = 191; DwarvenGuardRinda.Faction = FactionMgr.GetFactionByID(0); - DwarvenGuardRinda.X = 805496; - DwarvenGuardRinda.Y = 701215; - DwarvenGuardRinda.Z = 4960; - DwarvenGuardRinda.Heading = 1570; + DwarvenGuardRinda.Position = Position.Create(regionID: 100, x: 805496, y: 701215, z: 4960, heading: 1570); DwarvenGuardRinda.RespawnInterval = -1; DwarvenGuardRinda.BodyType = 0; @@ -169,15 +166,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + hobgoblinsnakefinder.Name + ", creating ..."); hobgoblinsnakefinder.GuildName = "Part of " + questTitle + " Quest"; hobgoblinsnakefinder.Realm = eRealm.None; - hobgoblinsnakefinder.CurrentRegionID = 100; hobgoblinsnakefinder.Size = 37; hobgoblinsnakefinder.Level = 1; hobgoblinsnakefinder.MaxSpeedBase = 191; hobgoblinsnakefinder.Faction = FactionMgr.GetFactionByID(0); - hobgoblinsnakefinder.X = 803189; - hobgoblinsnakefinder.Y = 695157; - hobgoblinsnakefinder.Z = 4926; - hobgoblinsnakefinder.Heading = 125; + hobgoblinsnakefinder.Position = Position.Create(regionID: 100, x: 803189, y: 695157, z: 4926, heading: 125); hobgoblinsnakefinder.RespawnInterval = -1; hobgoblinsnakefinder.BodyType = 0; diff --git a/GameServerScripts/quests/Midgard/StolenEggs.cs b/GameServerScripts/quests/Midgard/StolenEggs.cs index 17e3365d5d..b638a7678b 100644 --- a/GameServerScripts/quests/Midgard/StolenEggs.cs +++ b/GameServerScripts/quests/Midgard/StolenEggs.cs @@ -37,6 +37,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using DOL.Language; using log4net; @@ -161,14 +162,10 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + hyndla.Name + ", creating ..."); hyndla.GuildName = "Part of " + questTitle + " Quest"; hyndla.Realm = eRealm.Midgard; - hyndla.CurrentRegionID = 100; hyndla.Size = 50; hyndla.Level = 40; - hyndla.X = GameLocation.ConvertLocalXToGlobalX(53049, 100); - hyndla.Y = GameLocation.ConvertLocalYToGlobalY(58068, 100); - hyndla.Z = 4985; - hyndla.Heading = 150; + hyndla.Position = Position.CreateInZone(zoneID: 100, x: 53049, y: 58068, z: 4985, heading: 150); //You don't have to store the created mob in the db if you don't want, //it will be recreated each time it is not found, just comment the following @@ -192,7 +189,6 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + njiedi.Name + ", creating ..."); njiedi.GuildName = "Stable Master"; njiedi.Realm = eRealm.Midgard; - njiedi.CurrentRegionID = 100; njiedi.Size = 51; njiedi.Level = 50; @@ -208,10 +204,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) // njiedi.AddNPCEquipment(Slot.FEET, 84, 10, 0, 0); // njiedi.AddNPCEquipment(Slot.CLOAK, 57, 32, 0, 0); - njiedi.X = GameLocation.ConvertLocalXToGlobalX(55561, 100); - njiedi.Y = GameLocation.ConvertLocalYToGlobalY(58225, 100); - njiedi.Z = 5005; - njiedi.Heading = 126; + njiedi.Position = Position.CreateInZone(zoneID: 100, x: 55561, y: 58225, z: 5005, heading: 126); StandardMobBrain brain = new StandardMobBrain(); brain.AggroLevel = 0; @@ -237,14 +230,10 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) askefruerTrainer = new GameNPC(); askefruerTrainer.Name = LanguageMgr.GetTranslation(ServerProperties.Properties.SERV_LANGUAGE, "Mid.StolenEggs.NPCAskefruerTrainer"); - askefruerTrainer.X = GameLocation.ConvertLocalXToGlobalX(54739, 100); - askefruerTrainer.Y = GameLocation.ConvertLocalYToGlobalY(18264, 100); - askefruerTrainer.Z = 5195; - askefruerTrainer.Heading = 79; + askefruerTrainer.Position = Position.CreateInZone(zoneID: 100, x: 54739, y: 18264, z: 5195, heading: 79); askefruerTrainer.Model = 678; //askefruerTrainer.GuildName = "Part of " + questTitle + " Quest"; askefruerTrainer.Realm = eRealm.None; - askefruerTrainer.CurrentRegionID = 100; askefruerTrainer.Size = 49; askefruerTrainer.Level = 3; @@ -541,13 +530,9 @@ protected void initGrifflet() grifflet.Name = LanguageMgr.GetTranslation(ServerProperties.Properties.SERV_LANGUAGE, "Mid.StolenEggs.InitGrifflet.NPCGrifflet"); //grifflet.GuildName = "Part of " + m_questPlayer.GetName(0, false) + "'s " + questTitle + " Quest"; grifflet.Flags ^= GameNPC.eFlags.PEACE; - grifflet.CurrentRegionID = askefruerTrainer.CurrentRegionID; grifflet.Size = 20; grifflet.Level = 3; - grifflet.X = askefruerTrainer.X + Util.Random(-150, 150); - grifflet.Y = askefruerTrainer.Y + Util.Random(-150, 150); - grifflet.Z = askefruerTrainer.Z; - grifflet.Heading = 93; + grifflet.Position = askefruerTrainer.Position.With(heading: 93) + Vector.Create(x: Util.Random(-150, 150), y: Util.Random(-150, 150)); grifflet.MaxSpeedBase = 200; StandardMobBrain brain = new StandardMobBrain(); diff --git a/GameServerScripts/quests/Midgard/Sveabone_Hilt_Sword.cs b/GameServerScripts/quests/Midgard/Sveabone_Hilt_Sword.cs index e5e8f15507..34d16e8ab5 100644 --- a/GameServerScripts/quests/Midgard/Sveabone_Hilt_Sword.cs +++ b/GameServerScripts/quests/Midgard/Sveabone_Hilt_Sword.cs @@ -36,8 +36,9 @@ using DOL.GS.Behaviour; using DOL.GS.Behaviour.Attributes; using DOL.AI.Brain; +using DOL.GS.Geometry; - namespace DOL.GS.Quests.Midgard { +namespace DOL.GS.Quests.Midgard { /* The first thing we do, is to declare the class we create * as Quest. To do this, we derive from the abstract class @@ -122,15 +123,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + Gridash.Name + ", creating ..."); Gridash.GuildName = "Part of " + questTitle + " Quest"; Gridash.Realm = eRealm.Midgard; - Gridash.CurrentRegionID = 100; Gridash.Size = 51; Gridash.Level = 21; Gridash.MaxSpeedBase = 191; Gridash.Faction = FactionMgr.GetFactionByID(0); - Gridash.X = 772795; - Gridash.Y = 753335; - Gridash.Z = 4600; - Gridash.Heading = 3356; + Gridash.Position = Position.Create(regionID: 100, x: 772795, y: 753335, z: 4600, heading: 3356); Gridash.RespawnInterval = -1; Gridash.BodyType = 0; diff --git a/GameServerScripts/quests/Midgard/The_Birthday_Gift.cs b/GameServerScripts/quests/Midgard/The_Birthday_Gift.cs index 5403198f28..52c59994b3 100644 --- a/GameServerScripts/quests/Midgard/The_Birthday_Gift.cs +++ b/GameServerScripts/quests/Midgard/The_Birthday_Gift.cs @@ -32,6 +32,7 @@ using DOL.Events; using DOL.GS.Behaviour; using DOL.GS.Behaviour.Attributes; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using DOL.GS.Quests; using DOL.Language; @@ -123,15 +124,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + BarkeepNognar.Name + ", creating ..."); BarkeepNognar.GuildName = "Part of " + questTitle + " Quest"; BarkeepNognar.Realm = eRealm.Midgard; - BarkeepNognar.CurrentRegionID = 100; BarkeepNognar.Size = 58; BarkeepNognar.Level = 15; BarkeepNognar.MaxSpeedBase = 191; BarkeepNognar.Faction = FactionMgr.GetFactionByID(0); - BarkeepNognar.X = 805429; - BarkeepNognar.Y = 726478; - BarkeepNognar.Z = 4717; - BarkeepNognar.Heading = 4073; + BarkeepNognar.Position = Position.Create(regionID: 100, x: 805429, y: 726478, z: 4717, heading: 4073); BarkeepNognar.RespawnInterval = -1; BarkeepNognar.BodyType = 0; @@ -168,15 +165,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + BarkeepPrugar.Name + ", creating ..."); BarkeepPrugar.GuildName = "Part of " + questTitle + " Quest"; BarkeepPrugar.Realm = eRealm.Midgard; - BarkeepPrugar.CurrentRegionID = 101; BarkeepPrugar.Size = 60; BarkeepPrugar.Level = 15; BarkeepPrugar.MaxSpeedBase = 191; BarkeepPrugar.Faction = FactionMgr.GetFactionByID(0); - BarkeepPrugar.X = 33230; - BarkeepPrugar.Y = 34802; - BarkeepPrugar.Z = 8027; - BarkeepPrugar.Heading = 1194; + BarkeepPrugar.Position = Position.Create(regionID: 101, x: 33230, y: 34802, z: 8027, heading: 1194); BarkeepPrugar.RespawnInterval = -1; BarkeepPrugar.BodyType = 0; diff --git a/GameServerScripts/quests/Midgard/TraitorInMularn.cs b/GameServerScripts/quests/Midgard/TraitorInMularn.cs index d192d6aa8b..d61fcd865b 100644 --- a/GameServerScripts/quests/Midgard/TraitorInMularn.cs +++ b/GameServerScripts/quests/Midgard/TraitorInMularn.cs @@ -35,6 +35,7 @@ using DOL.Database; using DOL.Events; using DOL.GS.Finance; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; /* I suggest you declare yourself some namespaces for your quests @@ -82,8 +83,8 @@ public class TraitorInMularn : BaseDalikorQuest private static ItemTemplate recruitsBoots = null; private static ItemTemplate recruitsQuiltedBoots = null; - private static GameLocation hindaEnd = new GameLocation("Lady Hinda", 100, 100, 56484, 55671, 4682, 29); - private static GameLocation hindaStart = new GameLocation("Lady Hinda", 100, 811022, 727295, 4677, 908); + private static Position hindaStart = Position.Create(regionID: 100, x: 811022, y: 727295, z: 4677, heading: 908 ); + private static Position hindaEnd = Position.Create(regionID: 100, x: 56484, y: 55671, z: 4682, heading: 29 ); /* We need to define the constructors from the base class here, else there might be problems @@ -152,13 +153,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) ladyHinda.Name = "Lady Hinda"; ladyHinda.GuildName = "Part of " + questTitle + " Quest"; ladyHinda.Realm = eRealm.None; - ladyHinda.CurrentRegionID = hindaStart.RegionID; ladyHinda.Size = 50; ladyHinda.Level = 30; - ladyHinda.X = hindaStart.X; - ladyHinda.Y = hindaStart.Y; - ladyHinda.Z = hindaStart.Z; - ladyHinda.Heading = hindaStart.Heading; + ladyHinda.Position = hindaStart; StandardMobBrain brain = new StandardMobBrain(); brain.AggroLevel = 0; @@ -442,7 +439,7 @@ protected static void PlayerUseSlot(DOLEvent e, object sender, EventArgs args) InventoryItem item = player.Inventory.GetItem((eInventorySlot)uArgs.Slot); if (item != null && item.Id_nb == necklaceOfDoppelganger.Id_nb) { - if ( player.IsWithinRadius( hindaEnd, 2500 ) ) + if (player.Coordinate.DistanceTo(hindaEnd) <= 2500) { foreach (GamePlayer visPlayer in player.GetPlayersInRadius(WorldMgr.VISIBILITY_DISTANCE)) { @@ -455,12 +452,9 @@ protected static void PlayerUseSlot(DOLEvent e, object sender, EventArgs args) if (!ladyHinda.IsAlive || ladyHinda.ObjectState != GameObject.eObjectState.Active) { - ladyHinda.X = hindaStart.X; - ladyHinda.Y = hindaStart.Y; - ladyHinda.Z = hindaStart.Z; - ladyHinda.Heading = hindaStart.Heading; + ladyHinda.Position = hindaStart; ladyHinda.AddToWorld(); - ladyHinda.WalkTo(hindaEnd.X, hindaEnd.Y, hindaEnd.Z, ladyHinda.MaxSpeed); + ladyHinda.WalkTo(hindaEnd.Coordinate, ladyHinda.MaxSpeed); } quest.Step = 3; } @@ -482,10 +476,7 @@ protected static void PlayerEnterWorld(DOLEvent e, object sender, EventArgs args if (quest.Step == 3 && (!ladyHinda.IsAlive || ladyHinda.ObjectState != GameObject.eObjectState.Active)) { - ladyHinda.X = hindaEnd.X; - ladyHinda.Y = hindaEnd.Y; - ladyHinda.Z = hindaEnd.Z; - ladyHinda.Heading = hindaEnd.Heading; + ladyHinda.Position = hindaEnd; ladyHinda.AddToWorld(); } } diff --git a/GameServerScripts/quests/Midgard/Trial_of_Strength.cs b/GameServerScripts/quests/Midgard/Trial_of_Strength.cs index 83e49383f8..11e03be243 100644 --- a/GameServerScripts/quests/Midgard/Trial_of_Strength.cs +++ b/GameServerScripts/quests/Midgard/Trial_of_Strength.cs @@ -36,6 +36,7 @@ using DOL.GS.Behaviour; using DOL.GS.Behaviour.Attributes; using DOL.AI.Brain; +using DOL.GS.Geometry; namespace DOL.GS.Quests.Midgard { @@ -125,15 +126,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + ToroldSterkkriger.Name + ", creating ..."); ToroldSterkkriger.GuildName = "Part of " + questTitle + " Quest"; ToroldSterkkriger.Realm = eRealm.Midgard; - ToroldSterkkriger.CurrentRegionID = 151; ToroldSterkkriger.Size = 50; ToroldSterkkriger.Level = 55; ToroldSterkkriger.MaxSpeedBase = 191; ToroldSterkkriger.Faction = FactionMgr.GetFactionByID(0); - ToroldSterkkriger.X = 287623; - ToroldSterkkriger.Y = 355226; - ToroldSterkkriger.Z = 3488; - ToroldSterkkriger.Heading = 3788; + ToroldSterkkriger.Position = Position.Create(regionID: 151, x: 287623, y: 355226, z: 3488, heading: 3788); ToroldSterkkriger.RespawnInterval = -1; ToroldSterkkriger.BodyType = 0; @@ -170,15 +167,11 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) log.Warn("Could not find " + JorundBruttstein.Name + ", creating ..."); JorundBruttstein.GuildName = "Part of " + questTitle + " Quest"; JorundBruttstein.Realm = eRealm.Midgard; - JorundBruttstein.CurrentRegionID = 151; JorundBruttstein.Size = 52; JorundBruttstein.Level = 50; JorundBruttstein.MaxSpeedBase = 191; JorundBruttstein.Faction = FactionMgr.GetFactionByID(0); - JorundBruttstein.X = 287884; - JorundBruttstein.Y = 356307; - JorundBruttstein.Z = 3488; - JorundBruttstein.Heading = 3163; + JorundBruttstein.Position = Position.Create(regionID: 151, x: 287884, y: 356307, z: 3488, heading: 3163); JorundBruttstein.RespawnInterval = -1; JorundBruttstein.BodyType = 0; diff --git a/GameServerScripts/quests/Midgard/epic/MidgardRogue50.cs b/GameServerScripts/quests/Midgard/epic/MidgardRogue50.cs index a16911d072..0870b7fc86 100644 --- a/GameServerScripts/quests/Midgard/epic/MidgardRogue50.cs +++ b/GameServerScripts/quests/Midgard/epic/MidgardRogue50.cs @@ -38,6 +38,7 @@ using System.Reflection; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; @@ -104,7 +105,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 100 && npc.X == 749099 && npc.Y == 813104) + if (npc.CurrentRegionID == 100) { Masrim = npc; break; @@ -119,13 +120,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Masrim.Name = "Masrim"; Masrim.GuildName = ""; Masrim.Realm = eRealm.Midgard; - Masrim.CurrentRegionID = 100; Masrim.Size = 52; Masrim.Level = 40; - Masrim.X = 749099; - Masrim.Y = 813104; - Masrim.Z = 4437; - Masrim.Heading = 2605; + Masrim.Position = Position.Create(regionID: 100, x: 749099, y: 813104, z: 4437, heading: 2605); Masrim.AddToWorld(); if (SAVE_INTO_DATABASE) { @@ -138,7 +135,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 100 && npc.X == 607233 && npc.Y == 786850) + if (npc.CurrentRegionID == 100) { Oona = npc; break; @@ -153,13 +150,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Oona.Name = "Oona"; Oona.GuildName = ""; Oona.Realm = eRealm.None; - Oona.CurrentRegionID = 100; Oona.Size = 50; Oona.Level = 65; - Oona.X = 607233; - Oona.Y = 786850; - Oona.Z = 4384; - Oona.Heading = 3891; + Oona.Position = Position.Create(regionID: 100, x: 607233, y: 786850, z: 4384, heading: 3891); Oona.Flags ^= GameNPC.eFlags.GHOST; Oona.AddToWorld(); if (SAVE_INTO_DATABASE) @@ -173,7 +166,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 101 && npc.X == 33400 && npc.Y == 33620) + if (npc.CurrentRegionID == 101) { MorlinCaan = npc; break; @@ -188,13 +181,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) MorlinCaan.Name = "Morlin Caan"; MorlinCaan.GuildName = "Smith"; MorlinCaan.Realm = eRealm.Midgard; - MorlinCaan.CurrentRegionID = 101; MorlinCaan.Size = 50; MorlinCaan.Level = 54; - MorlinCaan.X = 33400; - MorlinCaan.Y = 33620; - MorlinCaan.Z = 8023; - MorlinCaan.Heading = 523; + MorlinCaan.Position = Position.Create(regionID: 101, x: 33400, y: 33620, z: 8023, heading: 523); MorlinCaan.AddToWorld(); if (SAVE_INTO_DATABASE) { @@ -1090,7 +1079,7 @@ public override void FinishQuest() *#26 seek out Loken in Raumarik Loc 47k, 25k, 4k, and kill him purp and 2 blue adds *#27 return to Masrim *#28 give her the ball of flame - *#29 talk with Masrim about Loken’s demise + *#29 talk with Masrim about Loken's demise *#30 go to MorlinCaan in Jordheim *#31 give her the sealed pouch *#32 you get your epic armor as a reward diff --git a/GameServerScripts/quests/Midgard/epic/Mystic50.cs b/GameServerScripts/quests/Midgard/epic/Mystic50.cs index 27b0805969..3251236199 100644 --- a/GameServerScripts/quests/Midgard/epic/Mystic50.cs +++ b/GameServerScripts/quests/Midgard/epic/Mystic50.cs @@ -44,6 +44,7 @@ using System.Reflection; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; @@ -121,7 +122,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 100 && npc.X == 802818 && npc.Y == 727413) + if (npc.CurrentRegionID == 100) { Danica = npc; break; @@ -136,13 +137,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Danica.Name = "Danica"; Danica.GuildName = ""; Danica.Realm = eRealm.Midgard; - Danica.CurrentRegionID = 100; Danica.Size = 51; Danica.Level = 50; - Danica.X = 802818; - Danica.Y = 727413; - Danica.Z = 4760; - Danica.Heading = 2116; + Danica.Position = Position.Create(regionID: 100, x: 802818, y: 727413, z: 4760, heading: 2116); Danica.AddToWorld(); if (SAVE_INTO_DATABASE) { @@ -155,7 +152,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 100 && npc.X == 621577 && npc.Y == 745848) + if (npc.CurrentRegionID == 100) { Kelic = npc; break; @@ -170,13 +167,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Kelic.Name = "Kelic"; Kelic.GuildName = ""; Kelic.Realm = eRealm.None; - Kelic.CurrentRegionID = 100; Kelic.Size = 100; Kelic.Level = 65; - Kelic.X = 621577; - Kelic.Y = 745848; - Kelic.Z = 4593; - Kelic.Heading = 3538; + Kelic.Position = Position.Create(regionID: 100, x: 621577, y: 745848, z: 4593, heading: 3538); Kelic.Flags ^= GameNPC.eFlags.GHOST; Kelic.MaxSpeedBase = 200; Kelic.AddToWorld(); @@ -1612,7 +1605,7 @@ public override void FinishQuest() *#26 seek out Loken in Raumarik Loc 47k, 25k, 4k, and kill him purp and 2 blue adds *#27 return to Inaksha *#28 give her the ball of flame - *#29 talk with Inaksha about Loken’s demise + *#29 talk with Inaksha about Loken's demise *#30 go to Miri in Jordheim *#31 give her the sealed pouch *#32 you get your epic armor as a reward diff --git a/GameServerScripts/quests/Midgard/epic/Seer50.cs b/GameServerScripts/quests/Midgard/epic/Seer50.cs index f509075374..9fa42dc4f6 100644 --- a/GameServerScripts/quests/Midgard/epic/Seer50.cs +++ b/GameServerScripts/quests/Midgard/epic/Seer50.cs @@ -39,6 +39,7 @@ using System.Reflection; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; @@ -105,7 +106,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 100 && npc.X == 805929 && npc.Y == 702449) + if (npc.CurrentRegionID == 100) { Inaksha = npc; break; @@ -120,13 +121,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Inaksha.Name = "Inaksha"; Inaksha.GuildName = ""; Inaksha.Realm = eRealm.Midgard; - Inaksha.CurrentRegionID = 100; Inaksha.Size = 50; Inaksha.Level = 41; - Inaksha.X = 805929; - Inaksha.Y = 702449; - Inaksha.Z = 4960; - Inaksha.Heading = 2116; + Inaksha.Position = Position.Create(regionID: 100, x: 805929, y: 702449, z: 4960, heading: 2116); Inaksha.AddToWorld(); if (SAVE_INTO_DATABASE) { @@ -139,7 +136,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 100 && npc.X == 636784 && npc.Y == 762433) + if (npc.CurrentRegionID == 100) { Loken = npc; break; @@ -154,13 +151,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Loken.Name = "Loken"; Loken.GuildName = ""; Loken.Realm = eRealm.None; - Loken.CurrentRegionID = 100; Loken.Size = 50; Loken.Level = 65; - Loken.X = 636784; - Loken.Y = 762433; - Loken.Z = 4596; - Loken.Heading = 3777; + Loken.Position = Position.Create(regionID: 100, x: 636784, y: 762433, z: 4596, heading: 3777); Loken.AddToWorld(); if (SAVE_INTO_DATABASE) { @@ -173,7 +166,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 101 && npc.X == 30641 && npc.Y == 32093) + if (npc.CurrentRegionID == 101) { Miri = npc; break; @@ -188,13 +181,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Miri.Name = "Miri"; Miri.GuildName = ""; Miri.Realm = eRealm.Midgard; - Miri.CurrentRegionID = 101; Miri.Size = 50; Miri.Level = 43; - Miri.X = 30641; - Miri.Y = 32093; - Miri.Z = 8305; - Miri.Heading = 3037; + Miri.Position = Position.Create(regionID: 101, x: 30641, y: 32093, z: 8305, heading: 3037); Miri.AddToWorld(); if (SAVE_INTO_DATABASE) { @@ -1004,7 +993,7 @@ public override string Description case 2: return "[Step #2] Return to Inaksha and give her the Ball of Flame!"; case 3: - return "[Step #3] Talk with Inaksha about Loken’s demise!"; + return "[Step #3] Talk with Inaksha about Loken's demise!"; case 4: return "[Step #4] Go to Miri in Jordheim and give her the Sealed Pouch for your reward!"; } @@ -1106,7 +1095,7 @@ public override void FinishQuest() *#26 seek out Loken in Raumarik Loc 47k, 25k, 4k, and kill him purp and 2 blue adds *#27 return to Inaksha *#28 give her the ball of flame - *#29 talk with Inaksha about Loken’s demise + *#29 talk with Inaksha about Loken's demise *#30 go to Miri in Jordheim *#31 give her the sealed pouch *#32 you get your epic armor as a reward diff --git a/GameServerScripts/quests/Midgard/epic/Viking50.cs b/GameServerScripts/quests/Midgard/epic/Viking50.cs index e3226b3790..711bf9404c 100644 --- a/GameServerScripts/quests/Midgard/epic/Viking50.cs +++ b/GameServerScripts/quests/Midgard/epic/Viking50.cs @@ -37,6 +37,7 @@ using System.Reflection; using DOL.Database; using DOL.Events; +using DOL.GS.Geometry; using DOL.GS.PacketHandler; using log4net; @@ -134,7 +135,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 100 && npc.X == 760118 && npc.Y == 758453) + if (npc.CurrentRegionID == 100) { Lynnleigh = npc; break; @@ -149,13 +150,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Lynnleigh.Name = "Lynnleigh"; Lynnleigh.GuildName = ""; Lynnleigh.Realm = eRealm.Midgard; - Lynnleigh.CurrentRegionID = 100; Lynnleigh.Size = 51; Lynnleigh.Level = 50; - Lynnleigh.X = 760118; - Lynnleigh.Y = 758453; - Lynnleigh.Z = 4737; - Lynnleigh.Heading = 2197; + Lynnleigh.Position = Position.Create(regionID: 100, x: 760118, y: 758453, z: 4737, heading: 2197); Lynnleigh.AddToWorld(); if (SAVE_INTO_DATABASE) { @@ -167,7 +164,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 100 && npc.X == 802597 && npc.Y == 727896) + if (npc.CurrentRegionID == 100) { Elizabeth = npc; break; @@ -181,13 +178,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Elizabeth.Model = 217; Elizabeth.Name = "Elizabeth"; Elizabeth.Realm = eRealm.Midgard; - Elizabeth.CurrentRegionID = 100; Elizabeth.Size = 51; Elizabeth.Level = 41; - Elizabeth.X = 802597; - Elizabeth.Y = 727896; - Elizabeth.Z = 4760; - Elizabeth.Heading = 2480; + Elizabeth.Position = Position.Create(regionID: 100, x: 802597, y: 727896, z: 4760, heading: 2480); Elizabeth.AddToWorld(); if (SAVE_INTO_DATABASE) { @@ -201,7 +194,7 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) if (npcs.Length > 0) foreach (GameNPC npc in npcs) - if (npc.CurrentRegionID == 100 && npc.X == 637680 && npc.Y == 767189) + if (npc.CurrentRegionID == 100) { Ydenia = npc; break; @@ -216,13 +209,9 @@ public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args) Ydenia.Name = "Ydenia of Seithkona"; Ydenia.GuildName = ""; Ydenia.Realm = eRealm.None; - Ydenia.CurrentRegionID = 100; Ydenia.Size = 100; Ydenia.Level = 65; - Ydenia.X = 637680; - Ydenia.Y = 767189; - Ydenia.Z = 4480; - Ydenia.Heading = 2156; + Ydenia.Position = Position.Create(regionID: 100, x: 637680, y: 767189, z: 4480, heading: 2156); Ydenia.Flags ^= GameNPC.eFlags.GHOST; Ydenia.MaxSpeedBase = 200; Ydenia.AddToWorld(); diff --git a/GameServerScripts/web/WebUIGenerator.cs b/GameServerScripts/web/WebUIGenerator.cs index fd3817998e..7a34aa419b 100644 --- a/GameServerScripts/web/WebUIGenerator.cs +++ b/GameServerScripts/web/WebUIGenerator.cs @@ -430,7 +430,7 @@ private static void InitJS() //X m_js.Append("document.write(\"\")"); m_js.Append(nl.NewLine); - m_js.AppendFormat("document.write(\"{0}\")", plr.X); + m_js.AppendFormat("document.write(\"{0}\")", plr.Position.X); m_js.Append(nl.NewLine); m_js.Append("document.write(\"\")"); m_js.Append(nl.NewLine); @@ -439,7 +439,7 @@ private static void InitJS() //Y m_js.Append("document.write(\"\")"); m_js.Append(nl.NewLine); - m_js.AppendFormat("document.write(\"{0}\")", plr.Y); + m_js.AppendFormat("document.write(\"{0}\")", plr.Position.Y); m_js.Append(nl.NewLine); m_js.Append("document.write(\"\")"); m_js.Append(nl.NewLine); diff --git a/GameServerScripts/web/XMLWebUIGenerator.cs b/GameServerScripts/web/XMLWebUIGenerator.cs index 0fb889d1cb..c69fdcbbfc 100644 --- a/GameServerScripts/web/XMLWebUIGenerator.cs +++ b/GameServerScripts/web/XMLWebUIGenerator.cs @@ -304,8 +304,8 @@ public static void Generate() pi.Alive = plr.IsAlive ? "yes" : "no"; pi.Realm = ((eRealm) plr.Realm).ToString(); pi.Region = plr.CurrentRegion.Name; - pi.X = plr.X; - pi.Y = plr.Y; + pi.X = plr.Position.X; + pi.Y = plr.Position.Y; } // 2008-01-29 Kakuri - Obsolete diff --git a/Tests/IntegrationTests/GameServer/gameutils/RegionTest.cs b/Tests/IntegrationTests/GameServer/gameutils/RegionTest.cs index de5ed6b4e0..5dcfe46b02 100644 --- a/Tests/IntegrationTests/GameServer/gameutils/RegionTest.cs +++ b/Tests/IntegrationTests/GameServer/gameutils/RegionTest.cs @@ -19,6 +19,7 @@ using System; using DOL.Events; using DOL.GS; +using DOL.GS.Geometry; using NUnit.Framework; namespace DOL.Integration.Server @@ -35,20 +36,16 @@ public RegionTest() [Test, Explicit] public void AddObject() { - Region region = WorldMgr.GetRegion(1); GameObject obj = new GameNPC(); obj.Name="TestObject"; - obj.X = 400000; - obj.Y = 200000; - obj.Z = 2000; - obj.CurrentRegion = region; + obj.Position = Position.Create(regionID: 1, x: 400000, y: 200000, z: 2000); obj.AddToWorld(); if (obj.ObjectID<0) Assert.Fail("Failed to add object to Region. ObjectId < 0"); - Assert.AreEqual(region.GetObject((ushort)obj.ObjectID),obj); + Assert.AreEqual(obj.CurrentRegion.GetObject((ushort)obj.ObjectID),obj); } @@ -56,26 +53,27 @@ public void AddObject() public void AddArea() { Region region = WorldMgr.GetRegion(1); - IArea insertArea = region.AddArea(new Area.Circle(null,1000,1000,0,500)); + var circleLocation = Coordinate.Create(1000,1000,0); + IArea insertArea = region.AddArea(new Area.Circle(null,circleLocation,500)); Assert.IsNotNull(insertArea); - var areas = region.GetAreasOfSpot(501,1000,0); + var areas = region.GetAreasOfSpot(Coordinate.Create(501,1000,0)); Assert.IsTrue(areas.Count>0); bool found = false; foreach( IArea ar in areas) { - if (ar == insertArea) + if (ar == insertArea) { - found = true; + found = true; break; } } Assert.IsTrue(found); // - areas = region.GetAreasOfSpot(1499,1000,2000); + areas = region.GetAreasOfSpot(Coordinate.Create(1499,1000,2000)); Assert.IsTrue(areas.Count>0); found = false; @@ -102,7 +100,7 @@ public void AddArea() region.RemoveArea(insertArea); - areas = region.GetAreasOfSpot(1499,1000,2000); + areas = region.GetAreasOfSpot(Coordinate.Create(1499,1000,2000)); Assert.IsTrue(areas.Count==0); } diff --git a/Tests/IntegrationTests/GameServer/quests/KillTaskTest.cs b/Tests/IntegrationTests/GameServer/quests/KillTaskTest.cs index b207b9fc97..b38cee98fc 100644 --- a/Tests/IntegrationTests/GameServer/quests/KillTaskTest.cs +++ b/Tests/IntegrationTests/GameServer/quests/KillTaskTest.cs @@ -69,11 +69,8 @@ public void CreateKillTask() GameNPC mob = new GameNPC(); mob.Name = task.MobName; - mob.X = player.X; - mob.Y = player.Y; - mob.Z = player.Z; + mob.Position = player.Position; mob.Level = player.Level; - mob.CurrentRegionID = player.CurrentRegionID; mob.AddToWorld(); // First we kill mob diff --git a/Tests/IntegrationTests/TestPacketLib.cs b/Tests/IntegrationTests/TestPacketLib.cs index 96df96df9b..dccdb67ab2 100644 --- a/Tests/IntegrationTests/TestPacketLib.cs +++ b/Tests/IntegrationTests/TestPacketLib.cs @@ -28,6 +28,7 @@ using DOL.GS.Keeps; using DOL.GS.Housing; using DOL.GS.Profession; +using DOL.GS.Geometry; namespace DOL.Tests { @@ -633,11 +634,13 @@ public void SendChangeTarget(GameObject newTarget) { if (SendChangeTargetMethod != null) SendChangeTargetMethod(this, newTarget); } - public Action SendChangeGroundTargetMethod { get; set; } + public Action SendChangeGroundTargetMethod { get; set; } + [Obsolete("Use .SendChangeGroundTarget(Coordinate) instead!")] public void SendChangeGroundTarget(Point3D newTarget) { - if (SendChangeGroundTargetMethod != null) SendChangeGroundTargetMethod(this, newTarget); + if (SendChangeGroundTargetMethod != null) SendChangeGroundTargetMethod(this, newTarget.ToCoordinate()); } + public void SendChangeGroundTarget(Coordinate newTarget) => SendChangeGroundTarget(newTarget); public Action SendPetWindowMethod { get; set; } public void SendPetWindow(GameLiving pet, ePetWindowAction windowAction, eAggressionState aggroState, eWalkState walkState) { @@ -693,6 +696,7 @@ public void SendLivingDataUpdate(GameLiving living, bool updateStrings) { if (SendLivingDataUpdateMethod != null) SendLivingDataUpdateMethod(this, living, updateStrings); } + public void SendSoundEffect(ushort soundId, Position position, ushort radius) { } public Action SendSoundEffectMethod { get; set; } public void SendSoundEffect(ushort soundId, ushort zoneId, ushort x, ushort y, ushort z, ushort radius) { @@ -923,6 +927,10 @@ public void SendMinotaurRelicMapUpdate(byte id, ushort region, int x, int y, int { if (SendMinotaurRelicMapUpdateMethod != null) SendMinotaurRelicMapUpdateMethod(this, id, region, x, y, z); } + public void SendMinotaurRelicMapUpdate(byte id, Position position) + { + if (SendMinotaurRelicMapUpdateMethod != null) SendMinotaurRelicMapUpdateMethod(this, id, position.RegionID, position.X, position.Y, position.Z); + } public Action SendMinotaurRelicWindowMethod { get; set; } public void SendMinotaurRelicWindow(GamePlayer player, int spell, bool flag) { diff --git a/Tests/UnitTests/Geometry/UT_Angle.cs b/Tests/UnitTests/Geometry/UT_Angle.cs new file mode 100644 index 0000000000..3158147ae8 --- /dev/null +++ b/Tests/UnitTests/Geometry/UT_Angle.cs @@ -0,0 +1,92 @@ +using System; +using NUnit.Framework; +using DOL.GS.Geometry; + +namespace DOL.UnitTests; + +[TestFixture] +public class UT_Angle +{ + [Test] + public void Equals_TwoNewAnglesWithZeroDegrees_True() + { + var angleA = Angle.Degrees(0); + var angleB = Angle.Degrees(0); + + Assert.IsTrue(angleA.Equals(angleB)); + } + + [Test] + public void Equals_TwoDifferentAngles_False() + { + var angleA = Angle.Degrees(0); + var angleB = Angle.Degrees(1); + + Assert.IsFalse(angleA.Equals(angleB)); + } + + [Test] + public void Equals_MinusOneDegreesAnd359Degrees_True() + { + var angleA = Angle.Degrees(-1); + var angleB = Angle.Degrees(359); + + Assert.IsTrue(angleA.Equals(angleB)); + } + + [Test] + public void Heading_One_InHeadingIsOne() + { + var angle = Angle.Heading(1); + + var expected = 1; + var actual = angle.InHeading; + Assert.AreEqual(expected, actual); + } + + [Test] + public void Degrees_One_InDegreesIsOne() + { + var angle = Angle.Heading(1); + + var expected = 1; + var actual = angle.InHeading; + Assert.AreEqual(expected, actual); + } + + [Test] + public void PlusOperator_OneHeadingWithOneHeading_TwoHeading() + { + var actual = Angle.Heading(1) + Angle.Heading(1); + + var expected = Angle.Heading(2); + Assert.AreEqual(expected, actual); + } + + [Test] + public void MinusOperator_OneHeadingMinusOneHeading_AngleZero() + { + var actual = Angle.Heading(1) - Angle.Heading(1); + + var expected = Angle.Zero; + Assert.AreEqual(expected, actual); + } + + [Test] + public void Radians_One2048thPi_OneHeading() + { + var actual = Angle.Radians(Math.PI/2048); + + var expected = Angle.Heading(1); + Assert.AreEqual(expected, actual); + } + + [Test] + public void Radians_One180thPi_OneDegree() + { + var actual = Angle.Radians(Math.PI/180); + + var expected = Angle.Degrees(1); + Assert.AreEqual(expected, actual); + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Geometry/UT_Motion.cs b/Tests/UnitTests/Geometry/UT_Motion.cs new file mode 100644 index 0000000000..615638b041 --- /dev/null +++ b/Tests/UnitTests/Geometry/UT_Motion.cs @@ -0,0 +1,44 @@ +using DOL.GS.Geometry; +using NUnit.Framework; + +namespace DOL.UnitTests; + +[TestFixture] +public class UT_Motion +{ + [Test] + public void GetLocationAfter_Zero_Start() + { + var start = Position.Zero; + + var actual = Motion.Create(start, destination: Coordinate.Nowhere, withSpeed: 0) + .GetPositonAfter(0); + + Assert.AreEqual(start, actual); + } + + [Test] + public void GetLocationAfter_FromZeroAfter1000MilliSecondsWithSpeed100AndOrientationZero_Plus100Y() + { + var start = Position.Zero; + var motion = Motion.Create(start, destination: Coordinate.Nowhere, withSpeed: 100); + + var actual = motion.GetPositonAfter(1000); + + var expected = start + Vector.Create(y: 100); + Assert.AreEqual(expected, actual); + } + + [Test] + public void GetLocationAfter_FromZeroAfter1000MilliSecondsWithSpeed100AndOrientationZeroAndDestination50Y_Destination() + { + var start = Position.Zero; + var destination = start + Vector.Create(y: 50); + var motion = Motion.Create(start, destination.Coordinate, withSpeed: 100); + + var actual = motion.GetPositonAfter(1000); + + var expected = destination; + Assert.AreEqual(destination, actual); + } +} \ No newline at end of file diff --git a/Tests/UnitTests/Geometry/UT_Vector.cs b/Tests/UnitTests/Geometry/UT_Vector.cs new file mode 100644 index 0000000000..5789a72324 --- /dev/null +++ b/Tests/UnitTests/Geometry/UT_Vector.cs @@ -0,0 +1,115 @@ +using System; +using DOL.GS.Geometry; +using NUnit.Framework; + +namespace DOL.UnitTests; + +[TestFixture] +public class UT_Vector +{ + [Test] + public void Equals_TwoNewVectors_True() + { + var vectorA = Vector.Create(); + var vectorB = Vector.Create(); + + Assert.IsTrue(vectorA.Equals(vectorB)); + } + + [Test] + public void Equals_VectorWithDifferentX_False() + { + var vectorA = Vector.Create(x: 0); + var vectorB = Vector.Create(x: 1); + + Assert.IsFalse(vectorA.Equals(vectorB)); + } + + [Test] + public void PlusOperator_TwoVectorsWithLengthOne_VectorWithLength2() + { + var vector = Vector.Create(orientation: Angle.Zero, length: 1); + + var actual = (vector + vector).Length; + + var expectedLength = 2; + Assert.AreEqual(expectedLength, actual); + } + + [Test] + public void Create_OrientationZeroWithLengthOne_SameAsVectorWithYOne() + { + var actual = Vector.Create(orientation: Angle.Zero, length: 1); + + var expected = Vector.Create(y: 1); + Assert.AreEqual(expected, actual); + } + + [Test] + public void Create_Orientation45DegreesWithLengthOneHundred_VectorWithXMinus71AndY71() + { + var actual = Vector.Create(orientation: Angle.Degrees(45), length: 100); + + var expected = Vector.Create(x: -71, y: 71); + Assert.AreEqual(expected, actual); + } + + [Test] + public void RotatedClockwise_VectorXOneHundredBy90Degrees_VectorWithYOneHundred() + { + var vector = Vector.Create(x: 100); + + var actual = vector.RotatedClockwise(Angle.Degrees(90)); + + var expected = Vector.Create(y: 100); + Assert.AreEqual(expected, actual); + } + + [Test] + public void RotatedClockwise_VectorXOneHundredBy45Degrees_VectorWithX71AndY71() + { + var vector = Vector.Create(x: 100); + + var actual = vector.RotatedClockwise(Angle.Degrees(45)); + + //rounded + var expected = Vector.Create(x: 71, y: 71); + Assert.AreEqual(expected, actual); + } + + [Test] + public void RotatedClockwise_VectorX50By45Degrees_VectorWithX35AndY35() + { + var vector = Vector.Create(x: 50); + + var actual = vector.RotatedClockwise(Angle.Degrees(45)); + + //rounded + var expected = Vector.Create(x: 35, y: 35); + Assert.AreEqual(expected, actual); + } + + + + [Test] + public void Length_VectorX1Y2Z2_3() + { + var vector = Vector.Create(x: 1, y: 2, z: 2); + + var actual = vector.Length; + + var expected = 3d; + Assert.AreEqual(expected, actual); + } + + [Test] + public void Length2D_VectorX3Y4Z100_5() + { + var vector = Vector.Create(x: 3, y: 4, z: 100); + + var actual = vector.Length2D; + + var expected = 5d; + Assert.AreEqual(expected, actual); + } +} \ No newline at end of file