public MyDroneStrafeBehaviour(MyRemoteControl remoteControl, MySpaceStrafeData strafeData, bool activate, List <MyUserControllableGun> weapons, List <MyFunctionalBlock> tools, Vector3D firstWaypoint) { m_remoteControl = remoteControl; ReturnPosition = m_remoteControl.PositionComp.GetPosition(); LoadStrafeData(strafeData); m_weapons = weapons; m_tools = tools; MyPlayer player = m_remoteControl.GetNearestPlayer(); m_target = player != null ? player.Character as MyEntity : null; m_lastTargetUpdate = MySandboxGame.TotalGamePlayTimeInMilliseconds; m_lastWeaponUpdate = m_lastTargetUpdate; m_waypointReachedTimeMs = m_lastTargetUpdate; m_firstWaypoint = firstWaypoint; NeedUpdate = activate; }
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; }