void NoCruiseLaunchStatusHandle(Actor self)
        {
            MoveForward(self);
            speed = speed + dSpeed > bmInfo.Speed.Length ? bmInfo.Speed.Length : speed + dSpeed;
            if (bm.CenterPosition.Z - initPos.Z < horizontalLength && (bm.CenterPosition - targetPos).HorizontalLength > horizontalLength * 3 / 5)
            {
                return;
            }

            if (bm.Pitch != WAngle.Zero)
            {
                var newTurnSpeed = new WAngle(8192 * bm.TurnSpeed.Angle / horizontalLength);
                if ((bm.Pitch.Angle < newTurnSpeed.Angle) || ((1024 - bm.Pitch.Angle) < newTurnSpeed.Angle))
                {
                    bm.Pitch = WAngle.Zero;
                }
                else
                {
                    bm.Pitch -= newTurnSpeed;
                }

                return;
            }

            status = BMFlyStatus.Hit;
        }
 void LaunchStatusHandle(Actor self)
 {
     MoveForward(self);
     speed = speed + dSpeed > bmInfo.Speed.Length ? bmInfo.Speed.Length : speed + dSpeed;
     if (bm.CenterPosition.Z - initPos.Z > bmInfo.BeginCruiseAltitude.Length)
     {
         status = BMFlyStatus.Cruise;
     }
 }
        void MoveForward(Actor self)
        {
            var move = new WVec(0, -speed, 0).Rotate(new WRot(bm.Pitch, WAngle.Zero, bm.Facing));

            bm.SetPosition(self, bm.CenterPosition + move);
            if (!self.IsInWorld)
            {
                status = BMFlyStatus.Unknown;
            }
        }
        void HitStatusHandle(Actor self)
        {
            MoveForward(self);
            speed += bmInfo.HitAcceleration.Length;
            var targetPitch = (targetPos - bm.CenterPosition).Pitch;
            var pitchDiff   = (targetPitch - bm.Pitch);

            if (pitchDiff != WAngle.Zero)
            {
                if ((pitchDiff.Angle < bm.TurnSpeed.Angle) || ((1024 - pitchDiff.Angle) < bm.TurnSpeed.Angle))
                {
                    bm.Pitch = targetPitch;
                }
                else
                {
                    if (pitchDiff.Angle < 512)
                    {
                        bm.Pitch += bm.TurnSpeed;
                    }
                    else
                    {
                        bm.Pitch -= bm.TurnSpeed;
                    }
                }
            }

            var targetYaw = (targetPos - bm.CenterPosition).Yaw;
            var yawDiff   = (targetYaw - bm.Facing);

            if (yawDiff != WAngle.Zero)
            {
                if ((yawDiff.Angle < bm.TurnSpeed.Angle) || ((1024 - yawDiff.Angle) < bm.TurnSpeed.Angle))
                {
                    bm.Facing = targetYaw;
                }
                else
                {
                    if (yawDiff.Angle < 512)
                    {
                        bm.Facing += bm.TurnSpeed;
                    }
                    else
                    {
                        bm.Facing -= bm.TurnSpeed;
                    }
                }
            }

            if ((targetPos - bm.CenterPosition).Length < bmInfo.ExplosionRange.Length)
            {
                status = BMFlyStatus.Unknown;
            }
        }
        void LazyCurveHandle(Actor self)
        {
            var pos = WPos.LerpQuadratic(initPos, targetPos, bm.Info.LaunchAngle, lazyCurveTick, lazyCurveLength);

            if (lazyCurveTick != 0)
            {
                bm.Pitch = (pos - bm.CenterPosition).Pitch;
            }

            bm.SetPosition(self, pos);
            lazyCurveTick++;
            if ((targetPos - bm.CenterPosition).Length < bmInfo.ExplosionRange.Length)
            {
                status = BMFlyStatus.Unknown;
            }
        }
        void CruiseStatusHandle(Actor self)
        {
            MoveForward(self);
            if (bm.Pitch != WAngle.Zero)
            {
                if ((bm.Pitch.Angle < bm.TurnSpeed.Angle) || ((1024 - bm.Pitch.Angle) < bm.TurnSpeed.Angle))
                {
                    bm.Pitch = WAngle.Zero;
                }
                else
                {
                    bm.Pitch -= bm.TurnSpeed;
                }
            }

            var targetYaw = (targetPos - bm.CenterPosition).Yaw;
            var yawDiff   = (targetYaw - bm.Facing);

            if (yawDiff != WAngle.Zero)
            {
                if ((yawDiff.Angle < bm.TurnSpeed.Angle) || ((1024 - yawDiff.Angle) < bm.TurnSpeed.Angle))
                {
                    bm.Facing = targetYaw;
                }
                else
                {
                    if (yawDiff.Angle < 512)
                    {
                        bm.Facing += bm.TurnSpeed;
                    }
                    else
                    {
                        bm.Facing -= bm.TurnSpeed;
                    }
                }
            }

            if ((targetPos - bm.CenterPosition).HorizontalLength < bmInfo.BeginHitRange.Length)
            {
                status = BMFlyStatus.Hit;
            }
        }
        void PrepareStatusHandle()
        {
            if (ticks >= bmInfo.PrepareTick)
            {
                if (bmInfo.WithoutCruise)
                {
                    status = BMFlyStatus.NoCruiseLaunch;
                    return;
                }

                if (bmInfo.LazyCurve)
                {
                    status = BMFlyStatus.LazyCurve;
                    return;
                }

                status = BMFlyStatus.Launch;
            }

            bm.Pitch += preparePitchIncrement;
        }