/// <summary> /// Determines if two grids are attached. /// </summary> /// <param name="grid0">The starting grid.</param> /// <param name="grid1">The grid to search for.</param> /// <param name="allowedConnections">The types of connections allowed between grids.</param> /// <returns>True iff the grids are attached.</returns> public static bool IsGridAttached(IMyCubeGrid grid0, IMyCubeGrid grid1, AttachmentKind allowedConnections) { Logger.DebugLog("condition: grid0 == null", Logger.severity.FATAL, condition: grid0 == null); Logger.DebugLog("condition: grid1 == null", Logger.severity.FATAL, condition: grid1 == null); if (grid0 == grid1) { return(true); } AttachedGrid attached1 = GetFor(grid0); if (attached1 == null) { return(false); } AttachedGrid attached2 = GetFor(grid1); if (attached2 == null) { return(false); } HashSet <AttachedGrid> search = s_searchSet.Get(); bool result = attached1.IsGridAttached(attached2, allowedConnections, search); search.Clear(); s_searchSet.Return(search); return(result); }
private void AddRemoveConnection(AttachmentKind kind, AttachedGrid attached, bool add) { Attachments attach; if (!Connections.TryGetValue(attached, out attach)) { if (add) { attach = new Attachments(myGrid, attached.myGrid); Connections.Add(attached, attach); } else { Log.AlwaysLog("cannot remove, no attachments of kind " + kind, Logger.severity.ERROR); return; } } if (add) { attach.Add(kind); } else { attach.Remove(kind); } }
private static AttachedGrid GetFor(IMyCubeGrid grid) { if (Globals.WorldClosed) { return(null); } Logger.DebugLog("grid == null", Logger.severity.FATAL, condition: grid == null); AttachedGrid attached; if (!Registrar.TryGetValue(grid.EntityId, out attached)) { if (grid.Closed) { return(null); } using (lock_construct.AcquireExclusiveUsing()) if (!Registrar.TryGetValue(grid.EntityId, out attached)) { attached = new AttachedGrid(grid); } } return(attached); }
/// <summary> /// Yields attached grids. /// </summary> /// <param name="startGrid">Grid to start search from.</param> /// <param name="allowedConnections">The types of connections allowed between grids.</param> /// <param name="runOnStartGrid">If true, yields the startGrid.</param> /// <returns>Each attached grid.</returns> public static IEnumerable <IMyCubeGrid> AttachedGrids(IMyCubeGrid startGrid, AttachmentKind allowedConnections, bool runOnStartGrid) { if (runOnStartGrid) { yield return(startGrid); } AttachedGrid attached = GetFor(startGrid); if (attached == null) { yield break; } HashSet <AttachedGrid> search = s_searchSet.Get(); try { foreach (IMyCubeGrid grid in attached.Attached(allowedConnections, search)) { yield return(grid); } } finally { search.Clear(); s_searchSet.Return(search); } }
protected AttachableBlockBase(IMyCubeBlock block, AttachedGrid.AttachmentKind kind) { myLogger = new Logger("AttachableBlockBase", block); AttachmentKind = kind; myBlock = block; myLogger.debugLog("Created for: " + block.DisplayNameText, "AttachableBlockBase()"); block.OnClose += Detach; Registrar.Add(this.myBlock, this); }
private void Attach(IMyCubeGrid grid, bool force) { if (!force && grid == curAttTo) { return; } Detach(); myGrid = myBlock.CubeGrid; myGrid.OnMarkForClose += Detach; grid.OnMarkForClose += Detach; Logger.DebugLog("attaching " + myGrid.DisplayName + " to " + grid.DisplayName, Logger.severity.DEBUG); AttachedGrid.AddRemoveConnection(AttachmentKind, myGrid, grid, true); curAttTo = grid; }
internal static void AddRemoveConnection(AttachmentKind kind, IMyCubeGrid grid1, IMyCubeGrid grid2, bool add) { if (grid1 == grid2 || Globals.WorldClosed) { return; } AttachedGrid attached1 = GetFor(grid1), attached2 = GetFor(grid2); if (attached1 == null || attached2 == null) { return; } attached1.AddRemoveConnection(kind, attached2, add); attached2.AddRemoveConnection(kind, attached1, add); }
/// <summary> /// Creates a GridFinder to find a friendly grid based on its name. /// </summary> public GridFinder(AllNavigationSettings navSet, ShipControllerBlock controller, string targetGrid, string targetBlock = null, AttachedGrid.AttachmentKind allowedAttachment = AttachedGrid.AttachmentKind.Permanent, bool mustBeRecent = false) { this.m_logger = new Logger(GetType().Name, controller.CubeBlock); m_logger.debugLog(navSet == null, "navSet == null", Logger.severity.FATAL); m_logger.debugLog(controller == null, "controller == null", Logger.severity.FATAL); m_logger.debugLog(controller.CubeBlock == null, "controller.CubeBlock == null", Logger.severity.FATAL); m_logger.debugLog(targetGrid == null, "targetGrid == null", Logger.severity.FATAL); this.m_targetGridName = targetGrid.LowerRemoveWhitespace(); if (targetBlock != null) this.m_targetBlockName = targetBlock.LowerRemoveWhitespace(); this.m_controlBlock = controller; this.m_allowedAttachment = allowedAttachment; this.MaximumRange = float.MaxValue; this.m_navSet = navSet; this.m_mustBeRecent = mustBeRecent; }
/// <summary> /// Creates a GridFinder to find a friendly grid based on its name. /// </summary> public GridFinder(AllNavigationSettings navSet, ShipControllerBlock controller, string targetGrid, string targetBlock = null, AttachedGrid.AttachmentKind allowedAttachment = AttachedGrid.AttachmentKind.Permanent) { this.m_logger = new Logger(GetType().Name + " friendly", controller.CubeBlock); m_logger.debugLog(navSet == null, "navSet == null", "GridFinder()", Logger.severity.FATAL); m_logger.debugLog(controller == null, "controller == null", "GridFinder()", Logger.severity.FATAL); m_logger.debugLog(controller.CubeBlock == null, "controller.CubeBlock == null", "GridFinder()", Logger.severity.FATAL); m_logger.debugLog(targetGrid == null, "targetGrid == null", "GridFinder()", Logger.severity.FATAL); if (!Registrar.TryGetValue(controller.CubeBlock.EntityId, out this.m_controller)) throw new NullReferenceException("ShipControllerBlock is not a ShipController"); this.m_targetGridName = targetGrid.LowerRemoveWhitespace(); if (targetBlock != null) this.m_targetBlockName = targetBlock.LowerRemoveWhitespace(); this.m_controlBlock = controller; this.m_allowedAttachment = allowedAttachment; this.MaximumRange = float.MaxValue; this.m_navSet = navSet; }
private bool IsGridAttached(AttachedGrid target, AttachmentKind allowedConnections, HashSet <AttachedGrid> searched) { if (!searched.Add(this)) { throw new Exception("AttachedGrid already searched"); } foreach (var gridAttach in Connections) { if ((gridAttach.Value.attachmentKinds & allowedConnections) == 0 || searched.Contains(gridAttach.Key)) { continue; } if (gridAttach.Key == target || gridAttach.Key.IsGridAttached(target, allowedConnections, searched)) { return(true); } } return(false); }
protected void Detach() { if (curAttTo == null) { return; } if (Globals.WorldClosed) { return; } myGrid.OnMarkForClose -= Detach; curAttTo.OnMarkForClose -= Detach; if (curAttToBlock != null) { curAttToBlock.OnMarkForClose -= Detach; curAttToBlock = null; } Logger.DebugLog("detaching " + myGrid.DisplayName + " from " + curAttTo.DisplayName, Logger.severity.DEBUG); AttachedGrid.AddRemoveConnection(AttachmentKind, myGrid, curAttTo, false); curAttTo = null; }
/// <summary> /// Finds a block that is attached to Controller /// </summary> /// <remarks> /// Search is performed immediately. /// </remarks> private bool GetLocalBlock(string searchFor, out IMyCubeBlock localBlock, AttachedGrid.AttachmentKind allowedAttachments = AttachedGrid.AttachmentKind.None) { IMyCubeBlock foundBlock = null; int bestNameLength = int.MaxValue; m_logger.debugLog("searching for localBlock: " + searchFor, "GetLocalBlock()"); AttachedGrid.RunOnAttachedBlock(Controller.CubeGrid, allowedAttachments, slim => { IMyCubeBlock Fatblock = slim.FatBlock; if (Fatblock != null && Controller.CubeBlock.canControlBlock(Fatblock)) { string blockName; try { blockName = Fatblock.getNameOnly().LowerRemoveWhitespace(); } catch (NullReferenceException ex) { m_logger.alwaysLog("Failed to process block name of " + Fatblock.DisplayNameText + '/' + Fatblock.DefinitionDisplayNameText, "GetLocalBlock()", Logger.severity.ERROR); throw ex; } if (blockName.Length < bestNameLength && blockName.Contains(searchFor)) { foundBlock = Fatblock; bestNameLength = blockName.Length; if (searchFor.Length == bestNameLength) { m_logger.debugLog("found a perfect match for: " + searchFor + ", block name: " + blockName, "GetLocalBlock()"); return true; } } } return false; }, true); if (foundBlock == null) { m_logger.debugLog("could not get a localBlock for " + searchFor, "GetLocalBlock()", Logger.severity.INFO); Errors.AppendLine("Not Found: " + searchFor); localBlock = null; return false; } localBlock = foundBlock; m_logger.debugLog("found localBlock: " + foundBlock.DisplayNameText, "GetLocalBlock()"); return true; }
public AttachableBlockUpdate(IMyCubeBlock block, AttachedGrid.AttachmentKind kind) : base(block, kind) { this.myLogger = new Logger("AttachableBlockPair", block); //Registrar.Add(this.myBlock, this); }
private void AddRemoveConnection(AttachmentKind kind, AttachedGrid attached, bool add) { using (lock_Connections.AcquireExclusiveUsing()) { Attachments attach; if (!Connections.TryGetValue(attached, out attach)) { if (add) { attach = new Attachments(myGrid, attached.myGrid); Connections.Add(attached, attach); } else { myLogger.alwaysLog("cannot remove, no attachments of kind " + kind, Logger.severity.ERROR); return; } } if (add) attach.Add(kind); else attach.Remove(kind); } }
private bool IsGridAttached(AttachedGrid target, AttachmentKind allowedConnections, uint searchId) { myLogger.debugLog(lastSearchId == searchId, "Already searched! lastSearchId == searchId", "IsGridAttached()", Logger.severity.ERROR); lastSearchId = searchId; using (lock_Connections.AcquireSharedUsing()) foreach (var gridAttachments in Connections) { if (searchId == gridAttachments.Key.lastSearchId) continue; if ((gridAttachments.Value.attachmentKinds & allowedConnections) == 0) continue; if (gridAttachments.Key == target) return true; if (gridAttachments.Key.IsGridAttached(target, allowedConnections, searchId)) return true; } return false; }
private void AddRemoveConnection(AttachmentKind kind, AttachedGrid attached, bool add) { using (lock_Connections.AcquireExclusiveUsing()) { Attachments attach; if (!Connections.TryGetValue(attached, out attach)) { attach = new Attachments(myGrid, attached.myGrid); Connections.Add(attached, attach); } if (add) attach.Add(kind); else attach.Remove(kind); } }
private static AttachedGrid GetFor(IMyCubeGrid grid) { AttachedGrid attached; if (!Registrar.TryGetValue(grid.EntityId, out attached)) { if (grid.Closed) return null; attached = new AttachedGrid(grid); } return attached; }
public FlyToGrid(Mover mover, AllNavigationSettings navSet, string targetGrid, AttachedGrid.AttachmentKind allowedAttachment = AttachedGrid.AttachmentKind.Permanent) : base(mover, navSet) { this.m_logger = new Logger(GetType().Name, m_controlBlock.CubeBlock, () => m_landingState.ToString()); this.m_targetBlock = m_navSet.Settings_Current.DestinationBlock; string blockName = m_targetBlock == null ? null : m_targetBlock.BlockName; this.m_gridFinder = new GridFinder(m_navSet, m_mover.Block, targetGrid, blockName, allowedAttachment); this.m_contBlock = m_navSet.Settings_Commands.NavigationBlock; PseudoBlock landingBlock = m_navSet.Settings_Current.LandingBlock; m_navBlock = landingBlock ?? m_navSet.Settings_Current.NavigationBlock; if (landingBlock != null) { if (landingBlock.Block is IMyFunctionalBlock) m_landingState = LandingState.Approach; else { m_logger.debugLog("landingBlock is not functional, player error? : " + landingBlock.Block.DisplayNameText, "FlyToGrid()", Logger.severity.INFO); m_landingState = LandingState.None; } if (m_targetBlock == null) { if (!(landingBlock.Block is IMyLandingGear)) { m_logger.debugLog("cannot land block without a target", "FlyToGrid()", Logger.severity.INFO); m_landingState = LandingState.None; } else { m_logger.debugLog("golden retriever mode enabled", "FlyToGrid()", Logger.severity.INFO); m_landGearWithoutTargetBlock = true; } } else if (landingBlock.Block is Ingame.IMyShipConnector) { m_gridFinder.BlockCondition = block => { Ingame.IMyShipConnector connector = block as Ingame.IMyShipConnector; return connector != null && (!connector.IsConnected || connector.OtherConnector == m_navBlock.Block); }; m_landingDirection = m_targetBlock.Forward ?? Base6Directions.GetFlippedDirection(landingBlock.Block.GetFaceDirection()[0]); } else if (landingBlock.Block is IMyShipMergeBlock) { m_gridFinder.BlockCondition = block => block is IMyShipMergeBlock; m_landingDirection = m_targetBlock.Forward ?? Base6Directions.GetFlippedDirection(landingBlock.Block.GetFaceDirection()[0]); (landingBlock.Block as IMyShipMergeBlock).BeforeMerge += MergeBlock_BeforeMerge; } else if (m_targetBlock.Forward.HasValue) m_landingDirection = m_targetBlock.Forward.Value; else { m_logger.debugLog("Player failed to specify landing direction and it could not be determined.", "FlyToGrid()", Logger.severity.INFO); m_landingState = LandingState.None; } if (m_landingState != LandingState.None) { float minDestRadius = m_controlBlock.CubeGrid.GetLongestDim() * 5f; if (m_navSet.Settings_Current.DestinationRadius < minDestRadius) { m_logger.debugLog("Increasing DestinationRadius from " + m_navSet.Settings_Current.DestinationRadius + " to " + minDestRadius, "FlyToGrid()", Logger.severity.DEBUG); m_navSet.Settings_Task_NavRot.DestinationRadius = minDestRadius; } new UnLander(mover, navSet, landingBlock); m_landingHalfSize = landingBlock.Block.GetLengthInDirection(landingBlock.Block.LocalMatrix.GetClosestDirection(landingBlock.LocalMatrix.Forward)) * 0.5f; m_logger.debugLog("m_landing direction: " + m_landingDirection + ", m_landingBlockSize: " + m_landingHalfSize, "FlyToGrid()"); } } m_navSet.Settings_Task_NavMove.NavigatorMover = this; }
/// <summary> /// Finds a block that is attached to Controller /// </summary> /// <remarks> /// Search is performed immediately. /// </remarks> private bool GetLocalBlock(string searchFor, out IMyCubeBlock localBlock, AttachedGrid.AttachmentKind allowedAttachments = AttachedGrid.AttachmentKind.None) { IMyCubeBlock foundBlock = null; int bestNameLength = int.MaxValue; m_logger.debugLog("searching for localBlock: " + searchFor, "GetLocalBlock()"); AttachedGrid.RunOnAttachedBlock(Controller.CubeGrid, allowedAttachments, slim => { IMyCubeBlock Fatblock = slim.FatBlock; if (Fatblock != null && Controller.CubeBlock.canControlBlock(Fatblock)) { string blockName = ShipController_Autopilot.IsAutopilotBlock(Fatblock) ? Fatblock.getNameOnly().LowerRemoveWhitespace() : Fatblock.DisplayNameText.LowerRemoveWhitespace(); //myLogger.debugLog("checking: " + blockName, "GetLocalBlock()"); if (blockName.Length < bestNameLength && blockName.Contains(searchFor)) { foundBlock = Fatblock; bestNameLength = blockName.Length; if (searchFor.Length == bestNameLength) { m_logger.debugLog("found a perfect match for: " + searchFor + ", block name: " + blockName, "GetLocalBlock()"); return true; } } } return false; }, true); if (foundBlock == null) { m_logger.debugLog("could not get a localBlock for " + searchFor, "GetLocalBlock()", Logger.severity.INFO); Errors.AppendLine("Not Found: " + searchFor); localBlock = null; return false; } localBlock = foundBlock; m_logger.debugLog("found localBlock: " + foundBlock.DisplayNameText, "GetLocalBlock()"); return true; }