/// <summary> /// Process the walk algorithm. /// </summary> /// <param name="entity">Current entity</param> private void Walk(IMovableEntity entity) { if (entity.MovableComponent.DestinationPosition.IsInCircle(entity.Object.Position, 0.1f)) { entity.MovableComponent.HasArrived = true; entity.MovableComponent.DestinationPosition = entity.Object.Position.Clone(); } else { entity.MovableComponent.HasArrived = false; double entitySpeed = entity.MovableComponent.Speed * entity.MovableComponent.SpeedFactor; double speed = ((entitySpeed * 100f) * entity.Context.GameTime); float distanceX = entity.MovableComponent.DestinationPosition.X - entity.Object.Position.X; float distanceZ = entity.MovableComponent.DestinationPosition.Z - entity.Object.Position.Z; double distance = Math.Sqrt(distanceX * distanceX + distanceZ * distanceZ); // Normalize double deltaX = distanceX / distance; double deltaZ = distanceZ / distance; double offsetX = deltaX * speed; double offsetZ = deltaZ * speed; if (Math.Abs(offsetX) > Math.Abs(distanceX)) { offsetX = distanceX; } if (Math.Abs(offsetZ) > Math.Abs(distanceZ)) { offsetZ = distanceZ; } entity.Object.Position.X += (float)offsetX; entity.Object.Position.Z += (float)offsetZ; } }
private void ProcessMovement(IMovableEntity entity) { if (!(entity is IAiEntity ai)) { return; } if (ai.Waypoints == null || ai.Waypoints.Length <= 0) { return; } byte speedIndex = (byte)(ai.Speed / 2 < 1 ? 1 : ai.Speed / 2); int maxindex = ai.Waypoints.Length > speedIndex ? speedIndex : ai.Waypoints.Length; Position <short> newPos = ai.Waypoints[maxindex - 1]; if (!ai.CanMove(newPos)) { return; } ai.Position = ai.Waypoints[maxindex - 1]; ai.Waypoints = ai.Waypoints.Skip(maxindex).ToArray(); Move(entity); }
/// <summary> /// Moves the entity toward the current mouse position. /// </summary> /// <param name="entity">The entity to move.</param> /// <param name="gameTime">The game time.</param> public void Move(IMovableEntity entity, GameTime gameTime) { System.Diagnostics.Debug.Assert(entity != null); System.Diagnostics.Debug.Assert(gameTime != null); var lMousePosition = new Vector2(this.InputState.CurrentMouseState.X, this.InputState.CurrentMouseState.Y); var lEntityCenter = this.Position + (entity.Size / 2f); const float lcOffset = 10; var lSpeed = this.Velocity.Length(); var lDirection = lMousePosition - lEntityCenter; if ((Math.Abs(lDirection.X) < lcOffset) && (Math.Abs(lDirection.Y) < lcOffset)) { return; } var lNewVelocity = lDirection; lNewVelocity.Normalize(); lNewVelocity *= lSpeed; this.Acceleration = Vector2.Zero; this.Velocity = lNewVelocity; this.Position += (float)gameTime.ElapsedGameTime.TotalSeconds * lNewVelocity; }
/// <summary> /// Moves the entity via basic newtonian physics based on the acceleration/velocity/position of the entity. /// </summary> /// <param name="entity">The entity to move.</param> /// <param name="gameTime">The current game time.</param> public void Move(IMovableEntity entity, GameTime gameTime) { System.Diagnostics.Debug.Assert(entity != null); System.Diagnostics.Debug.Assert(gameTime != null); var lSeconds = (float)gameTime.ElapsedGameTime.TotalSeconds; this.Velocity += this.Acceleration * lSeconds; this.Position += this.Velocity * lSeconds; }
public static bool CanMove(this IMovableEntity mov, short x, short y) { if (mov.Speed == 0) { return(false); } double waitingtime = PositionHelper.GetDistance(mov.Position, x, y) / (double)mov.Speed; return(mov.LastMove.AddMilliseconds(waitingtime) <= DateTime.UtcNow); }
public static void SendDestinationPosition(IMovableEntity movableEntity) { using (var packet = new FFPacket()) { packet.StartNewMergedPacket(movableEntity.Id, SnapshotType.DESTPOS); packet.Write(movableEntity.MovableComponent.DestinationPosition.X); packet.Write(movableEntity.MovableComponent.DestinationPosition.Y); packet.Write(movableEntity.MovableComponent.DestinationPosition.Z); packet.Write <byte>(1); SendToVisible(packet, movableEntity); } }
private void OnFollow(IMovableEntity entity, FollowEventArgs e) { var entityToFollow = entity.FindEntity <IEntity>(e.TargetId); if (entityToFollow == null) { Logger.Error($"Cannot find entity with object id: {e.TargetId} around {entity.Object.Name}"); return; } entity.Follow.Target = entityToFollow; entity.Moves.DestinationPosition = entityToFollow.Object.Position.Clone(); entity.Object.MovingFlags = ObjectState.OBJSTA_FMOVE; WorldPacketFactory.SendFollowTarget(entity, entityToFollow, e.Distance); }
/// <summary> /// This movement hints an item to move toward the target as if /// the target weere a source of gravity. /// </summary> /// <param name="entity">The entity to move.</param> /// <param name="gameTime">The current game time.</param> public void Move(IMovableEntity entity, GameTime gameTime) { // We will move toward the entity as normal, but we will // move the direction of the acceleration vector to // always point toward the target entity. // We also don't adjust the speed of the entity, // only its direction. System.Diagnostics.Debug.Assert(entity != null); System.Diagnostics.Debug.Assert(gameTime != null); var lSeconds = (float)gameTime.ElapsedGameTime.TotalSeconds; this.Acceleration = Vector2.Normalize(this.TargetEntity.MovementBehavior.Position - this.Position) * this.Acceleration.Length(); this.Velocity = Vector2.Normalize(this.Velocity + (this.Acceleration * lSeconds)) * this.Velocity.Length(); this.Position += this.Velocity * lSeconds; }
/// <inheritdoc /> public void SendDestinationPosition(IMovableEntity movableEntity) { if (movableEntity is IPlayerEntity playerEntity) { if (playerEntity.PlayerData.Mode.HasFlag(ModeType.TRANSPARENT_MODE)) { return; } } using var packet = new FFPacket(); packet.StartNewMergedPacket(movableEntity.Id, SnapshotType.DESTPOS); packet.Write(movableEntity.Moves.DestinationPosition.X); packet.Write(movableEntity.Moves.DestinationPosition.Y); packet.Write(movableEntity.Moves.DestinationPosition.Z); packet.Write <byte>(1); SendToVisible(packet, movableEntity); }
/// <summary> /// Moves the entity in the shape of a sin wave. /// </summary> /// <param name="entity">The entity to move.</param> /// <param name="gameTime">The current game time.</param> public void Move(IMovableEntity entity, GameTime gameTime) { System.Diagnostics.Debug.Assert(entity != null); System.Diagnostics.Debug.Assert(gameTime != null); // If the non-offset position has not been changed yet, // we set it to the position. if (this.NonOffsetPosition == Vector2.Zero) { this.NonOffsetPosition = this.Position; } var lSeconds = (float)gameTime.ElapsedGameTime.TotalSeconds; this.Velocity += this.Acceleration * lSeconds; this.NonOffsetPosition += this.Velocity * lSeconds; var lSineSeconds = (float)Math.Sin(gameTime.TotalGameTime.TotalSeconds * (Math.PI / this.Period.TotalSeconds)); var lOffset = this.Radius * lSineSeconds; this.Position = this.NonOffsetPosition + lOffset; }
/// <summary> /// This movement pattern attempts to follow another entity. /// </summary> /// <param name="entity">The entity to move.</param> /// <param name="gameTime">The current game time.</param> public void Move(IMovableEntity entity, GameTime gameTime) { // We will follow the other entity by constantly shifting // our velocity vector to point toward the other entity. // We follow all other physical laws. // Any acceleration only effects our speed increase per second // and will not cause us to change direction off of our target. System.Diagnostics.Debug.Assert(entity != null); System.Diagnostics.Debug.Assert(gameTime != null); var lSeconds = (float)gameTime.ElapsedGameTime.TotalSeconds; var lSpeed = this.Velocity.Length() + (this.Acceleration.Length() * lSeconds); var lDirection = this.TargetEntity.MovementBehavior.Position - this.Position; lDirection.Normalize(); this.Velocity = lDirection * lSpeed; this.Position += this.Velocity * lSeconds; }
private void OnFollow(IMovableEntity entity, FollowEventArgs e) { var entityToFollow = entity.FindEntity <IEntity>(e.TargetId); if (entityToFollow == null) { Logger.Error($"Cannot find entity with object id: {e.TargetId} around {entity.Object.Name}"); return; } if (entity.Follow.Target != entityToFollow) { entity.Follow.Target = entityToFollow; entity.MovableComponent.DestinationPosition = entityToFollow.Object.Position.Clone(); } if (entity is IMonsterEntity monster) { monster.Timers.NextMoveTime = Time.TimeInSeconds() + 5; } WorldPacketFactory.SendFollowTarget(entity, entityToFollow, e.Distance); }
public void Dispose() { _substantialEntity = null; }
/// <summary> /// Does nothing - the entity doen't move. /// </summary> /// <param name="entity">The entity to move.</param> /// <param name="gameTime">The current game time.</param> public void Move(IMovableEntity entity, GameTime gameTime) { }
/// <summary> /// Process the walk algorithm. /// </summary> /// <param name="entity">Current entity</param> private void Walk(IMovableEntity entity) { if (entity.Object.Position.IsInCircle(entity.Moves.DestinationPosition, ArrivalRangeRadius)) { entity.Moves.HasArrived = true; entity.Moves.DestinationPosition = entity.Object.Position.Clone(); entity.Object.MovingFlags &= ~ObjectState.OBJSTA_FMOVE; entity.Object.MovingFlags |= ObjectState.OBJSTA_STAND; if (entity is IMonsterEntity monster) { monster.Behavior.OnArrived(monster); } else if (entity is IPlayerEntity player) { player.Behavior.OnArrived(player); } } else { entity.Moves.HasArrived = false; float entitySpeed = entity.Moves.Speed * entity.Moves.SpeedFactor; // TODO: Add speed bonuses if (entity.Object.MotionFlags.HasFlag(StateFlags.OBJSTAF_WALK)) { entitySpeed /= 5f; } else if (entity.Object.MovingFlags.HasFlag(ObjectState.OBJSTA_BMOVE)) { entitySpeed /= 4f; } float distanceX = entity.Moves.DestinationPosition.X - entity.Object.Position.X; float distanceZ = entity.Moves.DestinationPosition.Z - entity.Object.Position.Z; double distance = Math.Sqrt(distanceX * distanceX + distanceZ * distanceZ); // Normalize double deltaX = distanceX / distance; double deltaZ = distanceZ / distance; double offsetX = deltaX * entitySpeed; double offsetZ = deltaZ * entitySpeed; if (Math.Abs(offsetX) > Math.Abs(distanceX)) { offsetX = distanceX; } if (Math.Abs(offsetZ) > Math.Abs(distanceZ)) { offsetZ = distanceZ; } if (entity.Type == WorldEntityType.Player && entity.Moves.IsMovingWithKeyboard) { float angle = entity.Object.Angle; var movementX = (float)(Math.Sin(angle * (Math.PI / 180)) * Math.Sqrt(offsetX * offsetX + offsetZ * offsetZ)); var movementZ = (float)(Math.Cos(angle * (Math.PI / 180)) * Math.Sqrt(offsetX * offsetX + offsetZ * offsetZ)); if (entity.Object.MovingFlags.HasFlag(ObjectState.OBJSTA_FMOVE)) { entity.Object.Position.X += movementX; entity.Object.Position.Z -= movementZ; } else if (entity.Object.MovingFlags.HasFlag(ObjectState.OBJSTA_BMOVE)) { entity.Object.Position.X -= movementX; entity.Object.Position.Z += movementZ; } } else { entity.Object.Position.X += (float)offsetX; entity.Object.Position.Z += (float)offsetZ; } } }
/// <summary> /// Gets the distance between two movable entities at their actual position /// </summary> /// <param name="src"></param> /// <param name="dest"></param> /// <returns></returns> public static int GetDistance(this IMovableEntity src, IMovableEntity dest) => PositionHelper.GetDistance(src.Position, dest.Position);
public BasicMovableComponent(IMovableEntity substantialEntity) { _substantialEntity = substantialEntity; }