OSDN Git Service

9fd9aef3e044c1df1aa20f459b2cde49b03f4089
[automap/automap.git] / Automap / Data / ColumnMeta.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Collections.Specialized;
4
5
6 using Vintagestory.API.MathTools;
7 using Vintagestory.API.Common;
8
9 using ProtoBuf;
10 using System.IO;
11 using System.Collections.ObjectModel;
12 using System.Text;
13 using Vintagestory.API.Client;
14
15 namespace Automap
16 {
17         [ProtoContract]
18         public struct ColumnMeta
19         {
20                 [ProtoMember(1)]
21                 [DisplayName(0, "Coords.")]
22                 public Vec2i Location;
23
24                 [ProtoMember(2)]
25                 [DisplayName(1, "Age")]
26                 public TimeSpan ChunkAge;//OLDEST CHUNK. from chunk last edit
27
28                 [ProtoMember(3)]
29                 [DisplayName(2, "Temp.")]
30                 public float Temperature;// Temperature - surface
31
32                 [ProtoMember(4)]
33                 [DisplayName(3, "Y Max.")]
34                 public ushort YMax;// Y feature height
35
36                 [ProtoMember(5)]
37                 //[DisplayName(10, "Rocks")]
38                 public Dictionary<int, uint> RockRatio;//[Column] Geographic region (rock) Ratio. [BlockID * count]
39
40                 [ProtoMember(6)]
41                 [DisplayName(4, "Fert.")]
42                 public float Fertility;
43
44                 [ProtoMember(7)]
45                 [DisplayName(5, "Forest")]
46                 public float ForestDensity;
47
48                 [ProtoMember(8)]
49                 [DisplayName(6, "Rain")]
50                 public float Rainfall;
51
52                 [ProtoMember(9)]
53                 [DisplayName(7, "Shrub")]
54                 public float ShrubDensity;
55
56                 [ProtoMember(10)]
57                 [DisplayName(8, "Air blocks")]
58                 public uint AirBlocks;
59
60                 [ProtoMember(11)]
61                 [DisplayName(9, "Non-air")]
62                 public uint NonAirBlocks;
63
64                 [ProtoMember(12)]
65                 public byte ChunkSize;
66
67
68                 [ProtoIgnore]
69                 public ushort[,] HeightMap;//Needs to be 'flattened' for Protocol-Buffer serialization
70
71                 [ProtoMember(13)]
72                 private ushort[] _flattened_HeightMap;
73
74
75                 public ColumnMeta(Vec2i loc, byte chunkSize = 32)
76                 {
77                         Location = loc;
78                         ChunkAge = TimeSpan.Zero;
79                         Temperature = 0f;
80                         YMax = 0;
81                         RockRatio = new Dictionary<int, uint>(10);
82                         Fertility = 0f;
83                         ForestDensity = 0f;
84                         Rainfall = 0f;
85                         ShrubDensity = 0f;
86                         AirBlocks = 0;
87                         NonAirBlocks = 0;
88                         ChunkSize = chunkSize;
89                         HeightMap = new ushort[ChunkSize, ChunkSize];
90                         _flattened_HeightMap = null;
91                 }
92
93                 internal void UpdateFieldsFrom(ClimateCondition climate, IMapChunk mapChunk, TimeSpan chunkAge)
94                 {
95                         this.ChunkAge = chunkAge;
96                         this.Temperature = climate.Temperature;
97                         this.Fertility = climate.Fertility;
98                         this.ForestDensity = climate.ForestDensity;
99                         this.Rainfall = climate.Rainfall;
100                         this.ShrubDensity = climate.ShrubDensity;
101
102                         this.YMax = mapChunk.YMax;
103                 }
104
105                 public void Write(StreamWriter stream, ICoreClientAPI ClientApi)
106                 {
107                         // this is gross i hate this
108                         stream.Write("['{0}_{1}',[",
109                                 Location.X,
110                                 Location.Y
111                                 );
112                         stream.Write("'{0}',", Location.PrettyCoords(ClientApi));
113                         stream.Write("'{0}',", ChunkAge);
114                         stream.Write("'{0}',", Temperature.ToString("F3"));
115                         stream.Write("'{0}',", YMax);
116                         stream.Write("'{0}',", Fertility.ToString("F3"));
117                         stream.Write("'{0}',", ForestDensity.ToString("F3"));
118                         stream.Write("'{0}',", Rainfall.ToString("F3"));
119                         stream.Write("'{0}',", ShrubDensity.ToString("F3"));
120                         stream.Write("'{0}',", AirBlocks);
121                         stream.Write("'{0}',", NonAirBlocks);
122                         stream.Write("]]");
123                 }
124
125                 [ProtoBeforeSerialization]
126                 private void PrepareData()
127                 {
128
129                         if (HeightMap != null)
130                         {
131                                 _flattened_HeightMap = new ushort[ChunkSize * ChunkSize];
132                                 int flatIndex = 0;
133
134                                 for (byte col = 0; col < ChunkSize; col++)
135                                 {
136                                         for (byte row = 0; row < ChunkSize; row++)
137                                         {
138                                                 _flattened_HeightMap[flatIndex] = HeightMap[col, row];
139                                                 flatIndex++;
140                                         }
141                                 }
142
143                         }
144
145                 }
146
147
148                 [ProtoAfterDeserialization]
149                 private void PostProcess()
150                 {
151                         if (this.HeightMap == null) this.HeightMap = new ushort[ChunkSize, ChunkSize];
152
153                         if (_flattened_HeightMap != null)
154                         {
155                                 int col, row;
156                                 _ = new BitVector32(0);
157                                 var rowSection = BitVector32.CreateSection((short) (ChunkSize - 1));
158                                 var colSection = BitVector32.CreateSection((short) (ChunkSize - 1), rowSection);
159
160                                 for (uint rowcol = 0; rowcol < (ChunkSize * ChunkSize); rowcol++)
161                                 {
162                                         BitVector32 bitMasker = new BitVector32(data: (int) rowcol);
163                                         row = bitMasker[rowSection];
164                                         col = bitMasker[colSection];
165                                         HeightMap[col, row] = _flattened_HeightMap[rowcol];
166                                 }
167
168                         }
169
170                 }
171
172
173         }
174
175         public class ColumnsMetadata : KeyedCollection<Vec2i, ColumnMeta>
176         {
177                 private ColumnsMetadata()
178                 {
179                         throw new NotSupportedException();
180                 }
181
182                 public ColumnsMetadata(Vec2i startChunkColumn)
183                 {
184                         North_mostChunk = startChunkColumn.Y;
185                         South_mostChunk = startChunkColumn.Y;
186                         East_mostChunk = startChunkColumn.X;
187                         West_mostChunk = startChunkColumn.X;
188                 }
189
190                 public int North_mostChunk
191                 {
192                         get; private set;
193                 }
194
195                 public int South_mostChunk
196                 {
197                         get; private set;
198                 }
199
200                 public int East_mostChunk
201                 {
202                         get; private set;
203                 }
204
205                 public int West_mostChunk
206                 {
207                         get; private set;
208                 }
209
210                 protected override Vec2i GetKeyForItem(ColumnMeta item)
211                 {
212                         return item.Location;
213                 }
214
215                 internal void Update(ColumnMeta metaData)
216                 {
217                         if (this.Contains(metaData.Location))
218                         {
219                                 this.Remove(metaData.Location);
220                                 this.Add(metaData);
221                         }
222                         else
223                         {
224                                 this.Add(metaData);
225                         }
226
227                 }
228
229                 public new void Add(ColumnMeta newItem)
230                 {
231                         if (North_mostChunk > newItem.Location.Y)
232                         {
233                                 North_mostChunk = newItem.Location.Y;
234                         }
235
236                         if (South_mostChunk < newItem.Location.Y)
237                         {
238                                 South_mostChunk = newItem.Location.Y;
239                         }
240
241                         if (East_mostChunk < newItem.Location.X)
242                         {
243                                 East_mostChunk = newItem.Location.X;
244                         }
245
246                         if (West_mostChunk > newItem.Location.X)
247                         {
248                                 West_mostChunk = newItem.Location.X;
249                         }
250
251                         base.Add(newItem);
252                 }
253
254         }
255 }