using MultiversalDiplomacy.Model; namespace MultiversalDiplomacy.Script; /// /// A script handler for interacting with a loaded game. /// public class SetupScriptHandler : IScriptHandler { public SetupScriptHandler(World world) { World = world; } public string Prompt => "5dp> "; public World World { get; set; } public IScriptHandler? HandleInput(string input) { var args = input.Split(' ', StringSplitOptions.RemoveEmptyEntries); if (args.Length == 0) { return new GameScriptHandler(World); } var command = args[0]; switch (command) { case "help": case "?": Console.WriteLine("commands:"); Console.WriteLine(" unit: add a unit to the map"); Console.WriteLine(" list: list things in a game category"); Console.WriteLine(" enter a blank line to complete setup"); break; case "list" when args.Length == 1: Console.WriteLine("usage:"); Console.WriteLine(" list powers: the powers in the game"); Console.WriteLine(" list units: units created so far"); break; case "list" when args[1] == "powers": Console.WriteLine("Powers:"); foreach (Power power in World.Powers) { Console.WriteLine($" {power.Name}"); } break; case "list" when args[1] == "units": Console.WriteLine("Units:"); foreach (Unit unit in World.Units) { Console.WriteLine($" {unit}"); } break; case "unit" when args.Length < 4: Console.WriteLine("usage: unit [power] [type] [province]"); break; case "unit": ParseUnit(args); break; default: Console.WriteLine("Unrecognized command"); break; } return this; } private void ParseUnit(string[] args) { // Parse the power name by substring matching. string powerArg = args[1].ToLower(); var matchingPowers = World.Powers.Where(p => p.Name.ToLower().StartsWith(powerArg)); if (matchingPowers.Count() < 1) { Console.WriteLine($"No power named \"{args[1]}\""); return; } if (matchingPowers.Count() > 1) { Console.WriteLine($"Ambiguous power \"{args[1]}\""); return; } Power power = matchingPowers.First(); // Parse the unit type by substring matching. string typeArg = args[2].ToLower(); var matchingTypes = Enum.GetNames().Where(t => t.ToLower().StartsWith(typeArg)); if (matchingTypes.Count() < 1) { Console.WriteLine($"No unit type \"{args[2]}\""); return; } if (matchingTypes.Count() > 1) { Console.WriteLine($"Ambiguous unit type \"{args[2]}\""); return; } UnitType type = (UnitType)Enum.Parse(typeof(UnitType), matchingTypes.First()); // Parse the province by matching the province name or one of its abbreviations, // allowing location specifications separated by a forward slash, e.g. spa/nc. string provinceArg = args[3].ToLower(); var matchingProvs = World.Provinces.Where(pr => pr.Abbreviations.Any(abv => abv.ToLower() == provinceArg) || pr.Name.ToLower() == provinceArg); if (matchingProvs.Count() < 1) { Console.WriteLine($"No province matches \"{args[3]}\""); return; } if (matchingTypes.Count() > 1) { Console.WriteLine($"Ambiguous province \"{args[3]}\""); return; } // TODO: this does not support multi-location provinces correctly Province province = matchingProvs.First(); Location location = province.Locations.First(loc => type == UnitType.Army && loc.Type == LocationType.Land || type == UnitType.Fleet && loc.Type == LocationType.Water); Unit unit = Unit.Build(location, World.RootSeason, power, type); World = World.Update(units: World.Units.Append(unit)); Console.WriteLine($"Created unit {unit}"); } }