Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
Terrain.cs
浏览该文件的文档.
1using System.Runtime.CompilerServices;
2using Engine;
3
4namespace Game {
5 public class Terrain : IDisposable {
6 public class ChunksStorage {
7 public const int Shift = 8;
8
9 public const int Capacity = 65536;
10
11 public const int CapacityMinusOne = 65535;
12
14
15 [MethodImpl(MethodImplOptions.AggressiveInlining)]
16 public virtual TerrainChunk Get(int x, int y) {
17 int num = (x + (y << Shift)) & CapacityMinusOne;
18 TerrainChunk terrainChunk;
19 while (true) {
20 terrainChunk = m_array[num];
21 if (terrainChunk == null) {
22 return null;
23 }
24 if (terrainChunk.Coords.X == x
25 && terrainChunk.Coords.Y == y) {
26 break;
27 }
28 num = (num + 1) & CapacityMinusOne;
29 }
30 return terrainChunk;
31 }
32
33 [MethodImpl(MethodImplOptions.AggressiveInlining)]
34 public virtual TerrainChunk Get(Point2 p) => Get(p.X, p.Y);
35
36 [MethodImpl(MethodImplOptions.AggressiveInlining)]
37 public virtual TerrainChunk Get(Point3 p) => Get(p.X, p.Z);
38
39 public virtual void Add(int x, int y, TerrainChunk chunk) {
40 int num = (x + (y << Shift)) & CapacityMinusOne;
41 while (m_array[num] != null) {
42 num = (num + 1) & CapacityMinusOne;
43 }
44 m_array[num] = chunk;
45 }
46
47 public virtual void Remove(int x, int y) {
48 int num = (x + (y << Shift)) & CapacityMinusOne;
49 while (true) {
50 TerrainChunk terrainChunk = m_array[num];
51 if (terrainChunk == null) {
52 return;
53 }
54 if (terrainChunk.Coords.X == x
55 && terrainChunk.Coords.Y == y) {
56 break;
57 }
58 num = (num + 1) & CapacityMinusOne;
59 }
60 m_array[num] = null;
61 }
62 }
63
64 public const int ContentsMask = 1023;
65
66 public const int LightMask = 15360;
67
68 public const int LightShift = 10;
69
70 public const int DataMask = -16384;
71
72 public const int DataShift = 14;
73
74 public const int TopHeightMask = 255;
75
76 public const int TopHeightShift = 0;
77
78 public const int TemperatureMask = 3840;
79
80 public const int TemperatureShift = 8;
81
82 public const int HumidityMask = 61440;
83
84 public const int HumidityShift = 12;
85
86 public const int BottomHeightMask = 16711680;
87
88 public const int BottomHeightShift = 16;
89
90 public const int SunlightHeightMask = -16777216;
91
92 public const int SunlightHeightShift = 24;
93
95
96 public HashSet<TerrainChunk> m_allocatedChunks;
97
99
101
102 public int SeasonHumidity;
103
104 public virtual TerrainChunk[] AllocatedChunks {
105 get {
106 if (m_allocatedChunksArray == null) {
108 }
110 }
111 }
112
113 public Terrain() {
116 }
117
118 public virtual void Dispose() {
119 foreach (TerrainChunk allocatedChunk in m_allocatedChunks) {
120 allocatedChunk.Dispose();
121 }
122 }
123
124 public virtual TerrainChunk LoopChunks(int startChunkX, int startChunkZ, bool skipStartChunk, out bool hasLooped) {
125 hasLooped = false;
126 TerrainChunk terrainChunk = null;
127 if (!skipStartChunk) {
128 terrainChunk = GetChunkAtCoords(startChunkX, startChunkZ);
129 if (terrainChunk != null) {
130 return terrainChunk;
131 }
132 }
133 TerrainChunk[] allocatedChunks = AllocatedChunks;
134 for (int i = 0; i < allocatedChunks.Length; i++) {
135 if (ComparePoints(allocatedChunks[i].Coords, new Point2(startChunkX, startChunkZ)) > 0
136 && (terrainChunk == null || ComparePoints(allocatedChunks[i].Coords, terrainChunk.Coords) < 0)) {
137 terrainChunk = allocatedChunks[i];
138 }
139 }
140 if (terrainChunk == null) {
141 for (int j = 0; j < allocatedChunks.Length; j++) {
142 if (terrainChunk == null
143 || ComparePoints(allocatedChunks[j].Coords, terrainChunk.Coords) < 0) {
144 terrainChunk = allocatedChunks[j];
145 hasLooped = true;
146 }
147 }
148 }
149 return terrainChunk;
150 }
151
152 public virtual TerrainChunk LoopChunks(int startChunkX, int startChunkZ, bool skipStartChunk) =>
153 LoopChunks(startChunkX, startChunkZ, skipStartChunk, out bool _);
154
155 public virtual TerrainChunk GetChunkAtCoords(int chunkX, int chunkZ) => m_allChunks.Get(chunkX, chunkZ);
156
157 public virtual TerrainChunk GetChunkAtCoords(Point2 p) => m_allChunks.Get(p.X, p.Y);
158
159 public virtual TerrainChunk GetChunkAtCoords(int chunkX, int chunkY, int chunkZ) =>
160 chunkY is >= 0 and < TerrainChunk.Height / TerrainChunk.Size ? m_allChunks.Get(chunkX, chunkZ) : null;
161
162 public virtual TerrainChunk GetChunkAtCoords(Point3 chunkP) => chunkP.Y is >= 0 and < TerrainChunk.Height / TerrainChunk.Size ? m_allChunks.Get(chunkP.X, chunkP.Z) : null;
163
165
167
168 public virtual TerrainChunk GetChunkAtCell(int x, int y, int z) => y is >= 0 and < TerrainChunk.Height
170 : null;
171
172 public virtual TerrainChunk GetChunkAtCell(Point3 p) => p.Y is >= 0 and < TerrainChunk.Height
174 : null;
175
176 public virtual TerrainChunk AllocateChunk(int chunkX, int chunkZ) {
177 if (GetChunkAtCoords(chunkX, chunkZ) != null) {
178 throw new InvalidOperationException("Chunk already allocated.");
179 }
180 TerrainChunk terrainChunk = new(this, chunkX, chunkZ);
181 m_allocatedChunks.Add(terrainChunk);
182 m_allChunks.Add(chunkX, chunkZ, terrainChunk);
184 return terrainChunk;
185 }
186
187 public virtual void FreeChunk(TerrainChunk chunk) {
188 if (!m_allocatedChunks.Remove(chunk)) {
189 throw new InvalidOperationException("Chunk not allocated.");
190 }
191 m_allChunks.Remove(chunk.Coords.X, chunk.Coords.Y);
193 chunk.Dispose();
194 }
195
196 public static int ComparePoints(Point2 c1, Point2 c2) {
197 if (c1.Y != c2.Y) {
198 return c1.Y <= c2.Y ? -1 : 1;
199 }
200 if (c1.X != c2.X) {
201 return c1.X <= c2.X ? -1 : 1;
202 }
203 return 0;
204 }
205
206 public static Point2 ToChunk(Vector2 p) => ToChunk(ToCell(p.X), ToCell(p.Y));
207
208 public static Point2 ToChunk(int x, int z) => new(x >> TerrainChunk.SizeBits, z >> TerrainChunk.SizeBits);
209
210 public static int ToCell(float x) => (int)MathF.Floor(x);
211
212 public static Point2 ToCell(float x, float y) => new((int)MathF.Floor(x), (int)MathF.Floor(y));
213
214 public static Point2 ToCell(Vector2 p) => new((int)MathF.Floor(p.X), (int)MathF.Floor(p.Y));
215
216 public static Point3 ToCell(float x, float y, float z) => new((int)MathF.Floor(x), (int)MathF.Floor(y), (int)MathF.Floor(z));
217
218 public static Point3 ToCell(Vector3 p) => new((int)MathF.Floor(p.X), (int)MathF.Floor(p.Y), (int)MathF.Floor(p.Z));
219
220 public virtual bool IsCellValid(int x, int y, int z) => y is >= 0 and < TerrainChunk.Height;
221
222 public virtual bool IsCellValid(Point3 p) => p.Y is >= 0 and < TerrainChunk.Height;
223
224 public virtual int GetCellValue(int x, int y, int z) => !IsCellValid(x, y, z) ? 0 : GetCellValueFast(x, y, z);
225
226 public virtual int GetCellValue(Point3 p) => !IsCellValid(p) ? 0 : GetCellValueFast(p);
227
228 public virtual int GetCellContents(int x, int y, int z) => !IsCellValid(x, y, z) ? 0 : GetCellContentsFast(x, y, z);
229
230 public virtual int GetCellContents(Point3 p) => !IsCellValid(p) ? 0 : GetCellContentsFast(p);
231
232 public virtual int GetCellLight(int x, int y, int z) => !IsCellValid(x, y, z) ? 0 : GetCellLightFast(x, y, z);
233
234 public virtual int GetCellLight(Point3 p) => !IsCellValid(p) ? 0 : GetCellLightFast(p);
235
236 public virtual int GetCellValueFast(int x, int y, int z) => GetChunkAtCell(x, z)?.GetCellValueFast(x & 0xF, y, z & 0xF) ?? 0;
237
238 public virtual int GetCellValueFast(Point3 p) => GetChunkAtCell(p)?.GetCellValueFast(p.X & 0xF, p.Y, p.Z & 0xF) ?? 0;
239
240 public virtual int GetCellValueFastChunkExists(int x, int y, int z) => GetChunkAtCell(x, z).GetCellValueFast(x & 0xF, y, z & 0xF);
241
242 public virtual int GetCellValueFastChunkExists(Point3 p) => GetChunkAtCell(p).GetCellValueFast(p.X & 0xF, p.Y, p.Z & 0xF);
243
244 public virtual int GetCellContentsFast(int x, int y, int z) => ExtractContents(GetCellValueFast(x, y, z));
245
247
248 public virtual int GetCellLightFast(int x, int y, int z) => ExtractLight(GetCellValueFast(x, y, z));
249
251
252 public virtual void SetCellValueFast(int x, int y, int z, int value) => GetChunkAtCell(x, z)?.SetCellValueFast(x & 0xF, y, z & 0xF, value);
253
254 public virtual void SetCellValueFast(Point3 p, int value) => GetChunkAtCell(p.X, p.Z)?.SetCellValueFast(p.X & 0xF, p.Y, p.Z & 0xF, value);
255
256 public virtual int CalculateTopmostCellHeight(int x, int z) => GetChunkAtCell(x, z)?.CalculateTopmostCellHeight(x & 0xF, z & 0xF) ?? 0;
257
258 public virtual int CalculateTopmostCellHeight(Point2 p) => GetChunkAtCell(p.X, p.Y)?.CalculateTopmostCellHeight(p.X & 0xF, p.Y & 0xF) ?? 0;
259
260 public virtual int GetShaftValue(int x, int z) => GetChunkAtCell(x, z)?.GetShaftValueFast(x & 0xF, z & 0xF) ?? 0;
261
262 public virtual int GetShaftValue(Point2 p) => GetChunkAtCell(p.X, p.Y)?.GetShaftValueFast(p.X & 0xF, p.Y & 0xF) ?? 0;
263
264 public virtual void SetShaftValue(int x, int z, int value) => GetChunkAtCell(x, z)?.SetShaftValueFast(x & 0xF, z & 0xF, value);
265
266 public virtual void SetShaftValue(Point2 p, int value) => GetChunkAtCell(p.X, p.Y)?.SetShaftValueFast(p.X & 0xF, p.Y & 0xF, value);
267
268 public virtual int GetTemperature(int x, int z) => ExtractTemperature(GetShaftValue(x, z));
269
271
272 public virtual void SetTemperature(int x, int z, int temperature) => SetShaftValue(x, z, ReplaceTemperature(GetShaftValue(x, z), temperature));
273
274 public virtual void SetTemperature(Point2 p, int temperature) => SetShaftValue(p, ReplaceTemperature(GetShaftValue(p), temperature));
275
276 public virtual int GetHumidity(int x, int z) => ExtractHumidity(GetShaftValue(x, z));
277
278 public virtual int GetHumidity(Point2 p) => ExtractHumidity(GetShaftValue(p));
279
280 public virtual void SetHumidity(int x, int z, int humidity) => SetShaftValue(x, z, ReplaceHumidity(GetShaftValue(x, z), humidity));
281
282 public virtual int GetTopHeight(int x, int z) => ExtractTopHeight(GetShaftValue(x, z));
283
284 public virtual void SetTopHeight(int x, int z, int topHeight) => SetShaftValue(x, z, ReplaceTopHeight(GetShaftValue(x, z), topHeight));
285
286 public virtual int GetBottomHeight(int x, int z) => ExtractBottomHeight(GetShaftValue(x, z));
287
288 public virtual void SetBottomHeight(int x, int z, int bottomHeight) => SetShaftValue(x, z, ReplaceBottomHeight(GetShaftValue(x, z), bottomHeight));
289
290 public virtual int GetSunlightHeight(int x, int z) => ExtractSunlightHeight(GetShaftValue(x, z));
291
293
294 public virtual void SetSunlightHeight(int x, int z, int sunlightHeight) => SetShaftValue(x, z, ReplaceSunlightHeight(GetShaftValue(x, z), sunlightHeight));
295
296 public virtual void SetSunlightHeight(Point2 p, int sunlightHeight) => SetShaftValue(p, ReplaceSunlightHeight(GetShaftValue(p), sunlightHeight));
297
298 public static int MakeBlockValue(int contents) => contents & ContentsMask;
299
300 public static int MakeBlockValue(int contents, int light, int data) =>
301 (contents & ContentsMask) | ((light << LightShift) & LightMask) | ((data << DataShift) & DataMask);
302
303 public static int ExtractContents(int value) => value & ContentsMask;
304
305 public static int ExtractLight(int value) => (value & LightMask) >> LightShift;
306
307 public static int ExtractData(int value) => (value & DataMask) >> DataShift;
308
309 public static int ExtractTopHeight(int value) => value & TopHeightMask;
310
311 public static int ExtractBottomHeight(int value) => (value & BottomHeightMask) >> BottomHeightShift;
312
313 public static int ExtractSunlightHeight(int value) => value >>> SunlightHeightShift;
314
315 public static int ExtractHumidity(int value) => (value & HumidityMask) >> HumidityShift;
316
317 public static int ExtractTemperature(int value) => (value & TemperatureMask) >> TemperatureShift;
318
322 public static int ReplaceContents(int value, int contents) => value ^ ((value ^ contents) & ContentsMask);
323
327 public static int ReplaceContents(int contents) => contents & ContentsMask;
328
329 public static int ReplaceLight(int value, int light) => value ^ ((value ^ (light << LightShift)) & LightMask);
330
331 public static int ReplaceData(int value, int data) => value ^ ((value ^ (data << DataShift)) & DataMask);
332
333 public static int ReplaceTopHeight(int value, int topHeight) => value ^ ((value ^ topHeight) & TopHeightMask);
334
335 public static int ReplaceBottomHeight(int value, int bottomHeight) =>
336 value ^ ((value ^ (bottomHeight << BottomHeightShift)) & BottomHeightMask);
337
338 public static int ReplaceSunlightHeight(int value, int sunlightHeight) => (value & 16777215) | (sunlightHeight << SunlightHeightShift);
339
340 public static int ReplaceHumidity(int value, int humidity) => value ^ ((value ^ (humidity << HumidityShift)) & HumidityMask);
341
342 public static int ReplaceTemperature(int value, int temperature) => value ^ ((value ^ (temperature << TemperatureShift)) & TemperatureMask);
343
344 public virtual int GetSeasonalTemperature(int x, int z) => Math.Max(GetTemperature(x, z) + SeasonTemperature, 0);
345
346 public virtual int GetSeasonalTemperature(int shaftValue) => Math.Max(ExtractTemperature(shaftValue) + SeasonTemperature, 0);
347
348 public virtual int GetSeasonalHumidity(int x, int z) => Math.Max(GetHumidity(x, z) + SeasonHumidity, 0);
349
350 public virtual int GetSeasonalHumidity(int shaftValue) => Math.Max(ExtractHumidity(shaftValue) + SeasonHumidity, 0);
351 }
352}
virtual TerrainChunk Get(Point2 p)
virtual TerrainChunk Get(int x, int y)
virtual void Add(int x, int y, TerrainChunk chunk)
virtual void Remove(int x, int y)
virtual TerrainChunk Get(Point3 p)
virtual void SetShaftValueFast(int x, int z, int value)
virtual int GetCellValueFast(int index)
virtual void SetCellValueFast(int x, int y, int z, int value)
virtual int GetShaftValueFast(int x, int z)
virtual int CalculateTopmostCellHeight(int x, int z)
virtual TerrainChunk AllocateChunk(int chunkX, int chunkZ)
HashSet< TerrainChunk > m_allocatedChunks
static int MakeBlockValue(int contents, int light, int data)
static int ReplaceTopHeight(int value, int topHeight)
virtual int GetCellValueFast(Point3 p)
static Point3 ToCell(Vector3 p)
static Point2 ToCell(Vector2 p)
const int HumidityMask
const int SunlightHeightShift
virtual int GetCellLight(Point3 p)
static Point2 ToChunk(Vector2 p)
static int ExtractTemperature(int value)
virtual void SetShaftValue(int x, int z, int value)
const int LightMask
static int ExtractContents(int value)
static int ReplaceHumidity(int value, int humidity)
const int DataMask
virtual int GetSeasonalHumidity(int shaftValue)
const int DataShift
virtual int GetCellValueFastChunkExists(int x, int y, int z)
virtual int GetCellLight(int x, int y, int z)
virtual void SetSunlightHeight(int x, int z, int sunlightHeight)
const int BottomHeightShift
static int ReplaceData(int value, int data)
virtual int GetCellValueFast(int x, int y, int z)
const int TopHeightMask
virtual TerrainChunk GetChunkAtCoords(int chunkX, int chunkY, int chunkZ)
const int TemperatureMask
static int ReplaceContents(int contents)
方块值的最低10位,替换为目标Content(value始终为0时)
virtual void SetTemperature(int x, int z, int temperature)
virtual void FreeChunk(TerrainChunk chunk)
virtual int GetSunlightHeight(int x, int z)
virtual void SetSunlightHeight(Point2 p, int sunlightHeight)
virtual int GetHumidity(int x, int z)
virtual TerrainChunk GetChunkAtCoords(Point3 chunkP)
virtual TerrainChunk LoopChunks(int startChunkX, int startChunkZ, bool skipStartChunk)
virtual void SetCellValueFast(int x, int y, int z, int value)
virtual int GetCellValueFastChunkExists(Point3 p)
virtual int GetTemperature(Point2 p)
virtual int GetBottomHeight(int x, int z)
const int SunlightHeightMask
virtual int GetCellValue(int x, int y, int z)
virtual int GetCellContentsFast(Point3 p)
virtual int GetCellContents(Point3 p)
virtual int GetCellLightFast(int x, int y, int z)
virtual bool IsCellValid(Point3 p)
virtual TerrainChunk GetChunkAtCell(Point2 p)
virtual TerrainChunk GetChunkAtCell(Point3 p)
static int ReplaceBottomHeight(int value, int bottomHeight)
static Point2 ToCell(float x, float y)
static int ComparePoints(Point2 c1, Point2 c2)
const int TopHeightShift
static int ToCell(float x)
static int ExtractBottomHeight(int value)
static Point2 ToChunk(int x, int z)
static int ReplaceSunlightHeight(int value, int sunlightHeight)
const int ContentsMask
virtual void SetHumidity(int x, int z, int humidity)
virtual int GetCellContents(int x, int y, int z)
static int ExtractLight(int value)
TerrainChunk[] m_allocatedChunksArray
virtual int GetSeasonalHumidity(int x, int z)
virtual int GetCellValue(Point3 p)
virtual int GetCellContentsFast(int x, int y, int z)
virtual bool IsCellValid(int x, int y, int z)
virtual void Dispose()
virtual int GetTopHeight(int x, int z)
virtual TerrainChunk LoopChunks(int startChunkX, int startChunkZ, bool skipStartChunk, out bool hasLooped)
virtual int CalculateTopmostCellHeight(Point2 p)
virtual TerrainChunk GetChunkAtCell(int x, int z)
const int BottomHeightMask
virtual int GetSeasonalTemperature(int shaftValue)
static int ExtractHumidity(int value)
static int ExtractTopHeight(int value)
virtual int GetShaftValue(Point2 p)
virtual TerrainChunk GetChunkAtCell(int x, int y, int z)
const int TemperatureShift
virtual int GetSunlightHeight(Point2 p)
virtual TerrainChunk GetChunkAtCoords(int chunkX, int chunkZ)
virtual TerrainChunk[] AllocatedChunks
virtual void SetShaftValue(Point2 p, int value)
virtual int GetHumidity(Point2 p)
virtual int GetShaftValue(int x, int z)
static int ReplaceTemperature(int value, int temperature)
virtual void SetCellValueFast(Point3 p, int value)
static int ReplaceLight(int value, int light)
virtual int GetSeasonalTemperature(int x, int z)
static int ExtractSunlightHeight(int value)
static int ReplaceContents(int value, int contents)
方块值的最低10位,替换为目标Content
const int LightShift
virtual TerrainChunk GetChunkAtCoords(Point2 p)
virtual void SetTopHeight(int x, int z, int topHeight)
virtual int GetCellLightFast(Point3 p)
static int MakeBlockValue(int contents)
static int ExtractData(int value)
virtual int CalculateTopmostCellHeight(int x, int z)
const int HumidityShift
virtual void SetTemperature(Point2 p, int temperature)
virtual void SetBottomHeight(int x, int z, int bottomHeight)
virtual int GetTemperature(int x, int z)
ChunksStorage m_allChunks
static Point3 ToCell(float x, float y, float z)