예제 #1
0
파일: Mob.cs 프로젝트: apieceofcaken/MiNET
        public override void OnTick(Entity[] entities)
        {
            base.OnTick(entities);

            if (HealthManager.IsDead)
            {
                return;
            }

            //RenderBbox(this);

            bool noPlayersWithin32 = false;

            if (Level.EnableChunkTicking && DespawnIfNotSeenPlayer)
            {
                if (Level.Players.Count(player => player.Value.IsSpawned && Vector3.Distance(KnownPosition, player.Value.KnownPosition) < 128) == 0)
                {
                    if (Log.IsDebugEnabled)
                    {
                        Log.Debug($"Despawn because didn't see any players within 128 blocks.");
                    }

                    DespawnEntity();
                    return;
                }
                if (DateTime.UtcNow - LastSeenPlayerTimer > TimeSpan.FromSeconds(30))
                {
                    if (Level.Players.Count(player => player.Value.IsSpawned && Vector3.Distance(KnownPosition, player.Value.KnownPosition) < 32) == 0)
                    {
                        if (Level.Random.Next(800) == 0)
                        {
                            if (Log.IsDebugEnabled)
                            {
                                Log.Debug($"Despawn because didn't see any players within 32 blocks for 30s or longer. Last seen {LastSeenPlayerTimer}");
                            }

                            DespawnEntity();
                            return;
                        }

                        noPlayersWithin32 = true;
                    }
                    else
                    {
                        LastSeenPlayerTimer = DateTime.UtcNow;
                    }
                }
                else
                {
                }
            }

            // Execute move
            bool onGroundBefore = IsMobOnGround(KnownPosition);

            KnownPosition.X += (float)Velocity.X;
            KnownPosition.Y += (float)Velocity.Y;
            KnownPosition.Z += (float)Velocity.Z;

            // Fix potential fall through ground because of speed
            bool inWater = IsMobInFluid(KnownPosition);

            IsOnGround = !inWater && IsMobOnGround(KnownPosition);
            if (!onGroundBefore && IsOnGround)
            {
                Block block = Level.GetBlock(KnownPosition);
                while (block.IsSolid)
                {
                    //KnownPosition.Y = (float) Math.Floor(KnownPosition.Y);
                    KnownPosition.Y = block.GetBoundingBox().Max.Y;
                    block           = Level.GetBlock(block.Coordinates.BlockUp());
                }

                //KnownPosition.Y = (float) (Math.Floor(KnownPosition.Y));
                Velocity *= new Vector3(0, 1, 0);
            }

            //if (Math.Abs(_lastSentDir - Direction) < 1.1) Direction = _lastSentDir;
            //if (Math.Abs(_lastSentHeadYaw - KnownPosition.HeadYaw) < 1.1) KnownPosition.HeadYaw = (float) _lastSentHeadYaw;

            if ((_lastSentPos - KnownPosition).Length() > 0.01 || KnownPosition.GetDirection() != _lastSentRotation)
            {
                _lastSentPos      = KnownPosition;
                _lastSentRotation = KnownPosition.GetDirection();

                if (!IsRidden)
                {
                    BroadcastMove();
                    BroadcastMotion();
                }
            }

            var oldVelocity = Velocity;

            // Below: Calculate velocity for next move

            _currentTargetBehavior = GetBehavior(TargetBehaviors, _currentTargetBehavior);
            _currentBehavior       = GetBehavior(Behaviors, _currentBehavior);

            _currentTargetBehavior?.OnTick(entities);
            _currentBehavior?.OnTick(entities);

            if (IsRidden)
            {
                return;
            }

            if (noPlayersWithin32)
            {
                Velocity = oldVelocity;
            }

            if (inWater && Level.Random.NextDouble() < 0.8)
            {
                Velocity += new Vector3(0, 0.039f, 0);
                Velocity *= new Vector3(0.2f, 1.0f, 0.2f);
            }
            else if (IsOnGround)
            {
                if (Velocity.Y < 0)
                {
                    Velocity *= new Vector3(1, 0, 1);
                }
            }
            else
            {
                Velocity -= new Vector3(0, (float)Gravity, 0);
            }

            float drag = (float)(1 - Drag);

            if (inWater)
            {
                drag = 0.8F;
            }

            Velocity *= drag;
        }
예제 #2
0
        public override void OnTick()
        {
            base.OnTick();

            if (HealthManager.IsDead)
            {
                return;
            }

            if (Level.EnableChunkTicking && DespawnIfNotSeenPlayer && DateTime.UtcNow - LastSeenPlayerTimer > TimeSpan.FromSeconds(30))
            {
                if (Level.Players.Count(player => player.Value.IsSpawned && Vector3.Distance(KnownPosition, player.Value.KnownPosition) < 32) == 0)
                {
                    if (Level.Random.Next(800) == 0)
                    {
                        if (Log.IsDebugEnabled)
                        {
                            Log.Debug($"Despawn because didn't see any players within 32 blocks for 30s or longer. Last seen {LastSeenPlayerTimer}");
                        }

                        DespawnEntity();
                        return;
                    }
                }
                else
                {
                    LastSeenPlayerTimer = DateTime.UtcNow;
                }
            }

            _currentBehavior = GetBehavior();

            // Execute move
            bool onGroundBefore = IsMobOnGround(KnownPosition);

            KnownPosition.X += (float)Velocity.X;
            KnownPosition.Y += (float)Velocity.Y;
            KnownPosition.Z += (float)Velocity.Z;

            // Fix potential fall through ground because of speed
            IsOnGround = IsMobOnGround(KnownPosition);
            if (!onGroundBefore && IsOnGround)
            {
                while (Level.GetBlock(KnownPosition).IsSolid)
                {
                    KnownPosition.Y = (float)Math.Floor(KnownPosition.Y + 1);
                }

                KnownPosition.Y = (float)Math.Floor(KnownPosition.Y);
                Velocity       *= new Vector3(0, 1, 0);
            }

            //if (Math.Abs(_lastSentDir - Direction) < 1.1) Direction = _lastSentDir;
            //if (Math.Abs(_lastSentHeadYaw - KnownPosition.HeadYaw) < 1.1) KnownPosition.HeadYaw = (float) _lastSentHeadYaw;

            if ((_lastSentPos - KnownPosition).Length() > 0.01 || KnownPosition.GetDirection() != _lastSentRotation)
            {
                _lastSentPos      = KnownPosition;
                _lastSentRotation = KnownPosition.GetDirection();

//				BroadcastMove();
//				BroadcastMotion();
                LastUpdatedTime = DateTime.UtcNow;
            }

            // Calculate velocity for next move
            _currentBehavior?.OnTick();

            bool inWater = IsMobInFluid(KnownPosition);

            if (inWater && Level.Random.NextDouble() < 0.8)
            {
                Velocity += new Vector3(0, 0.039f, 0);
            }
            else if (IsOnGround)
            {
                if (Velocity.Y < 0)
                {
                    Velocity *= new Vector3(1, 0, 1);
                }
            }
            else
            {
                Velocity -= new Vector3(0, (float)Gravity, 0);
            }

            float drag = (float)(1 - Drag);

            if (inWater)
            {
                drag = 0.8F;
            }

            Velocity *= drag;
        }