public void Apply(IGenContext context) { if (context is T map) { this.Apply(map); } }
private void addToQueue(ZoneGenContext zoneContext, IGenContext context, StablePriorityQueue <Priority, IGenStep> queue) { int id = zoneContext.CurrentID; IMonsterHouseBaseStep monsterHouseStep = HouseStepSpawns.Pick(context.Rand).CreateNew(); SpawnList <MapItem> itemListSlice = Items.GetSpawnList(id); for (int jj = 0; jj < itemListSlice.Count; jj++) { monsterHouseStep.Items.Add(new MapItem(itemListSlice.GetSpawn(jj)), itemListSlice.GetSpawnRate(jj)); } SpawnList <ItemTheme> itemThemeListSlice = ItemThemes.GetSpawnList(id); for (int jj = 0; jj < itemThemeListSlice.Count; jj++) { monsterHouseStep.ItemThemes.Add(itemThemeListSlice.GetSpawn(jj).Copy(), itemThemeListSlice.GetSpawnRate(jj)); } SpawnList <MobSpawn> mobListSlice = Mobs.GetSpawnList(id); for (int jj = 0; jj < mobListSlice.Count; jj++) { MobSpawn newSpawn = mobListSlice.GetSpawn(jj).Copy(); monsterHouseStep.Mobs.Add(newSpawn, mobListSlice.GetSpawnRate(jj)); } SpawnList <MobTheme> mobThemeListSlice = MobThemes.GetSpawnList(id); for (int jj = 0; jj < mobThemeListSlice.Count; jj++) { monsterHouseStep.MobThemes.Add(mobThemeListSlice.GetSpawn(jj).Copy(), mobThemeListSlice.GetSpawnRate(jj)); } queue.Enqueue(Priority, monsterHouseStep); }
public override void Apply(ZoneGenContext zoneContext, IGenContext context, StablePriorityQueue <Priority, IGenStep> queue) { //find the first postproc that is a GridRoom postproc and add this to its special rooms //NOTE: if a room-based generator is not found as the generation step, it will just skip this floor but treat it as though it was placed. if (SpreadPlan.CheckIfDistributed(zoneContext, context)) { //TODO: allow arbitrary components to be added RoomGenOption genDuo = Spawns.Pick(context.Rand); SetGridSpecialRoomStep <MapGenContext> specialStep = new SetGridSpecialRoomStep <MapGenContext>(); SetSpecialRoomStep <ListMapGenContext> listSpecialStep = new SetSpecialRoomStep <ListMapGenContext>(); specialStep.Filters = genDuo.Filters; if (specialStep.CanApply(context)) { specialStep.Rooms = new PresetPicker <RoomGen <MapGenContext> >(genDuo.GridOption); specialStep.RoomComponents.Set(new ImmutableRoom()); queue.Enqueue(PriorityGrid, specialStep); } else if (listSpecialStep.CanApply(context)) { listSpecialStep.Rooms = new PresetPicker <RoomGen <ListMapGenContext> >(genDuo.ListOption); listSpecialStep.RoomComponents.Set(new ImmutableRoom()); PresetPicker <PermissiveRoomGen <ListMapGenContext> > picker = new PresetPicker <PermissiveRoomGen <ListMapGenContext> >(); picker.ToSpawn = new RoomGenAngledHall <ListMapGenContext>(0); listSpecialStep.Halls = picker; queue.Enqueue(PriorityList, listSpecialStep); } } }
public override void Apply(ZoneGenContext zoneContext, IGenContext context, StablePriorityQueue <Priority, IGenStep> queue) { ItemSpawnStep <BaseMapGenContext> spawnStep = new ItemSpawnStep <BaseMapGenContext>(); spawnStep.Spawns = Spawns.GetSpawnList(zoneContext.CurrentID); queue.Enqueue(Priority, spawnStep); }
public override void Apply(ZoneGenContext zoneContext, IGenContext context, StablePriorityQueue <Priority, IGenStep> queue) { if (SpreadPlan.CheckIfDistributed(zoneContext, context)) { IGenPriority genStep = Spawns.Pick(context.Rand); queue.Enqueue(genStep.Priority, genStep.GetItem()); } }
public override void Apply(ZoneGenContext zoneContext, IGenContext context, StablePriorityQueue <Priority, IGenStep> queue) { LuaFunction luafun = LuaEngine.Instance.LuaState.GetFunction("ZONE_GEN_SCRIPT." + Script); if (luafun != null) { LuaTable args = LuaEngine.Instance.RunString("return " + ArgTable).First() as LuaTable; luafun.Call(new object[] { zoneContext, context, queue, seed, args }); } }
public override void Apply(ZoneGenContext zoneContext, IGenContext context, StablePriorityQueue <Priority, IGenStep> queue) { TileSpawnStep <BaseMapGenContext> spawnStep = new TileSpawnStep <BaseMapGenContext>(); SpawnList <EffectTile> spawner = Spawns.GetSpawnList(zoneContext.CurrentID); for (int ii = 0; ii < spawner.Count; ii++) { spawnStep.Spawns.Add(spawner.GetSpawn(ii), spawner.GetSpawnRate(ii)); } queue.Enqueue(Priority, spawnStep); }
public override void Apply(ZoneGenContext zoneContext, IGenContext context, StablePriorityQueue <Priority, IGenStep> queue) { GameProgress progress = DataManager.Instance.Save; if (progress != null && progress.Rescue != null && progress.Rescue.Rescuing) { if (progress.Rescue.SOS.Goal.ID == zoneContext.CurrentZone && progress.Rescue.SOS.Goal.StructID.Segment == zoneContext.CurrentSegment && progress.Rescue.SOS.Goal.StructID.ID == zoneContext.CurrentID) { queue.Enqueue(Priority, new RescueSpawner <BaseMapGenContext>()); } } }
public static void Init(IGenContext newMap) { curMap = newMap; currentDepth = 0; stepStack = new List <string>(); gridDebugString = new List <DebugState>(); listDebugString = new List <DebugState>(); tileDebugString = new List <DebugState>(); stepStack.Add(""); gridDebugString.Add(new DebugState()); listDebugString.Add(new DebugState()); tileDebugString.Add(new DebugState()); }
public override void Apply(ZoneGenContext zoneContext, IGenContext context, StablePriorityQueue <Priority, IGenStep> queue) { int id = zoneContext.CurrentID; foreach (int floorId in SpreadPlan.DropPoints) { if (floorId != zoneContext.CurrentID) { continue; } foreach (IGenPriority vaultStep in VaultSteps) { queue.Enqueue(vaultStep.Priority, vaultStep.GetItem()); } { SpawnList <MapItem> itemListSlice = Items.GetSpawnList(id); PickerSpawner <ListMapGenContext, MapItem> constructedSpawns = new PickerSpawner <ListMapGenContext, MapItem>(new LoopedRand <MapItem>(itemListSlice, ItemAmount[id])); List <IStepSpawner <ListMapGenContext, MapItem> > steps = new List <IStepSpawner <ListMapGenContext, MapItem> >(); steps.Add(constructedSpawns); if (ItemSpawners.ContainsItem(id)) { IStepSpawner <ListMapGenContext, MapItem> treasures = ItemSpawners[id].Copy(); steps.Add(treasures); } PresetMultiRand <IStepSpawner <ListMapGenContext, MapItem> > groupRand = new PresetMultiRand <IStepSpawner <ListMapGenContext, MapItem> >(steps.ToArray()); RandomRoomSpawnStep <ListMapGenContext, MapItem> detourItems = ItemPlacements[id].Copy(); detourItems.Spawn = new MultiStepSpawner <ListMapGenContext, MapItem>(groupRand); queue.Enqueue(ItemPriority, detourItems); } SpawnList <MobSpawn> mobListSlice = Mobs.GetSpawnList(id); if (mobListSlice.CanPick) { //secret enemies SpecificTeamSpawner specificTeam = new SpecificTeamSpawner(); MobSpawn newSpawn = mobListSlice.Pick(context.Rand).Copy(); specificTeam.Spawns.Add(newSpawn); //use bruteforce clone for this PlaceRandomMobsStep <ListMapGenContext> secretMobPlacement = MobPlacements[id].Copy(); secretMobPlacement.Spawn = new LoopedTeamSpawner <ListMapGenContext>(specificTeam, MobAmount[id]); queue.Enqueue(MobPriority, secretMobPlacement); } } }
public static void StressTest <T>(MapGen <T> layout, int amount) where T : class, IGenContext { ExampleDebug.Printing = -1; ulong structSeed = 0; try { Dictionary <int, int> generatedItems = new Dictionary <int, int>(); Dictionary <int, int> generatedEnemies = new Dictionary <int, int>(); var watch = new Stopwatch(); TimeSpan minTime = TimeSpan.MaxValue; TimeSpan maxTime = TimeSpan.MinValue; for (int ii = 0; ii < amount; ii++) { structSeed = MathUtils.Rand.NextUInt64(); TimeSpan before = watch.Elapsed; watch.Start(); IGenContext context = layout.GenMap(structSeed); watch.Stop(); TimeSpan diff = watch.Elapsed - before; if (diff > maxTime) { maxTime = diff; } if (diff < minTime) { minTime = diff; } } var avgTime = new TimeSpan(watch.Elapsed.Ticks / amount); Console.WriteLine($"Completed in {watch.Elapsed.ToString()}."); Console.WriteLine($"MIN: {minTime.ToString()} AVG: {avgTime.ToString()} MAX: {maxTime.ToString()}"); } catch (Exception ex) { Debug.Write("ERROR: " + structSeed); PrintError(ex); throw; } finally { ExampleDebug.Printing = 0; } }
public override void Apply(ZoneGenContext zoneContext, IGenContext context, StablePriorityQueue <Priority, IGenStep> queue) { MobSpawnStep <BaseMapGenContext> spawnStep = new MobSpawnStep <BaseMapGenContext>(); PoolTeamSpawner spawner = new PoolTeamSpawner(); spawner.Spawns = Spawns.GetSpawnList(zoneContext.CurrentID); spawner.TeamSizes = TeamSizes.GetSpawnList(zoneContext.CurrentID); spawnStep.Spawns.Add(spawner, spawner.Spawns.SpawnTotal); SpawnList <SpecificTeamSpawner> specificSpawner = SpecificSpawns.GetSpawnList(zoneContext.CurrentID); for (int ii = 0; ii < specificSpawner.Count; ii++) { spawnStep.Spawns.Add(specificSpawner.GetSpawn(ii), specificSpawner.GetSpawnRate(ii)); } queue.Enqueue(Priority, spawnStep); }
public override void Apply(ZoneGenContext zoneContext, IGenContext context, StablePriorityQueue <Priority, IGenStep> queue) { bool added = false; foreach (int floorId in SpreadPlan.DropPoints) { if (floorId != zoneContext.CurrentID) { continue; } addToQueue(zoneContext, context, queue); added = true; } if (added) { return; } GameProgress progress = DataManager.Instance.Save; if (progress != null && progress.ActiveTeam != null) { int totalMod = 0; foreach (Character chara in progress.ActiveTeam.Players) { foreach (FlagType state in ModStates) { CharState foundState; if (chara.CharStates.TryGet(state.FullType, out foundState)) { totalMod += ((ModGenState)foundState).Mod; } } } if (context.Rand.Next(100) < totalMod) { addToQueue(zoneContext, context, queue); return; } } }
public static void TestFloor(Stopwatch watch, ZoneSegmentBase structure, ZoneGenContext zoneContext, Dictionary <int, int> generatedItems, Dictionary <int, int> generatedEnemies, List <TimeSpan> generationTimes) { TimeSpan before = watch.Elapsed; watch.Start(); IGenContext context = structure.GetMap(zoneContext); watch.Stop(); TimeSpan diff = watch.Elapsed - before; generationTimes.Add(diff); BaseMapGenContext mapContext = context as BaseMapGenContext; if (generatedItems != null) { foreach (MapItem mapItem in mapContext.Map.Items) { if (mapItem.IsMoney) { MathUtils.AddToDictionary <int>(generatedItems, -1, mapItem.Value); MathUtils.AddToDictionary <int>(generatedItems, 0, 1); } else { MathUtils.AddToDictionary <int>(generatedItems, mapItem.Value, 1); } } } if (generatedEnemies != null) { foreach (Team team in mapContext.Map.MapTeams) { foreach (Character character in team.Players) { MathUtils.AddToDictionary <int>(generatedEnemies, character.BaseForm.Species, 1); } } } }
public override void Apply(ZoneGenContext zoneContext, IGenContext context, StablePriorityQueue <Priority, IGenStep> queue) { int id = zoneContext.CurrentID; foreach (int floorId in SpreadPlan.DropPoints) { if (floorId != zoneContext.CurrentID) { continue; } { SpawnList <AddBossRoomStep <ListMapGenContext> > bossListSlice = BossSteps.GetSpawnList(id); if (!bossListSlice.CanPick) { return; } AddBossRoomStep <ListMapGenContext> bossStep = bossListSlice.Pick(context.Rand).Copy(); queue.Enqueue(BossRoomPriority, bossStep); } foreach (IGenPriority vaultStep in VaultSteps) { queue.Enqueue(vaultStep.Priority, vaultStep.GetItem()); } { SpawnList <MapItem> itemListSlice = Items.GetSpawnList(id); PickerSpawner <ListMapGenContext, MapItem> constructedSpawns = new PickerSpawner <ListMapGenContext, MapItem>(new LoopedRand <MapItem>(itemListSlice, ItemAmount[id])); IStepSpawner <ListMapGenContext, MapItem> treasures = ItemSpawners[id].Copy(); PresetMultiRand <IStepSpawner <ListMapGenContext, MapItem> > groupRand = new PresetMultiRand <IStepSpawner <ListMapGenContext, MapItem> >(constructedSpawns, treasures); RandomRoomSpawnStep <ListMapGenContext, MapItem> detourItems = ItemPlacements[id].Copy(); detourItems.Spawn = new MultiStepSpawner <ListMapGenContext, MapItem>(groupRand); queue.Enqueue(RewardPriority, detourItems); } } }
public override void Apply(ZoneGenContext zoneContext, IGenContext context, StablePriorityQueue <Priority, IGenStep> queue) { SpawnDict <string, SpawnList <InvItem> > spawns = new SpawnDict <string, SpawnList <InvItem> >(); //contains all LISTS that intersect the current ID foreach (string key in Spawns.Keys) { //get all items within the spawnrangelist that intersect the current ID SpawnList <InvItem> slicedList = Spawns[key].Spawns.GetSpawnList(zoneContext.CurrentID); // add the spawnlist under the current key, with the key having the spawnrate for this id if (slicedList.CanPick && Spawns[key].SpawnRates.ContainsItem(zoneContext.CurrentID) && Spawns[key].SpawnRates[zoneContext.CurrentID] > 0) { spawns.Add(key, slicedList, Spawns[key].SpawnRates[zoneContext.CurrentID]); } } ItemSpawnStep <BaseMapGenContext> spawnStep = new ItemSpawnStep <BaseMapGenContext>(); spawnStep.Spawns = spawns; queue.Enqueue(Priority, spawnStep); }
public static ConsoleKey PrintListRoomHalls(IGenContext map, string msg, bool printDebug, bool printViewer) { IFloorPlanGenContext context = map as IFloorPlanGenContext; if (context == null) { return(ConsoleKey.Enter); } StringBuilder str = new StringBuilder(); FloorPlan plan = context.RoomPlan; if (plan == null) { return(ConsoleKey.Enter); } for (int yy = 0; yy < plan.DrawRect.Bottom; yy++) { for (int xx = 0; xx < plan.DrawRect.Right; xx++) { str.Append(' '); } } for (int ii = 0; ii < plan.RoomCount; ii++) { char chosenChar = '@'; //if (ii < 26) chosenChar = (char)('A' + ii % 26); IRoomGen gen = plan.GetRoom(ii); for (int xx = gen.Draw.Left; xx < gen.Draw.Right; xx++) { for (int yy = gen.Draw.Top; yy < gen.Draw.Bottom; yy++) { int index = yy * plan.DrawRect.Right + xx; if (str[index] == ' ') { str[index] = chosenChar; } else { str[index] = '!'; } } } } for (int ii = 0; ii < plan.HallCount; ii++) { char chosenChar = '#'; //if (ii < 26) chosenChar = (char)('a' + ii % 26); IRoomGen gen = plan.GetHall(ii); for (int xx = gen.Draw.Left; xx < gen.Draw.Right; xx++) { for (int yy = gen.Draw.Top; yy < gen.Draw.Bottom; yy++) { int index = yy * plan.DrawRect.Right + xx; if (str[index] == ' ') { str[index] = chosenChar; } else if (str[index] >= 'a' && str[index] <= 'z' || str[index] == '#') { str[index] = '+'; } else { str[index] = '!'; } } } } for (int yy = plan.DrawRect.Bottom - 1; yy > 0; yy--) { str.Insert(plan.DrawRect.Right * yy, '\n'); } string newStr = str.ToString(); if (listDebugString[currentDepth].MapString == newStr) { return(ConsoleKey.Enter); } listDebugString[currentDepth].MapString = newStr; if (printDebug) { Debug.WriteLine(msg); Debug.Print(newStr); } if (printViewer) { SteppingIn = false; Console.Clear(); Console.WriteLine(msg); Loc start = new Loc(Console.CursorLeft, Console.CursorTop); Console.Write(newStr); Loc end = new Loc(Console.CursorLeft, Console.CursorTop + 1); Console.SetCursorPosition(start.X, start.Y); int prevFarthestPrint = end.Y; while (true) { int farthestPrint = end.Y; Loc mapLoc = new Loc(Console.CursorLeft, Console.CursorTop) - start; rewriteLine(farthestPrint, String.Format("X:{0} Y:{1}", mapLoc.X.ToString("D3"), mapLoc.Y.ToString("D3"))); farthestPrint++; for (int ii = 0; ii < plan.RoomCount; ii++) { FloorRoomPlan roomPlan = plan.GetRoomPlan(ii); if (roomPlan.RoomGen.Draw.Contains(mapLoc)) { //stats string roomString = String.Format("Room #{0}: {1}x{2} {3}", ii, roomPlan.RoomGen.Draw.X, roomPlan.RoomGen.Draw.Y, roomPlan.RoomGen.ToString()); rewriteLine(farthestPrint, roomString); farthestPrint++; string componentString = String.Format("Components: {0}", String.Join(", ", roomPlan.Components)); rewriteLine(farthestPrint, componentString); farthestPrint++; //borders StringBuilder lineString = new StringBuilder(" "); for (int xx = 0; xx < roomPlan.RoomGen.Draw.Width; xx++) { lineString.Append(roomPlan.RoomGen.GetFulfillableBorder(Dir4.Up, xx) ? "^" : " "); } rewriteLine(farthestPrint, lineString.ToString()); farthestPrint++; for (int yy = 0; yy < roomPlan.RoomGen.Draw.Height; yy++) { lineString = new StringBuilder(roomPlan.RoomGen.GetFulfillableBorder(Dir4.Left, yy) ? "<" : " "); for (int xx = 0; xx < roomPlan.RoomGen.Draw.Width; xx++) { lineString.Append("#"); } lineString.Append(roomPlan.RoomGen.GetFulfillableBorder(Dir4.Right, yy) ? ">" : " "); rewriteLine(farthestPrint, lineString.ToString()); farthestPrint++; } lineString = new StringBuilder(" "); for (int xx = 0; xx < roomPlan.RoomGen.Draw.Width; xx++) { lineString.Append(roomPlan.RoomGen.GetFulfillableBorder(Dir4.Down, xx) ? "V" : " "); } rewriteLine(farthestPrint, lineString.ToString()); farthestPrint++; } } for (int ii = 0; ii < plan.HallCount; ii++) { FloorHallPlan hallPlan = plan.GetHallPlan(ii); if (hallPlan.RoomGen.Draw.Contains(mapLoc)) { string roomString = String.Format("Hall #{0}: {1}x{2} {3}", ii, hallPlan.RoomGen.Draw.X, hallPlan.RoomGen.Draw.Y, hallPlan.RoomGen.ToString()); rewriteLine(farthestPrint, roomString); farthestPrint++; string componentString = String.Format("Components: {0}", String.Join(", ", hallPlan.Components)); rewriteLine(farthestPrint, componentString); farthestPrint++; } } for (int ii = farthestPrint; ii < prevFarthestPrint; ii++) { clearLine(ii); } prevFarthestPrint = farthestPrint; Console.SetCursorPosition(start.X + mapLoc.X, start.Y + mapLoc.Y); ConsoleKeyInfo key = Console.ReadKey(true); if (key.Key == ConsoleKey.UpArrow) { Console.SetCursorPosition(Console.CursorLeft, Math.Max(start.Y, Console.CursorTop - 1)); } else if (key.Key == ConsoleKey.DownArrow) { Console.SetCursorPosition(Console.CursorLeft, Math.Min(Console.CursorTop + 1, end.Y - 1)); } else if (key.Key == ConsoleKey.LeftArrow) { Console.SetCursorPosition(Math.Max(start.X, Console.CursorLeft - 1), Console.CursorTop); } else if (key.Key == ConsoleKey.RightArrow) { Console.SetCursorPosition(Math.Min(Console.CursorLeft + 1, end.X - 1), Console.CursorTop); } else { return(key.Key); } } } else { return(ConsoleKey.Enter); } }
public static ConsoleKey PrintGridRoomHalls(IGenContext map, string msg, bool printDebug, bool printViewer) { if (!(map is IRoomGridGenContext context)) { return(ConsoleKey.Enter); } var str = new StringBuilder(); GridPlan plan = context.GridPlan; if (plan == null) { return(ConsoleKey.Enter); } for (int yy = 0; yy < plan.GridHeight; yy++) { if (yy > 0) { str.Append('\n'); } for (int xx = 0; xx < plan.GridWidth; xx++) { int roomIndex = plan.GetRoomIndex(new Loc(xx, yy)); if (roomIndex == -1) { str.Append('0'); } else // if (roomIndex < 26) { str.Append((char)('A' + (roomIndex % 26))); } /* else * str.Append('@'); */ if (xx < plan.GridWidth - 1) { if (plan.GetHall(new LocRay4(xx, yy, Dir4.Right)) != null) { str.Append('#'); } else { str.Append('.'); } } } if (yy < plan.GridHeight - 1) { str.Append('\n'); for (int xx = 0; xx < plan.GridWidth; xx++) { if (plan.GetHall(new LocRay4(xx, yy, Dir4.Down)) != null) { str.Append('#'); } else { str.Append('.'); } if (xx < plan.GridWidth - 1) { str.Append(' '); } } } } string newStr = str.ToString(); if (gridDebugString[currentDepth].MapString == newStr) { return(ConsoleKey.Enter); } gridDebugString[currentDepth].MapString = newStr; if (printDebug) { Debug.WriteLine(msg); Debug.Print(newStr); } if (printViewer) { SteppingIn = false; Console.Clear(); Console.WriteLine(msg); Loc start = new Loc(Console.CursorLeft, Console.CursorTop); Console.Write(newStr); Loc end = new Loc(Console.CursorLeft, Console.CursorTop + 1); Console.SetCursorPosition(start.X, start.Y); int prevFarthestPrint = end.Y; while (true) { int farthestPrint = end.Y; Loc gridLoc = new Loc(Console.CursorLeft, Console.CursorTop) - start; Loc mapLoc = gridLoc / 2; RewriteLine(farthestPrint, $"X:{gridLoc.X / 2f:0.0} Y:{gridLoc.Y / 2f:0.0}"); farthestPrint++; bool alignX = gridLoc.X % 2 == 0; bool alignY = gridLoc.Y % 2 == 0; if (alignX && alignY) { int index = plan.GetRoomIndex(mapLoc); GridRoomPlan roomPlan = plan.GetRoomPlan(mapLoc); if (roomPlan != null) { string roomString = $"Room #{index}: {roomPlan.RoomGen}"; if (roomPlan.Immutable) { roomString += " [Immutable]"; } if (roomPlan.PreferHall) { roomString += " [Hall]"; } RewriteLine(farthestPrint, roomString); farthestPrint++; } } else if (alignX) { IPermissiveRoomGen hall = plan.GetHall(new LocRay4(mapLoc, Dir4.Down)); if (hall != null) { RewriteLine(farthestPrint, "Hall: " + hall); farthestPrint++; } } else if (alignY) { IPermissiveRoomGen hall = plan.GetHall(new LocRay4(mapLoc, Dir4.Right)); if (hall != null) { RewriteLine(farthestPrint, "Hall: " + hall); farthestPrint++; } } for (int ii = farthestPrint; ii < prevFarthestPrint; ii++) { ClearLine(ii); } prevFarthestPrint = farthestPrint; Console.SetCursorPosition(start.X + gridLoc.X, start.Y + gridLoc.Y); ConsoleKeyInfo key = Console.ReadKey(true); if (key.Key == ConsoleKey.UpArrow) { Console.SetCursorPosition(Console.CursorLeft, Math.Max(start.Y, Console.CursorTop - 1)); } else if (key.Key == ConsoleKey.DownArrow) { Console.SetCursorPosition(Console.CursorLeft, Math.Min(Console.CursorTop + 1, end.Y - 1)); } else if (key.Key == ConsoleKey.LeftArrow) { Console.SetCursorPosition(Math.Max(start.X, Console.CursorLeft - 1), Console.CursorTop); } else if (key.Key == ConsoleKey.RightArrow) { Console.SetCursorPosition(Math.Min(Console.CursorLeft + 1, end.X - 1), Console.CursorTop); } else { return(key.Key); } } } else { return(ConsoleKey.Enter); } }
public static void MapMenu(string prevState, int zoneIndex, SegLoc floorIndex, ZoneSegmentBase structure) { ulong zoneSeed = MathUtils.Rand.NextUInt64(); try { ulong newSeed; if (UInt64.TryParse((string)Registry.GetValue(DiagManager.REG_PATH, "SeedChoice", ""), out newSeed)) { zoneSeed = newSeed; } Registry.SetValue(DiagManager.REG_PATH, "SeedChoice", zoneSeed.ToString()); while (true) { Console.Clear(); ConsoleKey key = ConsoleKey.Enter; string state = prevState + ">" + floorIndex.ID + ": "; bool threwException = false; try { ZoneGenContext newContext = CreateZoneGenContext(zoneSeed, zoneIndex, floorIndex, structure); IGenContext context = structure.GetMap(newContext); ExampleDebug.SteppingIn = false; BaseMapGenContext stairsMap = context as BaseMapGenContext; state += stairsMap.Map.Name.DefaultText.Replace('\n', ' '); string seedMsg = "ZSeed: " + zoneSeed + " MSeed: " + newContext.Seed; //Console.WriteLine(state); key = ExampleDebug.PrintTiles(context, state + "\n" + "Arrow Keys=Navigate|Enter=Retry|ESC=Back|F2=Stress Test|F3=Custom Seed|F4=Step In" + "\n" + seedMsg, true, true, true); } catch (Exception ex) { DiagManager.Instance.LogInfo("ERROR at F" + floorIndex.ID + " SEED:" + zoneSeed); PrintError(ex); Console.WriteLine("Press Enter to retry error scenario."); key = Console.ReadKey().Key; threwException = true; } if (key == ConsoleKey.Escape) { Registry.SetValue(DiagManager.REG_PATH, "SeedChoice", ""); break; } else if (key == ConsoleKey.F2) { while (true) { Console.Clear(); Console.WriteLine(state + ">Bulk Gen"); Console.WriteLine("Specify amount to bulk gen"); int amt = GetInt(false); if (amt > -1) { Console.WriteLine("Generating floor " + amt + " times."); StressTestFloor(structure, zoneIndex, floorIndex, amt); ConsoleKeyInfo afterKey = Console.ReadKey(); if (afterKey.Key == ConsoleKey.Escape) { break; } } else if (amt == -1) { break; } } } else if (key == ConsoleKey.F3) { Console.Clear(); Console.WriteLine(state + ">Custom Seed"); Console.WriteLine("Specify a ZONE seed value"); string input = Console.ReadLine(); ulong customSeed; if (UInt64.TryParse(input, out customSeed)) { zoneSeed = customSeed; } } else if (key == ConsoleKey.F4) { ExampleDebug.SteppingIn = true; } else if (key == ConsoleKey.Enter) { if (!threwException) { zoneSeed = MathUtils.Rand.NextUInt64(); } } Registry.SetValue(DiagManager.REG_PATH, "SeedChoice", zoneSeed.ToString()); } } catch (Exception ex) { DiagManager.Instance.LogInfo("ERROR at F" + floorIndex.ID + " ZSEED:" + zoneSeed); PrintError(ex); Registry.SetValue(DiagManager.REG_PATH, "SeedChoice", ""); Console.ReadKey(); } }
public override void Apply(ZoneGenContext zoneContext, IGenContext context, StablePriorityQueue <Priority, IGenStep> queue) { RandRange amount = new RandRange(chosenStart + chosenAdd * zoneContext.CurrentID); queue.Enqueue(Priority, new MoneySpawnStep <BaseMapGenContext>(amount)); }
public override bool CheckIfDistributed(ZoneGenContext zoneContext, IGenContext context) { return(FloorRange.Contains(zoneContext.CurrentID) && context.Rand.Next(100) < Chance); }
public abstract void Apply(ZoneGenContext zoneContext, IGenContext context, StablePriorityQueue <Priority, IGenStep> queue);
public static ConsoleKey PrintGridRoomHalls(IGenContext map, string msg, bool printDebug, bool printViewer) { IRoomGridGenContext context = map as IRoomGridGenContext; if (context == null) { return(ConsoleKey.Enter); } StringBuilder str = new StringBuilder(); GridPlan plan = context.GridPlan; if (plan == null) { return(ConsoleKey.Enter); } for (int yy = 0; yy < plan.GridHeight; yy++) { if (yy > 0) { str.Append('\n'); } for (int xx = 0; xx < plan.GridWidth; xx++) { int roomIndex = plan.GetRoomIndex(new Loc(xx, yy)); if (roomIndex == -1) { str.Append('0'); } else// if (roomIndex < 26) { str.Append((char)('A' + roomIndex % 26)); } //else // str.Append('@'); if (xx < plan.GridWidth - 1) { if (plan.GetHall(new LocRay4(xx, yy, Dir4.Right)) != null) { str.Append('#'); } else { str.Append('.'); } } } if (yy < plan.GridHeight - 1) { str.Append('\n'); for (int xx = 0; xx < plan.GridWidth; xx++) { if (plan.GetHall(new LocRay4(xx, yy, Dir4.Down)) != null) { str.Append('#'); } else { str.Append('.'); } if (xx < plan.GridWidth - 1) { str.Append(' '); } } } } string newStr = str.ToString(); if (gridDebugString[currentDepth].MapString == newStr) { return(ConsoleKey.Enter); } gridDebugString[currentDepth].MapString = newStr; if (printDebug) { Debug.WriteLine(msg); Debug.Print(newStr); } if (printViewer) { SteppingIn = false; Console.Clear(); Console.WriteLine(msg); Loc start = new Loc(Console.CursorLeft, Console.CursorTop); Console.Write(newStr); Loc end = new Loc(Console.CursorLeft, Console.CursorTop + 1); Console.SetCursorPosition(start.X, start.Y); int prevFarthestPrint = end.Y; while (true) { int farthestPrint = end.Y; Loc gridLoc = new Loc(Console.CursorLeft, Console.CursorTop) - start; Loc mapLoc = gridLoc / 2; rewriteLine(farthestPrint, String.Format("X:{0:0.0} Y:{1:0.0}", ((float)gridLoc.X / 2), ((float)gridLoc.Y / 2))); farthestPrint++; bool alignX = gridLoc.X % 2 == 0; bool alignY = gridLoc.Y % 2 == 0; if (alignX && alignY) { int index = plan.GetRoomIndex(mapLoc); GridRoomPlan roomPlan = plan.GetRoomPlan(mapLoc); if (roomPlan != null) { string roomString = String.Format("Room #{0}: {1}", index, roomPlan.RoomGen.ToString()); if (roomPlan.PreferHall) { roomString += " [Hall]"; } rewriteLine(farthestPrint, roomString); farthestPrint++; string componentString = String.Format("Components: {0}", String.Join(", ", roomPlan.Components)); rewriteLine(farthestPrint, componentString); farthestPrint++; } } else if (alignX) { GridHallPlan hall = plan.GetHall(new LocRay4(mapLoc, Dir4.Down)); if (hall != null) { rewriteLine(farthestPrint, "Hall: " + hall.RoomGen.ToString()); farthestPrint++; string componentString = String.Format("Components: {0}", String.Join(", ", hall.Components)); rewriteLine(farthestPrint, componentString); farthestPrint++; } } else if (alignY) { GridHallPlan hall = plan.GetHall(new LocRay4(mapLoc, Dir4.Right)); if (hall != null) { rewriteLine(farthestPrint, "Hall: " + hall.RoomGen.ToString()); farthestPrint++; } } for (int ii = farthestPrint; ii < prevFarthestPrint; ii++) { clearLine(ii); } prevFarthestPrint = farthestPrint; Console.SetCursorPosition(start.X + gridLoc.X, start.Y + gridLoc.Y); ConsoleKeyInfo key = Console.ReadKey(true); if (key.Key == ConsoleKey.UpArrow) { Console.SetCursorPosition(Console.CursorLeft, Math.Max(start.Y, Console.CursorTop - 1)); } else if (key.Key == ConsoleKey.DownArrow) { Console.SetCursorPosition(Console.CursorLeft, Math.Min(Console.CursorTop + 1, end.Y - 1)); } else if (key.Key == ConsoleKey.LeftArrow) { Console.SetCursorPosition(Math.Max(start.X, Console.CursorLeft - 1), Console.CursorTop); } else if (key.Key == ConsoleKey.RightArrow) { Console.SetCursorPosition(Math.Min(Console.CursorLeft + 1, end.X - 1), Console.CursorTop); } else { return(key.Key); } } } else { return(ConsoleKey.Enter); } }
public static ConsoleKey PrintListRoomHalls(IGenContext map, string msg, bool printDebug, bool printViewer) { if (!(map is IFloorPlanGenContext context)) { return(ConsoleKey.Enter); } var str = new StringBuilder(); FloorPlan plan = context.RoomPlan; if (plan == null) { return(ConsoleKey.Enter); } for (int yy = 0; yy < plan.DrawRect.Bottom; yy++) { for (int xx = 0; xx < plan.DrawRect.Right; xx++) { str.Append(' '); } } for (int ii = 0; ii < plan.RoomCount; ii++) { char chosenChar = (char)('A' + (ii % 26)); IRoomGen gen = plan.GetRoom(ii); for (int xx = gen.Draw.Left; xx < gen.Draw.Right; xx++) { for (int yy = gen.Draw.Top; yy < gen.Draw.Bottom; yy++) { int index = (yy * plan.DrawRect.Right) + xx; if (str[index] == ' ') { str[index] = chosenChar; } else { str[index] = '!'; } } } } for (int ii = 0; ii < plan.HallCount; ii++) { char chosenChar = (char)('a' + (ii % 26)); IRoomGen gen = plan.GetHall(ii); for (int xx = gen.Draw.Left; xx < gen.Draw.Right; xx++) { for (int yy = gen.Draw.Top; yy < gen.Draw.Bottom; yy++) { int index = (yy * plan.DrawRect.Right) + xx; if (str[index] == ' ') { str[index] = chosenChar; } else if ((str[index] >= 'a' && str[index] <= 'z') || str[index] == '#') { str[index] = '+'; } else { str[index] = '!'; } } } } for (int yy = plan.DrawRect.Bottom - 1; yy > 0; yy--) { str.Insert(plan.DrawRect.Right * yy, '\n'); } string newStr = str.ToString(); if (listDebugString[currentDepth].MapString == newStr) { return(ConsoleKey.Enter); } listDebugString[currentDepth].MapString = newStr; if (printDebug) { Debug.WriteLine(msg); Debug.Print(newStr); } if (printViewer) { SteppingIn = false; Console.Clear(); Console.WriteLine(msg); Loc start = new Loc(Console.CursorLeft, Console.CursorTop); Console.Write(newStr); Loc end = new Loc(Console.CursorLeft, Console.CursorTop + 1); Console.SetCursorPosition(start.X, start.Y); int prevFarthestPrint = end.Y; while (true) { int farthestPrint = end.Y; Loc mapLoc = new Loc(Console.CursorLeft, Console.CursorTop) - start; RewriteLine(farthestPrint, $"X:{mapLoc.X:D3} Y:{mapLoc.Y:D3}"); farthestPrint++; for (int ii = 0; ii < plan.RoomCount; ii++) { FloorRoomPlan roomPlan = plan.GetRoomPlan(ii); if (roomPlan.RoomGen.Draw.Contains(mapLoc)) { // stats string roomString = $"Room #{ii}: {roomPlan.RoomGen.Draw.X}x{roomPlan.RoomGen.Draw.Y} {roomPlan.RoomGen}"; if (roomPlan.Immutable) { roomString += " [Immutable]"; } RewriteLine(farthestPrint, roomString); farthestPrint++; // borders var lineString = new StringBuilder(" "); for (int xx = 0; xx < roomPlan.RoomGen.Draw.Width; xx++) { lineString.Append(roomPlan.RoomGen.GetFulfillableBorder(Dir4.Up, xx) ? "^" : " "); } RewriteLine(farthestPrint, lineString.ToString()); farthestPrint++; for (int yy = 0; yy < roomPlan.RoomGen.Draw.Height; yy++) { lineString = new StringBuilder(roomPlan.RoomGen.GetFulfillableBorder(Dir4.Left, yy) ? "<" : " "); for (int xx = 0; xx < roomPlan.RoomGen.Draw.Width; xx++) { lineString.Append("#"); } lineString.Append(roomPlan.RoomGen.GetFulfillableBorder(Dir4.Right, yy) ? ">" : " "); RewriteLine(farthestPrint, lineString.ToString()); farthestPrint++; } lineString = new StringBuilder(" "); for (int xx = 0; xx < roomPlan.RoomGen.Draw.Width; xx++) { lineString.Append(roomPlan.RoomGen.GetFulfillableBorder(Dir4.Down, xx) ? "V" : " "); } RewriteLine(farthestPrint, lineString.ToString()); farthestPrint++; } } for (int ii = 0; ii < plan.HallCount; ii++) { IPermissiveRoomGen gen = plan.GetHall(ii); if (gen.Draw.Contains(mapLoc)) { string roomString = $"Hall #{ii}: {gen.Draw.X}x{gen.Draw.Y} {gen}"; RewriteLine(farthestPrint, roomString); farthestPrint++; } } for (int ii = farthestPrint; ii < prevFarthestPrint; ii++) { ClearLine(ii); } prevFarthestPrint = farthestPrint; Console.SetCursorPosition(start.X + mapLoc.X, start.Y + mapLoc.Y); ConsoleKeyInfo key = Console.ReadKey(true); if (key.Key == ConsoleKey.UpArrow) { Console.SetCursorPosition(Console.CursorLeft, Math.Max(start.Y, Console.CursorTop - 1)); } else if (key.Key == ConsoleKey.DownArrow) { Console.SetCursorPosition(Console.CursorLeft, Math.Min(Console.CursorTop + 1, end.Y - 1)); } else if (key.Key == ConsoleKey.LeftArrow) { Console.SetCursorPosition(Math.Max(start.X, Console.CursorLeft - 1), Console.CursorTop); } else if (key.Key == ConsoleKey.RightArrow) { Console.SetCursorPosition(Math.Min(Console.CursorLeft + 1, end.X - 1), Console.CursorTop); } else { return(key.Key); } } } else { return(ConsoleKey.Enter); } }
public override void Apply(ZoneGenContext zoneContext, IGenContext context, StablePriorityQueue <Priority, IGenStep> queue) { queue.Enqueue(Priority, new MapNameIDStep <BaseMapGenContext>(zoneContext.CurrentID, LocalText.FormatLocalText(Name, (zoneContext.CurrentID + 1).ToString()))); }
public static ConsoleKey PrintTiles(IGenContext map, string msg, bool printDebug, bool printViewer, bool forcePrint) { BaseMapGenContext context = map as BaseMapGenContext; StairsMapGenContext stairsContext = map as StairsMapGenContext; if (context == null) { return(ConsoleKey.Enter); } if (!context.TilesInitialized) { return(ConsoleKey.Enter); } StringBuilder str = new StringBuilder(); for (int yy = 0; yy < context.Height; yy++) { if (yy > 0) { str.Append('\n'); } for (int xx = 0; xx < context.Width; xx++) { Loc loc = new Loc(xx, yy); char tileChar = ' '; Tile tile = (Tile)context.GetTile(loc); if (tile.ID <= 0)//floor { tileChar = '.'; } else if (tile.ID == 1)//unbreakable { tileChar = 'X'; } else if (tile.ID == 2)//wall { tileChar = '#'; } else if (tile.ID == 3)//water { tileChar = '~'; } else if (tile.ID == 4)//lava { tileChar = '^'; } else if (tile.ID == 5)//abyss { tileChar = '_'; } else { tileChar = '?'; } if (tile.Effect.ID > -1)//traps always override { tileChar = '='; } if (stairsContext != null) { for (int ii = 0; ii < ((IViewPlaceableGenContext <MapGenEntrance>)stairsContext).Count; ii++) { if (((IViewPlaceableGenContext <MapGenEntrance>)stairsContext).GetLoc(ii) == loc) { tileChar = '<'; break; } } for (int ii = 0; ii < ((IViewPlaceableGenContext <MapGenExit>)stairsContext).Count; ii++) { if (((IViewPlaceableGenContext <MapGenExit>)stairsContext).GetLoc(ii) == loc) { tileChar = '>'; break; } } } foreach (MapItem item in context.Map.Items) { if (item.TileLoc == loc) { if (item.IsMoney) { tileChar = '*'; } else { ItemData itemEntry = DataManager.Instance.GetItem(item.Value); if (itemEntry.ItemStates.Contains <FoodState>()) { tileChar = ';'; } else if (itemEntry.ItemStates.Contains <EdibleState>()) { tileChar = '!'; } else if (itemEntry.ItemStates.Contains <OrbState>() || itemEntry.ItemStates.Contains <WandState>()) { tileChar = '/'; } else if (itemEntry.ItemStates.Contains <RecruitState>()) { tileChar = '?'; } else if (itemEntry.UsageType == ItemData.UseType.Learn || itemEntry.ItemStates.Contains <UtilityState>() || itemEntry.ItemStates.Contains <MachineState>()) { tileChar = '%'; } else { tileChar = '$'; } } break; } } foreach (Team team in context.Map.MapTeams) { foreach (Character character in team.Players) { if (character.CharLoc == loc) { tileChar = character.Name[0]; break; } } } str.Append(tileChar); } } string newStr = str.ToString(); if (tileDebugString[currentDepth].MapString == newStr && !forcePrint) { return(ConsoleKey.Enter); } tileDebugString[currentDepth].MapString = newStr; if (printDebug) { Debug.WriteLine(msg); Debug.Print(newStr); } if (printViewer) { //TODO: print with highlighting (use the bounds variable) //TODO: print with color SteppingIn = false; Console.Clear(); Console.WriteLine(msg); Loc start = new Loc(Console.CursorLeft, Console.CursorTop); Console.Write(newStr); Loc end = new Loc(Console.CursorLeft, Console.CursorTop + 1); Console.SetCursorPosition(start.X, start.Y); int prevFarthestPrint = end.Y; while (true) { int farthestPrint = end.Y; Loc mapLoc = new Loc(Console.CursorLeft, Console.CursorTop) - start; rewriteLine(farthestPrint, String.Format("X:{0} Y:{1}", mapLoc.X.ToString("D3"), mapLoc.Y.ToString("D3"))); farthestPrint++; Tile tile = context.Tiles[mapLoc.X][mapLoc.Y]; rewriteLine(farthestPrint, String.Format("Terrain {0}: {1}", tile.Data.GetID(), tile.Data.GetID() > -1 ? tile.Data.GetData().Name.ToLocal() : "---")); farthestPrint++; rewriteLine(farthestPrint, String.Format("Tile {0}: {1}", tile.Effect.GetID(), tile.Effect.GetID() > -1 ? tile.Effect.GetData().Name.ToLocal() : "---")); farthestPrint++; for (int ii = 0; ii < context.Map.EntryPoints.Count; ii++) { if (context.Map.EntryPoints[ii].Loc == mapLoc) { rewriteLine(farthestPrint, String.Format("***Entrance {0}***", ii)); farthestPrint++; } } foreach (MapItem item in context.Map.Items) { if (item.TileLoc == mapLoc) { if (item.IsMoney) { rewriteLine(farthestPrint, String.Format("Money: {0}", item.Value)); } else { rewriteLine(farthestPrint, String.Format("Item: {0}", item.GetDungeonName().Replace("\u000D7", "(X)"))); } farthestPrint++; } } foreach (Team team in context.Map.MapTeams) { foreach (Character character in team.Players) { if (character.CharLoc == mapLoc) { rewriteLine(farthestPrint, String.Format("Monster:")); farthestPrint++; string nameString = String.Format(" Lv.{0} {1} ", character.Level, character.BaseName); foreach (int status in character.StatusEffects.Keys) { nameString += String.Format("[{0}]", ((StatusData)character.StatusEffects[status].GetData()).Name.ToLocal()); } rewriteLine(farthestPrint, nameString); farthestPrint++; rewriteLine(farthestPrint, String.Format(" @{0} *{1} ?{2}", character.EquippedItem.ID > -1 ? ((ItemData)character.EquippedItem.GetData()).Name.ToLocal() : "---", character.Intrinsics[0].Element.ID > -1 ? ((IntrinsicData)character.Intrinsics[0].Element.GetData()).Name.ToLocal() : "---", character.Tactic.Name)); farthestPrint++; rewriteLine(farthestPrint, String.Format(" {0}{1} {2}{3} {4}{5} {6}{7}", character.Skills[0].Element.Enabled ? "+" : "-", character.BaseSkills[0].SkillNum > -1 ? DataManager.Instance.GetSkill(character.Skills[0].Element.SkillNum).Name.ToLocal() : "---", character.Skills[1].Element.Enabled ? "+" : "-", character.BaseSkills[1].SkillNum > -1 ? DataManager.Instance.GetSkill(character.Skills[1].Element.SkillNum).Name.ToLocal() : "---", character.Skills[2].Element.Enabled ? "+" : "-", character.BaseSkills[2].SkillNum > -1 ? DataManager.Instance.GetSkill(character.Skills[2].Element.SkillNum).Name.ToLocal() : "---", character.Skills[3].Element.Enabled ? "+" : "-", character.BaseSkills[3].SkillNum > -1 ? DataManager.Instance.GetSkill(character.Skills[3].Element.SkillNum).Name.ToLocal() : "---")); farthestPrint++; } } } for (int ii = farthestPrint; ii < prevFarthestPrint; ii++) { clearLine(ii); } prevFarthestPrint = farthestPrint; Console.SetCursorPosition(start.X + mapLoc.X, start.Y + mapLoc.Y); ConsoleKeyInfo key = Console.ReadKey(true); if (key.Key == ConsoleKey.UpArrow) { Console.SetCursorPosition(Console.CursorLeft, Math.Max(start.Y, Console.CursorTop - 1)); } else if (key.Key == ConsoleKey.DownArrow) { Console.SetCursorPosition(Console.CursorLeft, Math.Min(Console.CursorTop + 1, end.Y - 1)); } else if (key.Key == ConsoleKey.LeftArrow) { Console.SetCursorPosition(Math.Max(start.X, Console.CursorLeft - 1), Console.CursorTop); } else if (key.Key == ConsoleKey.RightArrow) { Console.SetCursorPosition(Math.Min(Console.CursorLeft + 1, end.X - 1), Console.CursorTop); } else { return(key.Key); } } } else { return(ConsoleKey.Enter); } }
public override bool CheckIfDistributed(ZoneGenContext zoneContext, IGenContext context) { return(dropPoints.Contains(zoneContext.CurrentID)); }
public abstract bool CheckIfDistributed(ZoneGenContext zoneContext, IGenContext context);
public bool CanApply(IGenContext context) { return(context is T); }
public static ConsoleKey PrintTiles(IGenContext map, string msg, bool printDebug, bool printViewer) { if (!(map is ITiledGenContext context)) { return(ConsoleKey.Enter); } if (!context.TilesInitialized) { return(ConsoleKey.Enter); } var str = new StringBuilder(); for (int yy = 0; yy < context.Height; yy++) { if (yy > 0) { str.Append('\n'); } for (int xx = 0; xx < context.Width; xx++) { if (context.GetTile(new Loc(xx, yy)).TileEquivalent(context.RoomTerrain)) { str.Append('.'); } else if (context.GetTile(new Loc(xx, yy)).TileEquivalent(context.WallTerrain)) { str.Append('#'); } else { if (context.TileBlocked(new Loc(xx, yy))) { str.Append('+'); } else { str.Append('_'); } } } } string newStr = str.ToString(); if (tileDebugString[currentDepth].MapString == newStr) { return(ConsoleKey.Enter); } tileDebugString[currentDepth].MapString = newStr; if (printDebug) { Debug.WriteLine(msg); Debug.Print(newStr); } if (printViewer) { // TODO: print with highlighting (use the bounds variable) // TODO: print with color SteppingIn = false; Console.Clear(); Console.WriteLine(msg); Loc start = new Loc(Console.CursorLeft, Console.CursorTop); Console.Write(newStr); Loc end = new Loc(Console.CursorLeft, Console.CursorTop + 1); Console.SetCursorPosition(start.X, start.Y); int prevFarthestPrint = end.Y; while (true) { int farthestPrint = end.Y; Loc mapLoc = new Loc(Console.CursorLeft, Console.CursorTop) - start; RewriteLine(farthestPrint, $"X:{mapLoc.X:D3} Y:{mapLoc.Y:D3}"); farthestPrint++; ITile tile = context.GetTile(mapLoc); RewriteLine(farthestPrint, $"Tile: {tile}"); farthestPrint++; for (int ii = farthestPrint; ii < prevFarthestPrint; ii++) { ClearLine(ii); } prevFarthestPrint = farthestPrint; Console.SetCursorPosition(start.X + mapLoc.X, start.Y + mapLoc.Y); ConsoleKeyInfo key = Console.ReadKey(true); if (key.Key == ConsoleKey.UpArrow) { Console.SetCursorPosition(Console.CursorLeft, Math.Max(start.Y, Console.CursorTop - 1)); } else if (key.Key == ConsoleKey.DownArrow) { Console.SetCursorPosition(Console.CursorLeft, Math.Min(Console.CursorTop + 1, end.Y - 1)); } else if (key.Key == ConsoleKey.LeftArrow) { Console.SetCursorPosition(Math.Max(start.X, Console.CursorLeft - 1), Console.CursorTop); } else if (key.Key == ConsoleKey.RightArrow) { Console.SetCursorPosition(Math.Min(Console.CursorLeft + 1, end.X - 1), Console.CursorTop); } else { return(key.Key); } } } else { return(ConsoleKey.Enter); } }