public static bool IsAirtightBetweenPositions(IMyCubeGrid grid, Vector3I startPos, Vector3I endPos) { var b1 = grid.GetCubeBlock(startPos); var b2 = grid.GetCubeBlock(endPos); if (b1 == b2) { if (b1 != null) { var def = b1.BlockDefinition as MyCubeBlockDefinition; if (def != null) { return(IsAirtightFromDefinition(def, b1.BuildLevelRatio) == AirTightMode.SEALED); } return(false); } return(false); } if (b1 != null && IsAirtightBlock(b1, startPos, endPos - startPos)) { return(true); } if (b2 != null) { return(IsAirtightBlock(b2, endPos, startPos - endPos)); } return(false); }
// TODO update this code when changed in game // all these are from Sandbox.Game.GameSystems.MyGridGasSystem // since that namespace is prohibited I have to copy it and convert it to work with modAPI private bool IsPressurized(IMyCubeGrid grid, Vector3I startPos, Vector3I endPos) { IMySlimBlock b1 = grid.GetCubeBlock(startPos); IMySlimBlock b2 = grid.GetCubeBlock(endPos); if (b1 == b2) { return(b1 != null && ((MyCubeBlockDefinition)b1.BlockDefinition).IsAirTight); } return((b1 != null && (((MyCubeBlockDefinition)b1.BlockDefinition).IsAirTight || IsPressurized(b1, startPos, endPos - startPos))) || (b2 != null && (((MyCubeBlockDefinition)b2.BlockDefinition).IsAirTight || IsPressurized(b2, endPos, startPos - endPos)))); }
/// <summary> /// Non-allocating version of Sandbox.Game.Entities.MyCubeGrid.GetBlocksInsideSphere() /// </summary> public void GetBlocksInsideSphere(IMyCubeGrid grid, List <IMySlimBlock> blockList, ref BoundingSphereD sphere) { if (grid.PositionComp != null) { MatrixD matrix = grid.PositionComp.WorldMatrixNormalizedInv; Vector3D result; Vector3D.Transform(ref sphere.Center, ref matrix, out result); BoundingSphere localSphere = new BoundingSphere(result, (float)sphere.Radius); BoundingBox boundingBox = BoundingBox.CreateFromSphere(localSphere); double gridSizeR = 1d / grid.GridSize; Vector3I searchMin = new Vector3I ( (int)Math.Round(boundingBox.Min.X * gridSizeR), (int)Math.Round(boundingBox.Min.Y * gridSizeR), (int)Math.Round(boundingBox.Min.Z * gridSizeR) ); Vector3I searchMax = new Vector3I ( (int)Math.Round(boundingBox.Max.X * gridSizeR), (int)Math.Round(boundingBox.Max.Y * gridSizeR), (int)Math.Round(boundingBox.Max.Z * gridSizeR) ); Vector3I start = Vector3I.Max(Vector3I.Min(searchMin, searchMax), grid.Min); Vector3I end = Vector3I.Min(Vector3I.Max(searchMin, searchMax), grid.Max); var gridIterator = new Vector3I_RangeIterator(ref start, ref end); Vector3I next = gridIterator.Current; blockHashBuffer.Clear(); while (gridIterator.IsValid()) { IMySlimBlock cube = grid.GetCubeBlock(next); float gridSizeHalf = grid.GridSize / 2f; if (cube != null) { var cubeBounds = new BoundingBox((cube.Min * grid.GridSize) - gridSizeHalf, (cube.Max * grid.GridSize) + gridSizeHalf); if (cubeBounds.Intersects(localSphere)) { blockHashBuffer.Add(cube); } } gridIterator.GetNext(out next); } blockList.Clear(); blockList.EnsureCapacity(blockHashBuffer.Count); foreach (IMySlimBlock block in blockHashBuffer) { blockList.Add(block); } } }
private void Cleanup() { HashSet <TargetEntity> remove = new HashSet <TargetEntity>(); foreach (var item in m_particles) { IMyEntity entity; if (!MyAPIGateway.Entities.TryGetEntityById(item.TargetGridId, out entity)) { remove.Add(item); continue; } IMyCubeGrid grid = entity as IMyCubeGrid; IMySlimBlock slimBlock = grid.GetCubeBlock(item.TargetPosition); if (slimBlock == null) { remove.Add(item); continue; } if (slimBlock.IsDestroyed || slimBlock.IsFullyDismounted || (slimBlock.FatBlock != null && slimBlock.FatBlock.Closed)) { remove.Add(item); continue; } } foreach (var item in remove) { item.Unload(); m_particles.Remove(item); } }
private void Actual_OnBlockAdded(IMySlimBlock obj) { SeenHolo sh; if (!m_holoEntities.TryGetValue(obj.CubeGrid.EntityId, out sh)) { Log.DebugLog("failed lookup of grid: " + obj.CubeGrid.DisplayName, Logger.severity.ERROR); obj.CubeGrid.OnBlockAdded -= Actual_OnBlockAdded; obj.CubeGrid.OnBlockRemoved -= Actual_OnBlockRemoved; return; } IMyCubeGrid holo = (IMyCubeGrid)sh.Holo; MyObjectBuilder_CubeBlock objBuilder = obj.GetObjectBuilder(); objBuilder.EntityId = 0L; holo.AddBlock(objBuilder, false); IMyCubeBlock cubeBlock = holo.GetCubeBlock(obj.Position).FatBlock; if (cubeBlock != null) { SetupProjection(cubeBlock); } }
/*============| IMyCubeGrid |============*/ public static void GetCubesOfType <T>(this IMyCubeGrid cubegrid, List <T> cubeList) where T : class { for (int x = cubegrid.Min.X; x <= cubegrid.Max.X; x++) { for (int y = cubegrid.Min.Y; y <= cubegrid.Max.Y; y++) { for (int z = cubegrid.Min.Z; z <= cubegrid.Max.Z; z++) { var vec = new Vector3I(x, y, z); var slimblock = cubegrid.GetCubeBlock(vec); T stator = null; if (slimblock != null) { stator = slimblock.FatBlock as T; } if (stator != null) { cubeList.Add(stator); } } } } }
private bool WalkLine(Vector3I start, Vector3I end, IMyCubeGrid grid) { var it = new MathUtility.Vector3ILineIterator(start, end); while (it.IsValid()) { IMySlimBlock block = grid.GetCubeBlock(it.Current); it.MoveNext(); if (block == null) { return(false); } if (!block.BlockDefinition.Id.SubtypeName.Contains("Shipyard")) { return(false); } if (block.BuildPercent() < ((MyCubeBlockDefinition)block.BlockDefinition).CriticalIntegrityRatio) { return(false); } } return(true); }
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 static byte[] SerializeAndSign(IMyCubeGrid grid, IMyPlayer player, Vector3I block) { var c = grid.GetCubeBlock(block)?.FatBlock as IMyCockpit; IMyCharacter pilot = c?.Pilot; c?.RemovePilot(); var ob = (MyObjectBuilder_CubeGrid)grid.GetObjectBuilder(); if (pilot != null) { c.AttachPilot(pilot); } IMyFaction fac = MyAPIGateway.Session.Factions.TryGetPlayerFaction(player.IdentityId); var data = new ClientData(ob, fac, block, Settings.Instance.HubIP); string obStr = MyAPIGateway.Utilities.SerializeToXML(data); string totalStr = DateTime.UtcNow.Ticks + obStr; string evalStr = totalStr + Settings.Instance.Password; var m = new MD5(); m.Value = evalStr; totalStr += m.FingerPrint; return(Encoding.UTF8.GetBytes(totalStr)); }
/// <summary> /// <param name="sync"></param> arg determines if it sends the paint request using the API, and automatically checks skin ownership. Must be false for mod-added skins. /// </summary> public void PaintBlock(bool sync, IMyCubeGrid grid, Vector3I gridPosition, PaintMaterial paint, ulong originalSenderSteamId) { IMySlimBlock slim = grid.GetCubeBlock(gridPosition); if (sync) { grid.SkinBlocks(gridPosition, gridPosition, paint.ColorMask, paint.Skin?.String); if (paint.Skin.HasValue) { // check if skin was applied to alert player CheckSkinned[slim] = new CheckData(paint.Skin.Value); // add or replace SetUpdateMethods(UpdateFlags.UPDATE_AFTER_SIM, true); } } else { // NOTE getting a MySlimBlock and sending it straight to arguments avoids getting prohibited errors. MyCubeGrid gridInternal = (MyCubeGrid)grid; gridInternal.ChangeColorAndSkin(gridInternal.GetCubeBlock(gridPosition), paint.ColorMask, paint.Skin); if (paint.Skin.HasValue) { CheckSkinned.Remove(slim); // prevent alerting if skin gets changed into an always-owned one } } }
public static IMyMotorStator Selector(IMyCubeGrid cubegrid) { if (cubegrid == null) { return(null); } for (int x = cubegrid.Min.X; x <= cubegrid.Max.X; x++) { for (int y = cubegrid.Min.Y; y <= cubegrid.Max.Y; y++) { for (int z = cubegrid.Min.Z; z <= cubegrid.Max.Z; z++) { var vec = new Vector3I(x, y, z); var slimblock = cubegrid.GetCubeBlock(vec); IMyMotorStator stator = null; if (slimblock != null) { stator = slimblock.FatBlock as IMyMotorStator; } if (stator != null && !stator.CustomName.Contains("[Ignore]")) { return(stator); } } } } return(null); }
/// <summary> /// Updates the appearance of the block if the integrity has changed. Only used for welding/griding. /// </summary> private static void UpdateBlockModel(IMySlimBlock realBlock, IMyCubeGrid holoGrid) { IMySlimBlock holoBlock = holoGrid.GetCubeBlock(realBlock.Position); Logger.DebugLog("holoBlock == null", Logger.severity.FATAL, condition: holoBlock == null); float realIntegrityRatio = (realBlock.BuildIntegrity - realBlock.CurrentDamage) / realBlock.MaxIntegrity; float holoIntegrityRatio = (holoBlock.BuildIntegrity - holoBlock.CurrentDamage) / holoBlock.MaxIntegrity; if (realIntegrityRatio == holoIntegrityRatio) { return; } float min, max; if (realIntegrityRatio > holoIntegrityRatio) { max = realIntegrityRatio; min = holoIntegrityRatio; } else { max = holoIntegrityRatio; min = realIntegrityRatio; } if (((MyCubeBlockDefinition)realBlock.BlockDefinition).ModelChangeIsNeeded(min, max)) { holoGrid.RemoveBlock(holoBlock); MyObjectBuilder_CubeBlock objBuilder = realBlock.GetObjectBuilder(); objBuilder.EntityId = 0L; holoGrid.AddBlock(objBuilder, false); IMyCubeBlock cubeBlock = holoGrid.GetCubeBlock(realBlock.Position).FatBlock; if (cubeBlock != null) { SetupProjection(cubeBlock); } } }
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)); }
/// <summary> /// Rejection test for intersection with the profiled grid. /// </summary> /// <param name="grid">Grid whose cells will be rejected and compared to the profiled grid's rejections.</param> /// <returns>True iff there is a collision</returns> public bool rejectionIntersects(IMyCubeGrid grid, IMyCubeBlock ignore, out MyEntity entity, out Vector3?pointOfObstruction) { m_logger.debugLog("m_grid == null", Logger.severity.FATAL, condition: m_grid == null); //m_logger.debugLog("testing grid: " + grid.getBestName(), "rejectionIntersects()"); GridCellCache gridCache = GridCellCache.GetCellCache(grid); MatrixD toLocal = m_grid.WorldMatrixNormalizedInv; Line pathLine = Path.get_Line(); float minDist = m_grid.GridSize + grid.GridSize; //if (!m_landing) // minDist += NotLandingBuffer; float pathRadius = Path.Radius + minDist; float minDistSquared = minDist * minDist; MyEntity entity_in = null; Vector3? pointOfObstruction_in = null; using (m_lock_rejcectionCells.AcquireSharedUsing()) gridCache.ForEach(cell => { Vector3 world = grid.GridIntegerToWorld(cell); //m_logger.debugLog("checking position: " + world, "rejectionIntersects()"); if (pathLine.PointInCylinder(pathRadius, world)) { //m_logger.debugLog("point in cylinder: " + world, "rejectionIntersects()"); Vector3 local = Vector3.Transform(world, toLocal); if (rejectionIntersects(local, minDistSquared)) { entity_in = grid.GetCubeBlock(cell).FatBlock as MyEntity ?? grid as MyEntity; if (ignore != null && entity_in == ignore) { return(false); } pointOfObstruction_in = pathLine.ClosestPoint(world); return(true); } } return(false); }); if (pointOfObstruction_in.HasValue) { entity = entity_in; pointOfObstruction = pointOfObstruction_in; return(true); } entity = null; pointOfObstruction = null; return(false); }
public void UpdateAfterBuild() { Vector3D pos = Block.GetPosition(); IMyCubeGrid grid = Projector.CubeGrid; Vector3I gridPos = grid.WorldToGridInteger(pos); IMySlimBlock newBlock = grid.GetCubeBlock(gridPos); if (newBlock != null) { Block = newBlock; } }
/// <summary> /// Finds a random block facing the sky. Raycast is slightly randomized to simulate wind blowing rain /// </summary> /// <param name="grid"></param> /// <param name="blocks"></param> /// <param name="gravityDirection"></param> /// <param name="physicsCast"></param> /// <returns></returns> public static IMySlimBlock GetRandomSkyFacingBlock(IMyCubeGrid grid, List <IMySlimBlock> blocks, Vector3D gravityDirection, out LineD line, bool physicsCast = false) { Vector3D posInt = grid.GridIntegerToWorld(blocks.GetRandomItemFromList().Position) + -gravityDirection * 2; Vector3D posExt = posInt + gravityDirection * Math.Max(25, grid.WorldVolume.Radius * 2); posExt = RandomPositionFromPoint(ref posExt, grid.WorldVolume.Radius); line = new LineD(); Vector3I?blockPos = grid.RayCastBlocks(posExt, posInt); if (!blockPos.HasValue) { return(null); } IMySlimBlock block = grid.GetCubeBlock(blockPos.Value); if (block == null) { return(null); } if (physicsCast) { var hits = new List <IHitInfo>(); MyAPIGateway.Physics.CastRay(posExt, grid.GridIntegerToWorld(blockPos.Value), hits); foreach (IHitInfo hit in hits) { if (hit?.HitEntity?.GetTopMostParent() == null) { continue; } if (hit.HitEntity.GetTopMostParent().EntityId != grid.EntityId) { return(null); } } } if (Debug) { Lines.Add(new LineD { From = posExt, To = grid.GridIntegerToWorld(blockPos.Value) }); } line = new LineD { From = posExt, To = grid.GridIntegerToWorld(blockPos.Value) }; return(block); }
Vector3I?MirrorHighlight(IMyCubeGrid grid, int axis, Vector3I originalPosition, List <Vector3I> alreadyMirrored) { Vector3I?mirrorPosition = null; switch (axis) { case 0: if (grid.XSymmetryPlane.HasValue) { mirrorPosition = originalPosition + new Vector3I(((grid.XSymmetryPlane.Value.X - originalPosition.X) * 2) - (grid.XSymmetryOdd ? 1 : 0), 0, 0); } break; case 1: if (grid.YSymmetryPlane.HasValue) { mirrorPosition = originalPosition + new Vector3I(0, ((grid.YSymmetryPlane.Value.Y - originalPosition.Y) * 2) - (grid.YSymmetryOdd ? 1 : 0), 0); } break; case 2: if (grid.ZSymmetryPlane.HasValue) { mirrorPosition = originalPosition + new Vector3I(0, 0, ((grid.ZSymmetryPlane.Value.Z - originalPosition.Z) * 2) + (grid.ZSymmetryOdd ? 1 : 0)); // reversed on odd } break; } if (mirrorPosition.HasValue && mirrorPosition.Value != originalPosition && !alreadyMirrored.Contains(mirrorPosition.Value)) { alreadyMirrored.Add(mirrorPosition.Value); IMySlimBlock block = grid.GetCubeBlock(mirrorPosition.Value); if (block != null) { mirroredValidTotal++; PaintMaterial paintMaterial = Main.Palette.GetLocalPaintMaterial(); bool validSelection = Main.LocalToolHandler.IsMirrorBlockValid(block, paintMaterial); if (validSelection) { mirroredValid++; } DrawBlockSelection(block, (validSelection ? SelectionState.Valid : SelectionState.Invalid)); } } return(mirrorPosition); // this must be returned regardless if block exists or not }
public bool tryFindCargoAtPosition(Vector3I Position, IMyCubeGrid Grid, out IMyTerminalBlock Match) { IMySlimBlock SlimBlock = Grid.GetCubeBlock(Position); if (SlimBlock != null && SlimBlock.FatBlock != null && SlimBlock.FatBlock is IMyTerminalBlock && SlimBlock.FatBlock.HasInventory) { Match = SlimBlock.FatBlock as IMyTerminalBlock; return(true); } else { Match = null; return(false); } }
public bool TryFindButtonPanel(Vector3I Position, IMyCubeGrid Grid, out IMyButtonPanel Match) { IMySlimBlock SlimBlock = Grid.GetCubeBlock(Position); if (SlimBlock != null && SlimBlock.FatBlock != null && SlimBlock.FatBlock is IMyTerminalBlock && SlimBlock.FatBlock is IMyButtonPanel) { Match = SlimBlock.FatBlock as IMyButtonPanel; return(true); } else { Match = null; return(false); } }
public static IMySlimBlock FirstBlock(this IMyCubeGrid grid, Vector3D worldStart, Vector3D worldEnd, Func <IMySlimBlock, bool> pred = null, Vector3I?gridSizeInflate = null) { for (var itr = CellEnumerator.EnumerateGridCells(grid, worldStart, worldEnd, gridSizeInflate); itr.IsValid; itr.MoveNext()) { var block = grid.GetCubeBlock(itr.Current); if (block != null && (pred == null || pred.Invoke(block))) { return(block); } } return(null); }
public static IMySlimBlock ProjectionResult(this IMySlimBlock block) { IMyProjector projector = block.CubeGrid.Projector(); if (projector == null) { return(null); } Vector3D pos = block.GetPosition(); IMyCubeGrid grid = projector.CubeGrid; Vector3I gridPos = grid.WorldToGridInteger(pos); return(grid.GetCubeBlock(gridPos)); }
public static List <IMySlimBlock> GetBlocksOnRay(this IMyCubeGrid Grid, Vector3D From, Vector3D To) { List <IMySlimBlock> Blocks = new List <IMySlimBlock>(); List <Vector3I> BlockPositions = new List <Vector3I>(); Grid.RayCastCells(From, To, BlockPositions); foreach (Vector3I Position in BlockPositions) { IMySlimBlock Block = Grid.GetCubeBlock(Position); if (Block != null) { Blocks.Add(Block); } } return(Blocks); }
/// <summary> /// Gets a block on the exterior hull of a ship /// </summary> /// <param name="grid"></param> /// <param name="blocks"></param> /// <returns></returns> public static IMySlimBlock GetRandomExteriorBlock(IMyCubeGrid grid, List <IMySlimBlock> blocks) { Vector3D posInt = grid.GridIntegerToWorld(blocks.GetRandomItemFromList().Position); Vector3D posExt = RandomPositionFromPoint(ref posInt, grid.WorldAABB.HalfExtents.Length()); if (Debug) { Lines.Add(new LineD { From = posExt, To = posInt }); } Vector3I?blockPos = grid.RayCastBlocks(posExt, posInt); return(blockPos.HasValue ? grid.GetCubeBlock(blockPos.Value) : null); }
private void Actual_OnBlockRemoved(IMySlimBlock obj) { SeenHolo sh; if (!m_holoEntities.TryGetValue(obj.CubeGrid.EntityId, out sh)) { Log.DebugLog("failed lookup of grid: " + obj.CubeGrid.DisplayName, Logger.severity.ERROR); obj.CubeGrid.OnBlockAdded -= Actual_OnBlockAdded; obj.CubeGrid.OnBlockRemoved -= Actual_OnBlockRemoved; return; } Vector3I position = obj.Position; IMyCubeGrid holo = (IMyCubeGrid)sh.Holo; holo.RemoveBlock(holo.GetCubeBlock(position)); }
private bool IsObstructing(IMyCubeGrid grid, Vector3D target) { List <Vector3I> cells = new List <Vector3I>(); grid.RayCastCells(turretPosition, target, cells, null, true); if (cells.Count == 0) { return(false); } if (grid != myCubeBlock.CubeGrid) { return(true); } //myLogger.debugLog("testing " + cells.Count + " of " + grid.getBestName() + " cells for obstruction", "IsObstructing()"); foreach (Vector3I pos in cells) { //if (pos == myCubeBlock.Position) //{ // //myLogger.debugLog("my cell: " + pos + ", world:" + grid.GridIntegerToWorld(pos), "IsObstructing()"); // continue; //} IMySlimBlock block = grid.GetCubeBlock(pos); if (block != null) { if (block.FatBlock == null) { //myLogger.debugLog("obstructing slim pos = " + pos + ", world = " + grid.GridIntegerToWorld(pos), "IsObstructing()"); } else { if (block.FatBlock == myCubeBlock) { continue; } //myLogger.debugLog("obstructing cube: " + block.FatBlock.DisplayNameText + ", pos = " + pos + ", world = " + grid.GridIntegerToWorld(pos), "IsObstructing()"); } return(true); } //myLogger.debugLog("empty cell: " + pos + ", world:" + grid.GridIntegerToWorld(pos), "IsObstructing()"); } return(false); }
public static void ApplyRegularDamage(IMyCubeGrid cubeGrid, Vector3D startCoords, Vector3D endCoords, float damageAmount, long damageOwner) { var newStartCoords = Vector3D.Normalize(startCoords - endCoords) * 50 + endCoords; var newEndCoords = Vector3D.Normalize(endCoords - startCoords) * 50 + endCoords; var cellList = new List <Vector3I>(); cubeGrid.RayCastCells(newStartCoords, newEndCoords, cellList); IMySlimBlock closestBlock = null; double closestBlockDist = 0; foreach (var cell in cellList) { var block = cubeGrid.GetCubeBlock(cell); if (block == null) { continue; } var blockPosition = Vector3D.Zero; block.ComputeWorldCenter(out blockPosition); var thisBlockDist = Vector3D.Distance(blockPosition, endCoords); if (closestBlock == null) { closestBlock = block; closestBlockDist = thisBlockDist; } if (thisBlockDist < closestBlockDist) { closestBlock = block; closestBlockDist = thisBlockDist; } } if (closestBlock == null) { return; } closestBlock.DoDamage(damageAmount, MyStringHash.GetOrCompute("Laser"), true, null, damageOwner); }
private void Cleanup() { // Old method caused a race condition when the background process was still removing entities but the in-game class was already unloaded. // Also a lot of other nasty bugs (leaks, crashes, hangs and SE not closing) appear to be caused by this. MyAPIGateway.Parallel.ForEach(new HashSet <TargetEntity>(m_particles), item => { // Invocation 0 try { if (item == null) { RemoveEntity(item); return; } IMyEntity entity; if (!MyAPIGateway.Entities.TryGetEntityById(item.TargetGridId, out entity)) { RemoveEntity(item); return; } IMyCubeGrid grid = entity as IMyCubeGrid; IMySlimBlock slimBlock = grid.GetCubeBlock(item.TargetPosition); if (slimBlock == null) { RemoveEntity(item); return; } if (slimBlock.IsDestroyed || slimBlock.IsFullyDismounted || (slimBlock.FatBlock != null && slimBlock.FatBlock.Closed)) { RemoveEntity(item); return; } } catch (System.Exception e) when(e.ToString().Contains("IndexOutOfRangeException")) { Logging.Instance.WriteLine("IndexOutOfRangeException occurred in ParticleEffectManager.Cleanup. This is likely harmless and can be ignored."); } catch (System.Exception e) { VRage.Utils.MyLog.Default.WriteLineAndConsole($"NaniteConstructionSystem.Particles.ParticleEffectManager.Cleanup (Invocation 0): \n{e}"); } }); }
public static double?GridHitCheck(IMyCubeGrid cubeGrid, LineD lineCheck, Vector3D lineStartPoint, Vector3D lineEndPoint) { // Hit a grid, do a raycast to it for block hit. Vector3I?gridBlockHit = cubeGrid.RayCastBlocks(lineStartPoint, lineEndPoint); if (gridBlockHit.HasValue) { // Get the block on hit grid IMySlimBlock blk = cubeGrid.GetCubeBlock(gridBlockHit.Value); if (blk.FatBlock != null) { var blockBBox = blk.FatBlock.LocalAABB; MyOrientedBoundingBoxD blockOBB = new MyOrientedBoundingBoxD(blockBBox, blk.FatBlock.WorldMatrix); double?blockIntersect = blockOBB.Intersects(ref lineCheck); if (blockIntersect != null) { var hitDist = blockOBB.Intersects(ref lineCheck); return(hitDist); } //DrawOBB(blockOBB, Color.Red, MySimpleObjectRasterizer.Wireframe, 0.01f); } else { var center = blk.GetPosition(); Vector3 halfExt; blk.ComputeScaledHalfExtents(out halfExt); BoundingBoxD blockBBox = new BoundingBoxD(-halfExt, halfExt); Quaternion rotMatrix = Quaternion.CreateFromRotationMatrix(blk.CubeGrid.WorldMatrix); MyOrientedBoundingBoxD blockOBB = new MyOrientedBoundingBoxD(center, blockBBox.HalfExtents, rotMatrix); var hitDist = blockOBB.Intersects(ref lineCheck); return(hitDist); //DrawOBB(blockOBB, Color.Green, MySimpleObjectRasterizer.Wireframe, 0.01f); } } return(double.MaxValue); }
public static void GetBlocksOnRay(this IMyCubeGrid Grid, ICollection <LineD> Rays, ICollection <IMySlimBlock> Blocks, Func <IMySlimBlock, bool> collect = null) { foreach (LineD Ray in Rays) { List <Vector3I> BlockPositions = new List <Vector3I>(); Grid.RayCastCells(Ray.From, Ray.To, BlockPositions); foreach (Vector3I Position in BlockPositions) { IMySlimBlock Block = Grid.GetCubeBlock(Position); if (Block == null) { continue; } if (collect == null || collect(Block)) { Blocks.Add(Block); } } } }
/// <summary> /// Searches for two other blocks that are perpendicular to the given one. /// If /// </summary> /// <param name="block">The given block</param> /// <returns></returns> public static List <IMyCubeBlock> FindPerpendicularTo(IMyTerminalBlock block) { if (block == null) { throw new Exception("The block is null."); } IMyCubeGrid grid = block.CubeGrid; int maxIndex = Math.Max(grid.Min.AbsMax(), grid.Max.AbsMax()); List <IMyCubeBlock> perpBlocks = new List <IMyCubeBlock>(); perpBlocks.Add(block); int firstIndex = -1; // do a kind of first breath search for (int i = 1; perpBlocks.Count < 3 && i < maxIndex; ++i) { for (int j = 0; j < directions.Count; ++j) { if (j == firstIndex) { continue; } VRageMath.Vector3I v = new VRageMath.Vector3I(directions[j]); IMySlimBlock slim = grid.GetCubeBlock(block.Position + i * v); if (slim != null && slim.FatBlock != null) { perpBlocks.Add(slim.FatBlock); if (perpBlocks.Count == 3) { break; } firstIndex = j; } } } return(perpBlocks); }
/// <summary> /// Rejection test for intersection with the profiled grid. /// </summary> /// <param name="grid">Grid whose cells will be rejected and compared to the profiled grid's rejections.</param> /// <returns>True iff there is a collision</returns> public bool rejectionIntersects(IMyCubeGrid grid, IMyCubeBlock ignore, out MyEntity entity, out Vector3? pointOfObstruction) { m_logger.debugLog(m_grid == null, "m_grid == null", Logger.severity.FATAL); //m_logger.debugLog("testing grid: " + grid.getBestName(), "rejectionIntersects()"); GridCellCache gridCache = GridCellCache.GetCellCache(grid); MatrixD toLocal = m_grid.WorldMatrixNormalizedInv; Line pathLine = Path.get_Line(); float minDist = m_grid.GridSize + grid.GridSize; //if (!m_landing) // minDist += NotLandingBuffer; float pathRadius = Path.Radius + minDist; float minDistSquared = minDist * minDist; MyEntity entity_in = null; Vector3? pointOfObstruction_in = null; using (m_lock_rejcectionCells.AcquireSharedUsing()) gridCache.ForEach(cell => { Vector3 world = grid.GridIntegerToWorld(cell); //m_logger.debugLog("checking position: " + world, "rejectionIntersects()"); if (pathLine.PointInCylinder(pathRadius, world)) { //m_logger.debugLog("point in cylinder: " + world, "rejectionIntersects()"); Vector3 local = Vector3.Transform(world, toLocal); if (rejectionIntersects(local, minDistSquared)) { entity_in = grid.GetCubeBlock(cell).FatBlock as MyEntity ?? grid as MyEntity; if (ignore != null && entity_in == ignore) return false; pointOfObstruction_in = pathLine.ClosestPoint(world); return true; } } return false; }); if (pointOfObstruction_in.HasValue) { entity = entity_in; pointOfObstruction = pointOfObstruction_in; return true; } entity = null; pointOfObstruction = null; return false; }
/// <summary> /// Updates the appearance of the block if the integrity has changed. Only used for welding/griding. /// </summary> private static void UpdateBlockModel(IMySlimBlock realBlock, IMyCubeGrid holoGrid) { IMySlimBlock holoBlock = holoGrid.GetCubeBlock(realBlock.Position); Static.logger.debugLog(holoBlock == null, "holoBlock == null", Logger.severity.FATAL); float realIntegrityRatio = (realBlock.BuildIntegrity - realBlock.CurrentDamage) / realBlock.MaxIntegrity; float holoIntegrityRatio = (holoBlock.BuildIntegrity - holoBlock.CurrentDamage) / holoBlock.MaxIntegrity; if (realIntegrityRatio == holoIntegrityRatio) return; float min, max; if (realIntegrityRatio > holoIntegrityRatio) { max = realIntegrityRatio; min = holoIntegrityRatio; } else { max = holoIntegrityRatio; min = realIntegrityRatio; } if (((MyCubeBlockDefinition)realBlock.BlockDefinition).ModelChangeIsNeeded(min, max)) { holoGrid.RemoveBlock(holoBlock); MyObjectBuilder_CubeBlock objBuilder = realBlock.GetObjectBuilder(); objBuilder.EntityId = 0L; holoGrid.AddBlock(objBuilder, false); IMyCubeBlock cubeBlock = holoGrid.GetCubeBlock(realBlock.Position).FatBlock; if (cubeBlock != null) SetupProjection(cubeBlock); } }