-
Notifications
You must be signed in to change notification settings - Fork 32
/
CellularResourceGenerator.cs
107 lines (91 loc) · 3.3 KB
/
CellularResourceGenerator.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
using Kethane.GeodesicGrid;
using System;
using System.Linq;
namespace Kethane
{
public abstract class CellularResourceGenerator : IResourceGenerator
{
public IBodyResources Load(CelestialBody body, ConfigNode node)
{
if (node == null)
{
var amounts = new CellMap<double>(MapOverlay.GridLevel);
Initialize(body, amounts);
return new BodyResources(amounts);
}
else
{
var bytes = Misc.FromBase64String(node.GetValue("amounts"));
ensureBigEndian(bytes);
var amounts = new CellMap<double>(MapOverlay.GridLevel);
var count = Cell.CountAtLevel(MapOverlay.GridLevel);
for (uint i = 0; i < count; i++) {
amounts[new Cell(i)] = BitConverter.ToDouble(bytes, (int)i * 8);
}
return new BodyResources(amounts);
}
}
public abstract void Initialize(CelestialBody body, CellMap<double> amounts);
private static void ensureBigEndian(byte[] bytes)
{
if (BitConverter.IsLittleEndian)
{
for (var i = 0; i < bytes.Length; i += 8)
{
for (var j = 0; j < 4; j++)
{
var temp = bytes[i + j];
bytes[i + j] = bytes[i + 7 - j];
bytes[i + 7 - j] = temp;
}
}
}
}
private class BodyResources : IBodyResources
{
private readonly CellMap<double> amounts;
public BodyResources(CellMap<double> amounts)
{
this.amounts = amounts;
MaxQuantity = amounts.Max(p => p.Value);
}
public ConfigNode Save()
{
var count = Cell.CountAtLevel(MapOverlay.GridLevel);
var bytes = new byte[count * 8];
for (uint i = 0; i < count; i++) {
var b = BitConverter.GetBytes(amounts[new Cell(i)]);
for (int j = 0; j < 8; j++)
{
bytes[i * 8 + j] = b[j];
}
}
ensureBigEndian(bytes);
var node = new ConfigNode();
node.AddValue("amounts", Misc.ToBase64String(bytes));
return node;
}
public ICellResource GetResource(Cell cell)
{
if (amounts[cell] <= 0) { return null; }
return new CellResource(this, cell);
}
public double MaxQuantity { get; private set; }
private class CellResource : ICellResource
{
private readonly BodyResources resources;
private readonly Cell cell;
public CellResource(BodyResources resources, Cell cell)
{
this.resources = resources;
this.cell = cell;
}
public double Quantity
{
get { return resources.amounts[cell]; }
set { resources.amounts[cell] = value; }
}
}
}
}
}