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; }