Skip to content
This repository has been archived by the owner on Jun 17, 2021. It is now read-only.

Commit

Permalink
Version 0.11.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Real-Gecko committed Oct 30, 2016
1 parent d596c32 commit 63f3877
Show file tree
Hide file tree
Showing 24 changed files with 1,594 additions and 617 deletions.
269 changes: 214 additions & 55 deletions BonVoyage/ActiveRover.cs
Original file line number Diff line number Diff line change
@@ -1,86 +1,245 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using KSP.UI.Screens;

namespace BonVoyage
{
public class ActiveRover {
public struct WayPoint {
public double latitude;
public double longitude;
public WayPoint(double lat, double lon) {
latitude = lat;
longitude = lon;
}
}

public string status;
public double toTravel;

public Vessel vessel;
public ConfigNode vesselConfigNode;
public double lastTime;
public double targetLatitude;
public double targetLongitude;
public double averageSpeed;
public double distanceTravelled;
public double distanceToTarget;
public bool solarPowered;
private ConfigNode vesselConfigNode;
private double lastTime;
public double LastTime { get { return lastTime; } }
private double targetLatitude;
private double targetLongitude;

private double averageSpeed;
private double speedMultiplier;
public double AverageSpeed { get { return averageSpeed * speedMultiplier; } }

private double distanceTravelled;
private double distanceToTarget;
public double yetToTravel { get { return distanceToTarget - distanceTravelled; } }

private bool solarPowered;
public bool bvActive;
public ConfigNode BVModule;
public List<WayPoint> path;
public ActiveRover(Vessel v) {
vessel = v;
private bool isManned;
private ConfigNode BVModule;
private List<PathUtils.WayPoint> path;

vesselConfigNode = new ConfigNode ();
vessel.protoVessel.Save (vesselConfigNode);

// This is annoying
var BVPart = vesselConfigNode.GetNode ("PART", "name", "BonVoyageModule");
if (BVPart == null)
BVPart = vesselConfigNode.GetNode ("PART", "name", "Malemute.RoverCab");
if (BVPart == null)
BVPart = vesselConfigNode.GetNode ("PART", "name", "KER.RoverCab");
if (BVPart == null)
BVPart = vesselConfigNode.GetNode ("PART", "name", "WBI.BuffaloCab");
if (BVPart == null)
BVPart = vesselConfigNode.GetNode("PART", "name", "ARESrovercockpit");
if (BVPart == null)
BVPart = vesselConfigNode.GetNode("PART", "name", "Puma Pod");
if (BVPart == null)
return;
/// <summary>
/// Initializes a new instance of the <see cref="BonVoyage.ActiveRover"/> class.
/// </summary>
/// <param name="v">Vessel.</param>
/// <param name="module">Bon Voyage Module.</param>
/// <param name="vcf">Vessel Config Node.</param>
public ActiveRover(Vessel v, ConfigNode module, ConfigNode vcf) {
vessel = v;
vesselConfigNode = vcf;

BVModule = BVPart.GetNode ("MODULE", "name", "BonVoyageModule");
if (BVModule == null)
return;
BVModule = module;

bvActive = bool.Parse (BVModule.GetValue ("isActive"));

// Workaround for update from versions prior to 1.0
try {
isManned = bool.Parse (BVModule.GetValue ("isManned"));
} catch {
isManned = true;
}

solarPowered = bool.Parse (BVModule.GetValue ("solarPowered"));

lastTime = double.Parse (BVModule.GetValue ("lastTime"));
distanceTravelled = double.Parse (BVModule.GetValue ("distanceTravelled"));
distanceToTarget = double.Parse (BVModule.GetValue ("distanceToTarget"));
solarPowered = bool.Parse (BVModule.GetValue ("solarPowered"));
targetLatitude = double.Parse (BVModule.GetValue ("targetLatitude"));
targetLongitude = double.Parse (BVModule.GetValue ("targetLongitude"));
averageSpeed = double.Parse(BVModule.GetValue ("averageSpeed"));
path = new List<WayPoint> ();
DecodePath ();

path = PathUtils.DecodePath(BVModule.GetValue("pathEncoded"));
speedMultiplier = 1.0;
}

private void DecodePath() {
string p = BVModule.GetValue("pathEncoded");
if (p == null)
/// <summary>
/// Update rover.
/// </summary>
/// <param name="currentTime">Current time.</param>
public void Update(double currentTime) {
if (vessel.isActiveVessel)
{
status = "current";
return;
}

if (!bvActive || vessel.loaded)
{
status = "idle";
return;
}

Vector3d vesselPos = vessel.mainBody.position - vessel.GetWorldPos3D();
Vector3d toKerbol = vessel.mainBody.position - FlightGlobals.Bodies[0].position;
double angle = Vector3d.Angle(vesselPos, toKerbol);

// Speed penalties at twighlight and at night
if (angle > 90 && isManned)
speedMultiplier = 0.25;
else if (angle > 85 && isManned)
speedMultiplier = 0.5;
else if (angle > 80 && isManned)
speedMultiplier = 0.75;
else
speedMultiplier = 1.0;

// No moving at night, or when there's not enougth solar light for solar powered rovers
if (angle > 90 && solarPowered)
{
status = "awaiting sunlight";
lastTime = currentTime;
BVModule.SetValue("lastTime", currentTime.ToString());
vessel.protoVessel = new ProtoVessel(vesselConfigNode, HighLogic.CurrentGame);
return;
char[] separators = new char[] { ';' };
string[] wps = p.Split (separators, StringSplitOptions.RemoveEmptyEntries);
foreach (var wp in wps) {
string[] latlon = wp.Split (':');
path.Add (new WayPoint (double.Parse(latlon [0]), double.Parse(latlon [1])));
}
path.Reverse (); // Don't ask me...

double deltaT = currentTime - lastTime;

double deltaS = AverageSpeed * deltaT;
double bearing = GeoUtils.InitialBearing(
vessel.latitude,
vessel.longitude,
targetLatitude,
targetLongitude
);
distanceTravelled += deltaS;
if (distanceTravelled >= distanceToTarget)
{
// vessel.latitude = targetLatitude;
// vessel.longitude = targetLongitude;
if (!MoveSafe (targetLatitude, targetLongitude))
distanceTravelled -= deltaS;
else {
distanceTravelled = distanceToTarget;

bvActive = false;
BVModule.SetValue ("isActive", "False");
BVModule.SetValue ("distanceTravelled", distanceToTarget.ToString ());

BVModule.GetNode ("EVENTS").GetNode ("Activate").SetValue ("active", "True");
BVModule.GetNode ("EVENTS").GetNode ("Deactivate").SetValue ("active", "False");

if (BonVoyage.Instance.AutoDewarp) {
if (TimeWarp.CurrentRate > 3)
TimeWarp.SetRate (3, true);
if (TimeWarp.CurrentRate > 0)
TimeWarp.SetRate (0, false);
ScreenMessages.PostScreenMessage (vessel.vesselName + " has arrived to destination at " + vessel.mainBody.name);
}
HoneyImHome ();
}
status = "idle";
}
else {
int step = Convert.ToInt32(Math.Floor(distanceTravelled / 1000));
double remainder = distanceTravelled % 1000;

if (step < path.Count - 1)
bearing = GeoUtils.InitialBearing(
path[step].latitude,
path[step].longitude,
path[step + 1].latitude,
path[step + 1].longitude
);
else
bearing = GeoUtils.InitialBearing(
path[step].latitude,
path[step].longitude,
targetLatitude,
targetLongitude
);

double[] newCoordinates = GeoUtils.GetLatitudeLongitude(
path[step].latitude,
path[step].longitude,
bearing,
remainder,
vessel.mainBody.Radius
);

// vessel.latitude = newCoordinates[0];
// vessel.longitude = newCoordinates[1];
if (!MoveSafe (newCoordinates [0], newCoordinates [1])) {
distanceTravelled -= deltaS;
status = "idle";
} else
status = "roving";
}
// vessel.altitude = GeoUtils.TerrainHeightAt(vessel.latitude, vessel.longitude, vessel.mainBody);
Save (currentTime);
}

/// <summary>
/// Save data to ProtoVessel.
/// </summary>
public void Save(double currentTime) {
lastTime = currentTime;
vesselConfigNode.SetValue("lat", vessel.latitude.ToString());
vesselConfigNode.SetValue("lon", vessel.longitude.ToString());
vesselConfigNode.SetValue("alt", vessel.altitude.ToString());
vesselConfigNode.SetValue("landedAt", vessel.mainBody.theName);
BVModule.SetValue("distanceTravelled", (distanceTravelled).ToString());
BVModule.SetValue("lastTime", currentTime.ToString());
vessel.protoVessel = new ProtoVessel(vesselConfigNode, HighLogic.CurrentGame);
}

/// <summary>
/// Prevent crazy torpedoing active vessel :D
/// </summary>
/// <returns><c>true</c>, if rover was moved, <c>false</c> otherwise.</returns>
/// <param name="latitude">Latitude.</param>
/// <param name="longitude">Longitude.</param>
private bool MoveSafe(double latitude, double longitude) {
double altitude = GeoUtils.TerrainHeightAt(latitude, longitude, vessel.mainBody);
if (FlightGlobals.ActiveVessel != null) {
Vector3d newPos = vessel.mainBody.GetWorldSurfacePosition (latitude, longitude, altitude);
Vector3d actPos = FlightGlobals.ActiveVessel.GetWorldPos3D ();
double distance = Vector3d.Distance (newPos, actPos);
if (distance <= 2400) {
return false;
}
// VesselRanges ranges = active.vesselRanges.GetSituationRanges(Vessel.Situations.LANDED || Vessel.Situations.FLYING);
// vessel.GoOffRails ();
// vessel.Load ();
}

vessel.latitude = latitude;
vessel.longitude = longitude;
vessel.altitude = altitude;
return true;
}

public double yetToTravel {
get { return distanceToTarget - distanceTravelled; }
/// <summary>
/// Notify that rover has arrived
/// </summary>
private void HoneyImHome() {
MessageSystem.Message message = new MessageSystem.Message (
"Rover arrived",
//------------------------------------------
"<color=#74B4E2>" + vessel.vesselName + "</color>" +
" has arrived to destination\n<color=#AED6EE>LAT:" +
targetLatitude.ToString ("F2") + "</color>\n<color=#AED6EE>LON:" +
targetLongitude.ToString ("F2") +
"</color>\n<color=#82BCE5>At " + vessel.mainBody.name + ".</color>\n" +
"Distance travelled: " +
"<color=#74B4E2>" + distanceTravelled.ToString ("N") + "</color> meters",
//------------------------------------------
MessageSystemButton.MessageButtonColor.GREEN,
MessageSystemButton.ButtonIcons.COMPLETE
);
MessageSystem.Instance.AddMessage (message);
}
}
}
Loading

0 comments on commit 63f3877

Please sign in to comment.