Exemple #1
0
        /// <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;
            }
        }
Exemple #2
0
        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);
        }
Exemple #6
0
        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);
            }
        }
Exemple #7
0
        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;
        }
Exemple #9
0
        /// <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;
        }
Exemple #12
0
        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)
 {
 }
Exemple #15
0
        /// <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;
 }