2 using System.Collections.Generic;
3 using System.Collections.Specialized;
4 using System.Diagnostics;
6 using System.Collections.ObjectModel;
9 using Vintagestory.API.MathTools;
10 using Vintagestory.API.Common;
11 using Vintagestory.API.Client;
17 [ProtoContract(ImplicitFields = ImplicitFields.None)]
18 public struct ColumnMeta
21 public Vec2i Location;
23 [DisplayName(0, "Coords.")]
25 public string PrettyLocation;
28 public TimeSpan ChunkAge;//OLDEST CHUNK. from chunk last edit
30 [DisplayName(1, "Age")]
32 public string ShortChunkAge { get => ChunkAge.ToString("c"); }
34 [DisplayName(2, "Temp.")]
36 public float Temperature;// Temperature - surface
38 [DisplayName(3, "Y Max.")]
40 public ushort YMax;// Y feature height
43 public Dictionary<int, uint> RockRatio;//[Column] Geographic region (rock) Ratio. [BlockID * count]
45 //[DisplayName(10, "Rocks")]
46 //public JArray FlatRocks
49 // string[] rocks = new string[this.RockRatio.Count];
51 // foreach (var roc in RockRatio)
53 // rocks[i++] = $"\"{roc.Key}\":\"{roc.Value}\"";
55 // return new JArray(rocks);
60 [DisplayName(4, "Fert.")]
62 public float Fertility;
64 //[DisplayName(5, "Forest")]
66 public float ForestDensity; // not given to client
68 [DisplayName(6, "Rain")]
70 public float Rainfall;
72 //[DisplayName(7, "Shrub")]
74 public float ShrubDensity; // not given to client
76 [DisplayName(8, "Air blocks")]
78 public uint AirBlocks;
80 [DisplayName(9, "Non-air")]
82 public uint NonAirBlocks;
85 public byte ChunkSize;
89 public ushort[,] HeightMap;//Needs to be 'flattened' for Protocol-Buffer serialization
92 private ushort[] _flattened_HeightMap;
94 public ColumnMeta(Vec2i loc, ICoreClientAPI clientAPI, byte chunkSize = 32)
97 PrettyLocation = loc.PrettyCoords(clientAPI);
98 ChunkAge = TimeSpan.Zero;
101 RockRatio = new Dictionary<int, uint>(10);
108 ChunkSize = chunkSize;
109 HeightMap = new ushort[ChunkSize, ChunkSize];
110 _flattened_HeightMap = null;
113 internal void UpdateFieldsFrom(ClimateCondition climate, IMapChunk mapChunk, TimeSpan chunkAge)
115 this.ChunkAge = chunkAge;
116 this.Temperature = climate.Temperature;
117 this.Fertility = climate.Fertility;
118 this.ForestDensity = climate.ForestDensity;
119 this.Rainfall = climate.Rainfall;
120 this.ShrubDensity = climate.ShrubDensity;
122 this.YMax = mapChunk.YMax;
125 [ProtoBeforeSerialization]
126 private void PrepareData()
129 if (HeightMap != null)
131 _flattened_HeightMap = new ushort[ChunkSize * ChunkSize];
134 for (byte col = 0; col < ChunkSize; col++)
136 for (byte row = 0; row < ChunkSize; row++)
138 _flattened_HeightMap[flatIndex] = HeightMap[col, row];
148 [ProtoAfterDeserialization]
149 private void PostProcess()
151 ChunkSize = (ChunkSize == byte.MinValue) ? (byte)32 : ChunkSize;//Not good - if chunk wasn't 32 orignally!
153 if (this.HeightMap == null || this.HeightMap.Length != (ChunkSize * ChunkSize)) {
154 this.HeightMap = new ushort[ChunkSize, ChunkSize];
157 if (_flattened_HeightMap != null)
160 var bitMasker = new BitVector32(0);
161 var rowSection = BitVector32.CreateSection((short) (ChunkSize - 1));
162 var colSection = BitVector32.CreateSection((short) (ChunkSize - 1), rowSection);
164 for (uint rowcol = 0; rowcol < (ChunkSize * ChunkSize); rowcol++)
166 bitMasker = new BitVector32(data: (int) rowcol);
167 row = bitMasker[rowSection];
168 col = bitMasker[colSection];
169 HeightMap[col, row] = _flattened_HeightMap[rowcol];
177 internal ColumnMeta Reload(ICoreClientAPI clientAPI)
179 this.PrettyLocation = Location.PrettyCoords(clientAPI);
180 Debug.Write(PrettyLocation == null ? "*" : ",");
185 public class ColumnsMetadata : KeyedCollection<Vec2i, ColumnMeta>
187 private ColumnsMetadata()
189 throw new NotSupportedException();
192 public ColumnsMetadata(Vec2i startChunkColumn)
194 North_mostChunk = startChunkColumn.Y;
195 South_mostChunk = startChunkColumn.Y;
196 East_mostChunk = startChunkColumn.X;
197 West_mostChunk = startChunkColumn.X;
200 public int North_mostChunk
205 public int South_mostChunk
210 public int East_mostChunk
215 public int West_mostChunk
220 protected override Vec2i GetKeyForItem(ColumnMeta item)
222 return item.Location;
225 internal void Update(ColumnMeta metaData)
227 if (this.Contains(metaData.Location))
229 this.Remove(metaData.Location);
239 public new void Add(ColumnMeta newItem)
241 if (North_mostChunk > newItem.Location.Y)
243 North_mostChunk = newItem.Location.Y;
246 if (South_mostChunk < newItem.Location.Y)
248 South_mostChunk = newItem.Location.Y;
251 if (East_mostChunk < newItem.Location.X)
253 East_mostChunk = newItem.Location.X;
256 if (West_mostChunk > newItem.Location.X)
258 West_mostChunk = newItem.Location.X;
264 public void ClearMetadata( )
266 for (int i = 0, maxItemsCount = this.Items.Count; i < maxItemsCount; i++) {
267 ColumnMeta entry = this.Items[i];
268 entry.HeightMap = null;
269 entry.RockRatio = null;//Also regenerated when any chunk in a column is changed...