Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
SubsystemMovingBlocks.cs
浏览该文件的文档.
1using System.Globalization;
2using System.Text;
3using Engine;
8
9namespace Game {
11 public class MovingBlockSet : IMovingBlockSet, IDisposable {
12 public string Id;
13
14 public object Tag;
15
16 public bool Stop;
17
18 public int RemainCounter;
19
21
23
25
26 public float Speed;
27
28 public float Acceleration;
29
30 public float Drag;
31
33
34 public List<MovingBlock> Blocks;
35
36 public Box Box;
37
39
41
42 public Point3 GeometryGenerationPosition = new(int.MaxValue);
43
45
47
49
52 List<MovingBlock> IMovingBlockSet.Blocks => Blocks;
53
55
56 public void Dispose() {
57 Geometry.ClearGeometry();
58 }
59
60 public virtual void UpdateBox() {
61 Point3? point = null;
62 Point3? point2 = null;
63 foreach (MovingBlock block in Blocks) {
64 point = point.HasValue ? Point3.Min(point.Value, block.Offset) : block.Offset;
65 point2 = point2.HasValue ? Point3.Max(point2.Value, block.Offset) : block.Offset;
66 }
67 if (point.HasValue) {
68 Box = new Box(
69 point.Value.X,
70 point.Value.Y,
71 point.Value.Z,
72 point2.Value.X - point.Value.X + 1,
73 point2.Value.Y - point.Value.Y + 1,
74 point2.Value.Z - point.Value.Z + 1
75 );
76 }
77 else {
78 Box = default;
79 }
80 }
81
82 public BoundingBox BoundingBox(bool extendToFillCells) {
83 Vector3 min = new(Position.X + Box.Left, Position.Y + Box.Top, Position.Z + Box.Near);
84 Vector3 max = new(Position.X + Box.Right, Position.Y + Box.Bottom, Position.Z + Box.Far);
85 if (extendToFillCells) {
86 min.X = MathF.Floor(min.X);
87 min.Y = MathF.Floor(min.Y);
88 min.Z = MathF.Floor(min.Z);
89 max.X = MathF.Ceiling(max.X);
90 max.Y = MathF.Ceiling(max.Y);
91 max.Z = MathF.Ceiling(max.Z);
92 }
93 return new BoundingBox(min, max);
94 }
95
96 void IMovingBlockSet.SetBlock(Point3 offset, int value) {
97 Blocks.RemoveAll(b => b.Offset == offset);
98 if (value != 0) {
99 Blocks.Add(new MovingBlock { Offset = offset, Value = value });
100 }
101 UpdateBox();
102 GeometryGenerationPosition = new Point3(int.MaxValue);
103 }
104
106 Stop = true;
107 }
108 }
109
111
113
115
117
118 public List<MovingBlockSet> m_movingBlockSets = [];
119
120 public List<MovingBlockSet> m_stopped = [];
121
122 public List<MovingBlockSet> m_removing = [];
123
124 public DynamicArray<TerrainChunkGeometry.Buffer> Buffers;
125
126 public DynamicArray<IMovingBlockSet> m_result = [];
127 public static DynamicArray<int> m_tmpIndices = [];
128 public static DynamicArray<TerrainVertex> m_vertexList = [];
130
132
134
135 public static int[] m_drawOrders = [10];
136
137 public List<IMovingBlockSet> MovingBlockSets => [..m_movingBlockSets];
138
140
141 public int[] DrawOrders => m_drawOrders;
142
143 public event Action<IMovingBlockSet, Point3> CollidedWithTerrain;
144
145 public event Action<IMovingBlockSet> Stopped;
146
147 public bool m_noDropOnMovingBlockStopped = false;
148
150 Vector3 targetPosition,
151 float speed,
152 float acceleration,
153 float drag,
154 Vector2 smoothness,
155 IEnumerable<MovingBlock> blocks,
156 string id,
157 object tag,
158 bool testCollision) {
159 MovingBlockSet movingBlockSet = new() {
160 Position = position,
161 StartPosition = position,
162 TargetPosition = targetPosition,
163 Speed = speed,
164 Acceleration = acceleration,
165 Drag = drag,
166 Smoothness = smoothness,
167 Id = id,
168 Tag = tag,
169 Blocks = blocks.ToList(),
170 Geometry = new TerrainGeometry(m_subsystemAnimatedTextures.AnimatedBlocksTexture)
171 };
172 for (int i = 0; i < movingBlockSet.Blocks.Count; i++) {
173 movingBlockSet.Blocks[i].MovingBlockSet = movingBlockSet;
174 }
175 movingBlockSet.UpdateBox();
176 bool canAdd = true;
178 "OnMovingBlockSetAdded",
179 loader => {
180 loader.OnMovingBlockSetAdded(ref movingBlockSet, this, ref testCollision, out bool doNotAdd);
181 canAdd &= !doNotAdd;
182 return false;
183 }
184 );
185 if (!canAdd) {
186 return null;
187 }
188 if (testCollision) {
189 MovingBlocksCollision(movingBlockSet);
190 if (movingBlockSet.Stop) {
191 return null;
192 }
193 }
195 GenerateGeometry(movingBlockSet);
196 }
197 m_movingBlockSets.Add(movingBlockSet);
198 return movingBlockSet;
199 }
200
201 public void RemoveMovingBlockSet(IMovingBlockSet movingBlockSet) {
202 MovingBlockSet movingBlockSet2 = (MovingBlockSet)movingBlockSet;
203 if (m_movingBlockSets.Remove(movingBlockSet2)) {
204 m_removing.Add(movingBlockSet2);
206 "OnMovingBlockSetRemoved",
207 loader => {
208 loader.OnMovingBlockSetRemoved(movingBlockSet2, this);
209 return false;
210 }
211 );
212 movingBlockSet2.RemainCounter = 4;
213 }
214 }
215
216 public void FindMovingBlocks(BoundingBox boundingBox, bool extendToFillCells, DynamicArray<IMovingBlockSet> result) {
217 foreach (MovingBlockSet movingBlockSet in m_movingBlockSets) {
218 if (!movingBlockSet.Stop
219 && ExclusiveBoxIntersection(boundingBox, movingBlockSet.BoundingBox(extendToFillCells))) {
220 result.Add(movingBlockSet);
221 }
222 }
223 }
224
225 public IMovingBlockSet FindMovingBlocks(string id, object tag) {
226 foreach (MovingBlockSet movingBlockSet in m_movingBlockSets) {
227 if (movingBlockSet.Id == id
228 && Equals(movingBlockSet.Tag, tag)) {
229 return movingBlockSet;
230 }
231 }
232 return null;
233 }
234
235 public MovingBlocksRaycastResult? Raycast(Vector3 start, Vector3 end, bool extendToFillCells, Func<int, float, bool> action = null) {
236 Ray3 ray = new(start, Vector3.Normalize(end - start));
237 BoundingBox boundingBox = new(Vector3.Min(start, end), Vector3.Max(start, end));
238 m_result.Clear();
239 FindMovingBlocks(boundingBox, extendToFillCells, m_result);
240 float num = float.MaxValue;
241 MovingBlockSet movingBlockSet = null;
242 try {
243 foreach (IMovingBlockSet item in m_result.Array) {
244 if (item is not MovingBlockSet item1
245 || item1.Stop) {
246 continue;
247 }
248 BoundingBox box = item.BoundingBox(extendToFillCells);
249 float? num2 = ray.Intersection(box);
250 if (num2.HasValue
251 && num2.Value < num) {
252 num = num2.Value;
253 movingBlockSet = item1;
254 }
255 }
256 }
257 catch (Exception e) {
258 Log.Error($"Moving Blocks raycast error{e}");
259 }
260 if (movingBlockSet != null) {
261 float distance = float.MaxValue;
262 MovingBlock rightMovingBlock = null;
263 int rightCollisionBoxIndex = -1;
264 BoundingBox? rightNearestBox = null;
265 foreach (MovingBlock movingBlock in movingBlockSet.Blocks) {
266 int blockValue = movingBlock.Value;
267 Block block = BlocksManager.Blocks[Terrain.ExtractContents(blockValue)];
268 Ray3 equalRay = new(
269 ray.Position - movingBlockSet.Position - new Vector3(movingBlock.Offset.X, movingBlock.Offset.Y, movingBlock.Offset.Z),
270 ray.Direction
271 );
272 float? dist = block.Raycast(
273 equalRay,
275 blockValue,
276 true,
277 out int collisionBoxIndex,
278 out BoundingBox nearestBox
279 );
280 if (dist.HasValue
281 && dist.Value < distance
282 && (action == null || action(blockValue, dist.Value))) {
283 distance = dist.Value;
284 rightMovingBlock = movingBlock;
285 rightCollisionBoxIndex = collisionBoxIndex;
286 rightNearestBox = nearestBox;
287 }
288 }
289 MovingBlocksRaycastResult value = default;
290 value.Ray = ray;
291 value.Distance = distance == float.MaxValue ? num : distance;
292 value.MovingBlockSet = movingBlockSet;
293 value.MovingBlock = rightMovingBlock;
294 value.CollisionBoxIndex = rightCollisionBoxIndex;
295 value.BlockBoundingBox = rightNearestBox;
296 return value;
297 }
298 return null;
299 }
300
301 public virtual void Update(float dt) {
303 foreach (MovingBlockSet movingBlockSet in m_movingBlockSets) {
304 bool pass = false;
306 "OnMovingBlockSetUpdate",
307 loader => {
308 loader.OnMovingBlockSetUpdate(movingBlockSet, this, pass, out bool skipVanilla);
309 pass |= skipVanilla;
310 return false;
311 }
312 );
313 if (pass) {
314 continue;
315 }
316 TerrainChunk chunkAtCell = m_subsystemTerrain.Terrain.GetChunkAtCell(
317 Terrain.ToCell(movingBlockSet.Position.X),
318 Terrain.ToCell(movingBlockSet.Position.Z)
319 );
320 if (chunkAtCell == null
321 || chunkAtCell.State <= TerrainChunkState.InvalidContents4) {
322 continue;
323 }
324 movingBlockSet.Speed += movingBlockSet.Acceleration * m_subsystemTime.GameTimeDelta;
325 if (movingBlockSet.Drag != 0f) {
326 movingBlockSet.Speed *= MathF.Pow(1f - movingBlockSet.Drag, m_subsystemTime.GameTimeDelta);
327 }
328 float x = Vector3.Distance(movingBlockSet.StartPosition, movingBlockSet.Position);
329 float num = Vector3.Distance(movingBlockSet.TargetPosition, movingBlockSet.Position);
330 float num2 = movingBlockSet.Smoothness.X > 0f ? MathUtils.Saturate((MathF.Sqrt(x) + 0.05f) / movingBlockSet.Smoothness.X) : 1f;
331 float num3 = movingBlockSet.Smoothness.Y > 0f ? MathUtils.Saturate((num + 0.05f) / movingBlockSet.Smoothness.Y) : 1f;
332 float num4 = num2 * num3;
333 bool flag = false;
334 Vector3 vector = num > 0f ? (movingBlockSet.TargetPosition - movingBlockSet.Position) / num : Vector3.Zero;
335 float x2 = m_subsystemTime.GameTimeDelta > 0f ? 0.95f / m_subsystemTime.GameTimeDelta : 0f;
336 float num5 = MathUtils.Min(movingBlockSet.Speed * num4, x2);
337 if (num5 * m_subsystemTime.GameTimeDelta >= num) {
338 movingBlockSet.Position = movingBlockSet.TargetPosition;
339 movingBlockSet.CurrentVelocity = Vector3.Zero;
340 flag = true;
341 }
342 else {
343 movingBlockSet.CurrentVelocity = num5 / num * (movingBlockSet.TargetPosition - movingBlockSet.Position);
344 movingBlockSet.Position += movingBlockSet.CurrentVelocity * m_subsystemTime.GameTimeDelta;
345 }
346 movingBlockSet.Stop = false;
347 MovingBlocksCollision(movingBlockSet);
348 TerrainCollision(movingBlockSet);
349 if (movingBlockSet.Stop) {
350 if (vector.X < 0f) {
351 movingBlockSet.Position.X = MathF.Ceiling(movingBlockSet.Position.X);
352 }
353 else if (vector.X > 0f) {
354 movingBlockSet.Position.X = MathF.Floor(movingBlockSet.Position.X);
355 }
356 if (vector.Y < 0f) {
357 movingBlockSet.Position.Y = MathF.Ceiling(movingBlockSet.Position.Y);
358 }
359 else if (vector.Y > 0f) {
360 movingBlockSet.Position.Y = MathF.Floor(movingBlockSet.Position.Y);
361 }
362 if (vector.Z < 0f) {
363 movingBlockSet.Position.Z = MathF.Ceiling(movingBlockSet.Position.Z);
364 }
365 else if (vector.Z > 0f) {
366 movingBlockSet.Position.Z = MathF.Floor(movingBlockSet.Position.Z);
367 }
368 }
369 if (movingBlockSet.Stop || flag) {
370 m_stopped.Add(movingBlockSet);
371 }
372 }
373 foreach (MovingBlockSet item in m_stopped) {
374 Stopped?.Invoke(item);
375 }
376 m_stopped.Clear();
377 }
378
379 public virtual void Draw(Camera camera, int drawOrder) {
380 foreach (TerrainChunkGeometry.Buffer buffer in Buffers) {
381 buffer.Dispose();
382 }
383 Buffers.Clear();
384 foreach (MovingBlockSet movingBlockSet2 in m_movingBlockSets) {
385 DrawMovingBlockSet(camera, movingBlockSet2);
386 }
387 int num = 0;
388 while (num < m_removing.Count) {
389 MovingBlockSet movingBlockSet = m_removing[num];
390 if (movingBlockSet.RemainCounter-- > 0) {
391 DrawMovingBlockSet(camera, movingBlockSet);
392 num++;
393 }
394 else {
395 m_removing.RemoveAt(num);
396 movingBlockSet.Dispose();
397 }
398 }
399 for (int i = 0; i < Buffers.Count; i++) {
401 Vector3 viewPosition = camera.ViewPosition;
402 Vector3 vector = new(MathF.Floor(viewPosition.X), 0f, MathF.Floor(viewPosition.Z));
403 Matrix value = Matrix.CreateTranslation(vector - viewPosition) * camera.ViewMatrix.OrientationMatrix * camera.ProjectionMatrix;
404 Display.BlendState = BlendState.AlphaBlend;
405 Display.DepthStencilState = DepthStencilState.Default;
406 Display.RasterizerState = RasterizerState.CullCounterClockwiseScissor;
407 m_shader.GetParameter("u_origin").SetValue(vector.XZ);
408 m_shader.GetParameter("u_viewProjectionMatrix").SetValue(value);
409 m_shader.GetParameter("u_viewPosition").SetValue(camera.ViewPosition);
410 m_shader.GetParameter("u_texture").SetValue(buffer.Texture);
411 m_shader.GetParameter("u_samplerState").SetValue(SamplerState.PointClamp);
412 m_shader.GetParameter("u_fogYMultiplier").SetValue(m_subsystemSky.VisibilityRangeYMultiplier);
413 m_shader.GetParameter("u_fogColor").SetValue(new Vector3(m_subsystemSky.ViewFogColor));
414 m_shader.GetParameter("u_fogBottomTopDensity")
415 .SetValue(new Vector3(m_subsystemSky.ViewFogBottom, m_subsystemSky.ViewFogTop, m_subsystemSky.ViewFogDensity));
416 m_shader.GetParameter("u_hazeStartDensity").SetValue(new Vector2(m_subsystemSky.ViewHazeStart, m_subsystemSky.ViewHazeDensity));
417 m_shader.GetParameter("u_alphaThreshold").SetValue(0.5f);
419 PrimitiveType.TriangleList,
420 m_shader,
421 buffer.VertexBuffer,
422 buffer.IndexBuffer,
423 0,
424 buffer.IndexBuffer.IndicesCount
425 );
426 }
427 }
428
429 public override void Load(ValuesDictionary valuesDictionary) {
430 m_subsystemTime = Project.FindSubsystem<SubsystemTime>(true);
431 m_subsystemTerrain = Project.FindSubsystem<SubsystemTerrain>(true);
432 m_subsystemSky = Project.FindSubsystem<SubsystemSky>(true);
434 m_shader = ContentManager.Get<Shader>("Shaders/AlphaTested");
435 Buffers = [];
436 foreach (ValuesDictionary value9 in valuesDictionary.GetValue<ValuesDictionary>("MovingBlockSets").Values) {
437 Vector3 value = value9.GetValue<Vector3>("Position");
438 Vector3 value2 = value9.GetValue<Vector3>("TargetPosition");
439 float value3 = value9.GetValue<float>("Speed");
440 float value4 = value9.GetValue<float>("Acceleration");
441 float value5 = value9.GetValue<float>("Drag");
442 Vector2 value6 = value9.GetValue("Smoothness", Vector2.Zero);
443 string value7 = value9.GetValue<string>("Id", null);
444 object value8 = value9.GetValue<object>("Tag", null);
445 List<MovingBlock> list = [];
446 string[] array = value9.GetValue<string>("Blocks").Split([';'], StringSplitOptions.RemoveEmptyEntries);
447 foreach (string obj2 in array) {
448 MovingBlock item = new();
449 string[] array2 = obj2.Split([','], StringSplitOptions.RemoveEmptyEntries);
450 item.Value = HumanReadableConverter.ConvertFromString<int>(array2[0]);
451 item.Offset.X = HumanReadableConverter.ConvertFromString<int>(array2[1]);
452 item.Offset.Y = HumanReadableConverter.ConvertFromString<int>(array2[2]);
453 item.Offset.Z = HumanReadableConverter.ConvertFromString<int>(array2[3]);
454 list.Add(item);
455 }
457 value,
458 value2,
459 value3,
460 value4,
461 value5,
462 value6,
463 list,
464 value7,
465 value8,
466 false
467 );
468 }
469 }
470
471 public override void Save(ValuesDictionary valuesDictionary) {
472 ValuesDictionary valuesDictionary2 = [];
473 valuesDictionary.SetValue("MovingBlockSets", valuesDictionary2);
474 int num = 0;
475 foreach (MovingBlockSet movingBlockSet in m_movingBlockSets) {
476 ValuesDictionary valuesDictionary3 = [];
477 valuesDictionary2.SetValue(num.ToString(CultureInfo.InvariantCulture), valuesDictionary3);
478 valuesDictionary3.SetValue("Position", movingBlockSet.Position);
479 valuesDictionary3.SetValue("TargetPosition", movingBlockSet.TargetPosition);
480 valuesDictionary3.SetValue("Speed", movingBlockSet.Speed);
481 valuesDictionary3.SetValue("Acceleration", movingBlockSet.Acceleration);
482 valuesDictionary3.SetValue("Drag", movingBlockSet.Drag);
483 if (movingBlockSet.Smoothness != Vector2.Zero) {
484 valuesDictionary3.SetValue("Smoothness", movingBlockSet.Smoothness);
485 }
486 if (movingBlockSet.Id != null) {
487 valuesDictionary3.SetValue("Id", movingBlockSet.Id);
488 }
489 if (movingBlockSet.Tag != null) {
490 valuesDictionary3.SetValue("Tag", movingBlockSet.Tag);
491 }
492 StringBuilder stringBuilder = new();
493 foreach (MovingBlock block in movingBlockSet.Blocks) {
494 stringBuilder.Append(HumanReadableConverter.ConvertToString(block.Value));
495 stringBuilder.Append(',');
496 stringBuilder.Append(HumanReadableConverter.ConvertToString(block.Offset.X));
497 stringBuilder.Append(',');
498 stringBuilder.Append(HumanReadableConverter.ConvertToString(block.Offset.Y));
499 stringBuilder.Append(',');
500 stringBuilder.Append(HumanReadableConverter.ConvertToString(block.Offset.Z));
501 stringBuilder.Append(';');
502 }
503 valuesDictionary3.SetValue("Blocks", stringBuilder.ToString());
504 num++;
505 }
506 }
507
508 public override void Dispose() {
509 if (m_blockGeometryGenerator != null
510 && m_blockGeometryGenerator.Terrain != null) {
511 m_blockGeometryGenerator.Terrain.Dispose();
512 }
513 foreach (MovingBlockSet movingBlockSet in m_movingBlockSets) {
514 movingBlockSet.Dispose();
515 }
516 foreach (MovingBlockSet item in m_removing) {
517 item.Dispose();
518 }
519 }
520
521 public void MovingBlocksCollision(MovingBlockSet movingBlockSet) {
522 BoundingBox boundingBox = movingBlockSet.BoundingBox(true);
523 m_result.Clear();
524 FindMovingBlocks(boundingBox, true, m_result);
525 for (int i = 0; i < m_result.Count; i++) {
526 if (m_result.Array[i] != movingBlockSet) {
527 movingBlockSet.Stop = true;
528 break;
529 }
530 }
531 }
532
533 public void TerrainCollision(MovingBlockSet movingBlockSet) {
534 Point3 point = default;
535 point.X = (int)MathF.Floor(movingBlockSet.Box.Left + movingBlockSet.Position.X);
536 point.Y = (int)MathF.Floor(movingBlockSet.Box.Top + movingBlockSet.Position.Y);
537 point.Z = (int)MathF.Floor(movingBlockSet.Box.Near + movingBlockSet.Position.Z);
538 Point3 point2 = default;
539 point2.X = (int)MathF.Ceiling(movingBlockSet.Box.Right + movingBlockSet.Position.X);
540 point2.Y = (int)MathF.Ceiling(movingBlockSet.Box.Bottom + movingBlockSet.Position.Y);
541 point2.Z = (int)MathF.Ceiling(movingBlockSet.Box.Far + movingBlockSet.Position.Z);
542 for (int i = point.X; i < point2.X; i++) {
543 for (int j = point.Z; j < point2.Z; j++) {
544 for (int k = point.Y; k < point2.Y; k++) {
545 if (Terrain.ExtractContents(m_subsystemTerrain.Terrain.GetCellValue(i, k, j)) != 0) {
546 CollidedWithTerrain?.Invoke(movingBlockSet, new Point3(i, k, j));
547 }
548 }
549 }
550 }
551 }
552
553 public void GenerateGeometry(MovingBlockSet movingBlockSet) {
554 Point3 point = default;
555 point.X = movingBlockSet.CurrentVelocity.X > 0f
556 ? (int)MathF.Floor(movingBlockSet.Position.X)
557 : (int)MathF.Ceiling(movingBlockSet.Position.X);
558 point.Y = movingBlockSet.CurrentVelocity.Y > 0f
559 ? (int)MathF.Floor(movingBlockSet.Position.Y)
560 : (int)MathF.Ceiling(movingBlockSet.Position.Y);
561 point.Z = movingBlockSet.CurrentVelocity.Z > 0f
562 ? (int)MathF.Floor(movingBlockSet.Position.Z)
563 : (int)MathF.Ceiling(movingBlockSet.Position.Z);
564 if (!(point != movingBlockSet.GeometryGenerationPosition)) {
565 return;
566 }
567 Point3 p = new(movingBlockSet.Box.Left, movingBlockSet.Box.Top, movingBlockSet.Box.Near);
568 Point3 point2 = new(movingBlockSet.Box.Width, movingBlockSet.Box.Height, movingBlockSet.Box.Depth);
569 int num = point.Y + p.Y;
570 point2.Y = MathUtils.Min(point2.Y, 254);
571 if (m_blockGeometryGenerator == null) {
572 int x = 2;
573 x = (int)MathUtils.NextPowerOf2((uint)x);
575 new Terrain(),
577 null,
578 Project.FindSubsystem<SubsystemFurnitureBlockBehavior>(true),
579 null,
580 Project.FindSubsystem<SubsystemPalette>(true)
581 );
582 for (int i = 0; i < x; i++) {
583 for (int j = 0; j < x; j++) {
584 m_blockGeometryGenerator.Terrain.AllocateChunk(i, j);
585 }
586 }
587 }
588 Terrain terrain = m_subsystemTerrain.Terrain;
589 for (int k = 0; k < point2.X + 2; k++) {
590 for (int l = 0; l < point2.Z + 2; l++) {
591 int x2 = k + p.X + point.X - 1;
592 int z = l + p.Z + point.Z - 1;
593 int shaftValue = terrain.GetShaftValue(x2, z);
594 m_blockGeometryGenerator.Terrain.SetTemperature(k, l, Terrain.ExtractTemperature(shaftValue));
595 m_blockGeometryGenerator.Terrain.SetHumidity(k, l, Terrain.ExtractHumidity(shaftValue));
596 for (int m = 0; m < point2.Y + 2; m++) {
597 if (m_blockGeometryGenerator.Terrain.IsCellValid(k, m + num, l)) {
598 int y = m + p.Y + point.Y - 1;
599 int cellValue = terrain.GetCellValue(x2, y, z);
600 int num2 = Terrain.ExtractContents(cellValue);
601 int light = Terrain.ExtractLight(cellValue);
602 int shadowStrength = BlocksManager.Blocks[num2].GetShadowStrength(cellValue);
603 int value = Terrain.MakeBlockValue(257, light, ShadowBlock.SetShadowStrength(0, shadowStrength));
604 m_blockGeometryGenerator.Terrain.SetCellValueFast(k, m + num, l, value);
605 }
606 }
607 }
608 }
609 m_blockGeometryGenerator.Terrain.SeasonTemperature = terrain.SeasonTemperature;
610 m_blockGeometryGenerator.Terrain.SeasonHumidity = terrain.SeasonHumidity;
611 foreach (MovingBlock block in movingBlockSet.Blocks) {
612 int x3 = block.Offset.X - p.X + 1;
613 int num3 = block.Offset.Y - p.Y + 1;
614 int z2 = block.Offset.Z - p.Z + 1;
615 if (m_blockGeometryGenerator.Terrain.IsCellValid(x3, num3 + num, z2)) {
616 int cellLightFast = m_blockGeometryGenerator.Terrain.GetCellLightFast(x3, num3 + num, z2);
617 int value2 = Terrain.ReplaceLight(block.Value, cellLightFast);
618 m_blockGeometryGenerator.Terrain.SetCellValueFast(x3, num3 + num, z2, value2);
619 }
620 }
621 m_blockGeometryGenerator.ResetCache();
622 movingBlockSet.Geometry.ClearGeometry();
623 for (int n = 1; n < point2.X + 1; n++) {
624 for (int num4 = 1; num4 < point2.Y + 1; num4++) {
625 for (int num5 = 1; num5 < point2.Z + 1; num5++) {
626 if (num4 + num > 0
627 && num4 + num < TerrainChunk.HeightMinusOne) {
628 int cellValueFast = m_blockGeometryGenerator.Terrain.GetCellValueFast(n, num4 + num, num5);
629 int num6 = Terrain.ExtractContents(cellValueFast);
630 if (num6 != 0) {
631 if (m_blockGeometryGenerator.Terrain.GetChunkAtCell(n + 1, num5) == null) {
632 m_blockGeometryGenerator.Terrain.AllocateChunk((n + 1) >> 4, num5 >> 4);
633 }
634 if (m_blockGeometryGenerator.Terrain.GetChunkAtCell(n, num5 + 1) == null) {
635 m_blockGeometryGenerator.Terrain.AllocateChunk(n >> 4, (num5 + 1) >> 4);
636 }
638 .GenerateTerrainVertices(m_blockGeometryGenerator, movingBlockSet.Geometry, cellValueFast, n, num4 + num, num5);
639 }
640 }
641 }
642 }
643 }
644 movingBlockSet.GeometryOffset = new Vector3(p) + new Vector3(0f, -num, 0f) - new Vector3(1f);
645 movingBlockSet.GeometryGenerationPosition = point;
646 }
647
648 public virtual void DrawMovingBlockSet(Camera camera, MovingBlockSet movingBlockSet) {
649 if (camera.ViewFrustum.Intersection(movingBlockSet.BoundingBox(false))) {
650 GenerateGeometry(movingBlockSet);
651 Vector3 vector = movingBlockSet.Position + movingBlockSet.GeometryOffset;
653 [movingBlockSet.Geometry],
654 Buffers,
655 item => {
656 item.X += vector.X;
657 item.Y += vector.Y;
658 item.Z += vector.Z;
659 return item;
660 }
661 );
662 }
663 }
664
666 if (b1.Max.X > b2.Min.X
667 && b1.Min.X < b2.Max.X
668 && b1.Max.Y > b2.Min.Y
669 && b1.Min.Y < b2.Max.Y
670 && b1.Max.Z > b2.Min.Z) {
671 return b1.Min.Z < b2.Max.Z;
672 }
673 return false;
674 }
675
676 public virtual void AddTerrainBlock(int x, int y, int z, int value, MovingBlock movingBlock) {
677 try {
678 if (movingBlock == null) {
679 throw new NullReferenceException("Moving Block Set cannot be null when stop block movement!");
680 }
681 movingBlock?.MovingBlockSet?.Stop();
682 m_subsystemTerrain.DestroyCell(
683 0,
684 x,
685 y,
686 z,
687 value,
689 false,
690 movingBlock
691 );
692 //m_subsystemTerrain.ChangeCell(x,y,z,value,true,movingBlock);
693 }
694 catch (Exception ex) {
695 Log.Error($"Add terrain block when moving blocks stop error: {ex}");
696 }
697 }
698 }
699}
Engine.Vector3 Vector3
bool Intersection(Vector3 point)
static readonly BlendState AlphaBlend
static readonly DepthStencilState Default
static void DrawIndexed(PrimitiveType primitiveType, Shader shader, VertexBuffer vertexBuffer, IndexBuffer indexBuffer, int startIndex, int indicesCount)
static readonly RasterizerState CullCounterClockwiseScissor
static void Error(object message)
定义 Log.cs:80
static uint NextPowerOf2(uint x)
static int Min(int x1, int x2)
static float Saturate(float x)
static object ConvertFromString(Type type, string data)
void GenerateTerrainVertices(BlockGeometryGenerator generator, TerrainGeometry geometry, int value, int x, int y, int z)
生成地形顶点(用于绘制放置的方块)
virtual int GetShadowStrength(int value)
virtual ? float Raycast(Ray3 ray, SubsystemTerrain subsystemTerrain, int value, bool useInteractionBoxes, out int nearestBoxIndex, out BoundingBox nearestBox)
BoundingFrustum ViewFrustum
static object Get(Type type, string name)
IMovingBlockSet MovingBlockSet
static int SetShadowStrength(int data, int shadowStrength)
BoundingBox BoundingBox(bool extendToFillCells)
void TerrainCollision(MovingBlockSet movingBlockSet)
override void Load(ValuesDictionary valuesDictionary)
DynamicArray< IMovingBlockSet > m_result
static bool ExclusiveBoxIntersection(BoundingBox b1, BoundingBox b2)
Action< IMovingBlockSet, Point3 > CollidedWithTerrain
virtual void AddTerrainBlock(int x, int y, int z, int value, MovingBlock movingBlock)
IMovingBlockSet AddMovingBlockSet(Vector3 position, Vector3 targetPosition, float speed, float acceleration, float drag, Vector2 smoothness, IEnumerable< MovingBlock > blocks, string id, object tag, bool testCollision)
IMovingBlockSet FindMovingBlocks(string id, object tag)
virtual void Draw(Camera camera, int drawOrder)
MovingBlocksRaycastResult? Raycast(Vector3 start, Vector3 end, bool extendToFillCells, Func< int, float, bool > action=null)
void GenerateGeometry(MovingBlockSet movingBlockSet)
void MovingBlocksCollision(MovingBlockSet movingBlockSet)
BlockGeometryGenerator m_blockGeometryGenerator
void RemoveMovingBlockSet(IMovingBlockSet movingBlockSet)
DynamicArray< TerrainChunkGeometry.Buffer > Buffers
static DynamicArray< TerrainVertex > m_vertexList
override void Save(ValuesDictionary valuesDictionary)
SubsystemAnimatedTextures m_subsystemAnimatedTextures
void FindMovingBlocks(BoundingBox boundingBox, bool extendToFillCells, DynamicArray< IMovingBlockSet > result)
static DynamicArray< int > m_tmpIndices
virtual void DrawMovingBlockSet(Camera camera, MovingBlockSet movingBlockSet)
TerrainChunkState State
static int ExtractTemperature(int value)
static int ExtractContents(int value)
virtual int GetCellValue(int x, int y, int z)
static int ToCell(float x)
static int ExtractLight(int value)
static int ExtractHumidity(int value)
virtual int GetShaftValue(int x, int z)
static int ReplaceLight(int value, int light)
static int MakeBlockValue(int contents)
static void CompileDrawSubsets(TerrainGeometry[] chunkSliceGeometries, DynamicArray< TerrainChunkGeometry.Buffer > buffers, Func< TerrainVertex, TerrainVertex > vertexTransform=null)
ValuesDictionary ValuesDictionary
static void HookAction(string HookName, Func< ModLoader, bool > action)
执行Hook
BoundingBox BoundingBox(bool extendToFillCells)
List< MovingBlock > Blocks
void SetBlock(Point3 offset, int value)
int Width
定义 Box.cs:9
static Matrix CreateTranslation(float x, float y, float z)
static Point3 Floor(Vector3 v)
static Point3 Min(Point3 p, int v)
static Point3 Max(Point3 p, int v)
static Point3 Ceiling(Vector3 v)
float? Intersection(BoundingBox box)
定义 Ray3.cs:20
static readonly Vector2 Zero
static Vector3 Normalize(Vector3 v)
static readonly Vector3 Zero
static float Distance(Vector3 v1, Vector3 v2)
static Vector3 Max(Vector3 v, float f)
static Vector3 Min(Vector3 v, float f)