예제 #1
0
 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;
             }
     }
 }
예제 #2
0
    public void Paint(ZACommons commons, EventDriver eventDriver)
    {
        if (Mode != Modes.Painting && Mode != Modes.Released)
        {
            return;
        }

        var camera = GetMainCamera(commons);

        // Can we raycast the desired distance?
        var scanTime = camera.TimeUntilScan(RaycastRange);

        if (scanTime > 0)
        {
            // Try later
            eventDriver.Schedule((double)scanTime / 1000.0, Paint);
            return;
        }

        MyDetectedEntityInfo info;

        if (GyroLock && LastTargetUpdate != null)
        {
            // If we're locked, attempt to cast at the predicted center
            var delta       = eventDriver.TimeSinceStart - (TimeSpan)LastTargetUpdate;
            var targetGuess = TargetPosition + TargetVelocity * delta.TotalSeconds;
            info = camera.Raycast(targetGuess);
        }
        else
        {
            // Otherwise just cast straight ahead
            info = camera.Raycast(RaycastRange);
        }
        if (info.IsEmpty())
        {
            // Missed? Increase range, try again and release gyro
            RaycastRange = Math.Min(RaycastRange * RAYCAST_RANGE_BUFFER, INITIAL_RAYCAST_RANGE);
            GyroLock     = false;
            eventDriver.Schedule(1, Paint);
            PostFeedback(commons, TRACKER_MISS_GROUP);
            return;
        }

        TargetUpdated(commons, eventDriver, info);

        // Also update saved info for refresh if ID is the same
        if (RefreshInfo != null && info.EntityId == ((MyDetectedEntityInfo)RefreshInfo).EntityId)
        {
            RefreshInfo       = info;
            RefreshUpdateTime = eventDriver.TimeSinceStart;
        }

        RaycastRange = (TargetPosition - camera.GetPosition()).Length() * RAYCAST_RANGE_BUFFER;

        BeginLock(commons, eventDriver);
        eventDriver.Schedule(TRACKER_UPDATE_RATE, Paint);

        PostFeedback(commons, TRACKER_PING_GROUP);
    }
예제 #3
0
 public void Init(ZACommons commons, EventDriver eventDriver, ZACustomData customData)
 {
     TransponderID = customData.GetString("transponderID");
     if (TransponderID.Length > 0)
     {
         eventDriver.Schedule(0, Run);
     }
     eventDriver.Schedule(RunDelay, Cleanup);
 }
예제 #4
0
    public void Init(ZACommons commons, EventDriver eventDriver)
    {
        IsControlled = null;

        ResetAbandonment(eventDriver);

        IsDocked = false;
        eventDriver.Schedule(0.0, Fast);
        eventDriver.Schedule(0.0, Slow);
    }
예제 #5
0
    public void Init(ZACommons commons, EventDriver eventDriver)
    {
        IsControlled = null;

        ResetAbandonment(eventDriver);

        IsDocked = false;
        eventDriver.Schedule(0.0, Fast);
        eventDriver.Schedule(0.0, Slow);
    }
예제 #6
0
    public void Init(ZACommons commons, EventDriver eventDriver)
    {
        var shipControl = (ShipControlCommons)commons;

        seeker.Init(shipControl,
                    shipUp: shipControl.ShipUp,
                    shipForward: shipControl.ShipForward);

        eventDriver.Schedule(0, Run);
        eventDriver.Schedule(FULL_BURN_DELAY, FullBurn);
    }
예제 #7
0
    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);
        }
    }
예제 #8
0
    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);
    }
예제 #9
0
    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);
    }
예제 #10
0
    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);
    }
예제 #11
0
    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);
        }
    }
예제 #12
0
    public void Brake(ZACommons commons, EventDriver eventDriver)
    {
        if (ShouldAbort(commons, eventDriver, Modes.Braking, Autodrop))
        {
            return;
        }

        var shipControl = (ShipControlCommons)commons;

        var controller = GetShipController(shipControl);

        if (controller == null)
        {
            return;
        }
        var gravity = controller.GetNaturalGravity();

        if (gravity.LengthSquared() > 0.0)
        {
            double yawPitchError;
            seeker.Seek(shipControl, gravity, out yawPitchError);

            cruiser.Cruise(shipControl, VTVLHELPER_BRAKING_SPEED,
                           condition: ThrusterCondition,
                           enableForward: false);

            eventDriver.Schedule(FramesPerRun, Brake);
        }
        else
        {
            // If we left gravity, just abort.
            Reset(shipControl);
        }
    }
예제 #13
0
    public void UndockDetach(ZACommons commons, EventDriver eventDriver)
    {
        // Unlock connectors
        var connectors = ZACommons.GetBlocksOfType <IMyShipConnector>(commons.Blocks, connector => connector.DefinitionDisplayNameText == "Connector");

        connectors.ForEach(block =>
        {
            var connector = (IMyShipConnector)block;
            if (connector.IsLocked && connector.IsConnected)
            {
                connector.ApplyAction("Unlock");
            }
        });

        // Unlock all landing gear
        var gears = ZACommons.GetBlocksOfType <IMyLandingGear>(commons.Blocks);

        gears.ForEach(block =>
        {
            var gear = (IMyLandingGear)block;
            if (gear.IsLocked)
            {
                gear.ApplyAction("Unlock");
            }
        });

        // 1 second from now, disable all connectors
        eventDriver.Schedule(1.0, UndockDisable);
    }
예제 #14
0
    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);
        }
    }
예제 #15
0
    public void Tock(ZACommons commons, EventDriver eventDriver)
    {
        var vents = GetAirVents(commons);

        vents.ForEach(vent =>
        {
            var level = vent.GetOxygenLevel();
            if (vent.Depressurize && level > 0.0f)
            {
                vent.Enabled = true;
            }
            else if (!vent.Depressurize)
            {
                if (level < MIN_AIR_VENT_PRESSURE)
                {
                    vent.Enabled = true;
                }
                else if (level > MAX_AIR_VENT_PRESSURE)
                {
                    vent.Enabled = false;
                }
            }
        });

        eventDriver.Schedule(RunDelay, Tick);
    }
예제 #16
0
 private void Start(ZACommons commons, EventDriver eventDriver, bool auto)
 {
     Show(commons);
     if (Mode == IDLE) eventDriver.Schedule(RunDelay, Run);
     Mode = auto ? AUTO : ACTIVE;
     SaveMode(commons);
 }
예제 #17
0
    public void Reorient(ZACommons commons, EventDriver eventDriver)
    {
        if (!Enabled)
        {
            return;
        }

        var shipControl = (ShipControlCommons)commons;

        double yawError, pitchError;
        var    gyroControl = seeker.Seek(shipControl, TargetVector,
                                         out yawError, out pitchError);

        if ((pitchError * pitchError + yawError * yawError) < MaxError)
        {
            gyroControl.Reset();
            shipControl.ThrustControl.Enable(true);
            gyroControl.Reset();
            gyroControl.EnableOverride(false);
            // Done
        }
        else
        {
            eventDriver.Schedule(FramesPerRun, Reorient);
        }
    }
예제 #18
0
    public void DetermineVelocity(ZACommons commons, EventDriver eventDriver)
    {
        if (!Enabled)
        {
            return;
        }

        var shipControl = (ShipControlCommons)commons;

        var velocity = (shipControl.ReferencePoint - LastPosition) /
                       ((double)SampleDelay / 60.0);

        TargetVector = -velocity;
        var speed = TargetVector.Normalize();

        if (speed > 0.1)
        {
            eventDriver.Schedule(FramesPerRun, Reorient);
        }
        else
        {
            var gyroControl = shipControl.GyroControl;
            gyroControl.Reset();
            gyroControl.EnableOverride(false);
            shipControl.ThrustControl.Enable(true);
        }
    }
예제 #19
0
    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);
    }
예제 #20
0
    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);
    }
예제 #21
0
    public void Prime(ZACommons commons, EventDriver eventDriver)
    {
        // Wake up batteries
        var batteryGroup = commons.GetBlockGroupWithName(StandardMissile.BATTERY_GROUP + MissileGroupSuffix);

        if (batteryGroup == null)
        {
            throw new Exception("Group missing: " + StandardMissile.BATTERY_GROUP + MissileGroupSuffix);
        }
        var systemsGroup = commons.GetBlockGroupWithName(StandardMissile.SYSTEMS_GROUP + MissileGroupSuffix);

        if (systemsGroup == null)
        {
            throw new Exception("Group missing: " + StandardMissile.SYSTEMS_GROUP + MissileGroupSuffix);
        }

        var batteries = ZACommons.GetBlocksOfType <IMyBatteryBlock>(batteryGroup.Blocks);

        batteries.ForEach(battery =>
        {
            battery.Enabled       = true;
            battery.OnlyDischarge = true;
        });

        // Activate flight systems
        ZACommons.EnableBlocks(systemsGroup.Blocks, true);

        eventDriver.Schedule(0.1 + ReleaseDelay, Release);
    }
예제 #22
0
    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);
        }
    }
예제 #23
0
    public void Run(ZACommons commons, EventDriver eventDriver)
    {
        // Bleah, might be merged, so use a group
        var payloadGroup = commons.GetBlockGroupWithName(PAYLOAD_GROUP + MISSILE_GROUP_SUFFIX);

        if (payloadGroup == null)
        {
            return;
        }
        var containers = ZACommons.GetBlocksOfType <IMyCargoContainer>(payloadGroup.Blocks);

        if (containers.Count == 0)
        {
            return;
        }

        // Leisurely pace of one stack per container per frame
        bool moved = false;

        for (var e = containers.GetEnumerator(); e.MoveNext();)
        {
            var container = e.Current;
            if (SplitContainerContents(container))
            {
                moved = true;
            }
        }

        if (moved)
        {
            eventDriver.Schedule(1, Run);
        }
    }
예제 #24
0
    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);
    }
예제 #25
0
    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);
    }
예제 #26
0
    public void Run(ZACommons commons, EventDriver eventDriver)
    {
        if (Indexes.Count == 0)
        {
            return;
        }

        var newIndexes = new Dictionary <string, int>();

        foreach (var kv in Indexes)
        {
            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);
    }
예제 #27
0
    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);
    }
예제 #28
0
    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);
    }
예제 #29
0
    public void Init(ZACommons commons, EventDriver eventDriver)
    {
        // Should we be holding on to this...?
        LauncherReference = SetLauncherReference(commons, TRACKER_REFERENCE_GROUP);

        eventDriver.Schedule(0, Run);
    }
    public void Prime(ZACommons commons, EventDriver eventDriver)
    {
        var relayBatteries = commons.GetBlockGroupWithName(BATTERY_GROUP);

        if (relayBatteries == null)
        {
            throw new Exception("Missing group: " + BATTERY_GROUP);
        }
        var relaySystems = commons.GetBlockGroupWithName(SYSTEMS_GROUP);

        if (relaySystems == null)
        {
            throw new Exception("Missing group: " + SYSTEMS_GROUP);
        }

        // Wake up batteries
        var batteries = ZACommons.GetBlocksOfType <IMyBatteryBlock>(relayBatteries.Blocks);

        ZACommons.EnableBlocks(batteries, true);
        ZACommons.SetBatteryRecharge(batteries, false);
        // And activate flight systems
        ZACommons.EnableBlocks(relaySystems.Blocks, true);

        eventDriver.Schedule(1.0, Release);
    }
예제 #31
0
    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);
    }
예제 #32
0
    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);
    }
예제 #33
0
    private void DoAction(ZACommons commons, EventDriver eventDriver,
                          string name)
    {
        string timers;
        var    projector = GetProjector(commons, name, out timers);

        if (projector == null)
        {
            return;
        }

        var parts      = timers.Split(new char[] { ACTION_DELIMITER }, 2);
        var startTimer = parts[0].Trim();
        var endTimer   = parts.Length > 1 ? parts[1].Trim() : "";

        // No timers, nothing to do
        if ((startTimer.Length + endTimer.Length) == 0)
        {
            return;
        }

        // Enable projector, if it isn't already
        projector.Enabled = true;

        // Start start timer, if we have one
        StartTimerBlock(commons, startTimer);

        // Start loop
        eventDriver.Schedule(RunDelay, new ProjectorActionHelper(name, endTimer).Run);
    }
예제 #34
0
 public void Init(ZACommons commons, EventDriver eventDriver, ZACustomData customData,
                  Action <ZACommons, EventDriver> postLaunch)
 {
     PostLaunch   = postLaunch;
     ReleaseDelay = customData.GetDouble("releaseDelay");
     eventDriver.Schedule(0, Prime);
 }
예제 #35
0
    public void Run(ZACommons commons, EventDriver eventDriver)
    {
        var myConnectors = ZACommons.GetBlocksOfType <IMyShipConnector>(commons.Blocks,
                                                                        block => block.DefinitionDisplayNameText == "Connector" &&
                                                                        ((IMyShipConnector)block).Status == MyShipConnectorStatus.Connected);
        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.Enabled = false);
            }
        }

        eventDriver.Schedule(RunDelay, Run);
    }
예제 #36
0
    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);
    }
예제 #37
0
    public void Release(ZACommons commons, EventDriver eventDriver)
    {
        // Enable mass
        var group = commons.GetBlockGroupWithName(StandardMissile.MASS_GROUP + MissileGroupSuffix);

        if (group != null)
        {
            ZACommons.EnableBlocks(group.Blocks, true);
        }

        var releaseGroup = commons.GetBlockGroupWithName(StandardMissile.RELEASE_GROUP + MissileGroupSuffix);

        if (releaseGroup == null)
        {
            throw new Exception("Group missing: " + StandardMissile.RELEASE_GROUP + MissileGroupSuffix);
        }

        // Unlock any landing gear
        ZACommons.ForEachBlockOfType <IMyLandingGear>(releaseGroup.Blocks,
                                                      gear => gear.ApplyAction("Unlock"));
        // And then turn everything off (connectors, merge blocks, etc)
        ZACommons.EnableBlocks(releaseGroup.Blocks, false);

        // Initialize flight control
        var shipControl = (ShipControlCommons)commons;

        shipControl.Reset(gyroOverride: true, thrusterEnable: null);

        eventDriver.Schedule(0.1, Demass);
    }
예제 #38
0
    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);
    }
예제 #39
0
    public void Init(ZACommons commons, EventDriver eventDriver)
    {
        var stateValue = commons.GetValue(StateKey);

        if (stateValue != null)
        {
            int state;
            if (int.TryParse(stateValue, out state))
            {
                // Use remembered state
                CurrentState = state;
                // Should really validate, but eh...
            }
        }
        else
        {
            CurrentState = STATE_ACTIVE;
        }

        if (PRODUCTION_MANAGER_SETUP)
        {
            Setup(LIMIT_PRODUCTION_MANAGER_SAME_GRID ? commons.Blocks : commons.AllBlocks);
        }
        else if (CurrentState != STATE_INACTIVE)
        {
            eventDriver.Schedule(0.0, Run);
        }
    }
예제 #40
0
    public void Run(ZACommons commons, EventDriver eventDriver)
    {
        var groups = commons.GetBlockGroupsWithPrefix(SIMPLE_AIRLOCK_GROUP_PREFIX);

        foreach (var group in groups)
        {
            var doors = ZACommons.GetBlocksOfType <IMyDoor>(group.Blocks,
                                                            door => door.CubeGrid == commons.Me.CubeGrid &&
                                                            door.IsFunctional);

            var opened = IsAnyDoorOpen(doors);
            foreach (var door in doors)
            {
                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.Enabled = false;
                    }
                }
                else
                {
                    if (!door.Enabled)
                    {
                        door.Enabled = true;
                    }
                }
            }
        }

        eventDriver.Schedule(RunDelay, Run);
    }
예제 #41
0
    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);
    }
    public void Run(ZACommons commons, EventDriver eventDriver)
    {
        if (!Active)
        {
            return;
        }

        TotalPower = 0.0f;
        var solarGroups = commons.GetBlockGroupsWithPrefix(MAX_POWER_GROUP_PREFIX);

        foreach (var group in solarGroups)
        {
            var rotor = GetRotor(group);
            if (rotor == null)
            {
                commons.Echo(string.Format("Group {0} ignored; needs exactly 1 rotor", group.Name));
                continue;
            }
            else if (rotor.CubeGrid != commons.Me.CubeGrid)
            {
                // Skip if rotor is on a different grid than this programmable block
                continue;
            }

            var solarPanelDetails = new SolarPanelDetails(group);
            var currentMaxPower   = solarPanelDetails.MaxPowerOutput;

            float maxPower;
            if (!MaxPowers.TryGetValue(group.Name, out maxPower))
            {
                maxPower = -100.0f;
            }

            var minError = solarPanelDetails.DefinedPowerOutput * SOLAR_ROTOR_MIN_ERROR;
            var delta    = currentMaxPower - maxPower;
            MaxPowers[group.Name] = currentMaxPower;

            if (delta > minError || currentMaxPower < minError /* failsafe */)
            {
                // Keep going
                rotor.Enabled = true;
            }
            else if (delta < -minError)
            {
                // Back up
                rotor.Enabled = true;
                rotor.ApplyAction("Reverse");
            }
            else
            {
                // Hold still for a moment
                rotor.Enabled = false;
            }

            TotalPower += currentMaxPower;
        }

        eventDriver.Schedule(RunDelay, Run);
    }
예제 #43
0
    public void DHRun(ZACommons commons, EventDriver eventDriver)
    {
        if (IsDocked) return;

        Run(commons);

        eventDriver.Schedule(RunDelay, DHRun);
    }
예제 #44
0
 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);
     });
 }
예제 #45
0
    public void Run(ZACommons commons, EventDriver eventDriver)
    {
        if (IsDocked) return;

        RunInternal(commons, eventDriver);

        eventDriver.Schedule(RunDelay, Run);
    }
예제 #46
0
 public void Init(ZACommons commons, EventDriver eventDriver)
 {
     Active = true;
     SaveActive(commons);
     MaxPowers.Clear();
     TotalPower = 0.0f;
     eventDriver.Schedule(0.0, Run);
 }
예제 #47
0
 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);
 }
예제 #48
0
 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);
             });
 }
예제 #49
0
    public void DockingAction(ZACommons commons, EventDriver eventDriver,
                              bool docked)
    {
        if (docked)
        {
            IsDocked = true;
        }
        else if (IsDocked)
        {
            IsControlled = null;

            ResetAbandonment(eventDriver);

            IsDocked = false;
            eventDriver.Schedule(FastRunDelay, Fast);
            eventDriver.Schedule(SlowRunDelay, Slow);
        }
    }
예제 #50
0
    public void Release(ZACommons commons, EventDriver eventDriver)
    {
        var relayRelease = commons.GetBlockGroupWithName(RELEASE_GROUP);
        if (relayRelease == null)
        {
            throw new Exception("Missing group: " + RELEASE_GROUP);
        }
        ZACommons.EnableBlocks(relayRelease.Blocks, false);

        eventDriver.Schedule(1.0, Burn);
    }
예제 #51
0
    public void Init(ZACommons commons, EventDriver eventDriver,
                     Action<ZACommons, EventDriver> postLaunch = null)
    {
        PostLaunch = postLaunch;

        var remote = GetRemoteControl(commons);
        // Determine current state
        if (IsInLauncher(commons))
        {
            eventDriver.Schedule(0.0, Prime);
        }
        else if (remote.GetValue<bool>("AutoPilot"))
        {
            eventDriver.Schedule(0.0, AutopilotEnd);
        }
        else
        {
            if (PostLaunch != null) PostLaunch(commons, eventDriver);
        }
    }
예제 #52
0
    public void Burn(ZACommons commons, EventDriver eventDriver)
    {
        // Boost away from launcher, initialize flight control
        var shipControl = (ShipControlCommons)commons;

        shipControl.Reset(gyroOverride: true, thrusterEnable: null);

        // Initiate main burn here, otherwise do it later
        var thrustControl = shipControl.ThrustControl;
        if (!BURN_DOWNWARD)
        {
            thrustControl.SetOverride(Base6Directions.Direction.Forward, BURN_FRACTION);
            eventDriver.Schedule(BURN_TIME, Arm);
        }
        else
        {
            thrustControl.SetOverride(Base6Directions.Direction.Down);
            eventDriver.Schedule(BURN_DOWNWARD_TIME, MainBurn);
        }
    }
예제 #53
0
 public void Init(ZACommons commons, EventDriver eventDriver,
                  Vector3D target, double speed,
                  double delay = 1.0)
 {
     if (!AutopilotEngaged)
     {
         AutopilotTarget = target;
         AutopilotSpeed = speed;
         AutopilotEngaged = true;
         eventDriver.Schedule(delay, Start);
     }
 }
예제 #54
0
 public void Start(ZACommons commons, EventDriver eventDriver)
 {
     var shipControl = (ShipControlCommons)commons;
     shipControl.Reset(gyroOverride: true, thrusterEnable: null);
     forwardCruiser.Init(shipControl,
                         localForward: shipControl.ShipForward);
     upCruiser.Init(shipControl,
                    localForward: shipControl.ShipUp);
     leftCruiser.Init(shipControl,
                      localForward: Base6Directions.GetLeft(shipControl.ShipUp, shipControl.ShipForward));
     eventDriver.Schedule(0, Run);
 }
예제 #55
0
    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);
    }
예제 #56
0
 public void Run(ZACommons commons, EventDriver eventDriver)
 {
     if (Mode == IDLE) return;
     var damaged = Show(commons) > 0;
     if (Mode == ACTIVE || damaged)
     {
         eventDriver.Schedule(RunDelay, Run);
     }
     else
     {
         ResetMode(commons);
     }
 }
예제 #57
0
 public void Init(ZACommons commons, EventDriver eventDriver)
 {
     commons.Blocks.ForEach(block =>
             {
                 if (block is IMyProgrammableBlock ||
                     block is IMyTimerBlock)
                 {
                     BlocksToCheck.Add(block);
                 }
             });
     StartPoint = ((ShipControlCommons)commons).ReferencePoint;
     eventDriver.Schedule(0, Run);
 }
예제 #58
0
 public void DockingAction(ZACommons commons, EventDriver eventDriver,
                           bool docked)
 {
     if (docked)
     {
         IsDocked = true;
     }
     else if (IsDocked)
     {
         IsDocked = false;
         eventDriver.Schedule(RunDelay, DHRun);
     }
 }
예제 #59
0
    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);
    }
예제 #60
0
    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);
    }