2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Collections.Specialized;
5 using System.Diagnostics;
6 using System.Collections.ObjectModel;
9 using Vintagestory.API.MathTools;
10 using Vintagestory.API.Common;
11 using Vintagestory.API.Client;
18 [ProtoContract(ImplicitFields = ImplicitFields.None)]
19 public struct ColumnMeta
22 public Vec2i Location;
24 [DisplayName(0, "Coords.")]
26 public string PrettyLocation;
29 public TimeSpan ChunkAge;//OLDEST CHUNK. from chunk last edit
31 [DisplayName(1, "Age")]
33 public string ShortChunkAge { get => ChunkAge.ToString("c"); }
35 [DisplayName(2, "Temp.")]
37 public float Temperature;// Temperature - surface
39 [DisplayName(3, "Y Max.")]
41 public ushort YMax;// Y feature height
44 public Dictionary<int, uint> RockRatio;//[Column] Geographic region (rock) Ratio. [BlockID * count]
46 //[DisplayName(10, "Rocks")]
47 //public JArray FlatRocks
50 // string[] rocks = new string[this.RockRatio.Count];
52 // foreach (var roc in RockRatio)
54 // rocks[i++] = $"\"{roc.Key}\":\"{roc.Value}\"";
56 // return new JArray(rocks);
61 [DisplayName(4, "Fert.")]
63 public float Fertility;
65 //[DisplayName(5, "Forest")]
67 public float ForestDensity; // not given to client
69 [DisplayName(6, "Rain")]
71 public float Rainfall;
73 //[DisplayName(7, "Shrub")]
75 public float ShrubDensity; // not given to client
77 [DisplayName(8, "Air blocks")]
79 public uint AirBlocks;
81 [DisplayName(9, "Non-air")]
83 public uint NonAirBlocks;
86 public byte ChunkSize;
90 public ushort[,] HeightMap;//Needs to be 'flattened' for Protocol-Buffer serialization
93 private ushort[] _flattened_HeightMap;
96 /// Column Presense Bitmap
99 public BitArray ColumnPresense;
101 public ColumnMeta(Vec2i loc, ICoreClientAPI clientAPI, byte chunkSize = 32, int maxChunkHeight = 16)
104 PrettyLocation = loc.PrettyCoords(clientAPI);
105 ChunkAge = TimeSpan.Zero;
108 RockRatio = new Dictionary<int, uint>(10);
115 ChunkSize = chunkSize;
116 HeightMap = new ushort[ChunkSize, ChunkSize];
117 _flattened_HeightMap = null;
118 ColumnPresense = new BitArray(maxChunkHeight, false);//TODO: get real chunk height MAX
121 internal void UpdateFieldsFrom(ClimateCondition climate, IMapChunk mapChunk, TimeSpan chunkAge)
123 this.ChunkAge = chunkAge;
124 this.Temperature = climate.Temperature;
125 this.Fertility = climate.Fertility;
126 this.ForestDensity = climate.ForestDensity;
127 this.Rainfall = climate.Rainfall;
128 this.ShrubDensity = climate.ShrubDensity;
130 this.YMax = mapChunk.YMax;
133 internal void ResetMetadata(int mapSizeY )
135 if (this.ColumnPresense == null) { this.ColumnPresense = new BitArray((mapSizeY / this.ChunkSize), false); }
138 HeightMap = new ushort[ChunkSize, ChunkSize];
139 RockRatio = new Dictionary<int, uint>(this.RockRatio.Count);
145 [ProtoBeforeSerialization]
146 private void PrepareData()
149 if (HeightMap != null)
151 _flattened_HeightMap = new ushort[ChunkSize * ChunkSize];
154 for (byte col = 0; col < ChunkSize; col++)
156 for (byte row = 0; row < ChunkSize; row++)
158 _flattened_HeightMap[flatIndex] = HeightMap[col, row];
168 [ProtoAfterDeserialization]
169 private void PostProcess()
171 ChunkSize = (ChunkSize == byte.MinValue) ? (byte)32 : ChunkSize;//Not good - if chunk wasn't 32 orignally!
173 if (this.HeightMap == null || this.HeightMap.Length != (ChunkSize * ChunkSize)) {
174 this.HeightMap = new ushort[ChunkSize, ChunkSize];
177 if (_flattened_HeightMap != null)
180 var bitMasker = new BitVector32(0);
181 var rowSection = BitVector32.CreateSection((short) (ChunkSize - 1));
182 var colSection = BitVector32.CreateSection((short) (ChunkSize - 1), rowSection);
184 for (uint rowcol = 0; rowcol < (ChunkSize * ChunkSize); rowcol++)
186 bitMasker = new BitVector32(data: (int) rowcol);
187 row = bitMasker[rowSection];
188 col = bitMasker[colSection];
189 HeightMap[col, row] = _flattened_HeightMap[rowcol];
197 internal ColumnMeta Reload(ICoreClientAPI clientAPI)
199 this.PrettyLocation = Location.PrettyCoords(clientAPI);
200 Debug.Write(PrettyLocation == null ? "*" : ",");
205 public class ColumnsMetadata : KeyedCollection<Vec2i, ColumnMeta>
207 private ColumnsMetadata()
209 throw new NotSupportedException();
212 public ColumnsMetadata(Vec2i startChunkColumn)
214 North_mostChunk = startChunkColumn.Y;
215 South_mostChunk = startChunkColumn.Y;
216 East_mostChunk = startChunkColumn.X;
217 West_mostChunk = startChunkColumn.X;
220 public int North_mostChunk
225 public int South_mostChunk
230 public int East_mostChunk
235 public int West_mostChunk
240 protected override Vec2i GetKeyForItem(ColumnMeta item)
242 return item.Location;
245 internal void Update(ColumnMeta metaData)
247 if (this.Contains(metaData.Location))
249 this.Remove(metaData.Location);
259 public new void Add(ColumnMeta newItem)
261 if (North_mostChunk > newItem.Location.Y)
263 North_mostChunk = newItem.Location.Y;
266 if (South_mostChunk < newItem.Location.Y)
268 South_mostChunk = newItem.Location.Y;
271 if (East_mostChunk < newItem.Location.X)
273 East_mostChunk = newItem.Location.X;
276 if (West_mostChunk > newItem.Location.X)
278 West_mostChunk = newItem.Location.X;
284 public void ClearMetadata( )
286 for (int i = 0, maxItemsCount = this.Items.Count; i < maxItemsCount; i++) {
287 ColumnMeta entry = this.Items[i];
288 entry.HeightMap = null;
289 entry.RockRatio = null;//Also regenerated when any chunk in a column is changed...