public bool MovePiston(Point3 position, int length) { Terrain terrain = m_subsystemTerrain.Terrain; int data = Terrain.ExtractData(terrain.GetCellValue(position.X, position.Y, position.Z)); int face = PistonBlock.GetFace(data); PistonMode mode = PistonBlock.GetMode(data); int maxExtension = PistonBlock.GetMaxExtension(data); int pullCount = PistonBlock.GetPullCount(data); int speed = PistonBlock.GetSpeed(data); Point3 point = CellFace.FaceToPoint3(face); length = MathUtils.Clamp(length, 0, maxExtension + 1); int num = 0; m_movingBlocks.Clear(); Point3 offset = point; MovingBlock item; while (m_movingBlocks.Count < 8) { int cellValue = terrain.GetCellValue(position.X + offset.X, position.Y + offset.Y, position.Z + offset.Z); int num2 = Terrain.ExtractContents(cellValue); int face2 = PistonHeadBlock.GetFace(Terrain.ExtractData(cellValue)); if (num2 != 238 || face2 != face) { break; } DynamicArray <MovingBlock> movingBlocks = m_movingBlocks; item = new MovingBlock { Offset = offset, Value = cellValue }; movingBlocks.Add(item); offset += point; num++; } if (length > num) { DynamicArray <MovingBlock> movingBlocks2 = m_movingBlocks; item = new MovingBlock { Offset = Point3.Zero, Value = Terrain.MakeBlockValue(238, 0, PistonHeadBlock.SetFace(PistonHeadBlock.SetMode(PistonHeadBlock.SetIsShaft(0, num > 0), mode), face)) }; movingBlocks2.Add(item); int num3 = 0; while (num3 < 8) { int cellValue2 = terrain.GetCellValue(position.X + offset.X, position.Y + offset.Y, position.Z + offset.Z); if (!IsBlockMovable(cellValue2, face, position.Y + offset.Y, out bool isEnd)) { break; } DynamicArray <MovingBlock> movingBlocks3 = m_movingBlocks; item = new MovingBlock { Offset = offset, Value = cellValue2 }; movingBlocks3.Add(item); num3++; offset += point; if (isEnd) { break; } } if (!IsBlockBlocking(terrain.GetCellValue(position.X + offset.X, position.Y + offset.Y, position.Z + offset.Z))) { GetSpeedAndSmoothness(speed, out float speed2, out Vector2 smoothness); Point3 p = position + (length - num) * point; if (m_subsystemMovingBlocks.AddMovingBlockSet(new Vector3(position) + 0.01f * new Vector3(point), new Vector3(p), speed2, 0f, 0f, smoothness, m_movingBlocks, "Piston", position, testCollision: true) != null) { m_allowPistonHeadRemove = true; try { foreach (MovingBlock movingBlock in m_movingBlocks) { if (movingBlock.Offset != Point3.Zero) { m_subsystemTerrain.ChangeCell(position.X + movingBlock.Offset.X, position.Y + movingBlock.Offset.Y, position.Z + movingBlock.Offset.Z, 0); } } } finally { m_allowPistonHeadRemove = false; } m_subsystemTerrain.ChangeCell(position.X, position.Y, position.Z, Terrain.MakeBlockValue(237, 0, PistonBlock.SetIsExtended(data, isExtended: true))); m_subsystemAudio.PlaySound("Audio/Piston", 1f, 0f, new Vector3(position), 2f, autoDelay: true); } } return(false); } if (length < num) { if (mode != 0) { int num4 = 0; for (int i = 0; i < pullCount + 1; i++) { int cellValue3 = terrain.GetCellValue(position.X + offset.X, position.Y + offset.Y, position.Z + offset.Z); if (!IsBlockMovable(cellValue3, face, position.Y + offset.Y, out bool isEnd2)) { break; } DynamicArray <MovingBlock> movingBlocks4 = m_movingBlocks; item = new MovingBlock { Offset = offset, Value = cellValue3 }; movingBlocks4.Add(item); offset += point; num4++; if (isEnd2) { break; } } if (mode == PistonMode.StrictPulling && num4 < pullCount + 1) { return(false); } } GetSpeedAndSmoothness(speed, out float speed3, out Vector2 smoothness2); float s = (length == 0) ? 0.01f : 0f; Vector3 targetPosition = new Vector3(position) + (length - num) * new Vector3(point) + s * new Vector3(point); if (m_subsystemMovingBlocks.AddMovingBlockSet(new Vector3(position), targetPosition, speed3, 0f, 0f, smoothness2, m_movingBlocks, "Piston", position, testCollision: true) != null) { m_allowPistonHeadRemove = true; try { foreach (MovingBlock movingBlock2 in m_movingBlocks) { m_subsystemTerrain.ChangeCell(position.X + movingBlock2.Offset.X, position.Y + movingBlock2.Offset.Y, position.Z + movingBlock2.Offset.Z, 0); } } finally { m_allowPistonHeadRemove = false; } m_subsystemAudio.PlaySound("Audio/Piston", 1f, 0f, new Vector3(position), 2f, autoDelay: true); } return(false); } return(true); }
public void UpdateMovableBlocks() { foreach (IMovingBlockSet movingBlockSet in m_subsystemMovingBlocks.MovingBlockSets) { if (movingBlockSet.Id == "Piston") { Point3 point = (Point3)movingBlockSet.Tag; int cellValue = m_subsystemTerrain.Terrain.GetCellValue(point.X, point.Y, point.Z); if (Terrain.ExtractContents(cellValue) == 237) { int data = Terrain.ExtractData(cellValue); PistonMode mode = PistonBlock.GetMode(data); int face = PistonBlock.GetFace(data); Point3 p = CellFace.FaceToPoint3(face); int num = int.MaxValue; foreach (MovingBlock block in movingBlockSet.Blocks) { num = MathUtils.Min(num, block.Offset.X * p.X + block.Offset.Y * p.Y + block.Offset.Z * p.Z); } float num2 = movingBlockSet.Position.X * (float)p.X + movingBlockSet.Position.Y * (float)p.Y + movingBlockSet.Position.Z * (float)p.Z; float num3 = point.X * p.X + point.Y * p.Y + point.Z * p.Z; if (num2 > num3) { if ((float)num + num2 - num3 > 1f) { movingBlockSet.SetBlock(p * (num - 1), Terrain.MakeBlockValue(238, 0, PistonHeadBlock.SetFace(PistonHeadBlock.SetIsShaft(PistonHeadBlock.SetMode(0, mode), isShaft: true), face))); } } else if (num2 < num3 && (float)num + num2 - num3 <= 0f) { movingBlockSet.SetBlock(p * num, 0); } } } } }