Ejemplo n.º 1
0
 public void LowBattery(ZACommons commons, EventDriver eventDriver,
                        bool started)
 {
     // Enable/disable reactor according to state
     ZACommons.EnableBlocks(ZACommons.GetBlocksOfType <IMyReactor>(commons.Blocks), started);
 }
Ejemplo n.º 2
0
 public void UndockDisable(ZACommons commons, EventDriver eventDriver)
 {
     ZACommons.EnableBlocks(ZACommons.GetBlocksOfType <IMyShipConnector>(commons.Blocks, connector => connector.DefinitionDisplayNameText == "Connector"),
                            false);
 }
Ejemplo n.º 3
0
    public void ManageShip(ZACommons commons, EventDriver eventDriver,
                           bool docked)
    {
        if (!docked)
        {
            for (var i = 0; i < DockingHandlers.Length; i++)
            {
                DockingHandlers[i].DockingAction(commons, eventDriver, false);
            }
        }

        ZACommons.EnableBlocks(ZACommons.GetBlocksOfType <IMyThrust>(commons.Blocks), !docked);
        ZACommons.EnableBlocks(ZACommons.GetBlocksOfType <IMyGyro>(commons.Blocks), !docked);
        var batteries = ZACommons.GetBlocksOfType <IMyBatteryBlock>(commons.Blocks);

        foreach (var battery in batteries)
        {
            battery.OnlyRecharge  = docked;
            battery.OnlyDischarge = !docked;
        }
        if (!docked)
        {
            ZACommons.EnableBlocks(ZACommons.GetBlocksOfType <IMyReactor>(commons.Blocks), true);
        }

        if (TOUCH_ANTENNA)
        {
            ZACommons.EnableBlocks(ZACommons.GetBlocksOfType <IMyRadioAntenna>(commons.Blocks), !docked);
            // Now defaults to off in 01.124. Thanks, Keen!
            if (!docked)
            {
                eventDriver.Schedule(2, (c, ed) =>
                {
                    ZACommons.GetBlocksOfType <IMyRadioAntenna>(commons.Blocks).ForEach(antenna => antenna.SetValue <bool>("EnableBroadCast", true));
                });
            }
        }
        if (TOUCH_LANTENNA)
        {
            ZACommons.EnableBlocks(ZACommons.GetBlocksOfType <IMyLaserAntenna>(commons.Blocks), !docked);
        }
        if (TOUCH_BEACON)
        {
            ZACommons.EnableBlocks(ZACommons.GetBlocksOfType <IMyBeacon>(commons.Blocks), !docked);
        }
        if (TOUCH_LIGHTS)
        {
            ZACommons.EnableBlocks(ZACommons.GetBlocksOfType <IMyLightingBlock>(commons.Blocks), !docked);
        }
        // Disable tools if we just docked
        if (TOUCH_TOOLS && docked)
        {
            ZACommons.EnableBlocks(ZACommons.GetBlocksOfType <IMyShipToolBase>(commons.Blocks), false);
        }
        if (TOUCH_OXYGEN)
        {
            ZACommons.EnableBlocks(ZACommons.GetBlocksOfType <IMyGasGenerator>(commons.Blocks), !docked);
            ZACommons.EnableBlocks(ZACommons.GetBlocksOfType <IMyOxygenFarm>(commons.Blocks), !docked);
            ZACommons.EnableBlocks(ZACommons.GetBlocksOfType <IMyAirVent>(commons.Blocks,
                                                                          vent => ((IMyAirVent)vent).Depressurize &&
                                                                          vent.CustomName.IndexOf("[Intake]", ZACommons.IGNORE_CASE) >= 0), !docked);
            var tanks = ZACommons.GetBlocksOfType <IMyGasTank>(commons.Blocks,
                                                               tank => tank.CustomName.IndexOf("[Excluded]", ZACommons.IGNORE_CASE) < 0);
            tanks.ForEach(tank => tank.Stockpile = docked);
        }
        if (TOUCH_SENSORS)
        {
            ZACommons.EnableBlocks(ZACommons.GetBlocksOfType <IMySensorBlock>(commons.Blocks), !docked);
        }

        if (docked)
        {
            for (var i = 0; i < DockingHandlers.Length; i++)
            {
                DockingHandlers[i].DockingAction(commons, eventDriver, true);
            }
        }

        IsDocked = docked;
        if (IsDocked)
        {
            eventDriver.Schedule(RunDelay, Sleep);
        }
    }
Ejemplo n.º 4
0
 private static List <IMyBatteryBlock> GetBatteries(ZACommons commons)
 {
     return(ZACommons.GetBlocksOfType <IMyBatteryBlock>(commons.Blocks,
                                                        battery => battery.IsFunctional &&
                                                        battery.CustomName.IndexOf("[Excluded]", ZACommons.IGNORE_CASE) < 0));
 }
Ejemplo n.º 5
0
    public void HandleCommand(ZACommons commons, EventDriver eventDriver,
                              string argument, Action preUndock = null)
    {
        argument = argument.Trim().ToLower();
        if (argument == "smartundock")
        {
            if (preUndock != null)
            {
                preUndock();
            }

            // First, determine which connector we were connected through
            IMyShipConnector connected = null;
            var connectors             = ZACommons.GetBlocksOfType <IMyShipConnector>(commons.Blocks,
                                                                                      connector => connector.DefinitionDisplayNameText == "Connector"); // Avoid Ejectors
            for (var e = connectors.GetEnumerator(); e.MoveNext();)
            {
                var connector = (IMyShipConnector)e.Current;
                if (connector.IsLocked && connector.IsConnected)
                {
                    // Assume the first one as well
                    connected = connector;
                    break;
                }
            }

            UndockTarget   = null;
            UndockBackward = null;
            if (connected != null)
            {
                // Undock in the forward direction of the *other* connector
                var other         = connected.OtherConnector;
                var forward       = other.Orientation.TransformDirection(Base6Directions.Direction.Forward);
                var forwardPoint  = other.CubeGrid.GridIntegerToWorld(other.Position + Base6Directions.GetIntVector(forward));
                var forwardVector = Vector3D.Normalize(forwardPoint - other.GetPosition());
                // Determine target undock point
                var shipControl = (ShipControlCommons)commons;
                UndockTarget = shipControl.ReferencePoint + SMART_UNDOCK_DISTANCE * forwardVector;

                // And original orientation
                UndockForward = shipControl.ReferenceForward;
                UndockUp      = shipControl.ReferenceUp;

                // Schedule the autopilot
                UndockBackward = connected.Orientation.TransformDirection(Base6Directions.Direction.Backward);
                BeginUndock(commons, eventDriver);
                Mode = UNDOCKING;
                SaveMode(commons);
            }
            SaveUndockTarget(commons);

            // Next, physically undock
            for (var e = connectors.GetEnumerator(); e.MoveNext();)
            {
                var connector = (IMyShipConnector)e.Current;
                if (connector.IsLocked)
                {
                    connector.ApplyAction("Unlock");
                }
            }
            ZACommons.EnableBlocks(connectors, false);
            // Unlock landing gears as well
            var gears = ZACommons.GetBlocksOfType <IMyLandingGear>(commons.Blocks);
            gears.ForEach(block =>
            {
                var gear = (IMyLandingGear)block;
                if (gear.IsLocked)
                {
                    gear.ApplyAction("Unlock");
                }
            });

            // Disable connectors 1 second from now
            eventDriver.Schedule(1.0, (c, ed) =>
            {
                ZACommons.EnableBlocks(ZACommons.GetBlocksOfType <IMyShipConnector>(c.Blocks, connector => connector.DefinitionDisplayNameText == "Connector"),
                                       false);         // Avoid Ejectors
            });
        }
        else if (argument == "rtb")
        {
            // No target, no RTB
            if (UndockTarget == null)
            {
                return;
            }

            // Schedule the autopilot
            BeginReturn(commons, eventDriver);
            Mode = RETURNING;
            SaveMode(commons);
        }
        else if (argument == "smartreset")
        {
            autopilot.Reset(commons);
            ResetMode(commons);
        }
    }
Ejemplo n.º 6
0
    public void SafeMode(ZACommons commons, EventDriver eventDriver)
    {
        var shipControl = (ShipControlCommons)commons;

        // Ensure dampeners are enabled (again, possibly)
        ZACommons.GetBlocksOfType <IMyShipController>(commons.Blocks).ForEach(block => {
            var controller = (IMyShipController)block;
            block.SetValue <bool>("DampenersOverride", true);
        });

        // Make sure we have working thrusters in all directions

        // Statically initialized arrays are a bit iffy in-game, so we
        // do this the hard way
        if (HaveWorkingThrusters(shipControl, Base6Directions.Direction.Forward) &&
            HaveWorkingThrusters(shipControl, Base6Directions.Direction.Backward) &&
            HaveWorkingThrusters(shipControl, Base6Directions.Direction.Left) &&
            HaveWorkingThrusters(shipControl, Base6Directions.Direction.Right) &&
            HaveWorkingThrusters(shipControl, Base6Directions.Direction.Up) &&
            HaveWorkingThrusters(shipControl, Base6Directions.Direction.Down))
        {
            // All looks well
            return;
        }

        // Check again after a second
        eventDriver.Schedule(1.0, (c, ed) =>
        {
            var sc = (ShipControlCommons)c;

            var forward  = HaveWorkingThrusters2(sc, Base6Directions.Direction.Forward);
            var backward = HaveWorkingThrusters2(sc, Base6Directions.Direction.Backward);
            var up       = HaveWorkingThrusters2(sc, Base6Directions.Direction.Up);
            var left     = HaveWorkingThrusters2(sc, Base6Directions.Direction.Left);
            var right    = HaveWorkingThrusters2(sc, Base6Directions.Direction.Right);
            var down     = HaveWorkingThrusters2(sc, Base6Directions.Direction.Down);

            if (forward && backward && up &&
                left && right && down)
            {
                // All is well
                return;
            }

            // Otherwise, pick a working direction and pass off to
            // ReverseThrust
            Base6Directions.Direction direction;
            if (forward)
            {
                direction = Base6Directions.Direction.Forward;
            }
            else if (backward)
            {
                direction = Base6Directions.Direction.Backward;
            }
            else if (up)
            {
                direction = Base6Directions.Direction.Up;
            }
            else if (left)
            {
                direction = Base6Directions.Direction.Left;
            }
            else if (right)
            {
                direction = Base6Directions.Direction.Right;
            }
            else if (down)
            {
                direction = Base6Directions.Direction.Down;
            }
            else
            {
                // Ha ha. No working thrusters at all.
                return;
            }

            new ReverseThrust().Init(c, ed,
                                     EMERGENCY_STOP_MAX_GYRO_ERROR,
                                     thrusterDirection: direction);
        });
    }
Ejemplo n.º 7
0
 private static List <IMyReactor> GetAllReactors(ZACommons commons)
 {
     return(ZACommons.GetBlocksOfType <IMyReactor>(commons.AllBlocks,
                                                   reactor => reactor.IsFunctional &&
                                                   reactor.CustomName.IndexOf("[Excluded]", ZACommons.IGNORE_CASE) < 0));
 }
Ejemplo n.º 8
0
 private List <IMyBatteryBlock> GetBatteries(ZACommons commons)
 {
     return(ZACommons.GetBlocksOfType <IMyBatteryBlock>(commons.Blocks, battery => battery.IsFunctional && battery.Enabled));
 }
Ejemplo n.º 9
0
    private void HandleCommandInternal(string argument)
    {
        var parts = argument.Split(new char[] { ' ' }, 2);

        if (parts.Length != 2)
        {
            return;
        }
        var command = parts[0];

        argument = parts[1].Trim();

        if (command == "inner" || command == "space" || command == "toggle")
        {
            ZACommons.BlockGroup room;
            if (roomsMap.TryGetValue(argument, out room))
            {
                var vents   = ToVents(ZACommons.GetBlocksOfType <IMyAirVent>(room.Blocks));
                var current = GetAirlockState(vents);
                int target  = AIRLOCK_STATE_UNKNOWN;
                switch (command)
                {
                case "space":
                    target = AIRLOCK_STATE_VACUUM;
                    break;

                case "inner":
                    target = AIRLOCK_STATE_PRESSURIZED;
                    break;

                case "toggle":
                    target = current == AIRLOCK_STATE_PRESSURIZED ?
                             AIRLOCK_STATE_VACUUM : AIRLOCK_STATE_PRESSURIZED;
                    break;
                }

                ChangeRoomState(room.Name,
                                vents, ToDoors(ZACommons.GetBlocksOfType <IMyDoor>(room.Blocks)),
                                current, target, null);
            }
        }
        else if (command == "open")
        {
            // Find named group
            ZACommons.BlockGroup group;
            if (doorVentGroups.TryGetValue(argument, out group))
            {
                var doors = ToDoors(ZACommons.GetBlocksOfType <IMyDoor>(group.Blocks));
                // Only need to do one (assumes door groups were set up correctly... heh)
                if (doors.Count > 0)
                {
                    var door = doors[0];
                    ZACommons.BlockGroup room;
                    if (doorVentRooms.TryGetValue(door, out room))
                    {
                        var otherVents = ToVents(ZACommons.GetBlocksOfType <IMyAirVent>(group.Blocks));
                        var roomVents  = ToVents(ZACommons.GetBlocksOfType <IMyAirVent>(room.Blocks));
                        var target     = GetAirlockState(otherVents);
                        var current    = GetAirlockState(roomVents);

                        ChangeRoomState(room.Name,
                                        roomVents,
                                        ToDoors(ZACommons.GetBlocksOfType <IMyDoor>(room.Blocks)),
                                        current, target, doors);
                    }
                }
            }
        }
    }
Ejemplo n.º 10
0
    public void Run(ZACommons commons)
    {
        // Only care about power producers on this ship
        var producers = ZACommons.GetBlocksOfType <IMyTerminalBlock>(commons.Blocks,
                                                                     block => block is IMyPowerProducer);

        // Limit to functional batteries
        var batteries = ZACommons.GetBlocksOfType <IMyBatteryBlock>(producers,
                                                                    battery => battery.IsFunctional);

        if (batteries.Count == 0)
        {
            return;                       // Nothing to do if no batteries to manage
        }
        // All other power producers
        var otherProducers = ZACommons.GetBlocksOfType <IMyTerminalBlock>(producers,
                                                                          block => !(block is IMyBatteryBlock));

        var batteryDetails = GetPowerDetails <IMyBatteryBlock>(batteries);
        var otherDetails   = GetPowerDetails <IMyTerminalBlock>(otherProducers);

        var totalDetails = batteryDetails + otherDetails;

        //commons.Echo("Battery Load: " + batteryDetails.ToString());
        //commons.Echo("Other Load: " + otherDetails.ToString());
        //commons.Echo("Total Load: " + totalDetails.ToString());

        // First, the degenerate cases...
        if (totalDetails.MaxPowerOutput == 0.0f)
        {
            return;                                      // Don't think this is possible...
        }
        if (otherDetails.MaxPowerOutput == 0.0f)
        {
            // Nothing but our batteries. Just put all batteries online.
            ZACommons.EnableBlocks(batteries, true);
            ZACommons.SetBatteryRecharge(batteries, false);
            return;
        }

        var totalLoad = totalDetails.CurrentPowerOutput / totalDetails.MaxPowerOutput;

        // If total system load exceeds threshold, attempt to bring a battery online.
        if (totalLoad > POWER_MANAGER_HIGH_LOAD_THRESHOLD)
        {
            QuietTimer = TimeSpan.FromSeconds(0);

            // Sort by stored power descending
            batteries.Sort(batteryComparerDesc);

            // Bring the first recharging battery online, shut down all other recharging batteries
            // (just shutting them down would probably free up a lot of power... need
            // separate case?)
            var found = false;
            for (var e = batteries.GetEnumerator(); e.MoveNext();)
            {
                var battery = e.Current;

                if (battery.Enabled && battery.ProductionEnabled)
                {
                    continue;                                               // Battery is already online, don't touch it
                }
                if (!found)
                {
                    // Found the first one, bring it online
                    if (!battery.Enabled)
                    {
                        battery.GetActionWithName("OnOff_On").Apply(battery);
                    }
                    ZACommons.SetBatteryRecharge(battery, false);
                    found = true;
                }
                else
                {
                    // Shut it down
                    if (battery.Enabled)
                    {
                        battery.GetActionWithName("OnOff_Off").Apply(battery);
                    }
                }
            }
        }
        else if (totalLoad < POWER_MANAGER_LOW_LOAD_THRESHOLD)
        {
            QuietTimer += commons.Program.ElapsedTime;

            if (QuietTimer >= QuietTimeout)
            {
                // NB We don't reset QuietTimer, so we will trigger at next tick again
                // (assuming load is still low)

                // Sort from low to high
                batteries.Sort(batteryComparer);

                // Any batteries actively discharging?
                if (batteryDetails.CurrentPowerOutput > 0.0f)
                {
                    // Take a battery offline, starting with the least charged.
                    // Note, we cannot actually start recharging until they are all offline
                    DisableOneBattery(batteries, totalDetails);
                }
                else
                {
                    // All batteries are down, enable one for charging
                    // (repeat next tick until we break low threshold, in which case QuietTimer
                    // will reset)
                    // But first, check if it would put us over the threshold
                    var first         = batteries[0];                                               // Assume all the same
                    var wouldBeOutput = otherDetails.CurrentPowerOutput + first.DefinedPowerOutput; // Assume MaxPowerOutput = MaxPowerInput (not available to us)
                    //commons.Echo("Would-be Output: " + ZACommons.FormatPower(wouldBeOutput));
                    var wouldBeLoad = wouldBeOutput / otherDetails.MaxPowerOutput;
                    //commons.Echo("Would-be Load: " + wouldBeLoad);

                    if (wouldBeLoad <= POWER_MANAGER_HIGH_LOAD_THRESHOLD)
                    {
                        RechargeOneBattery(batteries);
                    }
                }
            }
        }
        else
        {
            QuietTimer = TimeSpan.FromSeconds(0);
        }
    }
    private IMyMotorStator GetRotor(ZACommons.BlockGroup group)
    {
        var rotors = ZACommons.GetBlocksOfType <IMyMotorStator>(group.Blocks);

        return(rotors.Count == 1 ? rotors[0] : null);
    }
Ejemplo n.º 12
0
    public void Run(ZACommons commons, EventDriver eventDriver)
    {
        var tanks = ZACommons.GetBlocksOfType <IMyOxygenTank>(commons.AllBlocks,
                                                              tank => tank.IsFunctional &&
                                                              tank.IsWorking &&
                                                              tank.CustomName.IndexOf("[Excluded]", ZACommons.IGNORE_CASE) < 0);

        var currentState = GetOxygenState(tanks);

        // Only act on level transitions
        if (PreviousState != currentState)
        {
            PreviousState = currentState;

            // We need a tri-state variable, so... nullable
            bool?generateOxygen = null;
            bool?farmOxygen     = null;

            switch (currentState)
            {
            case OXYGEN_LEVEL_HIGH:
                // Turn off all oxygen production
                generateOxygen = false;
                farmOxygen     = false;
                break;

            case OXYGEN_LEVEL_NORMAL:
                // Do nothing (but keep farms up)
                farmOxygen = true;
                break;

            case OXYGEN_LEVEL_BUFFER:
                // Start producing oxygen
                generateOxygen = true;
                farmOxygen     = true;
                break;

            case OXYGEN_LEVEL_LOW:
                // Definitely start producing oxygen
                generateOxygen = true;
                farmOxygen     = true;
                // For now, it's intentional that we start timer blocks
                // on all grids... we'll see how it goes
                ZACommons.StartTimerBlockWithName(commons.AllBlocks, LOW_OXYGEN_NAME);
                break;
            }

            if (generateOxygen != null)
            {
                // Limit to this grid -- don't mess with any other ship's systems
                var generators =
                    ZACommons.GetBlocksOfType <IMyOxygenGenerator>(commons.Blocks,
                                                                   block => block.IsFunctional);
                ZACommons.EnableBlocks(generators, (bool)generateOxygen);
            }
            if (farmOxygen != null)
            {
                var farms =
                    ZACommons.GetBlocksOfType <IMyOxygenFarm>(commons.Blocks,
                                                              block => block.IsFunctional);

                // Farms don't implement IMyFunctionalBlock??
                ZACommons.EnableBlocks(farms, (bool)farmOxygen);

                // We'll count atmosphere intake vents too, since they're "free"
                var vents =
                    ZACommons.GetBlocksOfType <IMyAirVent>(commons.Blocks,
                                                           vent => vent.IsFunctional &&
                                                           ((IMyAirVent)vent).IsDepressurizing &&
                                                           vent.CustomName.IndexOf("[Intake]", ZACommons.IGNORE_CASE) >= 0);

                ZACommons.EnableBlocks(vents, (bool)farmOxygen);
            }
        }

        eventDriver.Schedule(RunDelay, Run);
    }