public void HandleCommand(ZACommons commons, EventDriver eventDriver, string argument) { var command = argument.Trim().ToLower(); switch (command) { case "start": { var shipControl = (ShipControlCommons)commons; SetTarget(shipControl); Start(shipControl, eventDriver); SaveTarget(shipControl); } break; case "reverse": { var shipControl = (ShipControlCommons)commons; SetTarget(shipControl); StartReverse(shipControl, eventDriver); SaveTarget(shipControl); } break; case "stop": { var shipControl = (ShipControlCommons)commons; shipControl.Reset(gyroOverride: false); Mode = IDLE; ForgetTarget(shipControl); } break; } }
public void Init(ZACommons commons, EventDriver eventDriver) { var previous = commons.GetValue(LOSMinerKey); if (previous != null) { var parts = previous.Split(';'); if (parts.Length == 13) { // Resume original mode and line-of-sight vector var newMode = int.Parse(parts[0]); StartPoint = new Vector3D(); StartDirection = new Vector3D(); StartUp = new Vector3D(); StartLeft = new Vector3D(); for (int i = 0; i < 3; i++) { StartPoint.SetDim(i, double.Parse(parts[i+1])); StartDirection.SetDim(i, double.Parse(parts[i+4])); StartUp.SetDim(i, double.Parse(parts[i+7])); StartLeft.SetDim(i, double.Parse(parts[i+10])); } if (newMode == MINING) { Start((ShipControlCommons)commons, eventDriver); } else if (newMode == REVERSING) { StartReverse((ShipControlCommons)commons, eventDriver); } } } }
public void Demass(ZACommons commons, EventDriver eventDriver) { var shipControl = (ShipControlCommons)commons; var deltaTime = (eventDriver.TimeSinceStart - InitialTime).TotalSeconds; var launcherDelta = LauncherVelocity * deltaTime; var distanceFromLauncher = (shipControl.ReferencePoint - (InitialPosition + launcherDelta)).LengthSquared(); if (distanceFromLauncher < DemassDistance * DemassDistance) { // Not yet eventDriver.Schedule(TicksPerRun, Demass); return; } // Disable mass var group = commons.GetBlockGroupWithName(MASS_GROUP); if (group != null) ZACommons.EnableBlocks(group.Blocks, false); // Start roll shipControl.GyroControl.EnableOverride(true); shipControl.GyroControl.SetAxisVelocity(GyroControl.Roll, MathHelper.Pi); // All done if (PostLaunch != null) PostLaunch(commons, eventDriver); }
public void Run(ZACommons commons, EventDriver eventDriver) { var myConnectors = ZACommons.GetBlocksOfType<IMyShipConnector>(commons.Blocks, block => block.DefinitionDisplayNameText == "Connector" && ((IMyShipConnector)block).IsLocked && ((IMyShipConnector)block).IsConnected); var currentConnectorCount = myConnectors.Count; if (currentConnectorCount > ConnectorCount) { // New connection, force re-evaluation State = null; } ConnectorCount = currentConnectorCount; var myReactors = ZACommons.GetBlocksOfType<IMyReactor>(commons.Blocks, block => block.IsWorking); var currentState = myReactors.Count > 0; // Only on state change if (State == null || currentState != (bool)State) { State = currentState; if (!(bool)State) { // Disable reactors on all connected grids var reactors = ZACommons.GetBlocksOfType<IMyReactor>(commons.AllBlocks, block => block.CubeGrid != commons.Me.CubeGrid); reactors.ForEach(block => block.SetValue<bool>("OnOff", false)); } } eventDriver.Schedule(RunDelay, Run); }
public void Init(ZACommons commons, EventDriver eventDriver, double maxError, Base6Directions.Direction thrusterDirection = Base6Directions.Direction.Forward) { MaxError = maxError; ThrusterDirection = thrusterDirection; var shipControl = (ShipControlCommons)commons; var forward = shipControl.ShipBlockOrientation.TransformDirection(ThrusterDirection); // Don't really care about "up," just pick a perpindicular direction seeker.Init(shipControl, shipUp: Base6Directions.GetPerpendicular(forward), shipForward: forward); var gyroControl = shipControl.GyroControl; gyroControl.Reset(); gyroControl.EnableOverride(true); LastPosition = shipControl.ReferencePoint; Enabled = true; shipControl.ThrustControl.Enable(false); eventDriver.Schedule(SampleDelay, DetermineVelocity); }
public void Run(ZACommons commons, EventDriver eventDriver) { var groups = commons.GetBlockGroupsWithPrefix(DOOR_AUTO_CLOSER_PREFIX); if (groups.Count > 0) { groups.ForEach(group => { // Determine open duration var parts = group.Name.Split(new char[] { DURATION_DELIMITER }, 2); var duration = DEFAULT_DOOR_OPEN_DURATION; if (parts.Length == 2) { if (!double.TryParse(parts[1], out duration)) { duration = DEFAULT_DOOR_OPEN_DURATION; } } var doors = ZACommons.GetBlocksOfType<IMyDoor>(group.Blocks, block => block.IsFunctional); CloseDoors(commons, eventDriver, doors, duration); }); } else { // Default behavior (all doors except vanilla Airtight Hangar Doors and tagged doors) var doors = ZACommons .GetBlocksOfType<IMyDoor>(commons.Blocks, block => block.IsFunctional && block.CustomName.IndexOf("[Excluded]", ZACommons.IGNORE_CASE) < 0 && block.DefinitionDisplayNameText != "Airtight Hangar Door"); CloseDoors(commons, eventDriver, doors, DEFAULT_DOOR_OPEN_DURATION); } eventDriver.Schedule(RunDelay, Run); }
public void Run(ZACommons commons, EventDriver eventDriver) { var groups = commons.GetBlockGroupsWithPrefix(SIMPLE_AIRLOCK_GROUP_PREFIX); for (var e = groups.GetEnumerator(); e.MoveNext();) { var doors = ZACommons.GetBlocksOfType<IMyDoor>(e.Current.Blocks, door => door.CubeGrid == commons.Me.CubeGrid && door.IsFunctional); var opened = IsAnyDoorOpen(doors); for (var f = doors.GetEnumerator(); f.MoveNext();) { var door = (IMyDoor)f.Current; if (door.OpenRatio == 0.0f && opened) { // This door is not open and some other door in the group is, lock it down if (door.Enabled) door.SetValue<bool>("OnOff", false); } else { if (!door.Enabled) door.SetValue<bool>("OnOff", true); } } } eventDriver.Schedule(RunDelay, Run); }
private void Reset(ZACommons commons) { var thrustControl = ((ShipControlCommons)commons).ThrustControl; var collect = ParseCruiseFlags(); thrustControl.Enable(true, collect); thrustControl.Reset(collect); }
private void CloseDoors(ZACommons commons, EventDriver eventDriver, List<IMyTerminalBlock> doors, double openDurationSeconds) { var openDuration = TimeSpan.FromSeconds(openDurationSeconds); doors.ForEach(block => { var door = (IMyDoor)block; if (door.Open) { TimeSpan closeTime; if (opened.TryGetValue(door, out closeTime)) { if (closeTime <= eventDriver.TimeSinceStart) { // Time to close it door.SetValue<bool>("Open", false); opened.Remove(door); } } else { opened.Add(door, eventDriver.TimeSinceStart + openDuration); } } else { opened.Remove(door); } }); }
public void DockingAction(ZACommons commons, EventDriver eventDriver, bool docked) { var wheels = ZACommons.GetBlocksOfType<IMyMotorSuspension>(commons.Blocks); ZACommons.EnableBlocks(wheels, !docked); if (!docked) { // Set suspension strength to configured value wheels.ForEach(wheel => { wheel.SetValue<float>("Strength", UNDOCK_SUSPENSION_STRENGTH); }); } else { // Apply handbrake var controllers = ZACommons.GetBlocksOfType<IMyShipController>(commons.Blocks); controllers.ForEach(controller => { if (!((IMyShipController)controller).HandBrake) { controller.SetValue<bool>("HandBrake", true); } }); } }
public void AcquireTarget(ZACommons commons) { // Find the sole text panel var panelGroup = commons.GetBlockGroupWithName("CM Target"); if (panelGroup == null) { throw new Exception("Missing group: CM Target"); } var panels = ZACommons.GetBlocksOfType<IMyTextPanel>(panelGroup.Blocks); if (panels.Count == 0) { throw new Exception("Expecting at least 1 text panel"); } var panel = panels[0] as IMyTextPanel; // Just use the first one var targetString = panel.GetPublicText(); // Parse target info var parts = targetString.Split(';'); if (parts.Length != 3) { throw new Exception("Expecting exactly 3 parts to target info"); } Target = new Vector3D(); for (int i = 0; i < 3; i++) { Target.SetDim(i, double.Parse(parts[i])); } }
public void Run(ZACommons commons, EventDriver eventDriver) { if (!AutopilotEngaged) { Reset(commons); return; } var shipControl = (ShipControlCommons)commons; var targetVector = AutopilotTarget - shipControl.ReferencePoint; var distance = targetVector.Normalize(); double yawError, pitchError; var gyroControl = seeker.Seek(shipControl, targetVector, out yawError, out pitchError); var targetSpeed = Math.Min(distance / AUTOPILOT_TTT_BUFFER, AutopilotSpeed); targetSpeed = Math.Max(targetSpeed, AUTOPILOT_MIN_SPEED); // Avoid Zeno's paradox... cruiser.Cruise(shipControl, eventDriver, targetSpeed); if (distance < AUTOPILOT_DISENGAGE_DISTANCE) { Reset(commons); if (DoneAction != null) DoneAction(commons, eventDriver); } else { eventDriver.Schedule(FramesPerRun, Run); } }
// Acquire target from CM Target text panel. If anything's wrong, // return null. private Vector3D? AcquireTarget(ZACommons commons) { // Find the sole text panel var panelGroup = commons.GetBlockGroupWithName("CM Target"); if (panelGroup == null) return null; var panels = ZACommons.GetBlocksOfType<IMyTextPanel>(panelGroup.Blocks); if (panels.Count == 0) return null; var panel = panels[0] as IMyTextPanel; // Just use the first one var targetString = panel.GetPublicText(); // Parse target info var parts = targetString.Split(';'); if (parts.Length != 3) return null; var target = new Vector3D(); for (int i = 0; i < 3; i++) { double coord; if (!double.TryParse(parts[i], out coord)) return null; target.SetDim(i, coord); } return target; }
public void LowBattery(ZACommons commons, EventDriver eventDriver, bool started) { if (started) { // Just change the name of the first active antenna for (var e = ZACommons.GetBlocksOfType<IMyRadioAntenna>(commons.Blocks).GetEnumerator(); e.MoveNext();) { var antenna = e.Current; if (antenna.IsFunctional && antenna.IsWorking) { OldAntennaName = antenna.CustomName; antenna.SetCustomName(Message); break; } } } else { // Scan for the antenna with the message, change it back for (var e = ZACommons.GetBlocksOfType<IMyRadioAntenna>(commons.Blocks).GetEnumerator(); e.MoveNext();) { var antenna = e.Current; if (antenna.CustomName == Message) { antenna.SetCustomName(OldAntennaName); break; } } } }
public void HandleCommand(ZACommons commons, EventDriver eventDriver, string argument, Action<ZACommons, Vector3D> targetAction) { argument = argument.Trim().ToLower(); switch (argument) { case "compute": var firstReference = GetReference(commons, STATIC_REFERENCE_GROUP); var rotorReference = GetReference(commons, ROTOR_REFERENCE_GROUP); var first = new Rangefinder.LineSample(firstReference); var second = new Rangefinder.LineSample(rotorReference); Vector3D closestFirst, closestSecond; if (Rangefinder.Compute(first, second, out closestFirst, out closestSecond)) { // Take midpoint of closestFirst-closestSecond segment var target = (closestFirst + closestSecond) / 2.0; targetAction(commons, target); } break; default: rotorStepper.HandleCommand(commons, eventDriver, argument); break; } }
public void HandleCommand(ZACommons commons, EventDriver eventDriver, string argument) { argument = argument.Trim().ToLower(); var parts = argument.Split(new char[] { ' ' }, 3); if (parts.Length < 3 || parts[0] != "sequence") return; var command = parts[1]; var sequence = parts[2]; if (command == "start") { var blocks = GetSequenceBlocks(commons, sequence); if (blocks == null) return; ZACommons.EnableBlocks(blocks, false); blocks[0].SetValue<bool>("OnOff", true); var first = Indexes.Count == 0; if (!Indexes.ContainsKey(sequence)) Indexes.Add(sequence, 0); if (first) { eventDriver.Schedule(SEQUENCER_FRAMES_PER_RUN, Run); } } else if (command == "stop") { var blocks = GetSequenceBlocks(commons, sequence); if (blocks != null) ZACommons.EnableBlocks(blocks, true); Indexes.Remove(sequence); } }
public void Prime(ZACommons commons, EventDriver eventDriver) { // Wake up batteries var batteryGroup = commons.GetBlockGroupWithName(BATTERY_GROUP + MISSILE_GROUP_SUFFIX); if (batteryGroup == null) { throw new Exception("Group missing: " + BATTERY_GROUP + MISSILE_GROUP_SUFFIX); } var systemsGroup = commons.GetBlockGroupWithName(SYSTEMS_GROUP + MISSILE_GROUP_SUFFIX); if (systemsGroup == null) { throw new Exception("Group missing: " + SYSTEMS_GROUP + MISSILE_GROUP_SUFFIX); } var batteries = ZACommons.GetBlocksOfType<IMyBatteryBlock>(batteryGroup.Blocks); batteries.ForEach(battery => { battery.SetValue<bool>("OnOff", true); battery.SetValue<bool>("Recharge", false); battery.SetValue<bool>("Discharge", true); }); // Activate flight systems ZACommons.EnableBlocks(systemsGroup.Blocks, true); eventDriver.Schedule(1.0, Release); }
private void Start(ZACommons commons, EventDriver eventDriver, bool auto) { Show(commons); if (Mode == IDLE) eventDriver.Schedule(RunDelay, Run); Mode = auto ? AUTO : ACTIVE; SaveMode(commons); }
public void Display(ZACommons commons) { if (Indexes.Count > 0) { commons.Echo("Sequencer active: " + string.Join(", ", Indexes.Keys)); } }
public void Run(ZACommons commons, EventDriver eventDriver) { var vents = ZACommons.GetBlocksOfType<IMyAirVent>(commons.AllBlocks, vent => vent.IsFunctional && vent.CustomName.IndexOf("[Excluded]", ZACommons.IGNORE_CASE) < 0 && vent.CustomName.IndexOf("[Intake]", ZACommons.IGNORE_CASE) < 0); vents.ForEach(block => { var vent = (IMyAirVent)block; var level = vent.GetOxygenLevel(); if (vent.IsDepressurizing && !vent.Enabled && level > 0.0f) { vent.SetValue<bool>("OnOff", true); } else if (!vent.IsDepressurizing) { if (level < MIN_AIR_VENT_PRESSURE && !vent.Enabled) { vent.SetValue<bool>("OnOff", true); } else if (level > MAX_AIR_VENT_PRESSURE && vent.Enabled) { vent.SetValue<bool>("OnOff", false); } } }); eventDriver.Schedule(RunDelay, Run); }
public void HandleCommand(ZACommons commons, EventDriver eventDriver, string argument) { argument = argument.Trim().ToLower(); var parts = argument.Split(new char[] { ' ' }, 2); if (parts.Length != 2 || parts[0] != "damecon") return; var command = parts[1]; switch (command) { case "reset": case "stop": commons.AllBlocks.ForEach(block => { if (block.GetProperty("ShowOnHUD") != null) block.SetValue<bool>("ShowOnHUD", false); }); ResetMode(commons); break; case "show": Show(commons); ResetMode(commons); break; case "start": Start(commons, eventDriver, false); break; case "auto": Start(commons, eventDriver, true); break; } }
public void Init(ZACommons commons, EventDriver eventDriver, params DockingHandler[] dockingHandlers) { DockingHandlers = dockingHandlers; var docked = ZACommons.IsConnectedAnywhere(commons.Blocks); ManageShip(commons, eventDriver, docked); }
public void Run(ZACommons commons, EventDriver eventDriver) { if (Indexes.Count == 0) return; var newIndexes = new Dictionary<string, int>(); for (var e = Indexes.GetEnumerator(); e.MoveNext();) { var kv = e.Current; var sequence = kv.Key; var index = kv.Value; var blocks = GetSequenceBlocks(commons, sequence); if (blocks == null) continue; ZACommons.EnableBlocks(blocks, false); // TODO sort? index++; index %= blocks.Count; blocks[index].SetValue<bool>("OnOff", true); newIndexes.Add(sequence, index); } Indexes = newIndexes; eventDriver.Schedule(SEQUENCER_FRAMES_PER_RUN, Run); }
public void HandleCommand(ZACommons commons, EventDriver eventDriver, string argument) { var command = argument.Trim().ToLower(); switch (command) { case "reactors": { // Turn on all reactors GetAllReactors(commons).ForEach(block => block.SetValue<bool>("OnOff", true)); eventDriver.Schedule(1.0, (c,ed) => { // Turn off all local batteries GetBatteries(c).ForEach(block => block.SetValue<bool>("OnOff", false)); }); break; } case "batteries": { // Turn on all local batteries // and disable recharge/discharge GetBatteries(commons).ForEach(block => { block.SetValue<bool>("OnOff", true); block.SetValue<bool>("Recharge", false); block.SetValue<bool>("Discharge", false); }); eventDriver.Schedule(1.0, (c,ed) => { // Turn off all reactors GetAllReactors(c).ForEach(block => block.SetValue<bool>("OnOff", false)); }); break; } } }
public void HandleCommand(ZACommons commons, string argument) { argument = argument.Trim().ToLower(); var parts = argument.Split(new char[] { ' ' }, 2); if (parts.Length < 2 || parts[0] != "rfinder") return; var command = parts[1]; switch(command) { case "origin": { var reference = GetReference(commons); if (reference == null) return; Origin = new Rangefinder.LineSample(reference); Last = null; Result.Clear(); break; } case "snapshot": { var reference = GetReference(commons); if (reference == null) return; var second = new Rangefinder.LineSample(reference); Last = null; Result.Clear(); Vector3D closestFirst, closestSecond; if (Rangefinder.Compute(Origin, second, out closestFirst, out closestSecond)) { var target = (closestFirst + closestSecond) / 2.0; Last = target; Result.Append(string.Format("Target: {0:F2}, {1:F2}, {2:F2}", target.GetDim(0), target.GetDim(1), target.GetDim(2))); Result.Append('\n'); var targetVector = target - reference.GetPosition(); Result.Append(string.Format("Distance: {0} m", (ulong)(targetVector.Length() + 0.5))); TargetAction(commons, target); } else { Result.Append("Parallel lines???"); } break; } case "restore": if (Last != null) { TargetAction(commons, (Vector3D)Last); } break; } }
private List<IMyTerminalBlock> GetSequenceBlocks(ZACommons commons, string sequence) { var groupName = SEQUENCER_PREFIX + sequence; var group = commons.GetBlockGroupWithName(groupName); if (group == null || group.Blocks.Count == 0) return null; return group.Blocks; }
public void DHRun(ZACommons commons, EventDriver eventDriver) { if (IsDocked) return; Run(commons); eventDriver.Schedule(RunDelay, DHRun); }
public void SafeMode(ZACommons commons, EventDriver eventDriver) { // Check after 1 second (let timer block's action take effect) eventDriver.Schedule(1.0, (c,ed) => { new EmergencyStop().SafeMode(c, ed); }); }
public void Init(ZACommons commons, EventDriver eventDriver) { pid.Kp = RotorKp; pid.Ki = RotorKi; pid.Kd = RotorKd; UpdateStepAmount(commons); }
public void Init(ZACommons commons, EventDriver eventDriver, Action<ZACommons, EventDriver> postLaunch = null) { PostLaunch = postLaunch; InitialPosition = ((ShipControlCommons)commons).ReferencePoint; InitialTime = eventDriver.TimeSinceStart; eventDriver.Schedule(0.0, Prime); }
private void AimRotorAtPoint(ZACommons commons, EventDriver eventDriver, RotorStepper stepper, Vector3D point, double sign) { var rotor = stepper.GetRotor(commons); var offset = point; // Convert to rotor's coordinate space offset = Vector3D.TransformNormal(offset, MatrixD.Transpose(rotor.WorldMatrix)); // Why you backwards, Atan2?? Or rather, Keen's world coordinates... var desiredAngle = Math.Atan2(-offset.X, offset.Z); stepper.SetPoint = desiredAngle * sign; stepper.Schedule(eventDriver); }
public void Refresh(ZACommons commons, EventDriver eventDriver) { if (Mode == Modes.Idle) { RefreshInfo = null; return; } // Refresh all local PBs, but don't update gyro lock info TargetUpdated(commons, eventDriver, (MyDetectedEntityInfo)RefreshInfo, full: true, localOnly: true, updateTime: RefreshUpdateTime, newOffset: false); eventDriver.Schedule(TRACKER_REFRESH_RATE, Refresh); }
public void Tick(ZACommons commons, EventDriver eventDriver) { // Enable all manageable air vents for 1 tick before performing checks. // Necessary as of 1.185. Thanks, Keen! var vents = GetAirVents(commons); vents.ForEach(vent => { vent.Enabled = true; }); eventDriver.Schedule(1, Tock); }
private void ConstrainSetPoint(ZACommons commons) { var piston = GetPiston(commons); if (SetPoint < piston.MinLimit) { SetPoint = piston.MinLimit; } else if (SetPoint > piston.MaxLimit) { SetPoint = piston.MaxLimit; } }
public void DockingAction(ZACommons commons, EventDriver eventDriver, bool docked) { if (docked) { IsDocked = true; } else if (IsDocked) { IsDocked = false; eventDriver.Schedule(RunDelay, DHRun); } }
public void Setup(List <IMyTerminalBlock> ship) { // First build map of defaults var defaultItemStocksMap = new Dictionary <string, ItemStock>(); for (int i = 0; i < defaultItemStocks.Length; i++) { var itemStock = defaultItemStocks[i]; defaultItemStocksMap.Add(itemStock.SubtypeName, itemStock); } // Get assemblers var assemblers = ZACommons.GetBlocksOfType <IMyAssembler>(ship); var candidates = new LinkedList <IMyAssembler>(); // If anything has already been appropriately named, remove it from our map for (var e = assemblers.GetEnumerator(); e.MoveNext();) { var assembler = (IMyAssembler)e.Current; ItemStock target; if (ItemStock.TryParse(assembler.CustomName, out target)) { defaultItemStocksMap.Remove(target.SubtypeName); } else { // Otherwise add assembler as candidate for renaming candidates.AddLast(assembler); } } for (var e = defaultItemStocksMap.Values.GetEnumerator(); e.MoveNext() && candidates.First != null;) { var itemStock = e.Current; // Get first candidate var candidate = candidates.First.Value; candidates.RemoveFirst(); // Rename appropriately StringBuilder builder = new StringBuilder(); builder.Append(candidate.CustomName); builder.Append(' '); builder.Append(DelimiterStart); builder.Append(itemStock.SubtypeName); builder.Append(DelimiterAmount); builder.Append(itemStock.Amount); builder.Append(DelimiterEnd); candidate.SetCustomName(builder); } }
public void Burn(ZACommons commons, EventDriver eventDriver) { if (ShouldAbort(commons, eventDriver, Modes.Burning, false)) { return; } var shipControl = (ShipControlCommons)commons; var controller = GetShipController(shipControl); if (controller == null) { return; } var gravity = controller.GetNaturalGravity(); if (gravity.LengthSquared() > 0.0) { // Override gyro, disable "bottom" thrusters shipControl.Reset(gyroOverride: true, thrusterEnable: true, thrusterCondition: ThrusterCondition); shipControl.ThrustControl.Enable(Base6Directions.GetFlippedDirection(BrakeDirection), false); var down = shipControl.ShipBlockOrientation.TransformDirection(BrakeDirection); seeker.Init(shipControl, shipUp: Base6Directions.GetPerpendicular(down), shipForward: down); if (Autodrop) { // "forward" & "right" var forward = Base6Directions.GetPerpendicular(BrakeDirection); var right = Base6Directions.GetCross(forward, BrakeDirection); // Actual orientations don't matter // Just as long as they're planar & perpendicular to down LongCruiser.Init(shipControl, localForward: forward); LatCruiser.Init(shipControl, localForward: right); } Mode = Modes.Gliding; eventDriver.Schedule(FramesPerRun, Glide); } else { cruiser.Cruise(shipControl, VTVLHELPER_BURN_SPEED, condition: ThrusterCondition); eventDriver.Schedule(FramesPerRun, Burn); } }
public void Run(ZACommons commons) { for (var e = commons.GetBlockGroupsWithPrefix(REDUNDANCY_PREFIX).GetEnumerator(); e.MoveNext();) { var group = e.Current; // Figure out how many to maintain var parts = group.Name.Split(new char[] { COUNT_DELIMITER }, 2); var count = 1; if (parts.Length == 2) { if (int.TryParse(parts[1], out count)) { count = Math.Max(count, 1); } else { count = 1; } } var running = 0; var spares = new LinkedList <IMyTerminalBlock>(); for (var f = group.Blocks.GetEnumerator(); f.MoveNext();) { var block = f.Current as IMyFunctionalBlock; if (block != null && block.CubeGrid == commons.Me.CubeGrid && block.IsFunctional) { if (block.IsWorking && block.Enabled) { running++; } else { spares.AddLast(block); } } } while (running < count && spares.First != null) { var block = spares.First.Value; spares.RemoveFirst(); block.SetValue <bool>("OnOff", true); running++; } } }
public void Init(ZACommons commons, EventDriver eventDriver, Action <ZACommons, EventDriver> nextStage) { NextStage = nextStage; OneTurnEnd = eventDriver.TimeSinceStart + TimeSpan.FromSeconds(ONE_TURN_DURATION); var shipControl = (ShipControlCommons)commons; seeker.Init(shipControl, shipUp: shipControl.ShipUp, shipForward: shipControl.ShipForward); eventDriver.Schedule(0, Run); }
public void Init(ZACommons commons, EventDriver eventDriver) { var shipControl = (ShipControlCommons)commons; var gyroControl = shipControl.GyroControl; gyroControl.Reset(); gyroControl.EnableOverride(true); Active = true; SaveActive(commons); MaxPower = null; // Use first-run initialization CurrentMaxPower = 0.0f; eventDriver.Schedule(0.0, Run); }
public void HandleCommand(ZACommons commons, EventDriver eventDriver, string argument) { argument = argument.Trim().ToLower(); switch (argument) { case "arm": if (Mode == Modes.Idle) { var camera = GetMainCamera(commons); camera.EnableRaycast = true; Mode = Modes.Armed; RaycastRange = INITIAL_RAYCAST_RANGE; } break; case "disarm": { var camera = GetMainCamera(commons); camera.EnableRaycast = false; Mode = Modes.Idle; break; } case "snapshot": BeginSnapshot(commons, eventDriver, localOnly: true); break; case "retarget": BeginSnapshot(commons, eventDriver, localOnly: false); break; case "paint": BeginPaint(commons, eventDriver, released: false); break; case "release": BeginPaint(commons, eventDriver, released: true); break; case "clear": { if (Mode != Modes.Idle) { Mode = Modes.Armed; RaycastRange = INITIAL_RAYCAST_RANGE; } break; } } }
public void Run(ZACommons commons, EventDriver eventDriver) { for (var e = commons.GetBlockGroupsWithPrefix(DOCKING_ACTION_PREFIX).GetEnumerator(); e.MoveNext();) { var group = e.Current; // Figure out action var parts = group.Name.Split(new char[] { ACTION_DELIMETER }, 2); string action = "on"; if (parts.Length == 2) { action = parts[1]; } // Determine state of first connector (should only have 1) bool connected = false; var connectors = ZACommons.GetBlocksOfType <IMyShipConnector>(group.Blocks); if (connectors.Count > 0) { var connector = (IMyShipConnector)connectors[0]; connected = connector.IsLocked && connector.IsConnected; } if ("on".Equals(action, ZACommons.IGNORE_CASE) || "off".Equals(action, ZACommons.IGNORE_CASE)) { bool enable; if ("on".Equals(action, ZACommons.IGNORE_CASE)) { enable = connected; } else { enable = !connected; } // Set state according to action group.Blocks.ForEach(block => { if (!(block is IMyShipConnector)) // ignore connectors { block.SetValue <bool>("OnOff", enable); } }); } // Ignore anything else for now } eventDriver.Schedule(RunDelay, Run); }
public SolarPanelDetails(IEnumerable <IMyTerminalBlock> blocks) { MaxPowerOutput = 0.0f; DefinedPowerOutput = 0.0f; foreach (var panel in ZACommons.GetBlocksOfType <IMySolarPanel>(blocks)) { if (panel.IsFunctional && panel.IsWorking) { MaxPowerOutput += panel.MaxOutput; DefinedPowerOutput += panel.CubeGrid.GridSize == 2.5f ? SOLAR_PANEL_MAX_POWER_LARGE : SOLAR_PANEL_MAX_POWER_SMALL; } } }
private void KickTimer(ZACommons commons) { IMyTimerBlock timer = null; // Name takes priority over group if (TimerName != null) { var blocks = ZACommons.SearchBlocksOfName(commons.Blocks, TimerName, block => block is IMyTimerBlock && ((IMyTimerBlock)block).Enabled); if (blocks.Count > 0) { timer = blocks[0] as IMyTimerBlock; } } if (timer == null && TimerGroup != null) { var group = commons.GetBlockGroupWithName(TimerGroup); if (group != null) { var blocks = ZACommons.GetBlocksOfType <IMyTimerBlock>(group.Blocks, block => block.CubeGrid == commons.Me.CubeGrid && ((IMyTimerBlock)block).Enabled); timer = blocks.Count > 0 ? (IMyTimerBlock)blocks[0] : null; } } if (timer != null) { // Rules are simple. If we have something in the tick queue, trigger now. // Otherwise, set timer delay appropriately (minimum 1 second) and kick. // If you want sub-second accuracy, always use ticks. if (TickQueue.First != null) { timer.ApplyAction("TriggerNow"); } else if (TimeQueue.First != null) { var next = (float)(TimeQueue.First.Value.When.TotalSeconds - TimeSinceStart.TotalSeconds); // Constrain appropriately (not sure if this will be done for us or if it // will just throw). Just do it to be safe. next = Math.Max(next, timer.GetMinimum <float>("TriggerDelay")); next = Math.Min(next, timer.GetMaximum <float>("TriggerDelay")); timer.SetValue <float>("TriggerDelay", next); timer.ApplyAction("Start"); } // NB If both queues are empty, we stop running } }
public void Run(ZACommons commons, EventDriver eventDriver) { foreach (var group in commons.GetBlockGroupsWithPrefix(DOCKING_ACTION_PREFIX)) { // Figure out action var parts = group.Name.Split(new char[] { ACTION_DELIMETER }, 2); string action = "on"; if (parts.Length == 2) { action = parts[1]; } // Determine state of first connector (should only have 1) bool connected = false; var connectors = ZACommons.GetBlocksOfType <IMyShipConnector>(group.Blocks); if (connectors.Count > 0) { var connector = connectors[0]; connected = connector.Status == MyShipConnectorStatus.Connected; } if ("on".Equals(action, ZACommons.IGNORE_CASE) || "off".Equals(action, ZACommons.IGNORE_CASE)) { bool enable; if ("on".Equals(action, ZACommons.IGNORE_CASE)) { enable = connected; } else { enable = !connected; } // Set state according to action group.Blocks.ForEach(block => { if (!(block is IMyShipConnector) && // ignore connectors block is IMyFunctionalBlock) { ((IMyFunctionalBlock)block).Enabled = enable; } }); } // Ignore anything else for now } eventDriver.Schedule(RunDelay, Run); }
private void OpenCloseDoorsAsNeeded(EventDriver eventDriver) { for (var e = rooms.GetEnumerator(); e.MoveNext();) { var room = e.Current; var vents = ToVents(ZACommons.GetBlocksOfType <IMyAirVent>(room.Blocks)); if (vents.Count == 0) { continue; } var doors = ToDoors(ZACommons.GetBlocksOfType <IMyDoor>(room.Blocks)); if (doors.Count == 0) { continue; } // Determine room state var state = GetAirlockState(vents); switch (state) { case AIRLOCK_STATE_VACUUM: // Close and lock all but space doors CloseDoorsAsNeeded(eventDriver, room, doors, spaceDoors, AIRLOCK_STATE_VACUUM); break; case AIRLOCK_STATE_PRESSURIZED: // Close and lock all but inner doors CloseDoorsAsNeeded(eventDriver, room, doors, innerDoors, AIRLOCK_STATE_PRESSURIZED); break; case AIRLOCK_STATE_UNKNOWN: // Close and lock all doors for (var f = doors.GetEnumerator(); f.MoveNext();) { var door = f.Current; door.SetValue <bool>("Open", false); if (door.OpenRatio == 0.0f && door.Enabled) { door.SetValue <bool>("OnOff", false); } } break; } } }
private void CruiseStart(ZACommons commons, EventDriver eventDriver, double desiredSpeed, string argument) { TargetSpeed = Math.Max(desiredSpeed, 0.0); thrustPID.Reset(); if (!Active) { SaveThrusterStates(commons); Active = true; eventDriver.Schedule(0, Run); } SaveLastCommand(commons, argument); }
public void Run(ZACommons commons, EventDriver eventDriver) { var shipControl = (ShipControlCommons)commons; var controller = shipControl.ShipController; if (controller != null) { var speed = controller.GetShipSpeed(); DoActions(commons, eventDriver, speed); LastSpeed = (double)speed; } eventDriver.Schedule(RunDelay, Run); }
public void Docked(ZACommons commons, EventDriver eventDriver) { ZACommons.ForEachBlockOfType <IMyLandingGear>(commons.Blocks, gear => { if (gear.IsFunctional && gear.IsWorking && gear.Enabled && !gear.IsLocked) { gear.ApplyAction("Lock"); } }); // Do everything else needed after docking ManageShip(commons, eventDriver, true); }
public void Init(ZACommons commons, EventDriver eventDriver) { var shipControl = (ShipControlCommons)commons; var target = AcquireTarget(commons); // Use current distance from target point, otherwise use default range var range = target != null ? ((Vector3D)target - shipControl.ReferencePoint).Length() : DefaultRange; // Target point is directly in front Target = shipControl.ReferencePoint + shipControl.ReferenceForward * range; dumbShell.Init(commons, eventDriver, postLaunch: DecoyLoop); }
public void ReorientStart(ZACommons commons, EventDriver eventDriver) { var shipControl = (ShipControlCommons)commons; seeker.Init(shipControl, shipUp: shipControl.ShipUp, shipForward: shipControl.ShipForward); shipControl.Reset(gyroOverride: true, thrusterEnable: null); Mode = Modes.Orienting; SaveMode(commons); eventDriver.Schedule(0, Reorient); }
public void Init(ZACommons commons, EventDriver eventDriver, Func <ZACommons, EventDriver, bool> livenessCheck = null) { LivenessCheck = livenessCheck; var lastCommand = commons.GetValue(LastCommandKey); if (lastCommand != null) { HandleCommand(commons, eventDriver, lastCommand); // Can't trust current state, force a reset on "cruise stop" ThrusterStates.Clear(); FirstStop = true; } }
public void FullBurn(ZACommons commons, EventDriver eventDriver) { var shipControl = (ShipControlCommons)commons; // Full burn var thrustControl = shipControl.ThrustControl; thrustControl.SetOverride(Base6Directions.Direction.Forward, true); // And disable thrusters in all other directions thrustControl.Enable(Base6Directions.Direction.Backward, false); thrustControl.Enable(Base6Directions.Direction.Up, false); thrustControl.Enable(Base6Directions.Direction.Down, false); thrustControl.Enable(Base6Directions.Direction.Left, false); thrustControl.Enable(Base6Directions.Direction.Right, false); }
private void BeginLock(ZACommons commons, EventDriver eventDriver) { if (Mode != Modes.Painting) { return; } if (!GyroLock) { var shipControl = (ShipControlCommons)commons; shipControl.GyroControl.EnableOverride(true); GyroLock = true; eventDriver.Schedule(1, Lock); } }
public void Init(ZACommons commons, EventDriver eventDriver) { var shipControl = (ShipControlCommons)commons; seeker.Init(shipControl, shipUp: shipControl.ShipUp, shipForward: shipControl.ShipForward); cruiser.Init(shipControl); velocimeter.Reset(); VTicks = 0; FullBurnTriggerLast = eventDriver.TimeSinceStart; eventDriver.Schedule(0, Run); }
public void Snapshot(ZACommons commons, EventDriver eventDriver) { if (Mode != Modes.Snapshot) { return; } var camera = GetSightingCamera(commons); if (camera == null) { Mode = Modes.Idle; return; } // Can we raycast the desired distance? var scanTime = camera.TimeUntilScan(FC_INITIAL_RAYCAST_RANGE); if (scanTime > 0) { // Try later eventDriver.Schedule((double)scanTime / 1000.0, Snapshot); return; } var info = camera.Raycast(FC_INITIAL_RAYCAST_RANGE); if (info.IsEmpty()) { // Missed? Try again eventDriver.Schedule(1, Snapshot); return; } TargetAimPoint = (Vector3D)info.HitPosition; TargetVelocity = new Vector3D(info.Velocity); LastTargetUpdate = eventDriver.TimeSinceStart; TargetID = info.EntityId; // Determine local offset of aim point, in case we get an update var offset = TargetAimPoint - info.Position; var toLocal = MatrixD.Transpose(info.Orientation); TargetOffset = Vector3D.TransformNormal(offset, toLocal); BeginLock(commons, eventDriver); }
public void Run(ZACommons commons) { foreach (var group in commons.GetBlockGroupsWithPrefix(REDUNDANCY_PREFIX)) { // Figure out how many to maintain var parts = group.Name.Split(new char[] { COUNT_DELIMITER }, 2); var count = 1; if (parts.Length == 2) { if (int.TryParse(parts[1], out count)) { count = Math.Max(count, 1); } else { count = 1; } } var running = 0; var spares = new LinkedList <IMyFunctionalBlock>(); foreach (var block in group.Blocks) { var fblock = block as IMyFunctionalBlock; if (fblock != null && fblock.CubeGrid == commons.Me.CubeGrid && fblock.IsFunctional) { if (fblock.IsWorking && fblock.Enabled) { running++; } else { spares.AddLast(fblock); } } } while (running < count && spares.First != null) { var block = spares.First.Value; spares.RemoveFirst(); block.Enabled = true; running++; } } }
public void HandleCommand(ZACommons commons, EventDriver eventDriver, string argument) { var command = argument.Trim().ToLower(); switch (command) { case "dock": DockStart(commons, eventDriver); break; case "undock": UndockStart(commons, eventDriver); break; } }
public void Run(ZACommons commons, EventDriver eventDriver) { var groups = commons.GetBlockGroupsWithPrefix(REFINERY_MANAGER_PREFIX); if (groups.Count > 0) { groups.ForEach(group => Balance(commons, group.Blocks)); } else { // Balance all refineries Balance(commons, commons.Blocks); } eventDriver.Schedule(RunDelay, Run); }
private IMyCubeBlock GetReference(ZACommons commons, string groupName) { var group = commons.GetBlockGroupWithName(groupName); if (group == null) { throw new Exception("Missing group: " + groupName); } var controllers = ZACommons.GetBlocksOfType <IMyShipController>(group.Blocks); if (controllers.Count == 0) { throw new Exception("Expecting at least 1 ship controller in " + groupName); } return(controllers[0]); }