OSDN Git Service

Pre-RC0: Pass 2; JSON Field metadata dynamic generation.
[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                 [ProtoBeforeSerialization]
106                 private void PrepareData()
107                 {
108
109                         if (HeightMap != null)
110                         {
111                                 _flattened_HeightMap = new ushort[ChunkSize * ChunkSize];
112                                 int flatIndex = 0;
113
114                                 for (byte col = 0; col < ChunkSize; col++)
115                                 {
116                                         for (byte row = 0; row < ChunkSize; row++)
117                                         {
118                                                 _flattened_HeightMap[flatIndex] = HeightMap[col, row];
119                                                 flatIndex++;
120                                         }
121                                 }
122
123                         }
124
125                 }
126
127
128                 [ProtoAfterDeserialization]
129                 private void PostProcess()
130                 {
131                         if (this.HeightMap == null) this.HeightMap = new ushort[ChunkSize, ChunkSize];
132
133                         if (_flattened_HeightMap != null)
134                         {
135                                 int col, row;
136                                 _ = new BitVector32(0);
137                                 var rowSection = BitVector32.CreateSection((short) (ChunkSize - 1));
138                                 var colSection = BitVector32.CreateSection((short) (ChunkSize - 1), rowSection);
139
140                                 for (uint rowcol = 0; rowcol < (ChunkSize * ChunkSize); rowcol++)
141                                 {
142                                         BitVector32 bitMasker = new BitVector32(data: (int) rowcol);
143                                         row = bitMasker[rowSection];
144                                         col = bitMasker[colSection];
145                                         HeightMap[col, row] = _flattened_HeightMap[rowcol];
146                                 }
147
148                         }
149
150                 }
151
152
153         }
154
155         public class ColumnsMetadata : KeyedCollection<Vec2i, ColumnMeta>
156         {
157                 private ColumnsMetadata()
158                 {
159                         throw new NotSupportedException();
160                 }
161
162                 public ColumnsMetadata(Vec2i startChunkColumn)
163                 {
164                         North_mostChunk = startChunkColumn.Y;
165                         South_mostChunk = startChunkColumn.Y;
166                         East_mostChunk = startChunkColumn.X;
167                         West_mostChunk = startChunkColumn.X;
168                 }
169
170                 public int North_mostChunk
171                 {
172                         get; private set;
173                 }
174
175                 public int South_mostChunk
176                 {
177                         get; private set;
178                 }
179
180                 public int East_mostChunk
181                 {
182                         get; private set;
183                 }
184
185                 public int West_mostChunk
186                 {
187                         get; private set;
188                 }
189
190                 protected override Vec2i GetKeyForItem(ColumnMeta item)
191                 {
192                         return item.Location;
193                 }
194
195                 internal void Update(ColumnMeta metaData)
196                 {
197                         if (this.Contains(metaData.Location))
198                         {
199                                 this.Remove(metaData.Location);
200                                 this.Add(metaData);
201                         }
202                         else
203                         {
204                                 this.Add(metaData);
205                         }
206
207                 }
208
209                 public new void Add(ColumnMeta newItem)
210                 {
211                         if (North_mostChunk > newItem.Location.Y)
212                         {
213                                 North_mostChunk = newItem.Location.Y;
214                         }
215
216                         if (South_mostChunk < newItem.Location.Y)
217                         {
218                                 South_mostChunk = newItem.Location.Y;
219                         }
220
221                         if (East_mostChunk < newItem.Location.X)
222                         {
223                                 East_mostChunk = newItem.Location.X;
224                         }
225
226                         if (West_mostChunk > newItem.Location.X)
227                         {
228                                 West_mostChunk = newItem.Location.X;
229                         }
230
231                         base.Add(newItem);
232                 }
233
234         }
235 }