/// <summary> /// Determines if the given grid has an autopilot block. Does check ServerSettings. /// </summary> /// <param name="grid">The grid to search</param> /// <returns>True iff the given grid contains one or more autopilot blocks.</returns> public static bool HasAutopilotBlock(IMyCubeGrid grid) { if (!ServerSettings.GetSetting <bool>(ServerSettings.SettingName.bAllowAutopilot)) { return(false); } var cache = CubeGridCache.GetFor(grid); foreach (IMyCubeBlock cockpit in cache.BlocksOfType(typeof(MyObjectBuilder_Cockpit))) { if (IsAutopilotBlock(cockpit)) { return(true); } } if (ServerSettings.GetSetting <bool>(ServerSettings.SettingName.bUseRemoteControl)) { foreach (IMyCubeBlock remote in cache.BlocksOfType(typeof(MyObjectBuilder_RemoteControl))) { if (IsAutopilotBlock(remote)) { return(true); } } } return(false); }
protected void EnableDrills(bool enable) { if (enable) { Log.DebugLog("Enabling drills", Logger.severity.DEBUG); } else { Log.DebugLog("Disabling drills", Logger.severity.DEBUG); } CubeGridCache cache = CubeGridCache.GetFor(m_controlBlock.CubeGrid); if (cache == null) { Log.DebugLog("Failed to get cache", Logger.severity.INFO); return; } MyAPIGateway.Utilities.TryInvokeOnGameThread(() => { foreach (IMyShipDrill drill in cache.BlocksOfType(typeof(MyObjectBuilder_Drill))) { if (!drill.Closed) { ((MyFunctionalBlock)drill).Enabled = enable; } } }); }
/// <summary> /// Enabled/disable all welders. /// </summary> private void EnableWelders(bool enable) { if (enable == m_weldersEnabled) { return; } m_weldersEnabled = enable; if (enable) { Log.DebugLog("Enabling welders", Logger.severity.DEBUG); } else { Log.DebugLog("Disabling welders", Logger.severity.DEBUG); } var cache = CubeGridCache.GetFor(m_controlBlock.CubeGrid); if (cache == null) { Log.DebugLog("Failed to get cache", Logger.severity.INFO); return; } MyAPIGateway.Utilities.TryInvokeOnGameThread(() => { foreach (MyShipWelder welder in cache.BlocksOfType(typeof(MyObjectBuilder_ShipWelder))) { if (!welder.Closed) { welder.Enabled = enable; } } }); }
///// <summary>Current stage of harvesting</summary> //private Action StageAction; public HarvesterAsteroid(Navigator myNav) { this.myNav = myNav; this.myCache = CubeGridCache.GetFor(myCubeGrid); this.myLogger = new Logger("HarvesterAsteroid", () => myCubeGrid.DisplayName, () => { return(CNS.moveState + ":" + CNS.rotateState); }); HarvestState = Navigator.ReportableState.H_Ready; }
public WeldGrid(Pathfinder pathfinder, string gridName, bool shopAfter) : base(pathfinder) { this.m_finder = new GridFinder(pathfinder.NavSet, m_controlBlock, gridName); this.m_shopAfter = shopAfter; PseudoBlock navBlock = m_navSet.Settings_Current.NavigationBlock; if (navBlock.Block is IMyShipWelder) { m_navWeld = new MultiBlock <MyObjectBuilder_ShipWelder>(navBlock.Block); } else { CubeGridCache cache = CubeGridCache.GetFor(m_controlBlock.CubeGrid); if (cache == null) { Log.DebugLog("failed to get cache", Logger.severity.WARNING); return; } if (cache.CountByType(typeof(MyObjectBuilder_ShipWelder)) < 1) { Log.DebugLog("no welders on ship", Logger.severity.WARNING); return; } m_navWeld = new MultiBlock <MyObjectBuilder_ShipWelder>(() => m_mover.Block.CubeGrid); } UpdateTimeout(); m_navSet.Settings_Task_NavMove.NavigatorMover = this; }
private bool GrinderFull() { if (Globals.UpdateCount < m_nextGrinderCheck) { return(m_grinderFull); } m_nextGrinderCheck = Globals.UpdateCount + 100ul; EnableGrinders(m_enabledGrinders); MyFixedPoint content = 0, capacity = 0; int grinderCount = 0; foreach (IMyShipGrinder grinder in CubeGridCache.GetFor(m_controlBlock.CubeGrid).BlocksOfType(typeof(MyObjectBuilder_ShipGrinder))) { MyInventoryBase grinderInventory = ((MyEntity)grinder).GetInventoryBase(0); content += grinderInventory.CurrentVolume; capacity += grinderInventory.MaxVolume; grinderCount++; } m_grinderFull = capacity <= 0 || (float)content / (float)capacity >= 0.9f; return(m_grinderFull); }
public ThrustProfiler(IMyCubeBlock autopilot) { if (autopilot == null) { throw new NullReferenceException("autopilot"); } m_autopilot = autopilot; myGrid = autopilot.CubeGrid; Standard = new StandardFlight(autopilot, Base6Directions.Direction.Forward, Base6Directions.Direction.Up); Gravity = new StandardFlight(autopilot, Base6Directions.Direction.Up, Base6Directions.Direction.Forward); for (int i = 0; i < 6; i++) { m_thrustersInDirection[i] = new List <MyThrust>(); } CubeGridCache cache = CubeGridCache.GetFor(myGrid); if (cache == null) { return; } foreach (MyThrust thrust in cache.BlocksOfType(typeof(MyObjectBuilder_Thrust))) { newThruster(thrust); } myGrid.OnBlockAdded += grid_OnBlockAdded; myGrid.OnBlockRemoved += grid_OnBlockRemoved; MyAPIGateway.Utilities.InvokeOnGameThread(ClearOverrides); }
public void UpdateTarget(AntennaRelay.LastSeen enemy) { if (enemy == null) { return; } foreach (IMyCubeGrid grid in AttachedGrid.AttachedGrids(m_block.CubeGrid, AttachedGrid.AttachmentKind.Terminal, true)) { CubeGridCache cache = CubeGridCache.GetFor(grid); if (cache == null) { continue; } foreach (IMyCubeBlock warhead in cache.BlocksOfType(typeof(MyObjectBuilder_Warhead))) { if (m_block.canControlBlock(warhead)) { Log.DebugLog("Starting countdown for " + warhead.getBestName(), Logger.severity.DEBUG); warhead.ApplyAction("StartCountdown"); } } } m_countingDown = true; }
/// <summary> /// Get all the blocks on the target grid that are damaged /// </summary> private void GetDamagedBlocks() { m_damagedBlocks.Clear(); m_projectedBlocks.Clear(); // get physical blocks foreach (IMySlimBlock slim in Attached.AttachedGrid.AttachedSlimBlocks((IMyCubeGrid)m_currentGrid.Entity, Attached.AttachedGrid.AttachmentKind.Permanent, true)) { if (slim.CurrentDamage > 0f || slim.BuildLevelRatio < 1f) { m_damagedBlocks.Add(slim); } } // get projections HashSet <IMyEntity> projections = null; foreach (IMyCubeGrid grid in Attached.AttachedGrid.AttachedGrids((IMyCubeGrid)m_currentGrid.Entity, Attached.AttachedGrid.AttachmentKind.Permanent, true)) { if (CubeGridCache.GetFor(grid).CountByType(typeof(MyObjectBuilder_Projector)) == 0) { continue; } using (MainLock.AcquireSharedUsing()) { if (projections == null) { projections = new HashSet <IMyEntity>(); MyAPIGateway.Entities.GetEntities(projections, entity => entity is MyCubeGrid && ((MyCubeGrid)entity).Projector != null); if (projections.Count == 0) { break; } } foreach (MyCubeGrid proj in projections) { if (proj.Projector.CubeGrid == grid) { foreach (IMySlimBlock block in proj.CubeBlocks) { m_projectedBlocks.Add(block); } } } } continue; } m_projectedBlocks.ApplyAdditions(); Log.DebugLog("damaged blocks: " + m_damagedBlocks.Count + ", projected blocks: " + m_projectedBlocks.Count); }
public AeroEffects(IMyCubeGrid grid) { this.m_grid = grid; this.m_cache = CubeGridCache.GetFor(m_grid); this.m_profileAt = Globals.UpdateCount + ProfileWait; m_grid.OnBlockAdded += OnBlockChange; m_grid.OnBlockRemoved += OnBlockChange; Registrar.Add(grid, this); }
public FlightControlAssist(MyCockpit cockpit) { this.m_cockpit = cockpit; this.m_aileron = m_elevator = m_rudder = new FlightControlStator[0]; CubeGridCache cache = CubeGridCache.GetFor(m_grid); Pseudo = new PseudoBlock(cockpit); Update.UpdateManager.Register(10, Update10, m_grid); }
///// <summary> ///// Sets the overrides of gyros to match RotateVelocity. Should be called on game thread. ///// </summary> //public void SetOverrides(ref DirectionWorld RotateVelocity) //{ // ReadOnlyList<IMyCubeBlock> gyros = CubeGridCache.GetFor(myGrid).GetBlocksOfType(typeof(MyObjectBuilder_Gyro)); // if (gyros == null) // return; // foreach (MyGyro gyro in gyros) // { // if (!gyro.GyroOverride) // SetOverride(gyro, true); // gyro.SetGyroTorque(RotateVelocity.ToBlock(gyro)); // } //} /// <summary> /// Disable overrides for every gyro. Should be called on game thread. /// </summary> public void ClearOverrides() { foreach (MyGyro gyro in CubeGridCache.GetFor(myGrid).BlocksOfType(typeof(MyObjectBuilder_Gyro))) { if (gyro.GyroOverride) { SetOverride(gyro, false); gyro.SetGyroTorque(Vector3.Zero); } } }
public RotorPicker(IMyTerminalBlock cockpit, string rotorName, ControlRotorParams rotorParams, SetControlRotors onComplete) { m_block = cockpit; m_onComplete = onComplete; IEnumerable <IMyMotorStator> selected; rotorParams(out selected, out m_sensitivity, out m_trim); m_trim = MathHelper.ToDegrees(m_trim); m_listbox = new MyTerminalControlListbox <MyCockpit>("Arms_RotorPicker", MyStringId.GetOrCompute(rotorName + " Rotors"), MyStringId.NullOrEmpty, true, 14); m_listbox.ListContent = ListContent; m_listbox.ItemSelected = ItemSelected; m_sensitivitySlider = new MyTerminalControlSlider <MyCockpit>("Arms_RotorPickerSensitivity", MyStringId.GetOrCompute("Control Sensitivity"), MyStringId.GetOrCompute("How sensitive the ship will be to input")); m_sensitivitySlider.DefaultValue = 1f; m_sensitivitySlider.Getter = b => m_sensitivity; m_sensitivitySlider.Setter = (b, value) => m_sensitivity = value; m_sensitivitySlider.SetLogLimits(0.01f, 100f); m_sensitivitySlider.Writer = (b, sb) => sb.Append(m_sensitivity); m_trimSlider = new MyTerminalControlSlider <MyCockpit>("Arms_RotorPickerTrim", MyStringId.GetOrCompute("Trim"), MyStringId.GetOrCompute("Default angle of rotors")); m_trimSlider.DefaultValue = 0f; m_trimSlider.Getter = b => m_trim; m_trimSlider.Setter = (b, value) => m_trim = value; m_trimSlider.SetLimits(-45f, 45f); m_trimSlider.Writer = (b, sb) => { sb.Append(m_trim); sb.Append('°'); }; m_save = new MyTerminalControlButton <MyCockpit>("Arms_RotorPickerSave", MyStringId.GetOrCompute("Save & Exit"), MyStringId.NullOrEmpty, SaveAndExit); CubeGridCache cache = CubeGridCache.GetFor(m_block.CubeGrid); if (cache == null) { return; } foreach (IMyMotorStator stator in cache.BlocksOfType(typeof(MyObjectBuilder_MotorStator))) { MyGuiControlListbox.Item item = new MyGuiControlListbox.Item(new StringBuilder(stator.DisplayNameText), userData: stator); m_allItems.Add(item); if (selected.Contains(stator)) { m_selected.Add(item); } } MyTerminalControls.Static.CustomControlGetter += CustomControlGetter; cockpit.RebuildControls(); }
public static float GetVolume(IMyEntity entity) { IMyCubeGrid grid = entity as IMyCubeGrid; if (grid != null) { CubeGridCache cache = CubeGridCache.GetFor(grid); if (cache != null) { return(cache.CellCount * grid.GridSize * grid.GridSize * grid.GridSize); } } return(entity.LocalAABB.Volume()); }
private void EnableGrinders(bool enable) { m_enabledGrinders = enable; MyAPIGateway.Utilities.TryInvokeOnGameThread(() => { foreach (IMyShipGrinder grinder in CubeGridCache.GetFor(m_controlBlock.CubeGrid).BlocksOfType(typeof(MyObjectBuilder_ShipGrinder))) { if (!grinder.Closed) { ((MyFunctionalBlock)grinder).Enabled = enable; } } }); }
public Miner(Pathfinder pathfinder, byte[] oreTargets) : base(pathfinder) { m_oreTargets = oreTargets; CubeGridCache cache = CubeGridCache.GetFor(m_controlBlock.CubeGrid); if (cache == null) { return; } if (cache.CountByType(typeof(MyObjectBuilder_Drill)) == 0) { Logger.DebugLog("No drills", Logger.severity.WARNING); return; } // if a drill has been chosen by player, use it PseudoBlock navBlock = m_navSet.Settings_Current.NavigationBlock; MultiBlock <MyObjectBuilder_Drill> navDrill = navBlock.Block is IMyShipDrill ? new MultiBlock <MyObjectBuilder_Drill>(navBlock.Block) : navDrill = new MultiBlock <MyObjectBuilder_Drill>(() => m_mover.Block.CubeGrid); if (navDrill.FunctionalBlocks == 0) { Logger.DebugLog("no working drills", Logger.severity.WARNING); return; } m_navSet.Settings_Task_NavRot.NavigatorMover = this; m_navSet.Settings_Task_NavRot.NavigationBlock = navDrill; BoundingSphereD nearby = new BoundingSphereD(navDrill.WorldPosition, m_controlBlock.CubeGrid.LocalVolume.Radius * 2d); List <MyVoxelBase> nearbyVoxels = new List <MyVoxelBase>(); MyGamePruningStructure.GetAllVoxelMapsInSphere(ref nearby, nearbyVoxels); foreach (MyVoxelBase voxel in nearbyVoxels) { if ((voxel is IMyVoxelMap || voxel is MyPlanet) && voxel.ContainsOrIntersects(ref nearby)) { Log.DebugLog("near a voxel, escape first", Logger.severity.DEBUG); m_stage = Stage.Mining; new EscapeMiner(m_pathfinder, voxel); return; } } m_stage = Stage.GetDeposit; }
private bool findProgBlock() { if (myProgBlock.IsOpen()) // already have one { return(true); } string instruction = myCubeBlock.getInstructions().RemoveWhitespace().ToLower(); string command = command_forProgram.RemoveWhitespace().ToLower(); int destNameIndex = instruction.IndexOf(command) + command.Length; if (destNameIndex >= instruction.Length) { myLogger.debugLog("destNameIndex = " + destNameIndex + ", instruction.Length = " + instruction.Length, "searchForAntenna()", Logger.severity.TRACE); return(false); } string destName = instruction.Substring(destNameIndex); myLogger.debugLog("searching for a programmable block: " + destName, "searchForAntenna()", Logger.severity.TRACE); ReadOnlyList <Ingame.IMyTerminalBlock> progBlocks = CubeGridCache.GetFor(myCubeBlock.CubeGrid).GetBlocksOfType(ProgOBtype); if (progBlocks == null) { myLogger.debugLog("no programmable blocks", "searchForAntenna()", Logger.severity.TRACE); return(false); } foreach (Ingame.IMyTerminalBlock block in progBlocks) { if (block.DisplayNameText.looseContains(destName)) { if (ProgrammableBlock.TryGet(block as IMyCubeBlock, out myProgBlock)) { myLogger.debugLog("found programmable block: " + block.DisplayNameText, "searchForAntenna()", Logger.severity.INFO); return(true); } else { myLogger.debugLog("failed to get receiver for: " + block.DisplayNameText, "searchForAntenna()", Logger.severity.WARNING); return(false); } } } return(false); }
public bool CanTarget(IMyCubeGrid grid) { CubeGridCache cache = null; if (m_destroySet) { cache = CubeGridCache.GetFor(grid); if (cache.TerminalBlocks > 0) { Log.DebugLog("destoy: " + grid.DisplayName); return(true); } else { Log.DebugLog("destroy set but no terminal blocks found: " + grid.DisplayName); } } if (m_currentTarget != null && grid == m_currentTarget.Entity && m_weapon_primary.CurrentTarget.TType != TargetType.None) { return(true); } TargetType gridType = grid.GridSizeEnum == MyCubeSize.Small ? TargetType.SmallGrid : grid.IsStatic ? TargetType.Station : TargetType.LargeGrid; BlockTypeList targetBlocks; if (m_cumulative_targeting.TryGetValue(gridType, out targetBlocks)) { if (cache == null) { cache = CubeGridCache.GetFor(grid); } foreach (IMyCubeBlock block in targetBlocks.Blocks(cache)) { return(true); } } else { Log.DebugLog("no targeting at all for grid type of: " + grid.DisplayName); } return(false); }
/// <summary> /// <para>In survival, returns fraction of drills filled</para> /// <para>In creative, returns content per drill * 0.01</para> /// </summary> private float DrillFullness() { if (Globals.UpdateCount < m_nextCheck_drillFull) { return(m_current_drillFull); } m_nextCheck_drillFull = Globals.UpdateCount + 100ul; MyFixedPoint content = 0, capacity = 0; int drillCount = 0; var cache = CubeGridCache.GetFor(m_controlBlock.CubeGrid); if (cache == null) { m_logger.debugLog("Failed to get cache", Logger.severity.INFO); return(float.MaxValue); } var allDrills = cache.GetBlocksOfType(typeof(MyObjectBuilder_Drill)); if (allDrills == null) { m_logger.debugLog("Failed to get block list", Logger.severity.INFO); return(float.MaxValue); } foreach (IMyShipDrill drill in allDrills) { MyInventoryBase drillInventory = ((MyEntity)drill).GetInventoryBase(0); content += drillInventory.CurrentVolume; capacity += drillInventory.MaxVolume; drillCount++; } if (MyAPIGateway.Session.CreativeMode) { m_current_drillFull = (float)content * 0.01f / drillCount; } else { m_current_drillFull = (float)content / (float)capacity; } return(m_current_drillFull); }
private int WorkingDecoys(IMyEntity target) { IMyCubeGrid grid = target as IMyCubeGrid; if (grid == null || RelationsBlock.canConsiderFriendly(grid)) { return(0); } CubeGridCache cache = CubeGridCache.GetFor(grid); if (cache == null) { return(0); } return(cache.CountByType(typeof(MyObjectBuilder_Decoy), block => block.IsWorking)); }
/// <summary> /// Determines if the ship is capable of digging a tunnel. /// </summary> private bool CanTunnel() { CubeGridCache cache = CubeGridCache.GetFor(m_grid); if (cache == null) { return(false); } BoundingSphere[] sensors = new BoundingSphere[cache.CountByType(typeof(MyObjectBuilder_Drill))]; int drillIndex = 0; foreach (MyShipDrill drill in cache.BlocksOfType(typeof(MyObjectBuilder_Drill))) { float offset = (float)MyShipDrillDefinition__SensorOffset.GetValue(drill.BlockDefinition); float radius = (float)MyShipDrillDefinition__SensorRadius.GetValue(drill.BlockDefinition); sensors[drillIndex++] = new BoundingSphere(drill.LocalPosition() + drill.PositionComp.LocalMatrix.Forward * offset, radius + MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF); } Vector3 forward = m_navBlock.LocalMatrix.Forward; foreach (Vector3I cell in m_grid.FirstBlocks(m_navBlock.LocalMatrix.Backward)) { IMySlimBlock block = m_grid.GetCubeBlock(cell); if (!(block.FatBlock is IMyShipDrill)) { Ray ray = new Ray(cell * m_grid.GridSize, forward); foreach (BoundingSphere sensor in sensors) { if (ray.Intersects(sensor).HasValue) { //Log.DebugLog(block.getBestName() + " is behind a drill"); goto NextBlock; } } //Log.DebugLog(block.getBestName() + " is not behind any drill"); return(false); } NextBlock :; } return(true); }
private void calculateLocalMatrix() { if (Grid.MarkedForClose) { return; } CubeGridCache cache = CubeGridCache.GetFor(Grid); if (cache == null) { return; } Block = null; FunctionalBlocks = 0; Matrix LocalMatrix = Matrix.Zero; Vector3 Translation = Vector3.Zero; foreach (IMyCubeBlock block in cache.BlocksOfType(typeof(T))) { if (Block == null) { Block = block; LocalMatrix = block.LocalMatrix; } if (block.IsFunctional) { FunctionalBlocks++; Translation += block.LocalMatrix.Translation; block.OnClose -= block_OnClose; block.OnClose += block_OnClose; } } if (FunctionalBlocks == 0) { return; } LocalMatrix.Translation = Translation / FunctionalBlocks; this.LocalMatrix = LocalMatrix; return; }
private void CalcGyroForce() { float force = 0f; CubeGridCache cache = CubeGridCache.GetFor(myGrid); if (cache == null) { return; } foreach (MyGyro g in cache.BlocksOfType(typeof(MyObjectBuilder_Gyro))) { if (g.IsWorking) { force += g.MaxGyroForce; // MaxGyroForce accounts for power ratio and modules } } GyroForce = force; }
private bool BatteriesCharged(IMyCubeGrid startGrid) { foreach (IMyCubeGrid attachedGrid in AttachedGrid.AttachedGrids(startGrid, AttachedGrid.AttachmentKind.Permanent, true)) { CubeGridCache cache = CubeGridCache.GetFor(attachedGrid); if (cache == null) { return(false); } foreach (IMyBatteryBlock battery in cache.BlocksOfType(typeof(MyObjectBuilder_BatteryBlock))) { if (battery.IsCharging) { return(false); } } } Logger.DebugLog("All batteries are recharged", Logger.severity.DEBUG); return(true); }
public TextPanelMonitor GetTextPanelMonitor(IMyTerminalBlock autopilot, AutopilotCommands autoCmds) { string panelName = m_panelName.ToString(); IMyTextPanel textPanel = null; int bestMatchLength = int.MaxValue; foreach (IMyCubeGrid grid in Attached.AttachedGrid.AttachedGrids((IMyCubeGrid)autopilot.CubeGrid, Attached.AttachedGrid.AttachmentKind.Permanent, true)) { CubeGridCache cache = CubeGridCache.GetFor(grid); if (cache == null) { continue; } foreach (IMyTextPanel panel in cache.BlocksOfType(typeof(MyObjectBuilder_TextPanel))) { if (!((IMyCubeBlock)autopilot).canControlBlock((IMyCubeBlock)panel)) { continue; } string name = panel.DisplayNameText; if (name.Length < bestMatchLength && name.Contains(panelName)) { textPanel = panel; bestMatchLength = name.Length; if (name.Length == panelName.Length) { return(new TextPanelMonitor(textPanel, autoCmds, m_identifier.ToString())); } } } } if (textPanel == null) { return(null); } return(new TextPanelMonitor(textPanel, autoCmds, m_identifier.ToString())); }
/// <summary> /// Yields CubeGridCache for each attached grid, if the grid is closed it is skipped. /// </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>CubeGridCache for each attached grid.</returns> public static IEnumerable <CubeGridCache> AttachedGridCache(IMyCubeGrid startGrid, AttachmentKind allowedConnections, bool runOnStartGrid) { if (runOnStartGrid) { CubeGridCache cache = CubeGridCache.GetFor(startGrid); if (cache != null) { yield return(cache); } } AttachedGrid attached = GetFor(startGrid); if (attached == null) { yield break; } HashSet <AttachedGrid> search = s_searchSet.Get(); try { foreach (IMyCubeGrid grid in attached.Attached(allowedConnections, search)) { CubeGridCache cache = CubeGridCache.GetFor(grid); if (cache != null) { yield return(cache); } } } finally { search.Clear(); s_searchSet.Return(search); } }
private void EnableDrills(bool enable) { if (enable) { m_logger.debugLog("Enabling drills", Logger.severity.DEBUG); } else { m_logger.debugLog("Disabling drills", Logger.severity.DEBUG); } var cache = CubeGridCache.GetFor(m_controlBlock.CubeGrid); if (cache == null) { m_logger.debugLog("Failed to get cache", Logger.severity.INFO); return; } var allDrills = cache.GetBlocksOfType(typeof(MyObjectBuilder_Drill)); if (allDrills == null) { m_logger.debugLog("Failed to get block list", Logger.severity.INFO); return; } MyAPIGateway.Utilities.TryInvokeOnGameThread(() => { foreach (IMyShipDrill drill in allDrills) { if (!drill.Closed) { drill.RequestEnable(enable); } } }); }
/// <summary> /// Test if it is safe for the grid to rotate. /// </summary> /// <param name="axis">Normalized axis of rotation in world space.</param> /// <returns>True iff the path is clear.</returns> private bool in_TestRotate(Vector3 axis) { IMyCubeGrid myGrid = m_block.CubeGrid; Vector3 centreOfMass = myGrid.Physics.CenterOfMassWorld; float longestDim = myGrid.GetLongestDim(); // calculate height Matrix toMyLocal = myGrid.WorldMatrixNormalizedInv; Vector3 myLocalCoM = Vector3.Transform(centreOfMass, toMyLocal); Vector3 myLocalAxis = Vector3.Transform(axis, toMyLocal.GetOrientation()); Vector3 myLocalCentre = myGrid.LocalAABB.Center; // CoM may not be on ship (it now considers mass from attached grids) Ray upper = new Ray(myLocalCentre + myLocalAxis * longestDim * 2f, -myLocalAxis); float? upperBound = myGrid.LocalAABB.Intersects(upper); if (!upperBound.HasValue) { Log.AlwaysLog("Math fail, upperBound does not have a value", Logger.severity.FATAL); } Ray lower = new Ray(myLocalCentre - myLocalAxis * longestDim * 2f, myLocalAxis); float?lowerBound = myGrid.LocalAABB.Intersects(lower); if (!lowerBound.HasValue) { Log.AlwaysLog("Math fail, lowerBound does not have a value", Logger.severity.FATAL); } //Log.DebugLog("LocalAABB: " + myGrid.LocalAABB + ", centre: " + myLocalCentre + ", axis: " + myLocalAxis + ", longest dimension: " + longestDim + ", upper ray: " + upper + ", lower ray: " + lower); float height = longestDim * 4f - upperBound.Value - lowerBound.Value; float furthest = 0f; foreach (IMyCubeGrid grid in AttachedGrid.AttachedGrids(myGrid, Attached.AttachedGrid.AttachmentKind.Physics, true)) { CubeGridCache cache = CubeGridCache.GetFor(grid); if (cache == null) { return(false); } foreach (Vector3I cell in cache.OccupiedCells()) { Vector3 rejection = Vector3.Reject(cell * myGrid.GridSize, myLocalAxis); float cellDistSquared = Vector3.DistanceSquared(myLocalCoM, rejection); if (cellDistSquared > furthest) { furthest = cellDistSquared; } } } float length = (float)Math.Sqrt(furthest) + myGrid.GridSize; //Log.DebugLog("height: " + height + ", length: " + length); BoundingSphereD surroundingSphere = new BoundingSphereD(centreOfMass, Math.Max(length, height) * MathHelper.Sqrt2); m_obstructions.Clear(); MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref surroundingSphere, m_obstructions); LineSegment axisSegment = new LineSegment(); m_closestPlanet = null; foreach (MyEntity entity in m_collector.Invoke(m_obstructions)) { if (entity is IMyVoxelBase) { IMyVoxelMap voxel = entity as IMyVoxelMap; if (voxel != null) { if (voxel.GetIntersectionWithSphere(ref surroundingSphere)) { Log.DebugLog("Too close to " + voxel.getBestName() + ", CoM: " + centreOfMass.ToGpsTag("Centre of Mass") + ", required distance: " + surroundingSphere.Radius); ObstructingEntity = voxel; return(false); } continue; } if (m_closestPlanet == null) { MyPlanet planet = entity as MyPlanet; if (planet == null) { continue; } double distToPlanetSq = Vector3D.DistanceSquared(centreOfMass, planet.PositionComp.GetPosition()); if (distToPlanetSq < planet.MaximumRadius * planet.MaximumRadius) { m_closestPlanet = planet; if (m_planetObstruction) { Log.DebugLog("planet blocking"); ObstructingEntity = m_closestPlanet; return(false); } } } continue; } IMyCubeGrid grid = entity as IMyCubeGrid; if (grid != null) { Matrix toLocal = grid.WorldMatrixNormalizedInv; Vector3 localAxis = Vector3.Transform(axis, toLocal.GetOrientation()); Vector3 localCentre = Vector3.Transform(centreOfMass, toLocal); axisSegment.From = localCentre - localAxis * height; axisSegment.To = localCentre + localAxis * height; CubeGridCache cache = CubeGridCache.GetFor(grid); if (cache == null) { return(false); } foreach (Vector3I cell in cache.OccupiedCells()) { if (axisSegment.PointInCylinder(length, cell * grid.GridSize)) { Log.DebugLog("axis segment: " + axisSegment.From + " to " + axisSegment.To + ", radius: " + length + ", hit " + grid.nameWithId() + " at " + cell); ObstructingEntity = grid; return(false); } } continue; } Log.DebugLog("No tests for object: " + entity.getBestName(), Logger.severity.INFO); ObstructingEntity = entity; return(false); } MyAPIGateway.Utilities.TryInvokeOnGameThread(TestPlanet); ObstructingEntity = null; return(true); }
/// <summary> /// Adds a disruption effect to a grid. /// </summary> /// <param name="grid">Grid that will be disrupted</param> /// <param name="duration">Duration of disruption</param> /// <param name="strength">Strength of disruption (in hackyness)</param> /// <param name="effectOwner">The owner of the disruption.</param> public void Start(IMyCubeGrid grid, TimeSpan duration, ref float strength, long effectOwner) { if (strength < MinCost) { Logger.DebugLog("strength: " + strength + ", below minimum: " + MinCost); return; } CubeGridCache cache = CubeGridCache.GetFor(grid); float applied = 0; if (!EffectOwnerCanAccess) { effectOwner = long.MinValue; } m_effectOwner = effectOwner; foreach (MyObjectBuilderType type in BlocksAffected) { foreach (IMyCubeBlock block in cache.BlocksOfType(type).OrderBy(OrderBy)) { if (!block.IsWorking || m_allAffected.Contains(block)) { Logger.DebugLog("cannot disrupt: " + block); continue; } float cost = BlockCost(block); if (cost > strength) { Logger.DebugLog("cannot disrupt block: " + block + ", cost: " + cost + " is greater than strength available: " + strength); continue; } StartEffect(block); Logger.DebugLog("disrupting: " + block + ", cost: " + cost + ", remaining strength: " + strength); strength -= cost; applied += cost; MyCubeBlock cubeBlock = block as MyCubeBlock; MyIDModule idMod = new MyIDModule() { Owner = cubeBlock.IDModule.Owner, ShareMode = cubeBlock.IDModule.ShareMode }; m_affected.Add(block, idMod); m_allAffected.Add(block); block.SetDamageEffect(true); cubeBlock.ChangeOwner(effectOwner, MyOwnershipShareModeEnum.Faction); if (strength < MinCost) { goto FinishedBlocks; } } } FinishedBlocks: if (m_affected.Count != 0) { Logger.DebugLog("Added new effect, strength: " + applied); m_expire = Globals.ElapsedTime.Add(duration); UpdateManager.Register(UpdateFrequency, UpdateEffect); // don't unregister on grid close, blocks can still be valid AllDisruptions.Add(this); } }
public MinerVoxel(Mover mover, byte[] OreTargets) : base(mover) { this.m_logger = new Logger(m_controlBlock.CubeBlock, () => m_state.ToString()); this.OreTargets = OreTargets; // get blocks var cache = CubeGridCache.GetFor(m_controlBlock.CubeGrid); var allDrills = cache.GetBlocksOfType(typeof(MyObjectBuilder_Drill)); if (allDrills == null || allDrills.Count == 0) { m_logger.debugLog("No Drills!", Logger.severity.INFO); return; } // if a drill has been chosen by player, use it PseudoBlock navBlock = m_navSet.Settings_Current.NavigationBlock; if (navBlock.Block is IMyShipDrill) { m_navDrill = new MultiBlock <MyObjectBuilder_Drill>(navBlock.Block); } else { m_navDrill = new MultiBlock <MyObjectBuilder_Drill>(() => m_mover.Block.CubeGrid); } if (m_navDrill.FunctionalBlocks == 0) { m_logger.debugLog("no working drills", Logger.severity.INFO); return; } m_longestDimension = m_controlBlock.CubeGrid.GetLongestDim(); m_navSet.Settings_Task_NavRot.NavigatorMover = this; // check for currently touching voxel, usually resume from save BoundingSphereD nearby = new BoundingSphereD(m_navDrill.WorldPosition, m_longestDimension * 4d); List <MyVoxelBase> nearbyVoxels = new List <MyVoxelBase>(); MyGamePruningStructure.GetAllVoxelMapsInSphere(ref nearby, nearbyVoxels); foreach (MyVoxelBase voxel in nearbyVoxels) { // skip planet physics, ship should be near planet as well if (voxel is IMyVoxelMap || voxel is MyPlanet) { m_logger.debugLog("near a voxel, escape first", Logger.severity.DEBUG); m_targetVoxel = voxel; m_state = State.Mining_Escape; var setLevel = m_navSet.GetSettingsLevel(AllNavigationSettings.SettingsLevelName.NavMove); setLevel.IgnoreAsteroid = true; setLevel.SpeedTarget = 1f; return; } } m_state = State.GetTarget; }