示例#1
0
文件: Mob.cs 项目: SharpMC/MiNET
        public override void OnTick()
        {
            base.OnTick();

            if (HealthManager.IsDead)
            {
                return;
            }

            if (Level.EnableChunkTicking && DespawnIfNotSeenPlayer && DateTime.UtcNow - LastSeenPlayerTimer > TimeSpan.FromSeconds(30))
            {
                if (Level.GetSpawnedPlayers().Count(e => Vector3.Distance(KnownPosition, e.KnownPosition) < 32) == 0)
                {
                    if (Level.Random.Next(800) == 0)
                    {
                        if (Log.IsDebugEnabled)
                        {
                            Log.Warn($"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();
            _currentBehavior?.OnTick();

            // 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 onGround = IsMobOnGround(KnownPosition);

            if (!onGroundBefore && onGround)
            {
                while (Level.GetBlock(KnownPosition).IsSolid)
                {
                    KnownPosition.Y = (float)Math.Floor(KnownPosition.Y + 1);
                }

                KnownPosition.Y = (float)Math.Floor(KnownPosition.Y);
            }

            //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 || Math.Abs(_lastSentHeadYaw - KnownPosition.HeadYaw) > 0.01 || Math.Abs(_lastSentDir - Direction) > 0.01)
            {
                _lastSentDir     = Direction;
                _lastSentPos     = KnownPosition;
                _lastSentHeadYaw = KnownPosition.HeadYaw;

                BroadcastMove();
                BroadcastMotion();
            }

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

            bool inWater = IsMobInFluid(KnownPosition);

            if (inWater && Level.Random.NextDouble() < 0.8)
            {
                Velocity += new Vector3(0, 0.039f, 0);
            }
            else if (onGround)
            {
                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;
        }