Ejemplo n.º 1
0
        private void UpdateZoneStatistics(IMyTextSurface textSurface, IReadOnlyDictionary <String, EntityState> zones)
        {
            var builder    = new StringBuilder();
            var zonestatus = new List <String>();
            var gridType   = "Ship";

            if (Me.CubeGrid.IsStatic)
            {
                gridType = "Station";
            }

            var zonepad = gridType.Length;

            if (zones.Any())
            {
                zonepad = Math.Max(zones.Max(z => z.Key.Length), gridType.Length);
            }

            builder.Append($"{gridType.PadLeft(zonepad)} ");

            if (GridState.HasFlag(EntityState.Destruct))
            {
                zonestatus.Add("Self Destruct");
            }

            if (GridState.HasFlag(EntityState.Battle))
            {
                zonestatus.Add("Battle Stations");
            }

            if (GridState.HasFlag(EntityState.LowPower))
            {
                zonestatus.Add("Low Power");
            }

            builder.AppendLine(String.Join(", ", zonestatus.DefaultIfEmpty("Normal")));

            foreach (var zone in zones.OrderBy(z => z.Key))
            {
                zonestatus.Clear();
                builder.Append($"{zone.Key.PadLeft(zonepad)} ");

                if (zone.Value.HasFlag(EntityState.Decompress))
                {
                    zonestatus.Add("Decompressed");
                }

                if (zone.Value.HasFlag(EntityState.Intruder))
                {
                    zonestatus.Add("Intruder");
                }

                builder.AppendLine(String.Join(", ", zonestatus.DefaultIfEmpty("Normal")));
            }

            textSurface.DrawScaledSpriteText(builder, textSurface.Font, textSurface.FontColor);
        }
Ejemplo n.º 2
0
        private IEnumerator <Int32> StateMachineExecutor()
        {
            Echo("Starting cycle.");

            var gridState     = GridState;
            var debugDisplays = 0;

            var zoneStatSurface = Me.GetSurface(0);

            zoneStatSurface.ContentType = ContentType.TEXT_AND_IMAGE;

            yield return(0);

            Echo("Restoring global statuses.");
            Configuration = new MyIni();

            if (Configuration.TryParse(Storage))
            {
                var state     = Convert.ToInt32(GridState);
                var power     = PowerThreshold;
                var countdown = Countdown;

                if (Configuration.Get(ConfigSection, nameof(GridState)).TryGetInt32(out state))
                {
                    GridState = (EntityState)state;
                }

                if (Configuration.Get(ConfigSection, nameof(PowerThreshold)).TryGetDouble(out power))
                {
                    PowerThreshold = power;
                }

                if (Configuration.Get(ConfigSection, nameof(Countdown)).TryGetSingle(out countdown))
                {
                    Countdown = countdown;
                }
            }
            else
            {
                Echo("The ships system configuration is empty, outdated or corrupt. Resetting to known good values.");

                Configuration.Set(ConfigSection, nameof(GridState), Convert.ToInt32(GridState));
                Configuration.Set(ConfigSection, nameof(PowerThreshold), PowerThreshold);
                Configuration.Set(ConfigSection, nameof(Countdown), Countdown);

                Storage = Configuration.ToString();
            }

            yield return(1);

            while (Execute)
            {
                Echo("Refreshing grid cache.");
                var grid      = GetGridBlocks();
                var zones     = new Dictionary <String, EntityState>();
                var countdown = Countdown;

                var outputs = grid.Where(b => b.Functions.HasFlag(BlockFunction.Debugger))
                              .Select(b => b.Target).OfType <IMyTextSurface>().ToList();

                foreach (var provider in grid.Where(b => b.Target is IMyTextSurfaceProvider))
                {
                    var target = provider.Target as IMyTextSurfaceProvider;
                    for (var i = 0; i < target.SurfaceCount; i++)
                    {
                        if (provider.GetEnumConfig <BlockFunction>($"functions-{i}", BlockFunction.None).HasFlag(BlockFunction.Debugger))
                        {
                            outputs.Add(target.GetSurface(i));
                        }
                    }
                }

                if (outputs.Any())
                {
                    Echo = message =>
                    {
                        var current = outputs.First().GetText().Split('\n').ToList();
                        while (current.Count() > 32)
                        {
                            current.RemoveAt(0);
                        }

                        current.Add(message);
                        var messages = String.Join("\n", current);
                        foreach (var output in outputs)
                        {
                            output.FontSize    = 0.5f;
                            output.TextPadding = 2;
                            output.Font        = "Monospace";
                            output.WriteText(messages);
                        }
                    };

                    if (debugDisplays != outputs.Count)
                    {
                        Echo($"Found {outputs.Count()} debugging displays.");
                        debugDisplays = outputs.Count;
                    }
                }
                else
                {
                    debugDisplays = 0;
                }

                var warheads = grid.Where(b => b.Functions.HasFlag(BlockFunction.SelfDestruct))
                               .Select(b => b.Target).OfType <IMyWarhead>()
                               .Where(w => w.IsWorking);

                if (warheads.Any())
                {
                    var activeWarheads = warheads.Where(w => w.IsCountingDown);
                    if (activeWarheads.Any())
                    {
                        countdown = Math.Min(countdown, activeWarheads.Min(w => w.DetonationTime));
                    }
                }
                else
                {
                    countdown = -1;
                }

                foreach (var zone in grid.SelectMany(b => b.Zones).Distinct())
                {
                    zones.Add(zone, EntityState.Default);
                }

                yield return(2);

                Echo("Enumerating zone statuses.");
                foreach (var zone in zones.ToList())
                {
                    if (TestDecompression(zone.Key, grid.Where(b => b.Zones.Contains(zone.Key))) && !zones[zone.Key].HasFlag(EntityState.Decompress))
                    {
                        Echo($"Decompression detected in zone {zone.Key}!");
                        zones[zone.Key] |= EntityState.Decompress;
                        UpdateNeeded     = true;
                    }
                    else if (zones[zone.Key].HasFlag(EntityState.Decompress))
                    {
                        zones[zone.Key] &= ~EntityState.Decompress;
                        UpdateNeeded     = true;
                    }

                    if (TestIntruder(zone.Key, grid.Where(b => b.Zones.Contains(zone.Key))) && !zones[zone.Key].HasFlag(EntityState.Intruder))
                    {
                        Echo($"Intruder detected in zone {zone.Key}!");
                        zones[zone.Key] |= EntityState.Intruder;
                        UpdateNeeded     = true;
                    }
                    else if (zones[zone.Key].HasFlag(EntityState.Intruder))
                    {
                        zones[zone.Key] &= ~EntityState.Intruder;
                        UpdateNeeded     = true;
                    }
                }

                yield return(3);

                Echo("Enumerating global statuses.");
                if (TestLowPower(grid) && !GridState.HasFlag(EntityState.LowPower))
                {
                    Echo("Low power detected");
                    GridState   |= EntityState.LowPower;
                    UpdateNeeded = true;
                }
                else if (GridState.HasFlag(EntityState.LowPower))
                {
                    GridState   &= ~EntityState.LowPower;
                    UpdateNeeded = true;
                }

                yield return(4);

                // Force updates;
                UpdateNeeded = true;
                if (UpdateNeeded)
                {
                    Echo("Applying block styles.");

                    foreach (var block in grid)
                    {
                        var states = GridState;
                        foreach (var zone in block.Zones)
                        {
                            if (zones[zone] != EntityState.Default)
                            {
                                states |= zones[zone];
                            }
                        }

                        Echo($"Styling {block.Target.DisplayName} in zones {String.Join(", ", block.Zones)}");
                        StyleBlock(block, states, countdown);
                    }

                    UpdateNeeded = false;
                }

                yield return(5);

                Echo("Saving global statuses.");
                Configuration.Set(ConfigSection, nameof(GridState), Convert.ToInt32(GridState));
                Configuration.Set(ConfigSection, nameof(PowerThreshold), PowerThreshold);
                Configuration.Set(ConfigSection, nameof(Countdown), Countdown);

                Storage = Configuration.ToString();

                foreach (var block in grid)
                {
                    block.Save();
                }

                yield return(6);

                Echo("Updating status screen.");
                UpdateZoneStatistics(zoneStatSurface, zones);

                yield return(7);
            }

            yield break;
        }
Ejemplo n.º 3
0
        private void ParseCommand(String argument)
        {
            var words   = argument.Split(' ');
            var command = words.ElementAtOrDefault(0).ToLower();

            switch (command)
            {
            case "activate":
                switch (words.ElementAtOrDefault(1).ToLower())
                {
                case "":
                    Execute = true;
                    QueueOnce();
                    break;

                case "battle":
                    if (!GridState.HasFlag(EntityState.Battle))
                    {
                        UpdateNeeded = true;
                        GridState   |= EntityState.Battle;
                    }
                    break;

                case "destruct":
                    if (!GridState.HasFlag(EntityState.Destruct))
                    {
                        UpdateNeeded = true;
                        GridState   |= EntityState.Destruct;
                    }
                    break;
                }
                break;

            case "deactivate":
                switch (words.ElementAtOrDefault(1).ToLower())
                {
                case "":
                    Execute = false;
                    break;

                case "battle":
                    if (GridState.HasFlag(EntityState.Battle))
                    {
                        UpdateNeeded = true;
                        GridState   &= ~EntityState.Battle;
                    }
                    break;

                case "destruct":
                    if (GridState.HasFlag(EntityState.Destruct))
                    {
                        UpdateNeeded = true;
                        GridState   &= ~EntityState.Destruct;
                    }
                    break;
                }
                break;

            case "toggle":
                switch (words.ElementAtOrDefault(1).ToLower())
                {
                case "":
                    if (Execute)
                    {
                        Execute = false;
                    }
                    else
                    {
                        Execute = true;
                        QueueOnce();
                    }
                    break;

                case "battle":
                    if (GridState.HasFlag(EntityState.Battle))
                    {
                        GridState &= ~EntityState.Battle;
                    }
                    else
                    {
                        GridState |= EntityState.Battle;
                    }
                    UpdateNeeded = true;
                    break;

                case "destruct":
                    if (GridState.HasFlag(EntityState.Destruct))
                    {
                        GridState &= ~EntityState.Destruct;
                    }
                    else
                    {
                        GridState |= EntityState.Destruct;
                    }
                    UpdateNeeded = true;
                    break;
                }
                break;

            case "set":
                switch (words.ElementAtOrDefault(1).ToLower())
                {
                case "lowpower":
                    var    powerValue = words.ElementAtOrDefault(2);
                    Double powerParsed;

                    if (Double.TryParse(powerValue, out powerParsed) && powerParsed >= 0 && powerParsed < 1)
                    {
                        PowerThreshold = powerParsed;
                        Echo($"Low power threshold has been set to {powerParsed}.");
                    }
                    else
                    {
                        Echo($"Low power threshold must be a decimal value >= 0 < 1.");
                    }
                    break;

                case "countdown":
                    var    countdownValue = words.ElementAtOrDefault(2);
                    Single countdownParsed;

                    if (Single.TryParse(countdownValue, out countdownParsed) && countdownParsed > 0)
                    {
                        Countdown = countdownParsed;
                        Echo($"Self Destruct timer has been set to {TimeSpan.FromSeconds(Countdown)}.");
                    }
                    else
                    {
                        Echo($"Self Destruct timer must be a decimal value greater than 0.");
                    }
                    break;
                }
                break;

            case "group":
                var verb       = String.Join(" ", words.Skip(1).Take(2));
                var parameters = String.Join(" ", words.Skip(3)).Split(';');

                if (parameters.Count() == 0 || parameters.Count() > 2)
                {
                    break;
                }

                var group  = parameters.ElementAt(0);
                var target = parameters.ElementAtOrDefault(1);

                var blocks = new List <IMyTerminalBlock>();
                var config = new MyIni();
                var values = new List <String>();

                GridTerminalSystem.GetBlockGroupWithName(group).GetBlocks(blocks);

                if (!blocks.Any())
                {
                    break;
                }

                switch (verb)
                {
                case "add function":
                case "function add":
                    if (target == "")
                    {
                        break;
                    }

                    foreach (var block in blocks)
                    {
                        config.TryParse(block.CustomData);
                        config.Get(ConfigSection, "functions").GetLines(values);

                        if (!values.Contains(target))
                        {
                            values.Add(target);
                            config.Set(ConfigSection, "functions", String.Join("\n", values));

                            block.CustomData = config.ToString();
                        }
                    }
                    break;

                case "remove function":
                case "function remove":
                    foreach (var block in blocks)
                    {
                        config.TryParse(block.CustomData);
                        config.Get(ConfigSection, "functions").GetLines(values);

                        if (target == "")
                        {
                            config.Delete(ConfigSection, "functions");
                            block.CustomData = config.ToString();
                        }
                        else if (values.Contains(target))
                        {
                            values.Remove(target);
                            config.Set(ConfigSection, "functions", String.Join("\n", values));
                        }
                    }
                    break;

                case "add zone":
                case "zone add":
                    if (target == "")
                    {
                        break;
                    }

                    foreach (var block in blocks)
                    {
                        config.TryParse(block.CustomData);
                        config.Get(ConfigSection, "zones").GetLines(values);

                        if (!values.Contains(target))
                        {
                            values.Add(target);
                            config.Set(ConfigSection, "zones", String.Join("\n", values));

                            block.CustomData = config.ToString();
                        }
                    }
                    break;

                case "remove zone":
                case "zone remove":
                    foreach (var block in blocks)
                    {
                        config.TryParse(block.CustomData);
                        config.Get(ConfigSection, "zones").GetLines(values);

                        if (target == "")
                        {
                            config.Delete(ConfigSection, "zones");
                            block.CustomData = config.ToString();
                        }
                        else if (values.Contains(target))
                        {
                            values.Remove(target);
                            config.Set(ConfigSection, "zones", String.Join("\n", values));
                        }
                    }
                    break;
                }
                break;
            }
        }