Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
TerrainBrush.cs
浏览该文件的文档.
1using Engine;
2
3namespace Game {
4 public class TerrainBrush {
5 public struct Cell : IComparable<Cell> {
6 public sbyte X;
7
8 public sbyte Y;
9
10 public sbyte Z;
11
12 public int Value;
13
14 public int CompareTo(Cell other) => Key(X, Y, Z) - Key(other.X, other.Y, other.Z);
15 }
16
17 public class Brush {
18 public int m_value;
19
20 public Func<int?, int?> m_handler1;
21
22 public Func<Point3, int?> m_handler2;
23
24 public static implicit operator Brush(int value) => new() { m_value = value };
25
26 public static implicit operator Brush(Func<int?, int?> handler) => new() { m_handler1 = handler };
27
28 public static implicit operator Brush(Func<Point3, int?> handler) => new() { m_handler2 = handler };
29
30 public int? Paint(TerrainBrush terrainBrush, Point3 p) {
31 if (m_handler1 != null) {
32 return m_handler1(terrainBrush.GetValue(p.X, p.Y, p.Z));
33 }
34 if (m_handler2 != null) {
35 return m_handler2(p);
36 }
37 return m_value;
38 }
39 }
40
41 public class Counter {
42 public int m_value;
43
44 public Func<int?, int> m_handler1;
45
46 public Func<Point3, int> m_handler2;
47
48 public static implicit operator Counter(int value) => new() { m_value = value };
49
50 public static implicit operator Counter(Func<int?, int> handler) => new() { m_handler1 = handler };
51
52 public static implicit operator Counter(Func<Point3, int> handler) => new() { m_handler2 = handler };
53
54 public int Count(TerrainBrush terrainBrush, Point3 p) {
55 if (m_handler1 != null) {
56 return m_handler1(terrainBrush.GetValue(p));
57 }
58 if (m_handler2 != null) {
59 return m_handler2(p);
60 }
61 if (terrainBrush.GetValue(p) != m_value) {
62 return 0;
63 }
64 return 1;
65 }
66 }
67
68 public Dictionary<int, Cell> m_cellsDictionary = [];
69
70 public Cell[] m_cells;
71
72 public Cell[] Cells => m_cells;
73
74 public static int Key(int x, int y, int z) => y + 128 + ((x + 128) << 8) + ((z + 128) << 16);
75
76 public void Compile() {
77 m_cells = new Cell[m_cellsDictionary.Values.Count];
78 int num = 0;
79 foreach (Cell value in m_cellsDictionary.Values) {
80 m_cells[num++] = value;
81 }
82 Array.Sort(m_cells);
83 m_cellsDictionary = null;
84 }
85
86 public int CountNonDiagonalNeighbors(int x, int y, int z, Counter counter) => 0
87 + counter.Count(this, new Point3(x - 1, y, z))
88 + counter.Count(this, new Point3(x + 1, y, z))
89 + counter.Count(this, new Point3(x, y - 1, z))
90 + counter.Count(this, new Point3(x, y + 1, z))
91 + counter.Count(this, new Point3(x, y, z - 1))
92 + counter.Count(this, new Point3(x, y, z + 1));
93
94 public int CountBox(int x,
95 int y,
96 int z,
97 int sizeX,
98 int sizeY,
99 int sizeZ,
100 Counter counter) {
101 int num = 0;
102 for (int i = x; i < x + sizeX; i++) {
103 for (int j = y; j < y + sizeY; j++) {
104 for (int k = z; k < z + sizeZ; k++) {
105 num += counter.Count(this, new Point3(i, j, k));
106 }
107 }
108 }
109 return num;
110 }
111
112 public void Replace(int oldValue, int newValue) {
113 Dictionary<int, Cell> dictionary = new();
114 foreach (KeyValuePair<int, Cell> item in m_cellsDictionary) {
115 Cell value = item.Value;
116 if (value.Value == oldValue) {
117 value.Value = newValue;
118 }
119 dictionary[item.Key] = value;
120 }
121 m_cellsDictionary = dictionary;
122 m_cells = null;
123 }
124
125 public void CalculateBounds(out Point3 min, out Point3 max) {
126 min = Point3.Zero;
127 max = Point3.Zero;
128 bool flag = true;
129 foreach (Cell value in m_cellsDictionary.Values) {
130 if (flag) {
131 flag = false;
132 min.X = max.X = value.X;
133 min.Y = max.Y = value.Y;
134 min.Z = max.Z = value.Z;
135 }
136 else {
137 min.X = MathUtils.Min(min.X, value.X);
138 min.Y = MathUtils.Min(min.Y, value.Y);
139 min.Z = MathUtils.Min(min.Z, value.Z);
140 max.X = MathUtils.Max(max.X, value.X);
141 max.Y = MathUtils.Max(max.Y, value.Y);
142 max.Z = MathUtils.Max(max.Z, value.Z);
143 }
144 }
145 }
146
147 public int? GetValue(Point3 p) => GetValue(p.X, p.Y, p.Z);
148
149 public int? GetValue(int x, int y, int z) {
150 int key = Key(x, y, z);
151 if (m_cellsDictionary.TryGetValue(key, out Cell value)) {
152 return value.Value;
153 }
154 return null;
155 }
156
157 public void AddCell(int x, int y, int z, Brush brush) {
158 int? num = brush.Paint(this, new Point3(x, y, z));
159 if (num.HasValue) {
160 int key = Key(x, y, z);
161 m_cellsDictionary[key] = new Cell { X = (sbyte)x, Y = (sbyte)y, Z = (sbyte)z, Value = num.Value };
162 m_cells = null;
163 }
164 }
165
166 public void AddBox(int x,
167 int y,
168 int z,
169 int sizeX,
170 int sizeY,
171 int sizeZ,
172 Brush brush) {
173 for (int i = x; i < x + sizeX; i++) {
174 for (int j = y; j < y + sizeY; j++) {
175 for (int k = z; k < z + sizeZ; k++) {
176 AddCell(i, j, k, brush);
177 }
178 }
179 }
180 }
181
182 public void AddRay(int x1,
183 int y1,
184 int z1,
185 int x2,
186 int y2,
187 int z2,
188 int sizeX,
189 int sizeY,
190 int sizeZ,
191 Brush brush) {
192 Vector3 vector = new Vector3(x1, y1, z1) + new Vector3(0.5f);
193 Vector3 vector2 = new Vector3(x2, y2, z2) + new Vector3(0.5f);
194 Vector3 vector3 = 0.33f * Vector3.Normalize(vector2 - vector);
195 int num = (int)MathF.Round(3f * Vector3.Distance(vector, vector2));
196 Vector3 vector4 = vector;
197 for (int i = 0; i < num; i++) {
198 int x3 = Terrain.ToCell(vector4.X);
199 int y3 = Terrain.ToCell(vector4.Y);
200 int z3 = Terrain.ToCell(vector4.Z);
201 AddBox(
202 x3,
203 y3,
204 z3,
205 sizeX,
206 sizeY,
207 sizeZ,
208 brush
209 );
210 vector4 += vector3;
211 }
212 }
213
214 public void PaintFastSelective(TerrainChunk chunk, int x, int y, int z, int onlyInValue) {
215 x -= chunk.Origin.X;
216 z -= chunk.Origin.Y;
217 Cell[] cells = Cells;
218 for (int i = 0; i < cells.Length; i++) {
219 Cell cell = cells[i];
220 int num = cell.X + x;
221 int num2 = cell.Y + y;
222 int num3 = cell.Z + z;
223 if (num >= 0
224 && num < TerrainChunk.Size
225 && num2 >= 0
226 && num2 < TerrainChunk.Height
227 && num3 >= 0
228 && num3 < TerrainChunk.Size) {
229 int index = TerrainChunk.CalculateCellIndex(num, num2, num3);
230 int cellValueFast = chunk.GetCellValueFast(index);
231 if (onlyInValue == cellValueFast) {
232 chunk.SetCellValueFast(index, cell.Value);
233 }
234 }
235 }
236 }
237
238 public void PaintFastSelective(Terrain terrain,
239 int x,
240 int y,
241 int z,
242 int minX,
243 int maxX,
244 int minY,
245 int maxY,
246 int minZ,
247 int maxZ,
248 int onlyInValue) {
249 Cell[] cells = Cells;
250 for (int i = 0; i < cells.Length; i++) {
251 Cell cell = cells[i];
252 int num = cell.X + x;
253 int num2 = cell.Y + y;
254 int num3 = cell.Z + z;
255 if (num >= minX
256 && num < maxX
257 && num2 >= minY
258 && num2 < maxY
259 && num3 >= minZ
260 && num3 < maxZ) {
261 int cellValueFast = terrain.GetCellValueFast(num, num2, num3);
262 if (onlyInValue == cellValueFast) {
263 terrain.SetCellValueFast(num, num2, num3, cell.Value);
264 }
265 }
266 }
267 }
268
269 public void PaintFastAvoidWater(TerrainChunk chunk, int x, int y, int z) {
270 Terrain terrain = chunk.Terrain;
271 x -= chunk.Origin.X;
272 z -= chunk.Origin.Y;
273 Cell[] cells = Cells;
274 for (int i = 0; i < cells.Length; i++) {
275 Cell cell = cells[i];
276 int num = cell.X + x;
277 int num2 = cell.Y + y;
278 int num3 = cell.Z + z;
279 if (num >= 0
280 && num < TerrainChunk.Size
281 && num2 >= 0
282 && num2 < TerrainChunk.Height
283 && num3 >= 0
284 && num3 < TerrainChunk.Size) {
285 int num4 = num + chunk.Origin.X;
286 int y2 = num2;
287 int num5 = num3 + chunk.Origin.Y;
288 if (chunk.GetCellContentsFast(num, num2, num3) != 18
289 && terrain.GetCellContents(num4 - 1, y2, num5) != 18
290 && terrain.GetCellContents(num4 + 1, y2, num5) != 18
291 && terrain.GetCellContents(num4, y2, num5 - 1) != 18
292 && terrain.GetCellContents(num4, y2, num5 + 1) != 18
293 && chunk.GetCellContentsFast(num, num2 + 1, num3) != 18) {
294 chunk.SetCellValueFast(num, num2, num3, cell.Value);
295 }
296 }
297 }
298 }
299
300 public void PaintFastAvoidWater(Terrain terrain,
301 int x,
302 int y,
303 int z,
304 int minX,
305 int maxX,
306 int minY,
307 int maxY,
308 int minZ,
309 int maxZ) {
310 Cell[] cells = Cells;
311 for (int i = 0; i < cells.Length; i++) {
312 Cell cell = cells[i];
313 int num = cell.X + x;
314 int num2 = cell.Y + y;
315 int num3 = cell.Z + z;
316 if (num >= minX
317 && num < maxX
318 && num2 >= minY
319 && num2 < maxY
320 && num3 >= minZ
321 && num3 < maxZ
322 && terrain.GetCellContentsFast(num, num2, num3) != 18
323 && terrain.GetCellContents(num - 1, num2, num3) != 18
324 && terrain.GetCellContents(num + 1, num2, num3) != 18
325 && terrain.GetCellContents(num, num2, num3 - 1) != 18
326 && terrain.GetCellContents(num, num2, num3 + 1) != 18
327 && terrain.GetCellContentsFast(num, num2 + 1, num3) != 18) {
328 terrain.SetCellValueFast(num, num2, num3, cell.Value);
329 }
330 }
331 }
332
333 public void PaintFast(TerrainChunk chunk, int x, int y, int z) {
334 x -= chunk.Origin.X;
335 z -= chunk.Origin.Y;
336 Cell[] cells = Cells;
337 for (int i = 0; i < cells.Length; i++) {
338 Cell cell = cells[i];
339 int num = cell.X + x;
340 int num2 = cell.Y + y;
341 int num3 = cell.Z + z;
342 if (num >= 0
343 && num < TerrainChunk.Size
344 && num2 >= 0
345 && num2 < TerrainChunk.Height
346 && num3 >= 0
347 && num3 < TerrainChunk.Size) {
348 chunk.SetCellValueFast(num, num2, num3, cell.Value);
349 }
350 }
351 }
352
353 public void PaintFast(Terrain terrain,
354 int x,
355 int y,
356 int z,
357 int minX,
358 int maxX,
359 int minY,
360 int maxY,
361 int minZ,
362 int maxZ) {
363 Cell[] cells = Cells;
364 for (int i = 0; i < cells.Length; i++) {
365 Cell cell = cells[i];
366 int num = cell.X + x;
367 int num2 = cell.Y + y;
368 int num3 = cell.Z + z;
369 if (num >= minX
370 && num < maxX
371 && num2 >= minY
372 && num2 < maxY
373 && num3 >= minZ
374 && num3 < maxZ) {
375 terrain.SetCellValueFast(num, num2, num3, cell.Value);
376 }
377 }
378 }
379
380 public void Paint(SubsystemTerrain terrain, int x, int y, int z) {
381 Cell[] cells = Cells;
382 for (int i = 0; i < cells.Length; i++) {
383 Cell cell = cells[i];
384 int x2 = cell.X + x;
385 int y2 = cell.Y + y;
386 int z2 = cell.Z + z;
387 terrain.ChangeCell(x2, y2, z2, cell.Value);
388 }
389 }
390 }
391}
Engine.Vector3 Vector3
static int Min(int x1, int x2)
static int Max(int x1, int x2)
virtual void ChangeCell(int x, int y, int z, int value, bool updateModificationCounter=true, MovingBlock movingBlock=null)
Func< Point3, int?> m_handler2
Func< int?, int?> m_handler1
int? Paint(TerrainBrush terrainBrush, Point3 p)
int Count(TerrainBrush terrainBrush, Point3 p)
Func< Point3, int > m_handler2
int CountBox(int x, int y, int z, int sizeX, int sizeY, int sizeZ, Counter counter)
void PaintFast(TerrainChunk chunk, int x, int y, int z)
void Paint(SubsystemTerrain terrain, int x, int y, int z)
void PaintFast(Terrain terrain, int x, int y, int z, int minX, int maxX, int minY, int maxY, int minZ, int maxZ)
void PaintFastSelective(Terrain terrain, int x, int y, int z, int minX, int maxX, int minY, int maxY, int minZ, int maxZ, int onlyInValue)
void PaintFastAvoidWater(Terrain terrain, int x, int y, int z, int minX, int maxX, int minY, int maxY, int minZ, int maxZ)
Dictionary< int, Cell > m_cellsDictionary
void CalculateBounds(out Point3 min, out Point3 max)
void Replace(int oldValue, int newValue)
void AddBox(int x, int y, int z, int sizeX, int sizeY, int sizeZ, Brush brush)
int? GetValue(int x, int y, int z)
int CountNonDiagonalNeighbors(int x, int y, int z, Counter counter)
void PaintFastAvoidWater(TerrainChunk chunk, int x, int y, int z)
void AddCell(int x, int y, int z, Brush brush)
void PaintFastSelective(TerrainChunk chunk, int x, int y, int z, int onlyInValue)
static int Key(int x, int y, int z)
void AddRay(int x1, int y1, int z1, int x2, int y2, int z2, int sizeX, int sizeY, int sizeZ, Brush brush)
int? GetValue(Point3 p)
static int CalculateCellIndex(int x, int y, int z)
virtual int GetCellValueFast(int index)
virtual void SetCellValueFast(int x, int y, int z, int value)
virtual int GetCellContentsFast(int x, int y, int z)
virtual int GetCellValueFast(int x, int y, int z)
virtual void SetCellValueFast(int x, int y, int z, int value)
static int ToCell(float x)
virtual int GetCellContents(int x, int y, int z)
virtual int GetCellContentsFast(int x, int y, int z)
static readonly Point3 Zero
static Vector3 Round(Vector3 v)
static Vector3 Normalize(Vector3 v)
static float Distance(Vector3 v1, Vector3 v2)