private void UpdateWaypoint()
        {
            int currentTime = MySandboxGame.TotalGamePlayTimeInMilliseconds;

            if (m_currentTarget != null && currentTime - m_lastTargetUpdate >= 1000)
            {
                m_lastTargetUpdate = currentTime;
                if (!IsValidTarget(m_currentTarget))
                {
                    m_currentTarget = null;
                }
            }

            //find new target player
            if ((m_currentTarget == null && currentTime - m_lastTargetUpdate >= 1000) || currentTime - m_lostStartTimeMs >= m_lostTimeMs)
            {
                FindNewTarget();
                m_lastTargetUpdate = currentTime;
                if (m_currentTarget != null)
                {
                    m_lostStartTimeMs   = currentTime;
                    m_farAwayFromTarget = true;
                }
                else
                {
                    m_lostStartTimeMs += 5000;
                }
            }

            if (m_farAwayFromTarget && currentTime - m_lastTargetUpdate >= 5000 && m_canSkipWaypoint)
            {
                m_lastTargetUpdate = currentTime;
                NeedUpdate         = true;
            }

            //weapon/suicide update
            float distSq = -1f;

            if (m_operational && currentTime - m_lastWeaponUpdate >= 300)
            {
                m_lastWeaponUpdate = currentTime;
                distSq             = m_currentTarget != null?Vector3.DistanceSquared((Vector3)m_currentTarget.PositionComp.GetPosition(), (Vector3)m_remoteControl.PositionComp.GetPosition()) : -1f;

                WeaponsUpdate(distSq);
                m_canRotateToTarget = distSq < m_rotationLimitSq && distSq >= 0;
            }

            if (currentTime - m_waypointReachedTimeMs >= m_waypointMaxTime && m_canSkipWaypoint)
            {
                NeedUpdate = true;
            }
            if (m_remoteControl.CurrentWaypoint == null && WaypointList.Count > 0)
            {
                NeedUpdate = true;
            }

            if (!NeedUpdate)
            {
                return;
            }

            //active and prepare waypoints
            IsActive = true;
            if (distSq < 0 && m_currentTarget != null)
            {
                distSq = Vector3.DistanceSquared((Vector3)m_currentTarget.PositionComp.GetPosition(), (Vector3)m_remoteControl.PositionComp.GetPosition());
            }
            m_farAwayFromTarget = distSq > m_maxManeuverDistanceSq;
            m_canRotateToTarget = distSq < m_rotationLimitSq && distSq >= 0;
            bool origUpdate = NeedUpdate;

            if (m_remoteControl.HasWaypoints())
            {
                m_remoteControl.ClearWaypoints();
                //MyGuiAudio.PlaySound(VRage.Audio.MyGuiSounds.PlayTakeItem); //debug
            }
            m_remoteControl.SetAutoPilotEnabled(true);
            NeedUpdate = origUpdate;

            Vector3D newWaypoint;

            m_canSkipWaypoint = true;
            if (m_forcedWaypoints.Count > 0)
            {
                if (m_cycleWaypoints)
                {
                    m_forcedWaypoints.Add(m_forcedWaypoints[0]);
                }
                newWaypoint = m_forcedWaypoints[0].PositionComp.GetPosition();
                m_forcedWaypoints.RemoveAt(0);
                m_canSkipWaypoint = false;
            }
            else if (m_currentTarget == null)
            {
                newWaypoint = m_remoteControl.WorldMatrix.Translation + Vector3.One * 0.01f;
            }
            else if (!m_operational && m_kamikazeBehavior)
            {
                //no functional weapons -> ram the player
                if (m_remoteControl.TargettingAimDelta > 0.02f)
                {
                    return;
                }
                newWaypoint = m_currentTarget.PositionComp.GetPosition() + m_currentTarget.WorldMatrix.Up * PlayerYAxisOffset * 2 - Vector3D.Normalize(m_remoteControl.PositionComp.GetPosition() - m_currentTarget.PositionComp.GetPosition()) * m_kamikazeBehaviorDistance;
            }
            else if (!m_operational && !m_kamikazeBehavior)
            {
                //no functional weapons -> try to escape
                newWaypoint = m_returnPosition + Vector3.One * 0.01f;
            }
            else if (m_farAwayFromTarget)
            {
                //too far away from target
                newWaypoint = m_currentTarget.PositionComp.GetPosition() + Vector3D.Normalize(m_remoteControl.PositionComp.GetPosition() - m_currentTarget.PositionComp.GetPosition()) * m_playerTargetDistance;
                if (m_useHoverMechanic)
                {
                    HoverMechanic(ref newWaypoint);
                }
            }
            else
            {
                //in proximity to target
                m_lostStartTimeMs = currentTime;
                if (currentTime - m_waypointReachedTimeMs <= m_waypointDelayMs)
                {
                    return;
                }
                newWaypoint = GetRandomPoint();
                if (m_useHoverMechanic)
                {
                    HoverMechanic(ref newWaypoint);
                }
            }

            //Add new point to waypoints
            Vector3D currentToWaypoint = newWaypoint - m_remoteControl.WorldMatrix.Translation;

            currentToWaypoint.Normalize();
            m_waypointReachedTimeMs = currentTime;
            bool commitKamikadze = m_kamikazeBehavior && !m_operational;

            m_remoteControl.ChangeFlightMode(MyRemoteControl.FlightMode.OneWay);
            m_remoteControl.SetAutoPilotSpeedLimit(commitKamikadze ? 100f : m_speedLimit);
            m_remoteControl.SetCollisionAvoidance((commitKamikadze || !m_canSkipWaypoint) ? false : m_avoidCollisions);
            m_remoteControl.ChangeDirection(Base6Directions.Direction.Forward);
            m_remoteControl.AddWaypoint(newWaypoint, m_farAwayFromTarget || commitKamikadze ? "Player Vicinity" : "Strafe");

            NeedUpdate = false;
            IsActive   = true;
        }
        private void UpdateWaypoint()
        {
            int currentTime = MySandboxGame.TotalGamePlayTimeInMilliseconds;

            //find new target player
            if ((m_target == null && currentTime - m_lastTargetUpdate >= 5000) || currentTime - m_lostStartTimeMs >= m_lostTimeMs)
            {
                MyPlayer player = m_remoteControl.GetNearestPlayer();
                m_target           = player != null ? player.Character as MyEntity : null;
                m_lastTargetUpdate = currentTime;
                if (m_target != null)
                {
                    m_lostStartTimeMs   = currentTime;
                    m_farAwayFromTarget = true;
                }
                else
                {
                    m_lostStartTimeMs += 5000;
                }
            }

            if (m_farAwayFromTarget && currentTime - m_lastTargetUpdate >= 5000)
            {
                m_lastTargetUpdate = currentTime;
                NeedUpdate         = true;
            }

            //weapon/suicide update
            float distSq = -1f;

            if (m_operational && currentTime - m_lastWeaponUpdate >= 300)
            {
                m_lastWeaponUpdate = currentTime;
                distSq             = Vector3.DistanceSquared((Vector3)m_target.PositionComp.GetPosition(), (Vector3)m_remoteControl.PositionComp.GetPosition());
                WeaponsUpdate(distSq);
            }

            if (currentTime - m_waypointReachedTimeMs >= m_waypointMaxTime)
            {
                NeedUpdate = true;
            }

            if (!NeedUpdate || m_target == null)
            {
                return;
            }

            //active and prepare waypoints
            IsActive = true;
            if (distSq < 0)
            {
                distSq = Vector3.DistanceSquared((Vector3)m_target.PositionComp.GetPosition(), (Vector3)m_remoteControl.PositionComp.GetPosition());
            }
            m_farAwayFromTarget = distSq > m_maxManeuverDistanceSq;
            bool origUpdate = NeedUpdate;

            if (m_remoteControl.HasWaypoints())
            {
                m_remoteControl.ClearWaypoints();
                //MyGuiAudio.PlaySound(MyGuiSounds.PlayTakeItem); //debug
            }
            m_remoteControl.SetAutoPilotEnabled(true);
            NeedUpdate = origUpdate;

            Vector3D newWaypoint;

            if (m_firstWaypoint != Vector3D.Zero)
            {
                newWaypoint     = m_firstWaypoint;
                m_firstWaypoint = Vector3D.Zero;
            }
            else if (!m_operational && m_kamikazeBehavior)
            {
                //no functional weapons -> ram the player
                if (m_remoteControl.TargettingAimDelta > 0.02f)
                {
                    return;
                }
                newWaypoint = m_target.PositionComp.GetPosition() + m_target.WorldMatrix.Up * PlayerYAxisOffset * 2 - Vector3D.Normalize(m_remoteControl.PositionComp.GetPosition() - m_target.PositionComp.GetPosition()) * m_kamikazeBehaviorDistance;
            }
            else if (!m_operational && !m_kamikazeBehavior)
            {
                //no functional weapons -> try to escape
                newWaypoint = ReturnPosition + Vector3.One * 0.01f;
            }
            else if (m_farAwayFromTarget)
            {
                //too far away from target
                newWaypoint = m_target.PositionComp.GetPosition() + Vector3D.Normalize(m_remoteControl.PositionComp.GetPosition() - m_target.PositionComp.GetPosition()) * m_playerTargetDistance;
            }
            else
            {
                //in proximity to target
                m_lostStartTimeMs = currentTime;
                if (currentTime - m_waypointReachedTimeMs <= m_waypointDelayMs)
                {
                    return;
                }
                newWaypoint = GetRandomPoint();
            }

            //Add new point to waypoints
            Vector3D currentToWaypoint = newWaypoint - m_remoteControl.WorldMatrix.Translation;

            currentToWaypoint.Normalize();
            m_waypointReachedTimeMs = currentTime;
            var strafeLocalDir = Vector3.TransformNormal((Vector3)currentToWaypoint, m_remoteControl.PositionComp.WorldMatrixNormalizedInv);

            Base6Directions.Direction strafeDir = Base6Directions.GetClosestDirection(ref strafeLocalDir);
            bool commitKamikadze = m_kamikazeBehavior && !m_operational;

            m_remoteControl.ChangeFlightMode(MyRemoteControl.FlightMode.OneWay);
            m_remoteControl.SetAutoPilotSpeedLimit(commitKamikadze ? 100f : m_speedLimit);
            m_remoteControl.SetCollisionAvoidance(commitKamikadze ? false : m_avoidCollisions);
            m_remoteControl.ChangeDirection(strafeDir);
            m_remoteControl.AddWaypoint(newWaypoint, m_farAwayFromTarget || commitKamikadze ? "Player Vicinity" : "Strafe");

            NeedUpdate = false;
            IsActive   = true;
        }