public GridStats(IMyCubeGrid grid) { this.grid = grid; var tot = 0; var termblock = 0; var damaged = 0; for (var z = grid.Min.Z; z <= grid.Max.Z; z++) { for (var y = grid.Min.Y; y <= grid.Max.Y; y++) { for (var x = grid.Min.X; x <= grid.Max.X; x++) { if (grid.CubeExists(new Vector3I(x, y, z))) { tot++; var block = grid.GetCubeBlock(new Vector3I(x, y, z)); if (block != null) { termblock++; if (!block.IsFullIntegrity) { damaged++; } } } } } } this.total = tot; this.terminal_block = termblock; this.damaged = damaged; }
public void draw(IScaledPixelDrawer drawer) { Func <Vector3I, Vector2I> project = v => new Vector2I(v.X, v.Z); var armor = new List <Vector2I>(); var pristine = new List <Vector2I>(); var dented = new List <Vector2I>(); var damaged = new List <Vector2I>(); var broken = new List <Vector2I>(); var lengths = gridMax - gridMin + new Vector3I(1, 1, 1); drawer.setScale(project(lengths).X, project(lengths).Y); foreach (var pos in gridBlocks) { var block = grid.GetCubeBlock(pos); Vector2I ppos = project(pos - gridMin); if (grid.CubeExists(pos)) { if (block == null) // Armor block { armor.Add(ppos); } else if (block.IsFullIntegrity) { pristine.Add(ppos); } else { var health = (block.BuildIntegrity - block.CurrentDamage) / block.MaxIntegrity; if (health < DENT_LIMIT) { damaged.Add(ppos); } else { dented.Add(ppos); } } } else { broken.Add(ppos); } } armor.ForEach(p => drawer.drawPixel(p.X, p.Y, ARMOR_COLOR)); pristine.ForEach(p => drawer.drawPixel(p.X, p.Y, PRISTINE_COLOR)); dented.ForEach(p => drawer.drawPixel(p.X, p.Y, DENTED_COLOR)); damaged.ForEach(p => drawer.drawPixel(p.X, p.Y, DAMAGED_COLOR)); broken.ForEach(p => drawer.drawPixel(p.X, p.Y, BROKEN_COLOR)); }
public static void RayCastGrid(this IMyCubeGrid grid, Vector3 rayStart, Vector3 direction, Action <Vector3I> visitor) { Matrix worldToLocal = Matrix.Invert(grid.WorldMatrix); direction.Normalize(); Vector3 transformedDirection = Vector3.TransformNormal(direction, worldToLocal); Vector3 currentPointF = Vector3.Transform(rayStart, worldToLocal) / grid.GridSize; Vector3I currentPoint = Vector3I.Round(currentPointF); if (!Inside(grid.Min, grid.Max, currentPoint)) { //find intersection BoundingBoxI bbI = new BoundingBoxI(grid.Min, grid.Max); var hit = bbI.Intersects(new Ray(currentPointF, transformedDirection)); if (!hit.HasValue) { //Program.instance.Log($"No misses bounding box"); return; //no intersection } currentPointF += (float)hit.Value * transformedDirection; currentPoint = Vector3I.Round(currentPointF); } //Program.instance.Log($"Starting at: {currentPoint}"); //Program.instance.Log($"Direction at: {transformedDirection}"); while (Inside(grid.Min, grid.Max, currentPoint)) { if (grid.CubeExists(currentPoint)) { visitor(currentPoint); } float toXShift = ClosestGridBlockChange(currentPointF.X, transformedDirection.X); float toYShift = ClosestGridBlockChange(currentPointF.Y, transformedDirection.Y); float toZShift = ClosestGridBlockChange(currentPointF.Z, transformedDirection.Z); currentPointF += transformedDirection * Min(toXShift, toYShift, toZShift); currentPoint = Vector3I.Round(currentPointF); //Program.instance.Log($"Shift by: {toXShift}, {toYShift}, {toZShift}"); //Program.instance.Log($"Walk:{currentPoint}"); } }
private void finishWalk() { try { while (true) { var pos = visitQueue.Dequeue(); if (visited.Add(pos)) { if (cubeGrid.CubeExists(pos)) { full.Add(pos); visitQueue.Enqueue(new Vector3I(pos.X - 1, pos.Y, pos.Z)); visitQueue.Enqueue(new Vector3I(pos.X + 1, pos.Y, pos.Z)); visitQueue.Enqueue(new Vector3I(pos.X, pos.Y - 1, pos.Z)); visitQueue.Enqueue(new Vector3I(pos.X, pos.Y + 1, pos.Z)); visitQueue.Enqueue(new Vector3I(pos.X, pos.Y, pos.Z - 1)); visitQueue.Enqueue(new Vector3I(pos.X, pos.Y, pos.Z + 1)); } } } } catch (InvalidOperationException) {} }
/// <summary> /// Yields the first occupied cells encountered when raycasting a grid in a given base direction. /// </summary> /// <param name="grid">The grid to get blocks from.</param> /// <param name="baseDirection">The direction of ray.</param> public static IEnumerable <Vector3I> FirstBlocks(this IMyCubeGrid grid, Vector3I baseDirection) { Logger.DebugLog("baseDirection(" + baseDirection + ") has a magnitude", Logger.severity.FATAL, condition: baseDirection.RectangularLength() != 1); BoundingBox localAABB = grid.LocalAABB; Vector3I min = grid.Min, max = grid.Max; // ??? //Vector3 minF; Vector3.Divide(ref localAABB.Min, grid.GridSize, out minF); //Vector3 maxF; Vector3.Divide(ref localAABB.Max, grid.GridSize, out maxF); //Vector3I min, max; //Func<float, int> round = f => (int)Math.Round(f); //minF.ApplyOperation(round, out min); //maxF.ApplyOperation(round, out max); Vector3I perp0, perp1; perp0 = Base6Directions.GetIntVector(Base6Directions.GetPerpendicular(Base6Directions.GetDirection(baseDirection))); Vector3I.Cross(ref baseDirection, ref perp0, out perp1); int baseStart; Vector3I.Dot(ref baseDirection, ref min, out baseStart); int baseEnd; Vector3I.Dot(ref baseDirection, ref max, out baseEnd); if (baseStart > baseEnd) { int temp = baseStart; baseStart = baseEnd; baseEnd = temp; } bool incrementBase = baseStart <= baseEnd; int perp0Min; Vector3I.Dot(ref perp0, ref min, out perp0Min); int perp0Max; Vector3I.Dot(ref perp0, ref max, out perp0Max); if (perp0Max < perp0Min) { int temp = perp0Max; perp0Max = perp0Min; perp0Min = temp; } int perp1Min; Vector3I.Dot(ref perp1, ref min, out perp1Min); int perp1Max; Vector3I.Dot(ref perp1, ref max, out perp1Max); if (perp1Max < perp1Min) { int temp = perp1Max; perp1Max = perp1Min; perp1Min = temp; } Logger.TraceLog("min: " + min + ", max: " + max, Logger.severity.DEBUG); Logger.TraceLog("base: " + baseDirection + ", perp0: " + perp0 + ", perp1: " + perp1, Logger.severity.DEBUG); Logger.TraceLog("base range: " + baseStart + ":" + baseEnd, Logger.severity.DEBUG); Logger.TraceLog("perp0 range: " + perp0Min + ":" + perp0Max, Logger.severity.DEBUG); Logger.TraceLog("perp1 range: " + perp1Min + ":" + perp1Max, Logger.severity.DEBUG); for (int perp0Value = perp0Min; perp0Value <= perp0Max; perp0Value++) { for (int perp1Value = perp1Min; perp1Value <= perp1Max; perp1Value++) { int baseValue = baseStart; while (true) { Vector3I cell = baseValue * baseDirection + perp0Value * perp0 + perp1Value * perp1; if (grid.CubeExists(cell)) { yield return(cell); break; } if (baseValue == baseEnd) { break; } if (incrementBase) { baseValue++; } else { baseValue--; } } } } yield break; }
Vector3I?MirrorPaint(bool sync, IMyCubeGrid grid, int axis, MirrorData mirrorPlanes, bool odd, Vector3I originalPosition, PaintMaterial paint, List <Vector3I> alreadyMirrored, ulong originalSenderSteamId) { Vector3I?mirrorPosition = null; switch (axis) { case 0: if (mirrorPlanes.X.HasValue) { mirrorPosition = originalPosition + new Vector3I(((mirrorPlanes.X.Value - originalPosition.X) * 2) - (odd ? 1 : 0), 0, 0); } break; case 1: if (mirrorPlanes.Y.HasValue) { mirrorPosition = originalPosition + new Vector3I(0, ((mirrorPlanes.Y.Value - originalPosition.Y) * 2) - (odd ? 1 : 0), 0); } break; case 2: if (mirrorPlanes.Z.HasValue) { mirrorPosition = originalPosition + new Vector3I(0, 0, ((mirrorPlanes.Z.Value - originalPosition.Z) * 2) + (odd ? 1 : 0)); // reversed on odd } break; } if (mirrorPosition.HasValue && originalPosition != mirrorPosition.Value && !alreadyMirrored.Contains(mirrorPosition.Value) && grid.CubeExists(mirrorPosition.Value)) { alreadyMirrored.Add(mirrorPosition.Value); PaintBlock(sync, grid, mirrorPosition.Value, paint, originalSenderSteamId); } return(mirrorPosition); }
private void update_terminal_block_status(int limit) { int count = 0; blocks_terminal = new List <IMyTerminalBlock>(); GridTerminalSystem.GetBlocksOfType <IMyTerminalBlock>(blocks_terminal); if (terminal_blocks_index >= blocks_terminal.Count) { terminal_blocks_index = 0; } while (count < limit && terminal_blocks_index < blocks_terminal.Count) { count++; IMyTerminalBlock block = blocks_terminal[terminal_blocks_index]; Vector3I pos = block.Position; if (!coords_ship_full.Contains(pos)) { //ignore blocks we didn't find at initialization. (safer) terminal_blocks_index++; continue; } if (!myGrid.CubeExists(block.Position)) { //Note :if the block is gone we can still reference it. safely_remove(coords_terminal_now, pos); safely_remove(coords_terminal_working, pos); safely_remove(coords_terminal_nothacked, pos); safely_remove(coords_gyro_now, pos); safely_remove(coords_thrust_now, pos); safely_remove(coords_weapon_now, pos); safely_remove(coords_power_now, pos); } else if (coords_terminal_full.Contains(pos)) { safely_add(coords_terminal_now, pos); if (block.IsFunctional) { safely_add(coords_terminal_working, pos); } if (!block.IsBeingHacked) { safely_add(coords_terminal_nothacked, pos); } if (!block.IsFunctional) { safely_remove(coords_terminal_working, pos); } if (block.IsBeingHacked) { safely_remove(coords_terminal_nothacked, pos); } if (block is IMyThrust) { safely_add(coords_thrust_now, pos); safely_add(coords_thrust_full, pos); } if (block is IMyGyro) { safely_add(coords_gyro_now, pos); safely_add(coords_gyro_full, pos); } if (is_weapon(block)) { safely_add(coords_weapon_now, pos); safely_add(coords_weapon_full, pos); } if (is_power(block)) { safely_add(coords_power_now, pos); safely_add(coords_power_full, pos); } } terminal_blocks_index++; } }