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 static void StressTestFloor(ZoneSegmentBase structure, int zoneIndex, SegLoc floorIndex, int amount) { ExampleDebug.Printing = -1; ulong zoneSeed = 0; try { Dictionary <int, int> generatedItems = new Dictionary <int, int>(); Dictionary <int, int> generatedEnemies = new Dictionary <int, int>(); List <TimeSpan> generationTimes = new List <TimeSpan>(); Stopwatch watch = new Stopwatch(); for (int ii = 0; ii < amount; ii++) { zoneSeed = MathUtils.Rand.NextUInt64(); ZoneGenContext zoneContext = CreateZoneGenContext(zoneSeed, zoneIndex, floorIndex, structure); TestFloor(watch, structure, zoneContext, generatedItems, generatedEnemies, generationTimes); } PrintContentAnalysis(generatedItems, generatedEnemies); PrintTimeAnalysis(generationTimes); } catch (Exception ex) { DiagManager.Instance.LogInfo("ERROR: " + zoneSeed); PrintError(ex); } finally { ExampleDebug.Printing = 0; } }
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 static void StressTestZone(ZoneData zone, int zoneIndex, int amount) { ExampleDebug.Printing = -1; int structureIndex = 0; ulong zoneSeed = 0; int floor = 0; try { List <List <TimeSpan> > generationTimes = new List <List <TimeSpan> >(); for (int ii = 0; ii < zone.Segments.Count; ii++) { generationTimes.Add(new List <TimeSpan>()); } Stopwatch watch = new Stopwatch(); for (int ii = 0; ii < amount; ii++) { zoneSeed = MathUtils.Rand.NextUInt64(); ReNoise totalNoise = new ReNoise(zoneSeed); for (int nn = 0; nn < zone.Segments.Count; nn++) { structureIndex = nn; ZoneSegmentBase structure = zone.Segments[nn]; ulong[] doubleSeed = totalNoise.GetTwoUInt64((ulong)structureIndex); ZoneGenContext zoneContext = CreateZoneGenContextSegment(doubleSeed[0], zoneIndex, structureIndex, structure); INoise idNoise = new ReNoise(doubleSeed[1]); foreach (int floorId in structure.GetFloorIDs()) { floor = floorId; zoneContext.CurrentID = floorId; zoneContext.Seed = idNoise.GetUInt64((ulong)floorId); TestFloor(watch, structure, zoneContext, null, null, generationTimes[nn]); } } } PrintTimeAnalysisTier2(generationTimes, "S"); } catch (Exception ex) { DiagManager.Instance.LogInfo("ERROR at S" + structureIndex + " F" + floor + " ZSeed:" + zoneSeed); PrintError(ex); } finally { ExampleDebug.Printing = 0; } }
public Map GetMap(SegLoc id) { if (!maps.ContainsKey(id)) { //NOTE: with the way this is currently done, the random numbers used by the maps end up being related to the random numbers used by the postprocs //not that anyone would really notice... ReRandom totalRand = new ReRandom(rand.FirstSeed); for (int ii = 0; ii < id.Segment; ii++) { totalRand.NextUInt64(); } ulong structSeed = totalRand.NextUInt64(); DiagManager.Instance.LogInfo("Struct Seed: " + structSeed); ReRandom structRand = new ReRandom(structSeed); for (int ii = 0; ii < id.ID; ii++) { structRand.NextUInt64(); } ulong mapSeed = structRand.NextUInt64(); //load the struct context if it isn't present yet if (!structureContexts.ContainsKey(id.Segment)) { ReRandom initRand = new ReRandom(structSeed); ZoneGenContext newContext = new ZoneGenContext(); newContext.CurrentZone = zoneIndex; newContext.CurrentSegment = id.Segment; foreach (ZonePostProc zoneStep in Structures[id.Segment].PostProcessingSteps) { //TODO: find a better way to feed ZonePostProcs into full structures. //Is there a way for them to be stateless? //Additionally, the ZonePostProcs themselves sometimes hold IGenSteps that are copied over to the layouts. //Is that really OK? (I would guess yes because there is no chance by design for them to be mutated when generating...) ZonePostProc newStep = zoneStep.Instantiate(initRand.NextUInt64()); newContext.ZoneSteps.Add(newStep); } structureContexts[id.Segment] = newContext; } ZoneGenContext zoneContext = structureContexts[id.Segment]; zoneContext.CurrentID = id.ID; zoneContext.Seed = mapSeed; //TODO: remove the need for this explicit cast //make a parameterized version of zonestructure and then make zonestructure itself put in basemapgencontext as the parameter Map map = ((BaseMapGenContext)Structures[id.Segment].GetMap(zoneContext)).Map; //uncomment this to cache the state of every map after its generation. it's not nice on memory though... //maps.Add(id, map); return(map); } return(maps[id]); }
public static ZoneGenContext CreateZoneGenContext(ulong zoneSeed, int zoneIndex, SegLoc floorIndex, ZoneSegmentBase structure) { ReNoise totalNoise = new ReNoise(zoneSeed); ulong[] doubleSeed = totalNoise.GetTwoUInt64((ulong)floorIndex.Segment); ZoneGenContext newContext = CreateZoneGenContextSegment(doubleSeed[0], zoneIndex, floorIndex.Segment, structure); INoise idNoise = new ReNoise(doubleSeed[1]); newContext.CurrentID = floorIndex.ID; newContext.Seed = idNoise.GetUInt64((ulong)floorIndex.ID); return(newContext); }
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 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 ZoneGenContext CreateZoneGenContextSegment(ulong structSeed, int zoneIndex, int structureIndex, ZoneSegmentBase structure) { INoise structNoise = new ReNoise(structSeed); ZoneGenContext newContext = new ZoneGenContext(); newContext.CurrentZone = zoneIndex; newContext.CurrentSegment = structureIndex; foreach (ZoneStep zoneStep in structure.ZoneSteps) { //TODO: find a better way to feed ZoneSteps into full zone segments. //Is there a way for them to be stateless? //Additionally, the ZoneSteps themselves sometimes hold IGenSteps that are copied over to the layouts. //Is that really OK? (I would guess yes because there is no chance by design for them to be mutated when generating...) ZoneStep newStep = zoneStep.Instantiate(structNoise.GetUInt64((ulong)newContext.ZoneSteps.Count)); newContext.ZoneSteps.Add(newStep); } return(newContext); }
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 static void StressTestStructure(ZoneSegmentBase structure, int zoneIndex, int structureIndex, int amount) { ExampleDebug.Printing = -1; ulong zoneSeed = 0; int floor = 0; try { List <Dictionary <int, int> > generatedItems = new List <Dictionary <int, int> >(); List <Dictionary <int, int> > generatedEnemies = new List <Dictionary <int, int> >(); List <List <TimeSpan> > generationTimes = new List <List <TimeSpan> >(); for (int ii = 0; ii < structure.FloorCount; ii++) { generatedItems.Add(new Dictionary <int, int>()); generatedEnemies.Add(new Dictionary <int, int>()); generationTimes.Add(new List <TimeSpan>()); } Stopwatch watch = new Stopwatch(); for (int ii = 0; ii < amount; ii++) { zoneSeed = MathUtils.Rand.NextUInt64(); ReNoise totalNoise = new ReNoise(zoneSeed); ulong[] doubleSeed = totalNoise.GetTwoUInt64((ulong)structureIndex); INoise idNoise = new ReNoise(doubleSeed[1]); ZoneGenContext zoneContext = CreateZoneGenContextSegment(doubleSeed[0], zoneIndex, structureIndex, structure); foreach (int floorId in structure.GetFloorIDs()) { floor = floorId; zoneContext.CurrentID = floorId; zoneContext.Seed = idNoise.GetUInt64((ulong)floorId); TestFloor(watch, structure, zoneContext, generatedItems[floorId], generatedEnemies[floorId], generationTimes[floorId]); } } Dictionary <int, int> totalGeneratedItems = new Dictionary <int, int>(); Dictionary <int, int> totalGeneratedEnemies = new Dictionary <int, int>(); for (int ii = 0; ii < structure.FloorCount; ii++) { DiagManager.Instance.LogInfo("F" + ii + ":"); PrintContentAnalysis(generatedItems[ii], generatedEnemies[ii]); foreach (int key in generatedItems[ii].Keys) { MathUtils.AddToDictionary <int>(totalGeneratedItems, key, generatedItems[ii][key]); } foreach (int key in generatedEnemies[ii].Keys) { MathUtils.AddToDictionary <int>(totalGeneratedEnemies, key, generatedEnemies[ii][key]); } } DiagManager.Instance.LogInfo("Overall:"); PrintContentAnalysis(totalGeneratedItems, totalGeneratedEnemies); PrintTimeAnalysisTier2(generationTimes, "F"); } catch (Exception ex) { DiagManager.Instance.LogInfo("ERROR at F" + floor + " ZSeed:" + zoneSeed); PrintError(ex); } finally { ExampleDebug.Printing = 0; } }
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(); } }