Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding monster movement #777

Merged
14 commits merged into from
May 2, 2018
24 changes: 24 additions & 0 deletions Source/ACE.Entity/Enum/MovementParams.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
namespace ACE.Entity.Enum
{
public enum MovementParams
{
CanWalk = (1 << 0),
CanRun = (1 << 1),
CanSideStep = (1 << 2),
CanWalkBackwards = (1 << 3),
CanCharge = (1 << 4),
FailWalk = (1 << 5),
UseFinalHeading = (1 << 6),
Sticky = (1 << 7),
MoveAway = (1 << 8),
MoveTowards = (1 << 9),
UseSpheres = (1 << 10),
SetHoldKey = (1 << 11),
Autonomous = (1 << 12),
ModifyRawState = (1 << 13),
ModifyInterpretedState = (1 << 14),
CancelMoveTo = (1 << 15),
StopCompletely = (1 << 16),
DisableJumpDuringLink = (1 << 17)
}
}
19 changes: 19 additions & 0 deletions Source/ACE.Entity/LandblockId.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,25 @@ public bool IsAdjacentTo(LandblockId block)
{
return (Math.Abs(this.LandblockX - block.LandblockX) <= 1 && Math.Abs(this.LandblockY - block.LandblockY) <= 1);
}

public LandblockId? TransitionX(int blockOffset)
{
var newX = LandblockX + blockOffset;
if (newX < 0 || newX > 254)
return null;
else
return new LandblockId((uint)newX << 24 | (uint)LandblockY << 16 | Raw & 0xFFFF);
}

public LandblockId? TransitionY(int blockOffset)
{
var newY = LandblockY + blockOffset;
if (newY < 0 || newY > 254)
return null;
else
return new LandblockId((uint)LandblockX << 24 | (uint)newY << 16 | Raw & 0xFFFF);
}

public override bool Equals(object obj)
{
if (obj is LandblockId)
Expand Down
126 changes: 118 additions & 8 deletions Source/ACE.Entity/Position.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,56 @@ public class Position : ICloneable
public LandblockId LandblockId
{
get => landblockId.Raw != 0 ? landblockId : new LandblockId(Cell);
set
{
landblockId = value;
}
set => landblockId = value;
}

// TODO: This is just named wrong needs to be fixed.
[JsonIgnore]
public uint Cell { get; set; }

public Vector3 Pos
{
get => new Vector3(PositionX, PositionY, PositionZ);
set => SetPosition(value);
}

public Vector3 GlobalPos
{
get
{
return new Vector3(PositionX, PositionY, PositionZ);
return ToGlobal();
}
}

public bool SetPosition(Vector3 pos)
{
PositionX = pos.X;
PositionY = pos.Y;
PositionZ = pos.Z;

var blockUpdate = SetLandblock();
SetLandCell();

return blockUpdate;
}

public Quaternion Rotation
{
get
get => new Quaternion(RotationX, RotationY, RotationZ, RotationW);
set
{
return new Quaternion(RotationX, RotationY, RotationZ, RotationW);
RotationW = value.W;
RotationX = value.X;
RotationY = value.Y;
RotationZ = value.Z;
}
}

public void Rotate(Vector3 dir)
{
Rotation = Quaternion.CreateFromYawPitchRoll(0, 0, (float)Math.Atan2(dir.Y, dir.X)) * Quaternion.CreateFromYawPitchRoll(0, 0, -(float)Math.PI / 2.0f);
}

[JsonProperty("positionX")]
public float PositionX { get; set; }

Expand Down Expand Up @@ -128,10 +152,94 @@ public Position InFrontOf(double distanceInFront = 3.0f, bool rotate180 = false)
return new Position(LandblockId.Raw, PositionX + dx, PositionY + dy, PositionZ + 0.5f, 0f, 0f, qz, qw);
}

public Position()
/// <summary>
/// Handles the Position crossing over landblock boundaries
/// </summary>
public bool SetLandblock()
{
if (Indoors) return false;

var changedBlock = false;

if (PositionX < 0)
{
var blockOffset = (int)PositionX / BlockLength - 1;
var landblock = LandblockId.TransitionX(blockOffset);
if (landblock != null)
{
LandblockId = landblock.Value;
PositionX -= BlockLength * blockOffset;
changedBlock = true;
}
else
PositionX = 0;
}

if (PositionX > BlockLength)
{
var blockOffset = (int)PositionX / BlockLength;
var landblock = LandblockId.TransitionX(blockOffset);
if (landblock != null)
{
LandblockId = landblock.Value;
PositionX -= BlockLength * blockOffset;
changedBlock = true;
}
else
PositionX = BlockLength;
}

if (PositionY < 0)
{
var blockOffset = (int)PositionY / BlockLength - 1;
var landblock = LandblockId.TransitionX(blockOffset);
if (landblock != null)
{
LandblockId = landblock.Value;
PositionY -= BlockLength * blockOffset;
changedBlock = true;
}
else
PositionY = 0;
}

if (PositionY > BlockLength)
{
var blockOffset = (int)PositionY / BlockLength;
var landblock = LandblockId.TransitionX(blockOffset);
if (landblock != null)
{
LandblockId = landblock.Value;
PositionY -= BlockLength * blockOffset;
changedBlock = true;
}
else
PositionY = BlockLength;
}

return changedBlock;
}

public bool SetLandCell()
{
if (Indoors) return false;

var cellX = (uint)PositionX / CellLength;
var cellY = (uint)PositionY / CellLength;

var cellID = cellX * CellSide + cellY + 1;

var curCellID = LandblockId.Raw & 0xFFFF;

if (cellID == curCellID)
return false;

LandblockId = new LandblockId((uint)((LandblockId.Raw & 0xFFFF0000) | cellID));
return true;
}

public Position() { }

public Position(uint newCell, float newPositionX, float newPositionY, float newPositionZ, float newRotationX, float newRotationY, float newRotationZ, float newRotationW)
{
LandblockId = new LandblockId(newCell);
Expand Down Expand Up @@ -427,6 +535,8 @@ public void CalculateObjCell(uint newCell)
}

public static readonly int BlockLength = 192;
public static readonly int CellSide = 8;
public static readonly int CellLength = 24;

public Vector3 ToGlobal()
{
Expand Down
8 changes: 4 additions & 4 deletions Source/ACE.Server/Entity/Landblock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public class Landblock : IActor
/// </summary>
private readonly Physics.Common.Landblock _landblock;

private readonly Dictionary<ObjectGuid, WorldObject> worldObjects = new Dictionary<ObjectGuid, WorldObject>();
public readonly Dictionary<ObjectGuid, WorldObject> worldObjects = new Dictionary<ObjectGuid, WorldObject>();
private readonly Dictionary<Adjacency, Landblock> adjacencies = new Dictionary<Adjacency, Landblock>();

/// <summary>
Expand Down Expand Up @@ -371,8 +371,8 @@ public ActionChain GetRemoveWorldObjectChain(ObjectGuid objectId, bool adjacency
/// <summary>
/// Should only be called by physics/relocation engines -- not from player
/// </summary>
/// <param name="objectId"></param>
/// <param name="adjacencyMove"></param>
/// <param name="objectId">The object ID to be removed from the current landblock</param>
/// <param name="adjacencyMove">Flag indicates if object is moving to an adjacent landblock</param>
public void RemoveWorldObjectForPhysics(ObjectGuid objectId, bool adjacencyMove)
{
RemoveWorldObjectInternal(objectId, adjacencyMove);
Expand Down Expand Up @@ -487,7 +487,7 @@ private void UpdateStatus(int pcount)
/// <summary>
/// Gets all landblocks in range of a position. (for indoors positions that is just this landblock)
/// </summary>
private List<Landblock> GetLandblocksInRange(Position pos, float distance)
public List<Landblock> GetLandblocksInRange(Position pos, float distance)
{
List<Landblock> inRange = new List<Landblock>();

Expand Down
2 changes: 1 addition & 1 deletion Source/ACE.Server/Managers/EmoteManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -905,7 +905,7 @@ public void ExecuteEmote(BiotaPropertiesEmote emote, BiotaPropertiesEmoteAction
}
else
{
if (sourceObject.CurrentMotionState.Commands[0].Motion == startingMotion.Commands[0].Motion)
if (sourceObject.CurrentMotionState.Commands.Count > 0 && sourceObject.CurrentMotionState.Commands[0].Motion == startingMotion.Commands[0].Motion)
{
actionChain.AddDelaySeconds(emoteAction.Delay);
actionChain.AddAction(sourceObject, () =>
Expand Down
8 changes: 4 additions & 4 deletions Source/ACE.Server/Managers/LandblockManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,25 +154,25 @@ private static void SetAdjacencies(LandblockId landblockId, bool autoLoad)
if (y > 0)
SetAdjacency(landblockId, landblockId.SouthWest, Adjacency.SouthWest, autoLoad);

if (y < 255)
if (y < 254)
SetAdjacency(landblockId, landblockId.NorthWest, Adjacency.NorthWest, autoLoad);
}

if (x < 255)
if (x < 254)
{
SetAdjacency(landblockId, landblockId.East, Adjacency.East, autoLoad);

if (y > 0)
SetAdjacency(landblockId, landblockId.SouthEast, Adjacency.SouthEast, autoLoad);

if (y < 255)
if (y < 254)
SetAdjacency(landblockId, landblockId.NorthEast, Adjacency.NorthEast, autoLoad);
}

if (y > 0)
SetAdjacency(landblockId, landblockId.South, Adjacency.South, autoLoad);

if (y < 255)
if (y < 254)
SetAdjacency(landblockId, landblockId.North, Adjacency.North, autoLoad);
}

Expand Down
10 changes: 5 additions & 5 deletions Source/ACE.Server/Network/Motion/UniversalMotion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace ACE.Server.Network.Motion
{
public class UniversalMotion : MotionState
{
public uint Flag { get; set; } = 0x0041EE0F;
public MovementParams Flag { get; set; } = (MovementParams)0x0041EE0F;

public float MinimumDistance { get; set; } = 0.00f;

Expand Down Expand Up @@ -43,7 +43,7 @@ public class UniversalMotion : MotionState
/// </summary>
public MotionStance Stance { get; }

public MovementData MovementData { get; }
public MovementData MovementData { get; set; }

public List<MotionItem> Commands { get; } = new List<MotionItem>();

Expand Down Expand Up @@ -124,7 +124,7 @@ public override byte[] GetPayload(ObjectGuid animationTargetGuid, SequenceManage
writer.Write(TargetGuid.Full);

Position.Serialize(writer, false);
writer.Write(Flag);
writer.Write((uint)Flag);
writer.Write(DistanceFrom);
writer.Write(MinimumDistance);
writer.Write(FailDistance);
Expand All @@ -146,14 +146,14 @@ public override byte[] GetPayload(ObjectGuid animationTargetGuid, SequenceManage
// movement type yet - coded it up but had not used or tested.
writer.Write(TargetGuid.Full);
writer.Write(Heading);
writer.Write(Flag);
writer.Write((uint)Flag);
writer.Write(Speed);
writer.Write(DesiredHeading); // always 0.0 in every pcap of this type.
break;
}
case MovementTypes.TurnToHeading:
{
writer.Write(Flag);
writer.Write((uint)Flag);
writer.Write(Speed);
writer.Write(Heading);
break;
Expand Down
12 changes: 12 additions & 0 deletions Source/ACE.Server/WorldObjects/Creature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ private void SetEphemeralValues()
GenerateWieldList();

Value = null; // Creatures don't have value. By setting this to null, it effectively disables the Value property. (Adding/Subtracting from null results in null)

QueueNextTick();
}


Expand Down Expand Up @@ -556,5 +558,15 @@ public override void ActOnUse(Player player)
//player.Session.Network.EnqueueSend(sendUseDoneEvent);
player.SendUseDoneEvent();
}

public static readonly float TickInterval = 1.0f;

public void QueueNextTick()
{
var nextTick = new ActionChain();
nextTick.AddDelaySeconds(TickInterval);
nextTick.AddAction(this, () => DoTick());
nextTick.EnqueueChain();
}
}
}
10 changes: 10 additions & 0 deletions Source/ACE.Server/WorldObjects/Creature_Navigation.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Numerics;
using ACE.Entity.Enum;
using ACE.Server.Entity;
using ACE.Server.Entity.Actions;
using ACE.Server.Network.Motion;
using ACE.Server.Physics;
Expand Down Expand Up @@ -66,7 +67,16 @@ public float Rotate(WorldObject target)

public void MoveTo(WorldObject target)
{
if (this is Player)
return;

var motion = new UniversalMotion(CurrentMotionState.Stance, target.Location, target.Guid);
motion.MovementTypes = MovementTypes.MoveToObject;
motion.Flag |= MovementParams.CanCharge | MovementParams.FailWalk | MovementParams.UseFinalHeading | MovementParams.Sticky | MovementParams.MoveAway;
motion.WalkRunThreshold = 1.0f;

CurrentMotionState = motion;
CurrentLandblock.EnqueueBroadcastMotion(this, motion);
}
}
}
Loading