Skip to content

Commit

Permalink
Merge branch 'hotfix-0.7.5'
Browse files Browse the repository at this point in the history
  • Loading branch information
Majiir committed Aug 6, 2013
2 parents 64a281b + 43bd90a commit 7ed38ea
Show file tree
Hide file tree
Showing 15 changed files with 312 additions and 428 deletions.
2 changes: 2 additions & 0 deletions Parts/kethane_radialDrill/part.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ MODULE
}
HeadTransform = 3 Cyl
TailTransform = 1 Cyl
HeadOffset = 0.5
TailOffset = 0.5
}

MODULE
Expand Down
33 changes: 6 additions & 27 deletions Plugin/Deposit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,18 @@

namespace Kethane
{
internal class Point
{
public float x, y;
public Point(float X, float Y)
{
x = X;
y = Y;
}

public static Point operator /(Point c1, float n)
{
return new Point(c1.x / n, c1.y / n);
}

public static Point operator *(Point c1, int n)
{
return new Point(c1.x * n, c1.y * n);
}

}

internal class Polygon
{
private Point[] _vertices;
private Vector2[] _vertices;

public Polygon(Point[] vertices)
public Polygon(Vector2[] vertices)
{
_vertices = vertices.ToArray();
}

public ReadOnlyCollection<Point> Vertices
public ReadOnlyCollection<Vector2> Vertices
{
get { return new ReadOnlyCollection<Point>(_vertices); }
get { return new ReadOnlyCollection<Vector2>(_vertices); }
}

public bool PointInPolygon(Vector2 p)
Expand Down Expand Up @@ -74,7 +53,7 @@ public static Deposit Generate(Vector2 Pos, float radius, System.Random random,
{
var initialQuantity = random.Range(resource.MinQuantity, resource.MaxQuantity);

var vertices = new List<Point>();
var vertices = new List<Vector2>();
int vertexCount = random.Next(resource.MinVertices, resource.MaxVertices);
for (int i = 0; i < vertexCount; i++)
{
Expand All @@ -83,7 +62,7 @@ public static Deposit Generate(Vector2 Pos, float radius, System.Random random,
float x = Pos.x + randomRadius * (float)Math.Cos(angle);
float z = Pos.y - randomRadius * (float)Math.Sin(angle);

vertices.Add(new Point(x, z));
vertices.Add(new Vector2(x, z));
}
var Shape = new Polygon(vertices.ToArray());

Expand Down
22 changes: 22 additions & 0 deletions Plugin/InstallChecker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using UnityEngine;

namespace Kethane
{
[KSPAddon(KSPAddon.Startup.MainMenu, true)]
internal class InstallChecker : MonoBehaviour
{
protected void Start()
{
var assemblies = AssemblyLoader.loadedAssemblies.Where(a => a.assembly == Assembly.GetExecutingAssembly()).Where(a => a.url != "Kethane/Plugins");
if (assemblies.Any())
{
var badPaths = assemblies.Select(a => a.path).Select(p => Uri.UnescapeDataString(new Uri(Path.GetFullPath(KSPUtil.ApplicationRootPath)).MakeRelativeUri(new Uri(p)).ToString().Replace('/', Path.DirectorySeparatorChar)));
PopupDialog.SpawnPopupDialog("Incorrect Kethane Installation", "Kethane has been installed incorrectly and will not function properly. All Kethane files should be located in KSP/GameData/Kethane. Do not move any files from inside the Kethane folder.\n\nIncorrect path(s):\n" + String.Join("\n", badPaths.ToArray()), "OK", false, HighLogic.Skin);
}
}
}
}
4 changes: 3 additions & 1 deletion Plugin/Kethane.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
<Compile Include="HeatSinkAnimator.cs" />
<Compile Include="IDetectorAnimator.cs" />
<Compile Include="IExtractorAnimator.cs" />
<Compile Include="InstallChecker.cs" />
<Compile Include="KethaneData.cs" />
<Compile Include="KethaneDetectorAnimator.cs" />
<Compile Include="KethaneDetectorAnimatorUnity.cs" />
<Compile Include="KethaneDrillAnimator.cs" />
Expand All @@ -71,9 +73,9 @@
<Compile Include="OrthogonalIntake.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ResourceDefinition.cs" />
<Compile Include="ScaledSpaceFix.cs" />
<Compile Include="SettingsManager.cs" />
<Compile Include="TimedMovingAverage.cs" />
<Compile Include="WeakReference.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Expand Down
255 changes: 6 additions & 249 deletions Plugin/KethaneController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,12 @@ namespace Kethane
{
internal class KethaneController
{
#region Static factory

private static Dictionary<WeakReference<Vessel>, KethaneController> controllers = new Dictionary<WeakReference<Vessel>, KethaneController>();

public static KethaneController GetInstance(Vessel vessel)
public static bool ScanningSound
{
foreach (var kvp in controllers.ToArray())
{
var wr = kvp.Key;
var v = wr.Target;
if (v == null)
{
controllers.Remove(wr);
}
else if (v == vessel)
{
return controllers[wr];
}
}

var commander = new KethaneController();
controllers[new WeakReference<Vessel>(vessel)] = commander;
return commander;
get { return Misc.Parse(SettingsManager.GetValue("ScanningSound"), true); }
set { SettingsManager.SetValue("ScanningSound", value); }
}

#endregion

public static Dictionary<string, Dictionary<string, List<Deposit>>> PlanetDeposits;
public static Dictionary<string, Dictionary<string, GeodesicGrid.Cell.Set>> Scans;
public static bool ScanningSound = true;

private static Dictionary<string, int> bodySeeds;
private static int depositSeed;
private static string lastGameLoaded;
private static long lastSaveFrame = -1;
private static SortedDictionary<String, ResourceDefinition> resourceDefinitions = null;

public static ResourceDefinition[] ResourceDefinitions
Expand All @@ -53,20 +24,11 @@ public static ResourceDefinition[] ResourceDefinitions
}
}

private static string selectedResource = "Kethane";
public static string SelectedResource { get { return selectedResource; } set { selectedResource = value; } }
public static string SelectedResource { get; set; }

public Vessel Vessel
static KethaneController()
{
get { return controllers.Single(p => p.Value == this).Key.Target; }
}

private KethaneController()
{
loadResourceDefinitions();
LoadKethaneDeposits();

ScanningSound = Misc.Parse(SettingsManager.GetValue("ScanningSound"), true);
SelectedResource = "Kethane";
}

private static void loadResourceDefinitions()
Expand Down Expand Up @@ -98,210 +60,5 @@ private static void loadResourceDefinitions()
}
Debug.Log(String.Format("[Kethane] Loaded {0} resource definitions", resourceDefinitions.Count));
}

public static void SaveKethaneDeposits()
{
if (PlanetDeposits == null) { return; }
if (lastGameLoaded != HighLogic.SaveFolder) { return; }
if (lastSaveFrame == Time.frameCount) { return; }
lastSaveFrame = Time.frameCount;

var timer = System.Diagnostics.Stopwatch.StartNew();

var configNode = new ConfigNode();
configNode.AddValue("Seed", depositSeed);
foreach (var resource in PlanetDeposits)
{
var resourceNode = new ConfigNode("Resource");
resourceNode.AddValue("Resource", resource.Key);

foreach (var body in resource.Value)
{
var bodyNode = new ConfigNode("Body");
bodyNode.AddValue("Name", body.Key);

if (bodySeeds[body.Key] != body.Key.GetHashCode() && resource.Key == "Kethane")
{
bodyNode.AddValue("SeedModifier", bodySeeds[body.Key]);
}

if (Scans.ContainsKey(resource.Key) && Scans[resource.Key].ContainsKey(body.Key))
{
bodyNode.AddValue("ScanMask", Convert.ToBase64String(Scans[resource.Key][body.Key].ToByteArray()).Replace('/', '.').Replace('=', '%'));
}

foreach (var deposit in body.Value)
{
var depositNode = new ConfigNode("Deposit");
depositNode.AddValue("Quantity", deposit.Quantity);
bodyNode.AddNode(depositNode);
}

resourceNode.AddNode(bodyNode);
}

configNode.AddNode(resourceNode);
}

configNode.Save(getConfigFilePath());

timer.Stop();
Debug.LogWarning(String.Format("Kethane deposits saved ({0}ms)", timer.ElapsedMilliseconds));

SettingsManager.SetValue("ScanningSound", ScanningSound);
SettingsManager.Save();
}

public static void LoadKethaneDeposits()
{
if (PlanetDeposits != null && lastGameLoaded == HighLogic.SaveFolder) { return; }
if (FlightGlobals.fetch == null) { return; }

var timer = System.Diagnostics.Stopwatch.StartNew();

var config = ConfigNode.Load(getConfigFilePath());

Scans = ResourceDefinitions.ToDictionary(d => d.Resource, d => FlightGlobals.Bodies.ToDictionary(b => b.name, b => new GeodesicGrid.Cell.Set(5)));

if ((config == null) || !int.TryParse(config.GetValue("Seed"), out depositSeed))
{
GenerateKethaneDeposits();
return;
}

bodySeeds = FlightGlobals.Bodies.ToDictionary(b => b.name, b => b.name.GetHashCode());

foreach (var node in config.GetNodes("Body").Concat(config.GetNodes("Resource").Where(r => r.GetValue("Resource") == "Kethane").SelectMany(r => r.GetNodes("Body"))))
{
int seed;
if (int.TryParse(node.GetValue("SeedModifier"), out seed))
{
bodySeeds[node.GetValue("Name")] = seed;
}
}

generateFromSeed();

loadBodyDeposits(config, "Kethane", "Kethane");

foreach (var resourceNode in config.GetNodes("Resource"))
{
loadBodyDeposits(resourceNode, resourceNode.GetValue("Resource"));
}

timer.Stop();
Debug.LogWarning(String.Format("Kethane deposits loaded ({0}ms)", timer.ElapsedMilliseconds));

lastGameLoaded = HighLogic.SaveFolder;
}

private static string getConfigFilePath()
{
return KSPUtil.ApplicationRootPath + "saves/" + HighLogic.SaveFolder + "/kethane.cfg";
}

private static void loadBodyDeposits(ConfigNode config, string resourceName, string amountKey = "Quantity")
{
if (!PlanetDeposits.ContainsKey(resourceName)) { return; }
foreach (var body in PlanetDeposits[resourceName])
{
var deposits = body.Value;

var bodyNode = config.GetNodes("Body").Where(b => b.GetValue("Name") == body.Key).SingleOrDefault();
if (bodyNode == null) { continue; }

var scanMask = bodyNode.GetValue("ScanMask");
if (scanMask != null)
{
try
{
Scans[resourceName][body.Key] = new GeodesicGrid.Cell.Set(5, Convert.FromBase64String(scanMask.Replace('.', '/').Replace('%', '=')));
}
catch (FormatException e)
{
Debug.LogError(String.Format("[Kethane] Failed to parse {0}/{1} scan string, resetting ({2})", body.Key, resourceName, e.Message));
}
}

var depositNodes = bodyNode.GetNodes("Deposit");
for (int i = 0; i < Math.Min(deposits.Count, depositNodes.Length); i++)
{
deposits[i].Quantity = Misc.Parse(depositNodes[i].GetValue(amountKey), deposits[i].InitialQuantity);
}
}
}

private static void generateFromSeed()
{
PlanetDeposits = resourceDefinitions.Values.ToDictionary(d => d.Resource, d => FlightGlobals.Bodies.ToDictionary(b => b.name, b => generate(b, d.ForBody(b))));
}

private static List<Deposit> generate(CelestialBody body, ResourceDefinition resource)
{
var random = new System.Random(depositSeed ^ (resource.Resource == "Kethane" ? bodySeeds[body.name] : 0) ^ resource.SeedModifier);

var deposits = new List<Deposit>();

for (int i = 0; i < resource.DepositCount; i++)
{
float R = random.Range(resource.MinRadius, resource.MaxRadius);
for (int j = 0; j < resource.NumberOfTries; j++)
{
Vector2 Pos = new Vector2(random.Range(R, 360 - R), random.Range(R, 180 - R));
var deposit = Deposit.Generate(Pos, R, random, resource);
if (!deposits.Any(d => d.Shape.Vertices.Any(v => deposit.Shape.PointInPolygon(new Vector2(v.x, v.y)))) && !deposit.Shape.Vertices.Any(v => deposits.Any(d => d.Shape.PointInPolygon(new Vector2(v.x, v.y)))))
{
deposits.Add(deposit);
break;
}
}
}

return deposits;
}

public static void GenerateKethaneDeposits(System.Random random = null, bool skipSave = false)
{
if (FlightGlobals.fetch == null) { return; }

Debug.LogWarning("Regenerating Kethane deposits");

if (random == null) { random = new System.Random(); }
depositSeed = random.Next();
bodySeeds = FlightGlobals.Bodies.ToDictionary(b => b.name, b => b.name.GetHashCode());
generateFromSeed();
lastGameLoaded = HighLogic.SaveFolder;
if (!skipSave)
{
SaveKethaneDeposits();
}
}

public Deposit GetDepositUnder(string resourceName)
{
return GetCellDeposit(resourceName, Vessel.mainBody, MapOverlay.GetCellUnder(Vessel.mainBody, Vessel.transform.position));
}

public static Deposit GetCellDeposit(string resourceName, CelestialBody body, GeodesicGrid.Cell cell)
{
if (resourceName == null || body == null || !PlanetDeposits.ContainsKey(resourceName) || !PlanetDeposits[resourceName].ContainsKey(body.name)) { return null; }

var pos = cell.Position;
var lat = (float)(Math.Atan2(pos.y, Math.Sqrt(pos.x * pos.x + pos.z * pos.z)) * 180 / Math.PI);
var lon = (float)(Math.Atan2(pos.z, pos.x) * 180 / Math.PI);

var x = lon + 180f;
var y = 90f - lat;

foreach (Deposit deposit in PlanetDeposits[resourceName][body.name])
{
if (deposit.Shape.PointInPolygon(new Vector2(x, y)))
{
return deposit;
}
}

return null;
}
}
}
Loading

0 comments on commit 7ed38ea

Please sign in to comment.