private CubeGridCache(IMyCubeGrid grid) { myLogger = new Logger("CubeGridCache", () => grid.DisplayName); CubeGrid = grid; List<IMySlimBlock> allSlims = new List<IMySlimBlock>(); CubeGrid.GetBlocks_Safe(allSlims, slim => slim.FatBlock != null); foreach (IMySlimBlock slim in allSlims) CubeGrid_OnBlockAdded(slim); CubeGrid.OnBlockAdded += CubeGrid_OnBlockAdded; CubeGrid.OnBlockRemoved += CubeGrid_OnBlockRemoved; CubeGrid.OnClosing += CubeGrid_OnClosing; Registrar.Add(CubeGrid, this); myLogger.debugLog("built for: " + CubeGrid.DisplayName, Logger.severity.DEBUG); }
private CubeGridCache(IMyCubeGrid grid) { CubeGrid = grid; List <IMySlimBlock> allSlims = new List <IMySlimBlock>(); CubeGrid.GetBlocks_Safe(allSlims, slim => slim.FatBlock is IMyTerminalBlock); foreach (IMySlimBlock slim in allSlims) { CubeGrid_OnBlockAdded(slim); } CubeGrid.OnBlockAdded += CubeGrid_OnBlockAdded; CubeGrid.OnBlockRemoved += CubeGrid_OnBlockRemoved; CubeGrid.OnClose += CubeGrid_OnClose; registry.Add(CubeGrid, this); // protected by GetFor() log("built for: " + CubeGrid.DisplayName, ".ctor()", Logger.severity.DEBUG); }
private CubeGridCache(IMyCubeGrid grid) { CubeGrid = grid; List <IMySlimBlock> allSlims = new List <IMySlimBlock>(); CubeGrid.GetBlocks_Safe(allSlims); using (lock_blocks.AcquireExclusiveUsing()) foreach (IMySlimBlock slim in allSlims) { Add(slim); } CubeGrid.OnBlockAdded += CubeGrid_OnBlockAdded; CubeGrid.OnBlockRemoved += CubeGrid_OnBlockRemoved; CubeGrid.OnClosing += CubeGrid_OnClosing; Registrar.Add(CubeGrid, this); Log.DebugLog("built for: " + CubeGrid.DisplayName, Logger.severity.DEBUG); }
private bool getClosestBlock(IMyCubeGrid grid, out IMyEntity closestBlock) { List <IMySlimBlock> allBlocks = new List <IMySlimBlock>(); grid.GetBlocks_Safe(allBlocks, slim => slim.FatBlock != null); double closestDistanceSquared = myTurretBase.Range * myTurretBase.Range; closestBlock = null; foreach (IMySlimBlock slim in allBlocks) { double distanceSquared = (slim.FatBlock.GetPosition() - turretPosition).LengthSquared(); if (distanceSquared < closestDistanceSquared && canLase(slim.FatBlock)) { closestDistanceSquared = distanceSquared; closestBlock = slim.FatBlock; } } return(closestBlock != null); }
/// <param name="offenders">entities to test</param> /// <param name="myGridShape">iff null, skip rejection test</param> private IMyEntity TestEntities(ICollection <IMyEntity> offenders, Capsule path, GridShapeProfiler myGridShape, out Vector3?pointOfObstruction, IMyCubeGrid GridDestination) { foreach (IMyEntity entity in offenders) { CheckInterrupt(); myLogger.debugLog("testing offender: " + entity.getBestName() + " at " + entity.GetPosition(), "TestEntities()"); IMyCubeGrid asGrid = entity as IMyCubeGrid; if (asGrid != null) { if (asGrid == GridDestination) { myLogger.debugLog("grid is destination: " + asGrid.DisplayName, "TestEntities()"); continue; } if (!path.IntersectsAABB(entity)) { myLogger.debugLog("no AABB intersection: " + asGrid.DisplayName, "TestEntities()"); continue; } myLogger.debugLog("searching blocks of " + entity.getBestName(), "TestEntities()"); uint cellCount = 0, cellRejectedCount = 0; // foreach block float GridSize = asGrid.GridSize; List <IMySlimBlock> allSlims = new List <IMySlimBlock>(); asGrid.GetBlocks_Safe(allSlims); foreach (IMySlimBlock slim in allSlims) { bool blockIntersects = false; Vector3 cellPosWorld = new Vector3(); //myLogger.debugLog("slim = " + slim.getBestName() + ", fat = " + slim.FatBlock + ", cell = " + slim.Position, "TestEntities()"); //if (slim.FatBlock != null) //{ // myLogger.debugLog("fatblock min = " + slim.FatBlock.Min + ", fatblock max = " + slim.FatBlock.Max, "TestEntities()"); // //myLogger.debugLog("fatblock AABB min = " + slim.FatBlock.LocalAABB.Min + ", fatblock AABB max = " + slim.FatBlock.LocalAABB.Max, "TestEntities()"); //} slim.ForEachCell((cell) => { CheckInterrupt(); cellPosWorld = asGrid.GridIntegerToWorld(cell); cellCount++; //myLogger.debugLog("slim = " + slim.getBestName() + ", cell = " + cell + ", world position = " + cellPosWorld, "TestEntities()"); // intersects capsule if (!path.Intersects(cellPosWorld, GridSize)) { return(false); } // rejection cellRejectedCount++; if (myGridShape == null || myGridShape.rejectionIntersects(RelativeVector3F.createFromWorldAbsolute(cellPosWorld, myCubeGrid), myCubeGrid.GridSize)) { myLogger.debugLog("obstructing grid = " + asGrid.DisplayName + ", cell = " + cellPosWorld + ", block = " + slim.getBestName(), "TestEntities()", Logger.severity.DEBUG); blockIntersects = true; return(true); } //myLogger.debugLog("rejection: no collision, cell = " + cellPosWorld + ", block = " + slim.getBestName(), "TestEntities()", Logger.severity.DEBUG); return(false); }); if (blockIntersects) { //myLogger.debugLog("closest point on line: {" + path.get_Line().From + ", " + path.get_Line().To + "} to " + cellPosWorld + " is " + path.get_Line().ClosestPoint(cellPosWorld), "TestEntities()"); pointOfObstruction = path.get_Line().ClosestPoint(cellPosWorld); return(entity); } } myLogger.debugLog("no obstruction for grid " + asGrid.DisplayName + ", tested " + cellCount + " against capsule and " + cellRejectedCount + " against rejection", "TestPath()"); continue; } // not a grid if (IgnoreAsteroids && entity is IMyVoxelMap) { myLogger.debugLog("Ignoring asteroid: " + entity.getBestName(), "TestEntities()"); continue; } myLogger.debugLog("not a grid, testing bounds", "TestEntities()"); if (!path.IntersectsAABB(entity)) { continue; } if (!path.IntersectsVolume(entity)) { continue; } myLogger.debugLog("no more tests for non-grids are implemented", "TestEntities()", Logger.severity.DEBUG); //myLogger.debugLog("closest point on line: {" + path.get_Line().From + ", " + path.get_Line().To + "} to " + entity.GetCentre() + " is " + path.get_Line().ClosestPoint(entity.GetCentre()), "TestEntities()"); pointOfObstruction = path.get_Line().ClosestPoint(entity.GetCentre()); return(entity); } myLogger.debugLog("no obstruction was found", "TestPath()", Logger.severity.DEBUG); pointOfObstruction = null; return(null); }
/// <summary> /// Gets the best block to target from a grid. /// </summary> /// <param name="grid">The grid to search</param> /// <param name="tType">Checked for destroy</param> /// <param name="target">The best block fromt the grid</param> /// <param name="distanceValue">The value assigned based on distance and position in blocksToTarget.</param> /// <remarks> /// <para>Decoy blocks will be given a distanceValue of the distance squared to weapon.</para> /// <para>Blocks from blocksToTarget will be given a distanceValue of the distance squared * (2 + index)^2.</para> /// <para>Other blocks will be given a distanceValue of the distance squared * (1e12).</para> /// </remarks> private bool GetTargetBlock(IMyCubeGrid grid, TargetType tType, out IMyCubeBlock target, out double distanceValue) { myLogger.debugLog("getting block from " + grid.DisplayName + ", target type = " + tType, "GetTargetBlock()"); Vector3D myPosition = ProjectilePosition(); CubeGridCache cache = CubeGridCache.GetFor(grid); target = null; distanceValue = double.MaxValue; if (cache.TotalByDefinition() == 0) { myLogger.debugLog("no terminal blocks on grid: " + grid.DisplayName, "GetTargetBlock()"); return false; } // get decoy block { var decoyBlockList = cache.GetBlocksOfType(typeof(MyObjectBuilder_Decoy)); if (decoyBlockList != null) foreach (IMyTerminalBlock block in decoyBlockList) { if (!block.IsWorking) continue; if (!CanRotateTo(block.GetPosition())) continue; if (Blacklist.Contains(block)) continue; double distanceSq = Vector3D.DistanceSquared(myPosition, block.GetPosition()); if (distanceSq > Options.TargetingRangeSquared) continue; if (distanceSq < distanceValue && CubeBlock.canConsiderHostile(block as IMyCubeBlock)) { target = block as IMyCubeBlock; distanceValue = distanceSq; } } if (target != null) { myLogger.debugLog("for type = " + tType + " and grid = " + grid.DisplayName + ", found a decoy block: " + target.DisplayNameText + ", distanceValue: " + distanceValue, "GetTargetBlock()"); return true; } } // get block from blocksToTarget int multiplier = 1; foreach (string blocksSearch in Options.blocksToTarget) { multiplier++; var master = cache.GetBlocksByDefLooseContains(blocksSearch); foreach (var blocksWithDef in master) foreach (IMyCubeBlock block in blocksWithDef) { if (!TargetableBlock(block, true)) { myLogger.debugLog("not targetable: " + block.DisplayNameText, "GetTargetBlock()"); continue; } if (Blacklist.Contains(block)) { myLogger.debugLog("blacklisted: " + block.DisplayNameText, "GetTargetBlock()"); continue; } double distanceSq = Vector3D.DistanceSquared(myPosition, block.GetPosition()); if (distanceSq > Options.TargetingRangeSquared) { myLogger.debugLog("too far: " + block.DisplayNameText + ", distanceSq = " + distanceSq + ", TargetingRangeSquared = " + Options.TargetingRangeSquared, "GetTargetBlock()"); continue; } distanceSq *= multiplier * multiplier * multiplier; //myLogger.debugLog("blocksSearch = " + blocksSearch + ", block = " + block.DisplayNameText + ", distance value = " + distanceSq, "GetTargetBlock()"); if (distanceSq < distanceValue && CubeBlock.canConsiderHostile(block)) { target = block; distanceValue = distanceSq; } //else // myLogger.debugLog("have a closer block than " + block.DisplayNameText + ", close = " + target.getBestName() + ", distance value = " + distanceValue, "GetTargetBlock()"); } if (target != null) // found a block from blocksToTarget { myLogger.debugLog("for type = " + tType + " and grid = " + grid.DisplayName + ", blocksSearch = " + blocksSearch + ", target = " + target.DisplayNameText + ", distanceValue = " + distanceValue, "GetTargetBlock()"); return true; } } // get any terminal block if (tType == TargetType.Moving || tType == TargetType.Destroy) { List<IMySlimBlock> allSlims = new List<IMySlimBlock>(); grid.GetBlocks_Safe(allSlims, (slim) => slim.FatBlock != null); foreach (IMySlimBlock slim in allSlims) if (TargetableBlock(slim.FatBlock, false)) { if (Blacklist.Contains(slim.FatBlock)) continue; double distanceSq = Vector3D.DistanceSquared(myPosition, slim.FatBlock.GetPosition()); if (distanceSq > Options.TargetingRangeSquared) continue; distanceSq *= 1e12; if (CubeBlock.canConsiderHostile(slim.FatBlock)) { target = slim.FatBlock; distanceValue = distanceSq; myLogger.debugLog("for type = " + tType + " and grid = " + grid.DisplayName + ", found a block: " + target.DisplayNameText + ", distanceValue = " + distanceValue, "GetTargetBlock()"); return true; } } } return false; }
/// <summary> /// Gets the best block to target from a grid. /// </summary> /// <param name="grid">The grid to search</param> /// <param name="tType">Checked for destroy</param> /// <param name="target">The best block fromt the grid</param> /// <param name="distanceValue">The value assigned based on distance and position in blocksToTarget.</param> /// <remarks> /// <para>Decoy blocks will be given a distanceValue of the distance squared to weapon.</para> /// <para>Blocks from blocksToTarget will be given a distanceValue of the distance squared * (index + 1)^3.</para> /// <para>Other blocks will be given a distanceValue of the distance squared * (1e12).</para> /// </remarks> public bool GetTargetBlock(IMyCubeGrid grid, TargetType tType, out IMyCubeBlock target, out double distanceValue, bool doRangeTest = true) { //myLogger.debugLog("getting block from " + grid.DisplayName + ", target type = " + tType, "GetTargetBlock()"); Vector3D myPosition = ProjectilePosition(); CubeGridCache cache = CubeGridCache.GetFor(grid); target = null; distanceValue = double.MaxValue; if (cache.TerminalBlocks == 0) { //myLogger.debugLog("no terminal blocks on grid: " + grid.DisplayName, "GetTargetBlock()"); return false; } // get decoy block { var decoyBlockList = cache.GetBlocksOfType(typeof(MyObjectBuilder_Decoy)); if (decoyBlockList != null) foreach (IMyCubeBlock block in decoyBlockList) { if (!TargetableBlock(block, true)) continue; double distanceSq = Vector3D.DistanceSquared(myPosition, block.GetPosition()); if (doRangeTest && distanceSq > Options.TargetingRangeSquared) continue; if (distanceSq < distanceValue && CubeBlock.canConsiderHostile(block)) { target = block; distanceValue = distanceSq; } } if (target != null) { //myLogger.debugLog("for type = " + tType + " and grid = " + grid.DisplayName + ", found a decoy block: " + target.DisplayNameText + ", distanceValue: " + distanceValue, "GetTargetBlock()"); return true; } } // get block from blocksToTarget if (!Options.blocksToTarget.IsNullOrEmpty()) { int index = 0; IMyCubeBlock in_target = target; double in_distValue = distanceValue; Options.listOfBlocks.ForEach(cache, ref index, block => { if (!TargetableBlock(block, true)) return; double distSq = Vector3D.DistanceSquared(myPosition, block.GetPosition()); if (doRangeTest && distSq > Options.TargetingRangeSquared) return; int multiplier = index + 1; distSq *= multiplier * multiplier * multiplier; if (distSq < in_distValue && CubeBlock.canConsiderHostile(block)) { in_target = block; in_distValue = distSq; } }); target = in_target; distanceValue = in_distValue; if (target != null) // found a block from blocksToTarget { //myLogger.debugLog("for type = " + tType + " and grid = " + grid.DisplayName + ", target = " + target.DisplayNameText + // ", distance = " + Vector3D.Distance(myPosition, target.GetPosition()) + ", distanceValue = " + distanceValue); return true; } } // get any IMyTerminalBlock bool destroy = (tType & TargetType.Moving) != 0 || (tType & TargetType.Destroy) != 0; if (destroy || Options.blocksToTarget.IsNullOrEmpty()) { List<IMySlimBlock> allSlims = new List<IMySlimBlock>(); grid.GetBlocks_Safe(allSlims, (slim) => slim.FatBlock is IMyTerminalBlock); double closest = double.MaxValue; foreach (IMySlimBlock slim in allSlims) if (TargetableBlock(slim.FatBlock, !destroy)) { double distanceSq = Vector3D.DistanceSquared(myPosition, slim.FatBlock.GetPosition()); if (doRangeTest && distanceSq > Options.TargetingRangeSquared) continue; distanceSq *= 1e12; if (distanceSq < closest && CubeBlock.canConsiderHostile(slim.FatBlock)) { target = slim.FatBlock; distanceValue = distanceSq; } } if (target != null) { //myLogger.debugLog("for type = " + tType + " and grid = " + grid.DisplayName + ", found a block: " + target.DisplayNameText + ", distanceValue = " + distanceValue); return true; } } return false; }