2 using System.Collections.Generic;
3 using System.Collections.Specialized;
6 using Vintagestory.API.MathTools;
7 using Vintagestory.API.Common;
11 using System.Collections.ObjectModel;
13 using Vintagestory.API.Client;
18 public struct ColumnMeta
21 [DisplayName(0, "Coords.")]
22 public Vec2i Location;
25 [DisplayName(1, "Age")]
26 public TimeSpan ChunkAge;//OLDEST CHUNK. from chunk last edit
29 [DisplayName(2, "Temp.")]
30 public float Temperature;// Temperature - surface
33 [DisplayName(3, "Y Max.")]
34 public ushort YMax;// Y feature height
37 //[DisplayName(10, "Rocks")]
38 public Dictionary<int, uint> RockRatio;//[Column] Geographic region (rock) Ratio. [BlockID * count]
41 [DisplayName(4, "Fert.")]
42 public float Fertility;
45 [DisplayName(5, "Forest")]
46 public float ForestDensity;
49 [DisplayName(6, "Rain")]
50 public float Rainfall;
53 [DisplayName(7, "Shrub")]
54 public float ShrubDensity;
57 [DisplayName(8, "Air blocks")]
58 public uint AirBlocks;
61 [DisplayName(9, "Non-air")]
62 public uint NonAirBlocks;
65 public byte ChunkSize;
69 public ushort[,] HeightMap;//Needs to be 'flattened' for Protocol-Buffer serialization
72 private ushort[] _flattened_HeightMap;
75 public ColumnMeta(Vec2i loc, byte chunkSize = 32)
78 ChunkAge = TimeSpan.Zero;
81 RockRatio = new Dictionary<int, uint>(10);
88 ChunkSize = chunkSize;
89 HeightMap = new ushort[ChunkSize, ChunkSize];
90 _flattened_HeightMap = null;
93 internal void UpdateFieldsFrom(ClimateCondition climate, IMapChunk mapChunk, TimeSpan chunkAge)
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;
102 this.YMax = mapChunk.YMax;
105 public void Write(StreamWriter stream, ICoreClientAPI ClientApi)
107 // this is gross i hate this
108 stream.Write("['{0}_{1}',[",
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);
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 if (this.HeightMap == null) this.HeightMap = new ushort[ChunkSize, ChunkSize];
153 if (_flattened_HeightMap != null)
156 _ = new BitVector32(0);
157 var rowSection = BitVector32.CreateSection((short) (ChunkSize - 1));
158 var colSection = BitVector32.CreateSection((short) (ChunkSize - 1), rowSection);
160 for (uint rowcol = 0; rowcol < (ChunkSize * ChunkSize); rowcol++)
162 BitVector32 bitMasker = new BitVector32(data: (int) rowcol);
163 row = bitMasker[rowSection];
164 col = bitMasker[colSection];
165 HeightMap[col, row] = _flattened_HeightMap[rowcol];
175 public class ColumnsMetadata : KeyedCollection<Vec2i, ColumnMeta>
177 private ColumnsMetadata()
179 throw new NotSupportedException();
182 public ColumnsMetadata(Vec2i startChunkColumn)
184 North_mostChunk = startChunkColumn.Y;
185 South_mostChunk = startChunkColumn.Y;
186 East_mostChunk = startChunkColumn.X;
187 West_mostChunk = startChunkColumn.X;
190 public int North_mostChunk
195 public int South_mostChunk
200 public int East_mostChunk
205 public int West_mostChunk
210 protected override Vec2i GetKeyForItem(ColumnMeta item)
212 return item.Location;
215 internal void Update(ColumnMeta metaData)
217 if (this.Contains(metaData.Location))
219 this.Remove(metaData.Location);
229 public new void Add(ColumnMeta newItem)
231 if (North_mostChunk > newItem.Location.Y)
233 North_mostChunk = newItem.Location.Y;
236 if (South_mostChunk < newItem.Location.Y)
238 South_mostChunk = newItem.Location.Y;
241 if (East_mostChunk < newItem.Location.X)
243 East_mostChunk = newItem.Location.X;
246 if (West_mostChunk > newItem.Location.X)
248 West_mostChunk = newItem.Location.X;